-
-
Save anonymous/1b2906f122c0c878e716380c076eee93 to your computer and use it in GitHub Desktop.
Patch for 73174
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 29e2a204fb42af061e66a9f847ffbc8f1d13897a | |
Author: Stanislav Malyshev <stas@php.net> | |
Date: Wed Sep 28 22:29:25 2016 -0700 | |
Fixed bug #73174 - heap overflow in php_pcre_replace_impl | |
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c | |
index 7589a78..2a8ff19 100644 | |
--- a/ext/pcre/php_pcre.c | |
+++ b/ext/pcre/php_pcre.c | |
@@ -1075,8 +1075,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub | |
char **subpat_names; /* Array for named subpatterns */ | |
int num_subpats; /* Number of captured subpatterns */ | |
int size_offsets; /* Size of the offsets array */ | |
- int new_len; /* Length of needed storage */ | |
- int alloc_len; /* Actual allocated length */ | |
+ size_t new_len; /* Length of needed storage */ | |
+ size_t alloc_len; /* Actual allocated length */ | |
int eval_result_len=0; /* Length of the eval'ed or | |
function-returned string */ | |
int match_len; /* Length of the current match */ | |
@@ -1146,8 +1146,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub | |
offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0); | |
- alloc_len = 2 * subject_len + 1; | |
- result = safe_emalloc(alloc_len, sizeof(char), 0); | |
+ result = safe_emalloc(subject_len, 2*sizeof(char), 1); | |
+ alloc_len = 2 * (size_t)subject_len + 1; | |
/* Initialize */ | |
match = NULL; | |
@@ -1212,8 +1212,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub | |
} | |
if (new_len + 1 > alloc_len) { | |
- alloc_len = 1 + alloc_len + 2 * new_len; | |
- new_buf = emalloc(alloc_len); | |
+ new_buf = safe_emalloc(2, new_len + 1, alloc_len); | |
+ alloc_len = 1 + alloc_len + 2 * (size_t)new_len; | |
memcpy(new_buf, result, *result_len); | |
efree(result); | |
result = new_buf; | |
@@ -1276,8 +1276,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub | |
} else { | |
new_len = *result_len + subject_len - start_offset; | |
if (new_len + 1 > alloc_len) { | |
- alloc_len = new_len + 1; /* now we know exactly how long it is */ | |
- new_buf = safe_emalloc(alloc_len, sizeof(char), 0); | |
+ new_buf = safe_emalloc(new_len, sizeof(char), 1); | |
+ alloc_len = (size_t)new_len + 1; /* now we know exactly how long it is */ | |
memcpy(new_buf, result, *result_len); | |
efree(result); | |
result = new_buf; | |
@@ -1308,6 +1308,12 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub | |
efree(offsets); | |
efree(subpat_names); | |
+ if(result && (size_t)(*result_len) > INT_MAX) { | |
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, max is %d", INT_MAX); | |
+ efree(result); | |
+ result = NULL; | |
+ } | |
+ | |
return result; | |
} | |
/* }}} */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment