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>

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31569 3c298f89-4303-0410-b956-a3cf2f4a3e73
master
Jo-Philipp Wich 2012-05-03 17:19:16 +00:00
parent ccd44980d6
commit 9151869423
1 changed files with 11 additions and 5 deletions

View File

@ -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 uh_urldecode(char *buf, int blen, const char *src, int slen)
{ {
int i; int i;
@ -315,11 +318,11 @@ int uh_urldecode(char *buf, int blen, const char *src, int slen)
(((x) <= 'F') ? ((x) - 'A' + 10) : \ (((x) <= 'F') ? ((x) - 'A' + 10) : \
((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( 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])); buf[len++] = (char)(16 * hex(src[i+1]) + hex(src[i+2]));
i += 2; i += 2;
@ -338,13 +341,16 @@ int uh_urldecode(char *buf, int blen, const char *src, int slen)
return len; 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 uh_urlencode(char *buf, int blen, const char *src, int slen)
{ {
int i; int i;
int len = 0; int len = 0;
const char hex[] = "0123456789abcdef"; 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] == '_') || if( isalnum(src[i]) || (src[i] == '-') || (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++] = '%';
buf[len++] = hex[(src[i] >> 4) & 15]; buf[len++] = hex[(src[i] >> 4) & 15];
buf[len++] = hex[(src[i] & 15) & 15]; buf[len++] = hex[ src[i] & 15];
} }
else else
{ {
@ -527,7 +533,7 @@ struct path_info * uh_path_lookup(struct client *cl, const char *url)
uh_urldecode( uh_urldecode(
&buffer[strlen(docroot)], &buffer[strlen(docroot)],
sizeof(buffer) - strlen(docroot) - 1, sizeof(buffer) - strlen(docroot) - 1,
url, (int)(pathptr - url) - 1 url, pathptr - url
); );
} }