cvs: php4 /ext/standard html.c

From: Date: Sat, 16 Mar 2002 09:44:30 +0000
Subject: cvs: php4 /ext/standard html.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-10216@lists.php.net to get a copy of this message
sesser Sat Mar 16 04:44:30 2002 EDT Modified files: /php4/ext/standard html.c Log: fixed possible bufferoverflow in get_next_char malformed input to htmlentities/htmlspecialchars with utf-8 encoding crashed the server ex: htmlentities("\xfd...(30times)", ENT_NOQUOTES, "utf-8"); Index: php4/ext/standard/html.c diff -u php4/ext/standard/html.c:1.44 php4/ext/standard/html.c:1.45 --- php4/ext/standard/html.c:1.44 Fri Mar 15 21:33:00 2002 +++ php4/ext/standard/html.c Sat Mar 16 04:44:30 2002 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: html.c,v 1.44 2002/03/16 02:33:00 wez Exp $ */ +/* $Id: html.c,v 1.45 2002/03/16 09:44:30 sesser Exp $ */ #include "php.h" #include "reg.h" @@ -137,21 +137,38 @@ { 0, NULL, 0, 0 } }; +#define MB_RETURN { \ + *newpos = pos; \ + mbseq[mbpos] = '\0'; \ + *mbseqlen = mbpos; \ + return this_char; } + +#define MB_WRITE(mbchar) { \ + mbspace--; \ + if (mbspace == 0) { \ + MB_RETURN; \ + } \ + mbseq[mbpos++] = (mbchar); } /* {{{ get_next_char */ inline static unsigned short get_next_char(enum entity_charset charset, - unsigned char *str, - int *newpos, - unsigned char *mbseq, - int *mbseqlen -) + unsigned char * str, + int * newpos, + unsigned char * mbseq, + int * mbseqlen) { int pos = *newpos; int mbpos = 0; + int mbspace = *mbseqlen; unsigned short this_char = str[pos++]; - mbseq[mbpos++] = (unsigned char)this_char; + if (mbspace <= 0) { + *mbseqlen = 0; + return this_char; + } + + MB_WRITE((unsigned char)this_char); switch(charset) { case cs_utf_8: @@ -232,7 +249,7 @@ if (more) { this_char = str[pos++]; - mbseq[mbpos++] = (unsigned char)this_char; + MB_WRITE((unsigned char)this_char); } } while(more); } @@ -250,7 +267,7 @@ { /* yes, this a wide char */ this_char <<= 8; - mbseq[mbpos++] = next_char; + MB_WRITE(next_char); this_char |= next_char; pos++; } @@ -271,7 +288,7 @@ { /* yes, this a wide char */ this_char <<= 8; - mbseq[mbpos++] = next_char; + MB_WRITE(next_char); this_char |= next_char; pos++; } @@ -289,7 +306,7 @@ { /* yes, this a jis kanji char */ this_char <<= 8; - mbseq[mbpos++] = next_char; + MB_WRITE(next_char); this_char |= next_char; pos++; } @@ -301,7 +318,7 @@ { /* JIS X 0201 kana */ this_char <<= 8; - mbseq[mbpos++] = next_char; + MB_WRITE(next_char); this_char |= next_char; pos++; } @@ -315,12 +332,13 @@ { /* JIS X 0212 hojo-kanji */ this_char <<= 8; - mbseq[mbpos++] = next_char; + MB_WRITE(next_char); this_char |= next_char; + pos++; this_char <<= 8; - mbseq[mbpos++] = next2_char; + MB_WRITE(next2_char); this_char |= next2_char; - pos+=2; + pos++; } } @@ -331,10 +349,7 @@ break; } } - *newpos = pos; - mbseq[mbpos] = '\0'; - *mbseqlen = mbpos; - return this_char; + MB_RETURN; } /* }}} */ @@ -489,8 +504,8 @@ i = 0; while (i < oldlen) { - int mbseqlen; unsigned char mbsequence[16]; /* allow up to 15 characters in a multibyte sequence */ + int mbseqlen = sizeof(mbsequence); unsigned short this_char = get_next_char(charset, old, &i, mbsequence, &mbseqlen); matches_map = 0;

« previous php.cvs (#10216) next »