Skip to content

Commit e1d2f86

Browse files
committed
Merge branch 'PHP-5.5.37' into PHP-5.5
* PHP-5.5.37: fix tests fix build Fix bug #72455: Heap Overflow due to integer overflows Fix bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize Fixed ##72433: Use After Free Vulnerability in PHP's GC algorithm and unserialize Fix bug #72407: NULL Pointer Dereference at _gdScaleVert Fix bug #72402: _php_mb_regex_ereg_replace_exec - double free Fix bug #72298 pass2_no_dither out-of-bounds access Fixed #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow Fix bug #72262 - do not overflow int Fix bug #72400 and #72403 - prevent signed int overflows for string lengths Fix bug #72275: don't allow smart_str to overflow int Fix bug #72340: Double Free Courruption in wddx_deserialize
2 parents 6f73079 + 5f107ab commit e1d2f86

File tree

20 files changed

+449
-246
lines changed

20 files changed

+449
-246
lines changed

Zend/tests/gc_024.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ var_dump(gc_collect_cycles());
1313
echo "ok\n";
1414
?>
1515
--EXPECT--
16-
int(1)
16+
int(2)
1717
ok

ext/gd/libgd/gd_gd2.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,18 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in
138138
if (gd2_compressed(*fmt)) {
139139
nc = (*ncx) * (*ncy);
140140
GD2_DBG(php_gd_error("Reading %d chunk index entries", nc));
141+
if (overflow2(sizeof(t_chunk_info), nc)) {
142+
goto fail1;
143+
}
141144
sidx = sizeof(t_chunk_info) * nc;
142145
if (sidx <= 0) {
143146
goto fail1;
144147
}
145148
cidx = gdCalloc(sidx, 1);
149+
if (cidx == NULL) {
150+
goto fail1;
151+
}
152+
146153
for (i = 0; i < nc; i++) {
147154
if (gdGetInt(&cidx[i].offset, in) != 1) {
148155
gdFree(cidx);

ext/gd/libgd/gd_interpolation.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,9 @@ static inline void _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_w
10491049
}
10501050

10511051
contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation);
1052+
if (contrib == NULL) {
1053+
return;
1054+
}
10521055
/* scale each column */
10531056
for (u = 0; u < dst_width - 1; u++) {
10541057
_gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib);

ext/gd/libgd/gd_topal.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
* If it is not working, it's not Thomas G. Lane's fault.
4444
*/
4545

46-
/*
46+
/*
4747
SETTING THIS ONE CAUSES STRIPED IMAGE
4848
to be done: solve this
4949
#define ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS
@@ -152,7 +152,7 @@
152152
* color space, and repeatedly splits the "largest" remaining box until we
153153
* have as many boxes as desired colors. Then the mean color in each
154154
* remaining box becomes one of the possible output colors.
155-
*
155+
*
156156
* The second pass over the image maps each input pixel to the closest output
157157
* color (optionally after applying a Floyd-Steinberg dithering correction).
158158
* This mapping is logically trivial, but making it go fast enough requires
@@ -1320,16 +1320,16 @@ pass2_no_dither (j_decompress_ptr cinfo,
13201320
#else
13211321
r = gdTrueColorGetRed (*inptr);
13221322
g = gdTrueColorGetGreen (*inptr);
1323-
/*
1323+
/*
13241324
2.0.24: inptr must not be incremented until after
1325-
transparency check, if any. Thanks to "Super Pikeman."
1325+
transparency check, if any. Thanks to "Super Pikeman."
13261326
*/
13271327
b = gdTrueColorGetBlue (*inptr);
13281328

13291329
/* If the pixel is transparent, we assign it the palette index that
13301330
* will later be added at the end of the palette as the transparent
13311331
* index. */
1332-
if ((oim->transparent >= 0) && (oim->transparent == *(inptr - 1)))
1332+
if ((oim->transparent >= 0) && (oim->transparent == *inptr))
13331333
{
13341334
*outptr++ = nim->colorsTotal;
13351335
inptr++;
@@ -1795,7 +1795,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color
17951795
}
17961796
} else {
17971797
nim = oim;
1798-
}
1798+
}
17991799
if (!oim->trueColor)
18001800
{
18011801
/* (Almost) nothing to do! */
@@ -2004,7 +2004,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color
20042004
}
20052005

