Procházet zdrojové kódy

ncd: NCDConfigTokenizer: remove the 128 characters limit on strings

ambrop7 před 14 roky
rodič
revize
d35acc0b4f

+ 1 - 0
blog_channels.txt

@@ -77,6 +77,7 @@ SPProtoDecoder 4
 LineBuffer 4
 BTap 4
 lwip 4
+NCDConfigTokenizer 4
 NCDConfigParser 4
 nsskey 4
 addr 4

+ 2 - 0
examples/ncd_tokenizer_test.c

@@ -68,9 +68,11 @@ static int tokenizer_output (void *user, int token, char *value, size_t pos)
             break;
         case NCD_TOKEN_NAME:
             printf("name %s\n", value);
+            free(value);
             break;
         case NCD_TOKEN_STRING:
             printf("string %s\n", value);
+            free(value);
             break;
         default:
             ASSERT(0);

+ 4 - 0
generated/blog_channel_NCDConfigTokenizer.h

@@ -0,0 +1,4 @@
+#ifdef BLOG_CURRENT_CHANNEL
+#undef BLOG_CURRENT_CHANNEL
+#endif
+#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDConfigTokenizer

+ 17 - 16
generated/blog_channels_defines.h

@@ -77,19 +77,20 @@
 #define BLOG_CHANNEL_LineBuffer 76
 #define BLOG_CHANNEL_BTap 77
 #define BLOG_CHANNEL_lwip 78
-#define BLOG_CHANNEL_NCDConfigParser 79
-#define BLOG_CHANNEL_nsskey 80
-#define BLOG_CHANNEL_addr 81
-#define BLOG_CHANNEL_PasswordListener 82
-#define BLOG_CHANNEL_NCDInterfaceMonitor 83
-#define BLOG_CHANNEL_NCDRfkillMonitor 84
-#define BLOG_CHANNEL_udpgw 85
-#define BLOG_CHANNEL_UdpGwClient 86
-#define BLOG_CHANNEL_SocksUdpGwClient 87
-#define BLOG_CHANNEL_BNetwork 88
-#define BLOG_CHANNEL_BConnection 89
-#define BLOG_CHANNEL_BSSLConnection 90
-#define BLOG_CHANNEL_BDatagram 91
-#define BLOG_CHANNEL_PeerChat 92
-#define BLOG_CHANNEL_BArpProbe 93
-#define BLOG_NUM_CHANNELS 94
+#define BLOG_CHANNEL_NCDConfigTokenizer 79
+#define BLOG_CHANNEL_NCDConfigParser 80
+#define BLOG_CHANNEL_nsskey 81
+#define BLOG_CHANNEL_addr 82
+#define BLOG_CHANNEL_PasswordListener 83
+#define BLOG_CHANNEL_NCDInterfaceMonitor 84
+#define BLOG_CHANNEL_NCDRfkillMonitor 85
+#define BLOG_CHANNEL_udpgw 86
+#define BLOG_CHANNEL_UdpGwClient 87
+#define BLOG_CHANNEL_SocksUdpGwClient 88
+#define BLOG_CHANNEL_BNetwork 89
+#define BLOG_CHANNEL_BConnection 90
+#define BLOG_CHANNEL_BSSLConnection 91
+#define BLOG_CHANNEL_BDatagram 92
+#define BLOG_CHANNEL_PeerChat 93
+#define BLOG_CHANNEL_BArpProbe 94
+#define BLOG_NUM_CHANNELS 95

+ 1 - 0
generated/blog_channels_list.h

@@ -77,6 +77,7 @@
 {.name = "LineBuffer", .loglevel = 4},
 {.name = "BTap", .loglevel = 4},
 {.name = "lwip", .loglevel = 4},
+{.name = "NCDConfigTokenizer", .loglevel = 4},
 {.name = "NCDConfigParser", .loglevel = 4},
 {.name = "nsskey", .loglevel = 4},
 {.name = "addr", .loglevel = 4},

+ 2 - 14
ncd/NCDConfigParser.c

@@ -100,23 +100,11 @@ static int tokenizer_output (void *user, int token, char *value, size_t position
         } break;
         
         case NCD_TOKEN_NAME: {
-            char *v = malloc(strlen(value) + 1);
-            if (!v) {
-                state->out.out_of_memory = 1;
-                break;
-            }
-            strcpy(v, value);
-            Parse(state->parser, NAME, v, &state->out);
+            Parse(state->parser, NAME, value, &state->out);
         } break;
         
         case NCD_TOKEN_STRING: {
-            char *v = malloc(strlen(value) + 1);
-            if (!v) {
-                state->out.out_of_memory = 1;
-                break;
-            }
-            strcpy(v, value);
-            Parse(state->parser, STRING, v, &state->out);
+            Parse(state->parser, STRING, value, &state->out);
         } break;
         
         default:

+ 54 - 34
ncd/NCDConfigTokenizer.c

