]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
unescape parameters
authorMax Kellermann <max@duempel.org>
Tue, 29 Jan 2008 13:45:29 +0000 (13:45 +0000)
committerPatrick McHardy <kaber@trash.net>
Tue, 29 Jan 2008 13:45:29 +0000 (13:45 +0000)
Max Kellermann <max@duempel.org>

ip6tables-restore.c
iptables-restore.c

index 12f8d8cd310f929ae91fa95eb181aa323aa18c5f..2d2f8b0423a1aa0332322924a8e2c6a2ffd50ffe 100644 (file)
@@ -311,8 +311,9 @@ int main(int argc, char *argv[])
                        char *parsestart;
 
                        /* the parser */
-                       char *param_start, *curchar;
-                       int quote_open;
+                       char *curchar;
+                       int quote_open, escaped;
+                       size_t param_len;
 
                        /* reset the newargv */
                        newargc = 0;
@@ -359,41 +360,45 @@ int main(int argc, char *argv[])
                         * longer a real hacker, but I can live with that */
 
                        quote_open = 0;
-                       param_start = parsestart;
+                       escaped = 0;
+                       param_len = 0;
 
                        for (curchar = parsestart; *curchar; curchar++) {
-                               if (*curchar == '"') {
-                                       /* quote_open cannot be true if there
-                                        * was no previous character.  Thus, 
-                                        * curchar-1 has to be within bounds */
-                                       if (quote_open && 
-                                           *(curchar-1) != '\\') {
+                               char param_buffer[1024];
+
+                               if (escaped) {
+                                       param_buffer[param_len++] = *curchar;
+                                       escaped = 0;
+                                       continue;
+                               }
+
+                               if (quote_open) {
+                                       if (*curchar == '\\') {
+                                               escaped = 1;
+                                               continue;
+                                       } else if (*curchar == '"') {
                                                quote_open = 0;
                                                *curchar = ' ';
                                        } else {
+                                               param_buffer[param_len++] = *curchar;
+                                               continue;
+                                       }
+                               } else {
+                                       if (*curchar == '"') {
                                                quote_open = 1;
-                                               param_start++;
+                                               continue;
                                        }
-                               } 
+                               }
+
                                if (*curchar == ' '
                                    || *curchar == '\t'
                                    || * curchar == '\n') {
-                                       char param_buffer[1024];
-                                       int param_len = curchar-param_start;
-
-                                       if (quote_open)
-                                               continue;
-
                                        if (!param_len) {
                                                /* two spaces? */
-                                               param_start++;
                                                continue;
                                        }
-                                       
-                                       /* end of one parameter */
-                                       strncpy(param_buffer, param_start,
-                                               param_len);
-                                       *(param_buffer+param_len) = '\0';
+
+                                       param_buffer[param_len] = '\0';
 
                                        /* check if table name specified */
                                        if (!strncmp(param_buffer, "-t", 3)
@@ -405,9 +410,14 @@ int main(int argc, char *argv[])
                                        }
 
                                        add_argv(param_buffer);
-                                       param_start += param_len + 1;
+                                       param_len = 0;
                                } else {
-                                       /* regular character, skip */
+                                       /* regular character, copy to buffer */
+                                       param_buffer[param_len++] = *curchar;
+
+                                       if (param_len >= sizeof(param_buffer))
+                                               exit_error(PARAMETER_PROBLEM, 
+                                                  "Parameter too long!");
                                }
                        }
 
index ade1a2fe9aa571d42c663fa95d10870e3b2b38a5..2522b0f53c2becde71d1487d7712f29de5b68de5 100644 (file)
@@ -319,7 +319,7 @@ main(int argc, char *argv[])
 
                        /* the parser */
                        char *curchar;
-                       int quote_open;
+                       int quote_open, escaped;
                        size_t param_len;
 
                        /* reset the newargv */
@@ -367,34 +367,39 @@ main(int argc, char *argv[])
                         * longer a real hacker, but I can live with that */
 
                        quote_open = 0;
+                       escaped = 0;
                        param_len = 0;
 
                        for (curchar = parsestart; *curchar; curchar++) {
                                char param_buffer[1024];
 
-                               if (*curchar == '"') {
-                                       /* quote_open cannot be true if there
-                                        * was no previous character.  Thus, 
-                                        * curchar-1 has to be within bounds */
-                                       if (quote_open && 
-                                           *(curchar-1) != '\\') {
+                               if (escaped) {
+                                       param_buffer[param_len++] = *curchar;
+                                       escaped = 0;
+                                       continue;
+                               }
+
+                               if (quote_open) {
+                                       if (*curchar == '\\') {
+                                               escaped = 1;
+                                               continue;
+                                       } else if (*curchar == '"') {
                                                quote_open = 0;
                                                *curchar = ' ';
-                                       } else if (!quote_open) {
+                                       } else {
+                                               param_buffer[param_len++] = *curchar;
+                                               continue;
+                                       }
+                               } else {
+                                       if (*curchar == '"') {
                                                quote_open = 1;
                                                continue;
                                        }
-                               } 
+                               }
+
                                if (*curchar == ' '
                                    || *curchar == '\t'
                                    || * curchar == '\n') {
-
-                                       if (quote_open) {
-                                               param_buffer[param_len++] = 
-                                                               *curchar;
-                                               continue;
-                                       }
-
                                        if (!param_len) {
                                                /* two spaces? */
                                                continue;
@@ -414,18 +419,6 @@ main(int argc, char *argv[])
                                        add_argv(param_buffer);
                                        param_len = 0;
                                } else {
-                                       /* Skip backslash that escapes quote: 
-                                        * the standard input does not require
-                                        * escaping. However, the output
-                                        * generated by iptables-save
-                                        * introduces bashlash to keep
-                                        * consistent with iptables
-                                        */
-                                       if (quote_open &&
-                                           *curchar == '\\' &&
-                                           *(curchar+1) == '"')
-                                               continue;
-
                                        /* regular character, copy to buffer */
                                        param_buffer[param_len++] = *curchar;