20062006
/* Success! Get rid of the truecolor image data. */
2007-
if (!cimP) {
2007+
if (!cimP) {
20082008
oim->trueColor = 0;
20092009
/* Junk the truecolor pixels */
20102010
for (i = 0; i < oim->sy; i++)

ext/gd/tests/bug72298.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Bug #72298: pass2_no_dither out-of-bounds access
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('gd')) die("skip gd extension not available\n");
6+
?>
7+
--FILE--
8+
<?php
9+
$img = imagecreatetruecolor (1 , 1);
10+
imagecolortransparent($img, 0);
11+
imagetruecolortopalette($img, false, 4);
12+
?>
13+
DONE
14+
--EXPECT--
15+
DONE

ext/gd/tests/bug72339.gd

64 MB
Binary file not shown.

ext/gd/tests/bug72339.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow
3+
--SKIPIF--
4+
<?php if (!function_exists("imagecreatefromgd2")) print "skip"; ?>
5+
--FILE--
6+
<?php imagecreatefromgd2(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug72339.gd"); ?>
7+
--EXPECTF--
8+
Warning: imagecreatefromgd2(): gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully
9+
in %sbug72339.php on line %d
10+
11+
Warning: imagecreatefromgd2(): '%sbug72339.gd' is not a valid GD2 file in %sbug72339.php on line %d

ext/mbstring/php_mbregex.c

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include "ext/standard/info.h"
3333
#include "php_mbregex.h"
3434
#include "mbstring.h"
35-
35+
3636
#include "php_onig_compat.h" /* must come prior to the oniguruma header */
3737
#include <oniguruma.h>
3838
#undef UChar
@@ -55,7 +55,7 @@ struct _zend_mb_regex_globals {
5555
#define MBREX(g) (MBSTRG(mb_regex_globals)->g)
5656

5757
/* {{{ static void php_mb_regex_free_cache() */
58-
static void php_mb_regex_free_cache(php_mb_regex_t **pre)
58+
static void php_mb_regex_free_cache(php_mb_regex_t **pre)
5959
{
6060
onig_free(*pre);
6161
}
@@ -78,7 +78,7 @@ static int _php_mb_regex_globals_ctor(zend_mb_regex_globals *pglobals TSRMLS_DC)
7878
/* }}} */
7979

8080
/* {{{ _php_mb_regex_globals_dtor */
81-
static void _php_mb_regex_globals_dtor(zend_mb_regex_globals *pglobals TSRMLS_DC)
81+
static void _php_mb_regex_globals_dtor(zend_mb_regex_globals *pglobals TSRMLS_DC)
8282
{
8383
zend_hash_destroy(&pglobals->ht_rc);
8484
}
@@ -466,7 +466,7 @@ static php_mb_regex_t *php_mbregex_compile_pattern(const char *pattern, int patl
466466
retval = *rc;
467467
}
468468
out:
469-
return retval;
469+
return retval;
470470
}
471471
/* }}} */
472472

@@ -483,15 +483,15 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT
483483
--len_left;
484484
*(p++) = 'i';
485485
}
486-
++len_req;
486+
++len_req;
487487
}
488488

489489
if ((option & ONIG_OPTION_EXTEND) != 0) {
490490
if (len_left > 0) {
491491
--len_left;
492492
*(p++) = 'x';
493493
}
494-
++len_req;
494+
++len_req;
495495
}
496496

497497
if ((option & (ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE)) ==
@@ -500,37 +500,37 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT
500500
--len_left;
501501
*(p++) = 'p';
502502
}
503-
++len_req;
503+
++len_req;
504504
} else {
505505
if ((option & ONIG_OPTION_MULTILINE) != 0) {
506506
if (len_left > 0) {
507507
--len_left;
508508
*(p++) = 'm';
509509
}
510-
++len_req;
510+
++len_req;
511511
}
512512

513513
if ((option & ONIG_OPTION_SINGLELINE) != 0) {
514514
if (len_left > 0) {
515515
--len_left;
516516
*(p++) = 's';
517517
}
518-
++len_req;
518+
++len_req;
519519
}
520-
}
520+
}
521521
if ((option & ONIG_OPTION_FIND_LONGEST) != 0) {
522522
if (len_left > 0) {
523523
--len_left;
524524
*(p++) = 'l';
525525
}
526-
++len_req;
526+
++len_req;
527527
}
528528
if ((option & ONIG_OPTION_FIND_NOT_EMPTY) != 0) {
529529
if (len_left > 0) {
530530
--len_left;
531531
*(p++) = 'n';
532532
}
533-
++len_req;
533+
++len_req;
534534
}
535535

536536
c = 0;
@@ -566,7 +566,7 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT
566566
--len_left;
567567
*(p++) = '\0';
568568
}
569-
++len_req;
569+
++len_req;
570570
if (len < len_req) {
571571
return len_req;
572572
}
@@ -577,11 +577,11 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT
577577

578578
/* {{{ _php_mb_regex_init_options */
579579
static void
580-
_php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, OnigSyntaxType **syntax, int *eval)
580+
_php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, OnigSyntaxType **syntax, int *eval)
581581
{
582582
int n;
583583
char c;
584-
int optm = 0;
584+
int optm = 0;
585585

586586
*syntax = ONIG_SYNTAX_RUBY;
587587

@@ -636,13 +636,13 @@ _php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, O
636636
*syntax = ONIG_SYNTAX_POSIX_EXTENDED;
637637
break;
638638
case 'e':
639-
if (eval != NULL) *eval = 1;
639+
if (eval != NULL) *eval = 1;
640640
break;
641641
default:
642642
break;
643643
}
644644
}
645-
if (option != NULL) *option|=optm;
645+
if (option != NULL) *option|=optm;
646646
}
647647
}
648648
/* }}} */
@@ -860,11 +860,11 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
860860
} else {
861861
/* FIXME: this code is not multibyte aware! */
862862
convert_to_long_ex(arg_pattern_zval);
863-
pat_buf[0] = (char)Z_LVAL_PP(arg_pattern_zval);
863+
pat_buf[0] = (char)Z_LVAL_PP(arg_pattern_zval);
864864
pat_buf[1] = '\0';
865865

866866
arg_pattern = pat_buf;
867-
arg_pattern_len = 1;
867+
arg_pattern_len = 1;
868868
}
869869
/* create regex pattern buffer */
870870
re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, options, MBREX(current_mbctype), syntax TSRMLS_CC);
@@ -934,7 +934,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
934934
}
935935
}
936936
}
937-
937+
938938
if (eval) {
939939
zval v;
940940
/* null terminate buffer */
@@ -953,32 +953,31 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
953953
eval_buf.len = 0;
954954
zval_dtor(&v);
955955
} else if (is_callable) {
956-
zval *retval_ptr;
956+
zval *retval_ptr = NULL;
957957
zval **args[1];
958958
zval *subpats;
959959
int i;
960-
960+
961961
MAKE_STD_ZVAL(subpats);
962962
array_init(subpats);
963-
963+
964964
for (i = 0; i < regs->num_regs; i++) {
965965
add_next_index_stringl(subpats, string + regs->beg[i], regs->end[i] - regs->beg[i], 1);
966-
}
967-
966+
}
967+
968968
args[0] = &subpats;
969969
/* null terminate buffer */
970970
smart_str_0(&eval_buf);
971-
971+
972972
arg_replace_fci.param_count = 1;
973973
arg_replace_fci.params = args;
974974
arg_replace_fci.retval_ptr_ptr = &retval_ptr;
975-
if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr) {
975+
if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr && retval_ptr) {
976976
convert_to_string_ex(&retval_ptr);
977977
smart_str_appendl(&out_buf, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr));
978978
eval_buf.len = 0;
979979
zval_ptr_dtor(&retval_ptr);
980980
} else {
981-
efree(description);
982981
if (!EG(exception)) {
983982
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function");
984983
}
@@ -991,7 +990,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
991990
pos = (OnigUChar *)string + n;
992991
} else {
993992
if (pos < string_lim) {
994-
smart_str_appendl(&out_buf, pos, 1);
993+
smart_str_appendl(&out_buf, pos, 1);
995994
}
996995
pos++;
997996
}
@@ -1013,7 +1012,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
10131012
smart_str_free(&eval_buf);
10141013

10151014
if (err <= -2) {
1016-
smart_str_free(&out_buf);
1015+
smart_str_free(&out_buf);
10171016
RETVAL_FALSE;
10181017
} else {
10191018
smart_str_appendc(&out_buf, '\0');
@@ -1063,7 +1062,7 @@ PHP_FUNCTION(mb_split)
10631062

10641063
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &arg_pattern, &arg_pattern_len, &string, &string_len, &count) == FAILURE) {
10651064
RETURN_FALSE;
1066-
}
1065+
}
10671066

10681067
if (count > 0) {
10691068
count--;
@@ -1317,7 +1316,7 @@ PHP_FUNCTION(mb_ereg_search_init)
13171316
if (zend_parse_parameters(argc TSRMLS_CC, "z|ss", &arg_str, &arg_pattern, &arg_pattern_len, &arg_options, &arg_options_len) == FAILURE) {
13181317
return;
13191318
}
1320-
1319+
13211320
if (argc > 1 && arg_pattern_len == 0) {
13221321
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty pattern");
13231322
RETURN_FALSE;
@@ -1416,7 +1415,7 @@ PHP_FUNCTION(mb_ereg_search_setpos)
14161415
/* }}} */
14171416

14181417
/* {{{ php_mb_regex_set_options */
1419-
static void _php_mb_regex_set_options(OnigOptionType options, OnigSyntaxType *syntax, OnigOptionType *prev_options, OnigSyntaxType **prev_syntax TSRMLS_DC)
1418+
static void _php_mb_regex_set_options(OnigOptionType options, OnigSyntaxType *syntax, OnigOptionType *prev_options, OnigSyntaxType **prev_syntax TSRMLS_DC)
14201419
{
14211420
if (prev_options != NULL) {
14221421
*prev_options = MBREX(regex_default_options);

ext/mbstring/tests/bug72402.phpt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #72402: _php_mb_regex_ereg_replace_exec - double free
3+
--SKIPIF--
4+
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
5+
--FILE--
6+
<?php
7+
function throwit() {
8+
throw new Exception('it');
9+
}
10+
$var10 = "throwit";
11+
try {
12+
$var14 = mb_ereg_replace_callback("", $var10, "");
13+
} catch(Exception $e) {}
14+
?>
15+
DONE
16+
--EXPECT--
17+
DONE

0 commit comments

Comments
 (0)