diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-11-29 15:58:50 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-11-29 15:58:50 +0000 |
commit | a35c9e91ba53073ff797d1d68d0d4e1836d934f0 (patch) | |
tree | a19543c721a5a98f9b96522303ca250b58d1bcca /networking | |
parent | 2425bdce34cd142b29eabad00927a9c473b05ecb (diff) | |
download | busybox-w32-a35c9e91ba53073ff797d1d68d0d4e1836d934f0.tar.gz busybox-w32-a35c9e91ba53073ff797d1d68d0d4e1836d934f0.tar.bz2 busybox-w32-a35c9e91ba53073ff797d1d68d0d4e1836d934f0.zip |
httpd: fix decode of '/' when called via -d
Diffstat (limited to 'networking')
-rw-r--r-- | networking/httpd.c | 66 |
1 files changed, 34 insertions, 32 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index f95e0c06e..49c2c76be 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -671,43 +671,47 @@ static char *encodeString(const char *string) | |||
671 | * | 671 | * |
672 | * $Parameters: | 672 | * $Parameters: |
673 | * (char *) string . . . The first string to decode. | 673 | * (char *) string . . . The first string to decode. |
674 | * (int) flag . . . 1 if need to decode '+' as ' ' for CGI | 674 | * (int) option_d . . 1 if called for httpd -d |
675 | * | 675 | * |
676 | * $Return: (char *) . . . . A pointer to the decoded string (same as input). | 676 | * $Return: (char *) . . . . A pointer to the decoded string (same as input). |
677 | * | 677 | * |
678 | * $Errors: None | 678 | * $Errors: None |
679 | * | 679 | * |
680 | ****************************************************************************/ | 680 | ****************************************************************************/ |
681 | static char *decodeString(char *orig, int flag_plus_to_space) | 681 | static char *decodeString(char *orig, int option_d) |
682 | { | 682 | { |
683 | /* note that decoded string is always shorter than original */ | 683 | /* note that decoded string is always shorter than original */ |
684 | char *string = orig; | 684 | char *string = orig; |
685 | char *ptr = string; | 685 | char *ptr = string; |
686 | char c; | ||
686 | 687 | ||
687 | while (*ptr) { | 688 | while ((c = *ptr++) != '\0') { |
688 | if (*ptr == '+' && flag_plus_to_space) { | 689 | unsigned value1, value2; |
690 | |||
691 | if (option_d && c == '+') { | ||
689 | *string++ = ' '; | 692 | *string++ = ' '; |
690 | ptr++; | 693 | continue; |
691 | } else if (*ptr != '%') { | 694 | } |
692 | *string++ = *ptr++; | 695 | if (c != '%') { |
693 | } else { | 696 | *string++ = c; |
694 | unsigned int value1, value2; | 697 | continue; |
695 | 698 | } | |
696 | ptr++; | 699 | if (sscanf(ptr, "%1X", &value1) != 1 |
697 | if (sscanf(ptr, "%1X", &value1) != 1 | 700 | || sscanf(ptr+1, "%1X", &value2) != 1 |
698 | || sscanf(ptr+1, "%1X", &value2) != 1 | 701 | ) { |
699 | ) { | 702 | if (!option_d) |
700 | if (!flag_plus_to_space) | 703 | return NULL; |
701 | return NULL; | 704 | *string++ = '%'; |
702 | *string++ = '%'; | 705 | continue; |
703 | } else { | 706 | } |
704 | value1 = value1 * 16 + value2; | 707 | value1 = value1 * 16 + value2; |
705 | if (value1 == '/' || value1 == 0) | 708 | if (!option_d && (value1 == '/' || value1 == '\0')) { |
706 | return orig+1; | 709 | /* caller takes it as indication of invalid |
707 | *string++ = value1; | 710 | * (dangerous wrt exploits) chars */ |
708 | ptr += 2; | 711 | return orig + 1; |
709 | } | ||
710 | } | 712 | } |
713 | *string++ = value1; | ||
714 | ptr += 2; | ||
711 | } | 715 | } |
712 | *string = '\0'; | 716 | *string = '\0'; |
713 | return orig; | 717 | return orig; |
@@ -1510,8 +1514,8 @@ static void handleIncoming(void) | |||
1510 | test = decodeString(url, 0); | 1514 | test = decodeString(url, 0); |
1511 | if (test == NULL) | 1515 | if (test == NULL) |
1512 | goto BAD_REQUEST; | 1516 | goto BAD_REQUEST; |
1513 | /* FIXME: bug? should be "url+1"? */ | 1517 | if (test == url+1) { |
1514 | if (test == (buf+1)) { | 1518 | /* '/' or NUL is encoded */ |
1515 | sendHeaders(HTTP_NOT_FOUND); | 1519 | sendHeaders(HTTP_NOT_FOUND); |
1516 | break; | 1520 | break; |
1517 | } | 1521 | } |
@@ -1909,12 +1913,12 @@ int httpd_main(int argc, char *argv[]) | |||
1909 | char *e; | 1913 | char *e; |
1910 | // FIXME: what the default group should be? | 1914 | // FIXME: what the default group should be? |
1911 | ugid.gid = -1; | 1915 | ugid.gid = -1; |
1912 | ugid.uid = strtoul(s_ugid, &e, 0); | 1916 | ugid.uid = bb_strtoul(s_ugid, &e, 0); |
1913 | if (*e == ':') { | 1917 | if (*e == ':') { |
1914 | e++; | 1918 | e++; |
1915 | ugid.gid = strtoul(e, &e, 0); | 1919 | ugid.gid = bb_strtoul(e, NULL, 0); |
1916 | } | 1920 | } |
1917 | if (*e != '\0') { | 1921 | if (errno) { |
1918 | /* not integer */ | 1922 | /* not integer */ |
1919 | if (!uidgid_get(&ugid, s_ugid)) | 1923 | if (!uidgid_get(&ugid, s_ugid)) |
1920 | bb_error_msg_and_die("unrecognized user[:group] " | 1924 | bb_error_msg_and_die("unrecognized user[:group] " |
@@ -1942,9 +1946,7 @@ int httpd_main(int argc, char *argv[]) | |||
1942 | #if ENABLE_FEATURE_HTTPD_CGI | 1946 | #if ENABLE_FEATURE_HTTPD_CGI |
1943 | { | 1947 | { |
1944 | char *p = getenv("PATH"); | 1948 | char *p = getenv("PATH"); |
1945 | if (p) { | 1949 | p = xstrdup(p); /* if gets NULL, returns NULL */ |
1946 | p = xstrdup(p); | ||
1947 | } | ||
1948 | clearenv(); | 1950 | clearenv(); |
1949 | if (p) | 1951 | if (p) |
1950 | setenv1("PATH", p); | 1952 | setenv1("PATH", p); |