@@ -22,12 +22,18 @@
 
 #include <string.h>
 #include <stddef.h>
+#include <stdlib.h>
 
 #include <misc/debug.h>
 #include <misc/string_begins_with.h>
+#include <misc/balloc.h>
+#include <misc/expstring.h>
+#include <base/BLog.h>
 
 #include <ncd/NCDConfigTokenizer.h>
 
+#include <generated/blog_channel_NCDConfigTokenizer.h>
+
 static int is_name_char (char c)
 {
     return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_');
@@ -57,7 +63,6 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
         int error = 0;
         int token;
         void *token_val = NULL;
-        char dec[NCD_MAX_SIZE + 1];
         
         if (*str == '#') {
             l = 1;
@@ -92,46 +97,56 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
         }
         else if (is_name_first_char(*str)) {
             l = 1;
-            while (l < left) {
-                if (!is_name_char(str[l])) {
-                    break;
-                }
+            while (l < left && is_name_char(str[l])) {
                 l++;
             }
             
-            // check size
-            if (l > NCD_MAX_SIZE) {
+            // allocate buffer
+            bsize_t bufsize = bsize_add(bsize_fromsize(l), bsize_fromint(1));
+            char *buf;
+            if (bufsize.is_overflow || !(buf = malloc(bufsize.value))) {
+                BLog(BLOG_ERROR, "malloc failed");
                 error = 1;
                 goto out;
             }
             
             // copy and terminate
-            memcpy(dec, str, l);
-            dec[l] = '\0';
+            memcpy(buf, str, l);
+            buf[l] = '\0';
             
-            if (!strcmp(dec, "process")) {
+            if (!strcmp(buf, "process")) {
                 token = NCD_TOKEN_PROCESS;
+                free(buf);
             }
-            else if (!strcmp(dec, "template")) {
+            else if (!strcmp(buf, "template")) {
                 token = NCD_TOKEN_TEMPLATE;
+                free(buf);
             }
             else {
                 token = NCD_TOKEN_NAME;
-                token_val = dec;
+                token_val = buf;
             }
         }
-        else if (*str == '"') {
-            size_t dec_len = 0;
+        else if (*str == '"') do {
+            // init string
+            ExpString estr;
+            if (!ExpString_Init(&estr)) {
+                BLog(BLOG_ERROR, "ExpString_Init failed");
+                goto string_fail0;
+            }
             
-            // decode string on the fly
+            // skip start quote
             l = 1;
+            
+            // decode string
             while (l < left) {
                 char dec_ch;
                 
+                // get character
                 if (str[l] == '\\') {
-                    if (!(l + 1 < left)) {
-                        error = 1;
-                        goto out;
+                    if (left - l < 2) {
+                        BLog(BLOG_ERROR, "escape character found in string but nothing follows");
+                        goto string_fail1;
                     }
                     
                     dec_ch = str[l + 1];
@@ -145,31 +160,37 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
                     l++;
                 }
                 
-                // check size
-                if (dec_len == NCD_MAX_SIZE) {
-                    error = 1;
-                    goto out;
+                // string cannot contain zeros bytes
+                if (dec_ch == '\0') {
+                    BLog(BLOG_ERROR, "string contains zero byte");
+                    goto string_fail1;
                 }
                 
-                // append decoded char
-                dec[dec_len] = dec_ch;
-                dec_len++;
+                // append character to string
+                if (!ExpString_AppendChar(&estr, dec_ch)) {
+                    BLog(BLOG_ERROR, "ExpString_AppendChar failed");
+                    goto string_fail1;
+                }
             }
             
-            // make sure closing quote was found
+            // make sure ending quote was found
             if (l == left) {
-                error = 1;
-                goto out;
+                BLog(BLOG_ERROR, "missing ending quote for string");
+                goto string_fail1;
             }
             
+            // skip ending quote
             l++;
             
-            // terminate
-            dec[dec_len] = '\0';
-            
             token = NCD_TOKEN_STRING;
-            token_val = dec;
-        }
+            token_val = ExpString_Get(&estr);
+            break;
+            
+        string_fail1:
+            ExpString_Free(&estr);
+        string_fail0:
+            error = 1;
+        } while (0);
         else if (is_space_char(*str)) {
             token = 0;
             l = 1;
@@ -179,7 +200,6 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
         }
         
     out:
-        
         // report error
         if (error) {
             output(user, NCD_ERROR, NULL, position);

+ 0 - 2
ncd/NCDConfigTokenizer.h

@@ -38,8 +38,6 @@
 #define NCD_TOKEN_ARROW 11
 #define NCD_TOKEN_TEMPLATE 12
 
-#define NCD_MAX_SIZE 128
-
 typedef int (*NCDConfigTokenizer_output) (void *user, int token, char *value, size_t position);
 
 void NCDConfigTokenizer_Tokenize (char *str, size_t str_len, NCDConfigTokenizer_output output, void *user);