diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2012-05-03 17:19:16 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2012-05-03 17:19:16 +0000 |
commit | 2bfb1e012abca1dbb3797bc5e72e2af3ee741dec (patch) | |
tree | 0094e86406fe46b6e66234dc7b44e7939542f68b | |
parent | 6e5db7ed6908dc1f91cad10cb7f2d84b0afcc852 (diff) | |
download | upstream-2bfb1e012abca1dbb3797bc5e72e2af3ee741dec.tar.gz upstream-2bfb1e012abca1dbb3797bc5e72e2af3ee741dec.tar.bz2 upstream-2bfb1e012abca1dbb3797bc5e72e2af3ee741dec.zip |
uhttpd URL-codec bug fixes.
* Fixed output-buffer-overflow bug in uh_urlencode() and uh_urldecode() [tested
input-buffer index against output-buffer length]. In reality, this would not
typically cause an overflow on decode, where the output string would be
expected to be shorter than the input string; and uh_urlencode() seems to have
been unreferenced in the source.
* Fixed bug: uh_urlencode() and uh_urldecode() both read one extra byte from the
input-string. While this could manifest in C code, the result was most
egregious when called from Lua, where it caused an extra null byte to be
embedded at the end of the output string.
* uh_urlencode() cleanup: removed redundant bitwise-and.
Signed-off-by: David Favro <openwrt@meta-dynamic.com>
SVN-Revision: 31569
-rw-r--r-- | package/uhttpd/src/uhttpd-utils.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c index a47f175ba6..1073f3bb34 100644 --- a/package/uhttpd/src/uhttpd-utils.c +++ b/package/uhttpd/src/uhttpd-utils.c @@ -305,6 +305,9 @@ int uh_http_send( } +/* blen is the size of buf; slen is the length of src. The input-string need +** not be, and the output string will not be, null-terminated. Returns the +** length of the decoded string. */ int uh_urldecode(char *buf, int blen, const char *src, int slen) { int i; @@ -315,11 +318,11 @@ int uh_urldecode(char *buf, int blen, const char *src, int slen) (((x) <= 'F') ? ((x) - 'A' + 10) : \ ((x) - 'a' + 10))) - for( i = 0; (i <= slen) && (i <= blen); i++ ) + for( i = 0; (i < slen) && (len < blen); i++ ) { if( src[i] == '%' ) { - if( ((i+2) <= slen) && isxdigit(src[i+1]) && isxdigit(src[i+2]) ) + if( ((i+2) < slen) && isxdigit(src[i+1]) && isxdigit(src[i+2]) ) { buf[len++] = (char)(16 * hex(src[i+1]) + hex(src[i+2])); i += 2; @@ -338,13 +341,16 @@ int uh_urldecode(char *buf, int blen, const char *src, int slen) return len; } +/* blen is the size of buf; slen is the length of src. The input-string need +** not be, and the output string will not be, null-terminated. Returns the +** length of the encoded string. */ int uh_urlencode(char *buf, int blen, const char *src, int slen) { int i; int len = 0; const char hex[] = "0123456789abcdef"; - for( i = 0; (i <= slen) && (i <= blen); i++ ) + for( i = 0; (i < slen) && (len < blen); i++ ) { if( isalnum(src[i]) || (src[i] == '-') || (src[i] == '_') || (src[i] == '.') || (src[i] == '~') ) @@ -355,7 +361,7 @@ int uh_urlencode(char *buf, int blen, const char *src, int slen) { buf[len++] = '%'; buf[len++] = hex[(src[i] >> 4) & 15]; - buf[len++] = hex[(src[i] & 15) & 15]; + buf[len++] = hex[ src[i] & 15]; } else { @@ -527,7 +533,7 @@ struct path_info * uh_path_lookup(struct client *cl, const char *url) uh_urldecode( &buffer[strlen(docroot)], sizeof(buffer) - strlen(docroot) - 1, - url, (int)(pathptr - url) - 1 + url, pathptr - url ); } |