]> granicus.if.org Git - php/commitdiff
MFH: 7dcada1 for 5.4
authorGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 5 Feb 2012 14:57:57 +0000 (14:57 +0000)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Mon, 19 Mar 2012 16:36:21 +0000 (16:36 +0000)
- Fixed possible unsigned int wrap around in html.c. Note that 5.3 has the same
  (potential) problem; even though the code is substantially different, the
  variable name and the fashion it was incremented was kept.

ext/standard/html.c

index 5b47a8378800c9cacb5394d00befa5d0f0f45a9b..65e63f41cc9f8668e75fd103fc35290dad0878de 100644 (file)
@@ -1258,9 +1258,13 @@ PHPAPI char *php_escape_html_entities_ex(unsigned char *old, size_t oldlen, size
                maxlen = 128;   
        } else {
                maxlen = 2 * oldlen;
+               if (maxlen < oldlen) {
+                       zend_error_noreturn(E_ERROR, "Input string is too long");
+                       return NULL;
+               }
        }
 
-       replaced = emalloc(maxlen + 1);
+       replaced = emalloc(maxlen + 1); /* adding 1 is safe: maxlen is even */
        len = 0;
        cursor = 0;
        while (cursor < oldlen) {
@@ -1272,8 +1276,9 @@ PHPAPI char *php_escape_html_entities_ex(unsigned char *old, size_t oldlen, size
 
                /* guarantee we have at least 40 bytes to write.
                 * In HTML5, entities may take up to 33 bytes */
-               if (len + 40 > maxlen) {
-                       replaced = erealloc(replaced, (maxlen += 128) + 1);
+               if (len > maxlen - 40) { /* maxlen can never be smaller than 128 */
+                       replaced = safe_erealloc(replaced, maxlen , 1, 128 + 1);
+                       maxlen += 128;
                }
 
                if (status == FAILURE) {
@@ -1402,8 +1407,11 @@ encode_amp:
                                }
                                /* checks passed; copy entity to result */
                                /* entity size is unbounded, we may need more memory */
-                               if (maxlen < len + ent_len + 2 /* & and ; */) {
-                                       replaced = erealloc(replaced, (maxlen += ent_len + 128) + 1);
+                               /* at this point maxlen - len >= 40 */
+                               if (maxlen - len < ent_len + 2 /* & and ; */) {
+                                       /* ent_len < oldlen, which is certainly <= SIZE_MAX/2 */
+                                       replaced = safe_erealloc(replaced, maxlen, 1, ent_len + 128 + 1);
+                                       maxlen += ent_len + 128;
                                }
                                replaced[len++] = '&';
                                memcpy(&replaced[len], &old[cursor], ent_len);