From: Stefan Esser Date: Sun, 28 Nov 2004 12:44:56 +0000 (+0000) Subject: MFH X-Git-Tag: php-4.3.10RC2~34 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a09961a655298befbcb7c62cf53bb9f67d97b7d2;p=php MFH --- diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 750bec3a4d..adef56a2f3 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -63,6 +63,13 @@ #include #endif +#define INC_OUTPUTPOS(a,b) \ + if ((a) < 0 || ((INT_MAX - outputpos)/(b)) < (a)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: integer overflow in format string", code); \ + RETURN_FALSE; \ + } \ + outputpos += (a)*(b); + /* Whether machine is little endian */ char machine_little_endian; @@ -246,7 +253,7 @@ PHP_FUNCTION(pack) switch ((int) code) { case 'h': case 'H': - outputpos += (arg + 1) / 2; /* 4 bit per arg */ + INC_OUTPUTPOS((arg + 1) / 2,1) /* 4 bit per arg */ break; case 'a': @@ -254,34 +261,34 @@ PHP_FUNCTION(pack) case 'c': case 'C': case 'x': - outputpos += arg; /* 8 bit per arg */ + INC_OUTPUTPOS(arg,1) /* 8 bit per arg */ break; case 's': case 'S': case 'n': case 'v': - outputpos += arg * 2; /* 16 bit per arg */ + INC_OUTPUTPOS(arg,2) /* 16 bit per arg */ break; case 'i': case 'I': - outputpos += arg * sizeof(int); + INC_OUTPUTPOS(arg,sizeof(int)) break; case 'l': case 'L': case 'N': case 'V': - outputpos += arg * 4; /* 32 bit per arg */ + INC_OUTPUTPOS(arg,4) /* 32 bit per arg */ break; case 'f': - outputpos += arg * sizeof(float); + INC_OUTPUTPOS(arg,sizeof(float)) break; case 'd': - outputpos += arg * sizeof(double); + INC_OUTPUTPOS(arg,sizeof(double)) break; case 'X': @@ -650,6 +657,11 @@ PHP_FUNCTION(unpack) sprintf(n, "%.*s", namelen, name); } + if (size != 0 && size != -1 && INT_MAX - size + 1 < inputpos) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: integer overflow", type); + inputpos = 0; + } + if ((inputpos + size) <= inputlen) { switch ((int) type) { case 'a': @@ -820,6 +832,10 @@ PHP_FUNCTION(unpack) } inputpos += size; + if (inputpos < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: outside of string", type); + inputpos = 0; + } } else if (arg < 0) { /* Reached end of input for '*' repeater */ break; diff --git a/main/php.h b/main/php.h index 1ea18721e2..70e1caa80c 100644 --- a/main/php.h +++ b/main/php.h @@ -224,6 +224,14 @@ char *strerror(int); #define LONG_MIN (- LONG_MAX - 1) #endif +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif + +#ifndef INT_MIN +#define INT_MIN (- INT_MAX - 1) +#endif + #define PHP_GCC_VERSION ZEND_GCC_VERSION #define PHP_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_MALLOC #define PHP_ATTRIBUTE_FORMAT ZEND_ATTRIBUTE_FORMAT