From 89a43425072feda1fc5546aaaaa7be7737c4f197 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 7 Mar 2016 22:01:44 +0100 Subject: [PATCH] fix incompatible pointers on 64-bit --- ext/mbstring/mbstring.c | 201 ++++++++++++++++++++++++++++++++++------ 1 file changed, 172 insertions(+), 29 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index d65e7c78b8..9968a1dc51 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2222,14 +2222,21 @@ PHP_FUNCTION(mb_strlen) int n; mbfl_string string; char *enc_name = NULL; - size_t enc_name_len; + size_t enc_name_len, string_len; mbfl_string_init(&string); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", (char **)&string.val, &string_len, &enc_name, &enc_name_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(string_len)) { + php_error_docref(NULL, E_WARNING, "String overflows the max allowed length of %u", UINT_MAX); + return; + } + + string.len = (uint32_t)string_len; + string.no_language = MBSTRG(language); if (enc_name == NULL) { string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; @@ -2258,7 +2265,7 @@ PHP_FUNCTION(mb_strpos) zend_long offset = 0; mbfl_string haystack, needle; char *enc_name = NULL; - size_t enc_name_len; + size_t enc_name_len, haystack_len, needle_len; mbfl_string_init(&haystack); mbfl_string_init(&needle); @@ -2267,10 +2274,21 @@ PHP_FUNCTION(mb_strpos) needle.no_language = MBSTRG(language); needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|ls", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &offset, &enc_name, &enc_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|ls", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &offset, &enc_name, &enc_name_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + if (enc_name != NULL) { haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name); if (haystack.no_encoding == mbfl_no_encoding_invalid) { @@ -2320,7 +2338,7 @@ PHP_FUNCTION(mb_strrpos) int n; mbfl_string haystack, needle; char *enc_name = NULL; - size_t enc_name_len; + size_t enc_name_len, haystack_len, needle_len; zval *zoffset = NULL; long offset = 0, str_flg; char *enc_name2 = NULL; @@ -2333,10 +2351,21 @@ PHP_FUNCTION(mb_strrpos) needle.no_language = MBSTRG(language); needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|zs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &zoffset, &enc_name, &enc_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|zs", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &zoffset, &enc_name, &enc_name_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + if (zoffset) { if (Z_TYPE_P(zoffset) == IS_STRING) { enc_name2 = Z_STRVAL_P(zoffset); @@ -2419,11 +2448,23 @@ PHP_FUNCTION(mb_stripos) zend_long offset = 0; mbfl_string haystack, needle; const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name; - size_t from_encoding_len; + size_t from_encoding_len, haystack_len, needle_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|ls", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &offset, &from_encoding, &from_encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|ls", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &offset, &from_encoding, &from_encoding_len) == FAILURE) { return; } + + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + if (needle.len == 0) { php_error_docref(NULL, E_WARNING, "Empty delimiter"); RETURN_FALSE; @@ -2446,12 +2487,23 @@ PHP_FUNCTION(mb_strripos) zend_long offset = 0; mbfl_string haystack, needle; const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name; - size_t from_encoding_len; + size_t from_encoding_len, haystack_len, needle_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|ls", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &offset, &from_encoding, &from_encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|ls", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &offset, &from_encoding, &from_encoding_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + n = php_mb_stripos(1, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, offset, from_encoding); if (n >= 0) { @@ -2469,7 +2521,7 @@ PHP_FUNCTION(mb_strstr) int n, len, mblen; mbfl_string haystack, needle, result, *ret = NULL; char *enc_name = NULL; - size_t enc_name_len; + size_t enc_name_len, haystack_len, needle_len; zend_bool part = 0; mbfl_string_init(&haystack); @@ -2479,10 +2531,21 @@ PHP_FUNCTION(mb_strstr) needle.no_language = MBSTRG(language); needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &part, &enc_name, &enc_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &part, &enc_name, &enc_name_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + if (enc_name != NULL) { haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name); if (haystack.no_encoding == mbfl_no_encoding_invalid) { @@ -2531,7 +2594,7 @@ PHP_FUNCTION(mb_strrchr) int n, len, mblen; mbfl_string haystack, needle, result, *ret = NULL; char *enc_name = NULL; - size_t enc_name_len; + size_t enc_name_len, haystack_len, needle_len; zend_bool part = 0; mbfl_string_init(&haystack); @@ -2541,10 +2604,21 @@ PHP_FUNCTION(mb_strrchr) needle.no_language = MBSTRG(language); needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &enc_name, &enc_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &part, &enc_name, &enc_name_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + if (enc_name != NULL) { haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name); if (haystack.no_encoding == mbfl_no_encoding_invalid) { @@ -2593,7 +2667,7 @@ PHP_FUNCTION(mb_strrchr) PHP_FUNCTION(mb_stristr) { zend_bool part = 0; - size_t from_encoding_len, len, mblen; + size_t from_encoding_len, len, mblen, haystack_len, needle_len; int n; mbfl_string haystack, needle, result, *ret = NULL; const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name; @@ -2605,10 +2679,21 @@ PHP_FUNCTION(mb_stristr) needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &part, &from_encoding, &from_encoding_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + if (!needle.len) { php_error_docref(NULL, E_WARNING, "Empty delimiter"); RETURN_FALSE; @@ -2657,7 +2742,7 @@ PHP_FUNCTION(mb_strrichr) { zend_bool part = 0; int n, len, mblen; - size_t from_encoding_len; + size_t from_encoding_len, haystack_len, needle_len; mbfl_string haystack, needle, result, *ret = NULL; const char *from_encoding = MBSTRG(current_internal_encoding)->name; mbfl_string_init(&haystack); @@ -2668,10 +2753,21 @@ PHP_FUNCTION(mb_strrichr) needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bs", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &part, &from_encoding, &from_encoding_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(from_encoding); if (haystack.no_encoding == mbfl_no_encoding_invalid) { php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", from_encoding); @@ -2716,7 +2812,7 @@ PHP_FUNCTION(mb_substr_count) int n; mbfl_string haystack, needle; char *enc_name = NULL; - size_t enc_name_len; + size_t enc_name_len, haystack_len, needle_len; mbfl_string_init(&haystack); mbfl_string_init(&needle); @@ -2725,10 +2821,21 @@ PHP_FUNCTION(mb_substr_count) needle.no_language = MBSTRG(language); needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|s", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &enc_name, &enc_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|s", (char **)&haystack.val, &haystack_len, (char **)&needle.val, &needle_len, &enc_name, &enc_name_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(haystack_len)) { + php_error_docref(NULL, E_WARNING, "Haystack length overflows the max allowed length of %u", UINT_MAX); + return; + } else if (ZEND_SIZE_T_UINT_OVFL(needle_len)) { + php_error_docref(NULL, E_WARNING, "Needle length overflows the max allowed length of %u", UINT_MAX); + return; + } + + haystack.len = (uint32_t)haystack_len; + needle.len = (uint32_t)needle_len; + if (enc_name != NULL) { haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name); if (haystack.no_encoding == mbfl_no_encoding_invalid) { @@ -2833,7 +2940,7 @@ PHP_FUNCTION(mb_strcut) { char *encoding = NULL; zend_long from, len; - size_t encoding_len; + size_t encoding_len, string_len; zend_bool len_is_null = 1; mbfl_string string, result, *ret; @@ -2841,10 +2948,17 @@ PHP_FUNCTION(mb_strcut) string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|l!s", (char **)&string.val, (int **)&string.len, &from, &len, &len_is_null, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|l!s", (char **)&string.val, &string_len, &from, &len, &len_is_null, &encoding, &encoding_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(string_len)) { + php_error_docref(NULL, E_WARNING, "String length overflows the max allowed length of %u", UINT_MAX); + return; + } + + string.len = (uint32_t)string_len; + if (encoding) { string.no_encoding = mbfl_name2no_encoding(encoding); if (string.no_encoding == mbfl_no_encoding_invalid) { @@ -2899,17 +3013,24 @@ PHP_FUNCTION(mb_strwidth) int n; mbfl_string string; char *enc_name = NULL; - size_t enc_name_len; + size_t enc_name_len, string_len; mbfl_string_init(&string); string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", (char **)&string.val, &string_len, &enc_name, &enc_name_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(string_len)) { + php_error_docref(NULL, E_WARNING, "String length overflows the max allowed length of %u", UINT_MAX); + return; + } + + string.len = (uint32_t)string_len; + if (enc_name != NULL) { string.no_encoding = mbfl_name2no_encoding(enc_name); if (string.no_encoding == mbfl_no_encoding_invalid) { @@ -3354,17 +3475,24 @@ PHP_FUNCTION(mb_encode_mimeheader) char *trans_enc_name = NULL; size_t trans_enc_name_len; char *linefeed = "\r\n"; - size_t linefeed_len; + size_t linefeed_len, string_len; zend_long indent = 0; mbfl_string_init(&string); string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|sssl", (char **)&string.val, &string.len, &charset_name, &charset_name_len, &trans_enc_name, &trans_enc_name_len, &linefeed, &linefeed_len, &indent) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|sssl", (char **)&string.val, &string_len, &charset_name, &charset_name_len, &trans_enc_name, &trans_enc_name_len, &linefeed, &linefeed_len, &indent) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(string_len)) { + php_error_docref(NULL, E_WARNING, "String length overflows the max allowed length of %u", UINT_MAX); + return; + } + + string.len = (uint32_t)string_len; + charset = mbfl_no_encoding_pass; transenc = mbfl_no_encoding_base64; @@ -3407,15 +3535,23 @@ PHP_FUNCTION(mb_encode_mimeheader) PHP_FUNCTION(mb_decode_mimeheader) { mbfl_string string, result, *ret; + size_t string_len; mbfl_string_init(&string); string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", (char **)&string.val, &string.len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", (char **)&string.val, &string_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(string_len)) { + php_error_docref(NULL, E_WARNING, "String length overflows the max allowed length of %u", UINT_MAX); + return; + } + + string.len = (uint32_t)string_len; + mbfl_string_init(&result); ret = mbfl_mime_header_decode(&string, &result, MBSTRG(current_internal_encoding)->no_encoding); if (ret != NULL) { @@ -3437,16 +3573,23 @@ PHP_FUNCTION(mb_convert_kana) char *optstr = NULL; size_t optstr_len; char *encname = NULL; - size_t encname_len; + size_t encname_len, string_len; mbfl_string_init(&string); string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ss", (char **)&string.val, &string.len, &optstr, &optstr_len, &encname, &encname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ss", (char **)&string.val, &string_len, &optstr, &optstr_len, &encname, &encname_len) == FAILURE) { return; } + if (ZEND_SIZE_T_UINT_OVFL(string_len)) { + php_error_docref(NULL, E_WARNING, "String length overflows the max allowed length of %u", UINT_MAX); + return; + } + + string.len = (uint32_t)string_len; + /* option */ if (optstr != NULL) { char *p = optstr; -- 2.40.0