summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2015-05-12 14:24:15 -0700
committerStanislav Malyshev <stas@php.net>2015-05-12 14:24:15 -0700
commitc08f9c2c786b0f7cbb401c18f6634cb5773f5baf (patch)
tree5092cb2f0c1fa69076b0bcc8f2bc8a46308514c4
parentc117548ea9365adac00960fe5f43425b2955310d (diff)
parentf473ea5464361848f6fc45a8456c78de6d9f53c6 (diff)
downloadphp-git-c08f9c2c786b0f7cbb401c18f6634cb5773f5baf.tar.gz
Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4: fix format update NEWS Add test for bug #69522 Update tests Fix bug #69522 - do not allow int overflow Forgot test file Fix bug #69403 and other int overflows Fixed bug #69418 - more s->p fixes for filenames Fixed bug #69364 - use smart_str to assemble strings Fix bug #69453 - don't try to cut empty string Fix bug #69545 - avoid overflow when reading list Conflicts: ext/pcntl/pcntl.c ext/standard/basic_functions.c ext/standard/pack.c ext/standard/tests/dir/opendir_variation1-win32.phpt
-rw-r--r--Zend/zend_alloc.c22
-rw-r--r--Zend/zend_operators.c9
-rw-r--r--ext/ftp/ftp.c82
-rw-r--r--ext/pcntl/pcntl.c72
-rw-r--r--ext/phar/tar.c2
-rw-r--r--ext/phar/tests/bug69453.phpt21
-rw-r--r--ext/phar/tests/bug69453.tar.pharbin0 -> 8192 bytes
-rw-r--r--ext/standard/basic_functions.c22
-rw-r--r--ext/standard/dir.c62
-rw-r--r--ext/standard/file.c4
-rw-r--r--ext/standard/pack.c141
-rw-r--r--ext/standard/string.c8
-rw-r--r--ext/standard/tests/dir/dir_variation1.phpt22
-rw-r--r--ext/standard/tests/dir/opendir_variation1.phpt12
-rw-r--r--ext/standard/tests/file/mkdir_rmdir_variation2.phpt2
-rw-r--r--ext/standard/tests/file/tempnam_variation3-win32.phpt18
-rw-r--r--ext/standard/tests/file/tempnam_variation3.phpt22
-rw-r--r--ext/standard/tests/general_functions/include_path.phpt4
-rw-r--r--ext/standard/tests/strings/bug69522.phpt11
-rw-r--r--main/rfc1867.c51
20 files changed, 320 insertions, 267 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index db71d52b69..cd422e2d3e 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -984,7 +984,7 @@ static void zend_mm_random(unsigned char *buf, size_t size) /* {{{ */
int has_context = 0;
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
- /* Could mean that the key container does not exist, let try
+ /* Could mean that the key container does not exist, let try
again by asking for a new one */
if (GetLastError() == NTE_BAD_KEYSET) {
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
@@ -1348,7 +1348,7 @@ static int zend_mm_check_ptr(zend_mm_heap *heap, void *ptr, int silent ZEND_FILE
}
if (!silent) {
TSRMLS_FETCH();
-
+
zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC);
zend_debug_alloc_output("---------------------------------------\n");
zend_debug_alloc_output("%s(%d) : Block "PTR_FMT" status:\n" ZEND_FILE_LINE_RELAY_CC, ptr);
@@ -2175,7 +2175,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_
#if ZEND_MM_CACHE
if (ZEND_MM_SMALL_SIZE(true_size)) {
size_t index = ZEND_MM_BUCKET_INDEX(true_size);
-
+
if (heap->cache[index] != NULL) {
zend_mm_free_block *best_fit;
zend_mm_free_block **cache;
@@ -2188,7 +2188,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_
heap->cache[index] = best_fit->prev_free_block;
ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
-
+
ptr = ZEND_MM_DATA_OF(best_fit);
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
@@ -2470,7 +2470,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
: "%0"(res),
"rm"(size),
"rm"(offset));
-
+
if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
@@ -2619,7 +2619,7 @@ ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
- int length;
+ size_t length;
char *p;
#ifdef ZEND_SIGNALS
TSRMLS_FETCH();
@@ -2627,13 +2627,13 @@ ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
HANDLE_BLOCK_INTERRUPTIONS();
- length = strlen(s)+1;
- p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
+ length = strlen(s);
+ p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (UNEXPECTED(p == NULL)) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
}
- memcpy(p, s, length);
+ memcpy(p, s, length+1);
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
}
@@ -2647,7 +2647,7 @@ ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_
HANDLE_BLOCK_INTERRUPTIONS();
- p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
+ p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (UNEXPECTED(p == NULL)) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
@@ -2668,7 +2668,7 @@ ZEND_API char *zend_strndup(const char *s, uint length)
HANDLE_BLOCK_INTERRUPTIONS();
- p = (char *) malloc(length+1);
+ p = (char *) malloc(safe_address(length, 1, 1));
if (UNEXPECTED(p == NULL)) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index c87591513a..e0812fccc4 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1319,14 +1319,19 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
zend_error(E_ERROR, "String size overflow");
}
- Z_STRVAL_P(result) = erealloc(Z_STRVAL_P(result), res_len+1);
+ Z_STRVAL_P(result) = safe_erealloc(Z_STRVAL_P(result), res_len, 1, 1);
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
Z_STRVAL_P(result)[res_len]=0;
Z_STRLEN_P(result) = res_len;
} else {
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
- char *buf = (char *) emalloc(length + 1);
+ char *buf;
+
+ if (Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
+ zend_error(E_ERROR, "String size overflow");
+ }
+ buf = (char *) safe_emalloc(length, 1, 1);
memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
index a6e0dfd609..4e1b072246 100644
--- a/ext/ftp/ftp.c
+++ b/ext/ftp/ftp.c
@@ -188,9 +188,9 @@ ftp_close(ftpbuf_t *ftp)
SSL_shutdown(ftp->ssl_handle);
SSL_free(ftp->ssl_handle);
}
-#endif
+#endif
closesocket(ftp->fd);
- }
+ }
ftp_gc(ftp);
efree(ftp);
return NULL;
@@ -262,7 +262,7 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
if (!ftp_getresp(ftp)) {
return 0;
}
-
+
if (ftp->resp != 234) {
if (!ftp_putcmd(ftp, "AUTH", "SSL")) {
return 0;
@@ -270,7 +270,7 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
if (!ftp_getresp(ftp)) {
return 0;
}
-
+
if (ftp->resp != 334) {
return 0;
} else {
@@ -278,7 +278,7 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
ftp->use_ssl_for_data = 1;
}
}
-
+
ctx = SSL_CTX_new(SSLv23_client_method());
if (ctx == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create the SSL context");
@@ -325,8 +325,8 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
if (!ftp_getresp(ftp)) {
return 0;
}
-
- ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
+
+ ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
}
}
#endif
@@ -360,7 +360,7 @@ ftp_reinit(ftpbuf_t *ftp)
{
if (ftp == NULL) {
return 0;
- }
+ }
ftp_gc(ftp);
@@ -395,7 +395,7 @@ ftp_syst(ftpbuf_t *ftp)
if (!ftp_putcmd(ftp, "SYST", NULL)) {
return NULL;
}
- if (!ftp_getresp(ftp) || ftp->resp != 215) {
+ if (!ftp_getresp(ftp) || ftp->resp != 215) {
return NULL;
}
syst = ftp->inbuf;
@@ -431,14 +431,14 @@ ftp_pwd(ftpbuf_t *ftp)
if (!ftp_putcmd(ftp, "PWD", NULL)) {
return NULL;
}
- if (!ftp_getresp(ftp) || ftp->resp != 257) {
+ if (!ftp_getresp(ftp) || ftp->resp != 257) {
return NULL;
}
/* copy out the pwd from response */
- if ((pwd = strchr(ftp->inbuf, '"')) == NULL) {
+ if ((pwd = strchr(ftp->inbuf, '"')) == NULL) {
return NULL;
}
- if ((end = strrchr(++pwd, '"')) == NULL) {
+ if ((end = strrchr(++pwd, '"')) == NULL) {
return NULL;
}
ftp->pwd = estrndup(pwd, end - pwd);
@@ -608,7 +608,7 @@ ftp_chmod(ftpbuf_t *ftp, const int mode, const char *filename, const int filenam
if (!ftp_getresp(ftp) || ftp->resp != 200) {
return 0;
}
-
+
return 1;
}
/* }}} */
@@ -625,7 +625,7 @@ ftp_alloc(ftpbuf_t *ftp, const long size, char **response)
}
snprintf(buffer, sizeof(buffer) - 1, "%ld", size);
-
+
if (!ftp_putcmd(ftp, "ALLO", buffer)) {
return 0;
}
@@ -642,7 +642,7 @@ ftp_alloc(ftpbuf_t *ftp, const long size, char **response)
return 0;
}
- return 1;
+ return 1;
}
/* }}} */
@@ -674,7 +674,7 @@ ftp_type(ftpbuf_t *ftp, ftptype_t type)
if (ftp == NULL) {
return 0;
}
- if (type == ftp->type) {
+ if (type == ftp->type) {
return 1;
}
if (type == FTPTYPE_ASCII) {
@@ -765,7 +765,7 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
if (!ftp_putcmd(ftp, "PASV", NULL)) {
return 0;
}
- if (!ftp_getresp(ftp) || ftp->resp != 227) {
+ if (!ftp_getresp(ftp) || ftp->resp != 227) {
return 0;
}
/* parse out the IP and port */
@@ -807,7 +807,7 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type,
if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
goto bail;
}
-
+
ftp->data = data;
if (resumepos > 0) {
@@ -900,7 +900,7 @@ ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, l
if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
goto bail;
}
- ftp->data = data;
+ ftp->data = data;
if (startpos > 0) {
snprintf(arg, sizeof(arg), "%ld", startpos);
@@ -1101,7 +1101,7 @@ ftp_putcmd(ftpbuf_t *ftp, const char *cmd, const char *args)
if (strpbrk(cmd, "\r\n")) {
return 0;
- }
+ }
/* build the output buffer */
if (args && args[0]) {
/* "cmd args\r\n\0" */
@@ -1247,7 +1247,7 @@ my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
#if HAVE_OPENSSL_EXT
if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) {
sent = SSL_write(ftp->ssl_handle, buf, size);
- } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
+ } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
sent = SSL_write(ftp->data->ssl_handle, buf, size);
} else {
#endif
@@ -1287,14 +1287,14 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
#if HAVE_OPENSSL_EXT
if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) {
nr_bytes = SSL_read(ftp->ssl_handle, buf, len);
- } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
+ } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) {
nr_bytes = SSL_read(ftp->data->ssl_handle, buf, len);
} else {
#endif
nr_bytes = recv(s, buf, len, 0);
#if HAVE_OPENSSL_EXT
}
-#endif
+#endif
return (nr_bytes);
}
/* }}} */
@@ -1511,7 +1511,7 @@ data_accept(databuf_t *data, ftpbuf_t *ftp TSRMLS_DC)
data_accepted:
#if HAVE_OPENSSL_EXT
-
+
/* now enable ssl if we need to */
if (ftp->use_ssl && ftp->use_ssl_for_data) {
ctx = SSL_CTX_new(SSLv23_client_method());
@@ -1531,23 +1531,23 @@ data_accepted:
SSL_CTX_free(ctx);
return 0;
}
-
-
+
+
SSL_set_fd(data->ssl_handle, data->fd);
if (ftp->old_ssl) {
SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);
}
-
+
if (SSL_connect(data->ssl_handle) <= 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_accept: SSL/TLS handshake failed");
SSL_shutdown(data->ssl_handle);
SSL_free(data->ssl_handle);
return 0;
}
-
+
data->ssl_active = 1;
- }
+ }
#endif
@@ -1562,14 +1562,14 @@ data_close(ftpbuf_t *ftp, databuf_t *data)
{
#if HAVE_OPENSSL_EXT
SSL_CTX *ctx;
-#endif
+#endif
if (data == NULL) {
return NULL;
}
if (data->listener != -1) {
#if HAVE_OPENSSL_EXT
if (data->ssl_active) {
-
+
ctx = SSL_get_SSL_CTX(data->ssl_handle);
SSL_CTX_free(ctx);
@@ -1577,9 +1577,9 @@ data_close(ftpbuf_t *ftp, databuf_t *data)
SSL_free(data->ssl_handle);
data->ssl_active = 0;
}
-#endif
+#endif
closesocket(data->listener);
- }
+ }
if (data->fd != -1) {
#if HAVE_OPENSSL_EXT
if (data->ssl_active) {
@@ -1590,9 +1590,9 @@ data_close(ftpbuf_t *ftp, databuf_t *data)
SSL_free(data->ssl_handle);
data->ssl_active = 0;
}
-#endif
+#endif
closesocket(data->fd);
- }
+ }
if (ftp) {
ftp->data = NULL;
}
@@ -1610,8 +1610,8 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
databuf_t *data = NULL;
char *ptr;
int ch, lastch;
- int size, rcvd;
- int lines;
+ size_t size, rcvd;
+ size_t lines;
char **ret = NULL;
char **entry;
char *text;
@@ -1629,7 +1629,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {
goto bail;
}
- ftp->data = data;
+ ftp->data = data;
if (!ftp_putcmd(ftp, cmd, path)) {
goto bail;
@@ -1653,7 +1653,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
lines = 0;
lastch = 0;
while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {
- if (rcvd == -1) {
+ if (rcvd == -1 || rcvd > ((size_t)(-1))-size) {
goto bail;
}
@@ -1858,7 +1858,7 @@ ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type
if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {
goto bail;
}
- if ((data = data_accept(data, ftp TSRMLS_CC)) == NULL) {
+ if ((data = data_accept(data, ftp TSRMLS_CC)) == NULL) {
goto bail;
}
ftp->data = data;
@@ -1914,7 +1914,7 @@ ftp_nb_continue_write(ftpbuf_t *ftp TSRMLS_DC)
goto bail;
}
ftp->data = data_close(ftp, ftp->data);
-
+
if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) {
goto bail;
}
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index bace3b056e..975b7f8108 100644
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -198,7 +198,7 @@ ZEND_GET_MODULE(pcntl)
static void pcntl_signal_handler(int);
static void pcntl_signal_dispatch();
-
+
void php_register_signal_constants(INIT_FUNC_ARGS)
{
@@ -234,7 +234,7 @@ void php_register_signal_constants(INIT_FUNC_ARGS)
REGISTER_LONG_CONSTANT("SIGTERM", (long) SIGTERM, CONST_CS | CONST_PERSISTENT);
#ifdef SIGSTKFLT
REGISTER_LONG_CONSTANT("SIGSTKFLT",(long) SIGSTKFLT, CONST_CS | CONST_PERSISTENT);
-#endif
+#endif
#ifdef SIGCLD
REGISTER_LONG_CONSTANT("SIGCLD", (long) SIGCLD, CONST_CS | CONST_PERSISTENT);
#endif
@@ -484,7 +484,7 @@ static void php_pcntl_register_errno_constants(INIT_FUNC_ARGS)
}
static PHP_GINIT_FUNCTION(pcntl)
-{
+{
memset(pcntl_globals, 0, sizeof(*pcntl_globals));
}
@@ -547,7 +547,7 @@ PHP_FUNCTION(pcntl_fork)
PCNTL_G(last_error) = errno;
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d", errno);
}
-
+
RETURN_LONG((long) id);
}
/* }}} */
@@ -560,7 +560,7 @@ PHP_FUNCTION(pcntl_alarm)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &seconds) == FAILURE)
return;
-
+
RETURN_LONG ((long) alarm(seconds));
}
/* }}} */
@@ -576,7 +576,7 @@ PHP_FUNCTION(pcntl_waitpid)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|l", &pid, &z_status, &options) == FAILURE)
return;
-
+
convert_to_long_ex(&z_status);
status = Z_LVAL_P(z_status);
@@ -604,7 +604,7 @@ PHP_FUNCTION(pcntl_wait)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &z_status, &options) == FAILURE)
return;
-
+
convert_to_long_ex(&z_status);
status = Z_LVAL_P(z_status);
@@ -628,7 +628,7 @@ PHP_FUNCTION(pcntl_wait)
}
/* }}} */
-/* {{{ proto bool pcntl_wifexited(int status)
+/* {{{ proto bool pcntl_wifexited(int status)
Returns true if the child status code represents a successful exit */
PHP_FUNCTION(pcntl_wifexited)
{
@@ -646,7 +646,7 @@ PHP_FUNCTION(pcntl_wifexited)
}
/* }}} */
-/* {{{ proto bool pcntl_wifstopped(int status)
+/* {{{ proto bool pcntl_wifstopped(int status)
Returns true if the child status code represents a stopped process (WUNTRACED must have been used with waitpid) */
PHP_FUNCTION(pcntl_wifstopped)
{
@@ -664,7 +664,7 @@ PHP_FUNCTION(pcntl_wifstopped)
}
/* }}} */
-/* {{{ proto bool pcntl_wifsignaled(int status)
+/* {{{ proto bool pcntl_wifsignaled(int status)
Returns true if the child status code represents a process that was terminated due to a signal */
PHP_FUNCTION(pcntl_wifsignaled)
{
@@ -682,7 +682,7 @@ PHP_FUNCTION(pcntl_wifsignaled)
}
/* }}} */
-/* {{{ proto int pcntl_wexitstatus(int status)
+/* {{{ proto int pcntl_wexitstatus(int status)
Returns the status code of a child's exit */
PHP_FUNCTION(pcntl_wexitstatus)
{
@@ -700,7 +700,7 @@ PHP_FUNCTION(pcntl_wexitstatus)
}
/* }}} */
-/* {{{ proto int pcntl_wtermsig(int status)
+/* {{{ proto int pcntl_wtermsig(int status)
Returns the number of the signal that terminated the process who's status code is passed */
PHP_FUNCTION(pcntl_wtermsig)
{
@@ -718,7 +718,7 @@ PHP_FUNCTION(pcntl_wtermsig)
}
/* }}} */
-/* {{{ proto int pcntl_wstopsig(int status)
+/* {{{ proto int pcntl_wstopsig(int status)
Returns the number of the signal that caused the process to stop who's status code is passed */
PHP_FUNCTION(pcntl_wstopsig)
{
@@ -754,19 +754,19 @@ PHP_FUNCTION(pcntl_exec)
char *path;
int path_len;
ulong key_num;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|aa", &path, &path_len, &args, &envs) == FAILURE) {
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|aa", &path, &path_len, &args, &envs) == FAILURE) {
return;
}
-
+
if (ZEND_NUM_ARGS() > 1) {
/* Build argument list */
args_hash = HASH_OF(args);
argc = zend_hash_num_elements(args_hash);
-
+
argv = safe_emalloc((argc + 2), sizeof(char *), 0);
*argv = path;
- for ( zend_hash_internal_pointer_reset(args_hash), current_arg = argv+1;
+ for ( zend_hash_internal_pointer_reset(args_hash), current_arg = argv+1;
(argi < argc && (zend_hash_get_current_data(args_hash, (void **) &element) == SUCCESS));
(argi++, current_arg++, zend_hash_move_forward(args_hash)) ) {
@@ -784,9 +784,9 @@ PHP_FUNCTION(pcntl_exec)
/* Build environment pair list */
envs_hash = HASH_OF(envs);
envc = zend_hash_num_elements(envs_hash);
-
+
envp = safe_emalloc((envc + 1), sizeof(char *), 0);
- for ( zend_hash_internal_pointer_reset(envs_hash), pair = envp;
+ for ( zend_hash_internal_pointer_reset(envs_hash), pair = envp;
(envi < envc && (zend_hash_get_current_data(envs_hash, (void **) &element) == SUCCESS));
(envi++, pair++, zend_hash_move_forward(envs_hash)) ) {
switch (return_val = zend_hash_get_current_key_ex(envs_hash, &key, &key_length, &key_num, 0, NULL)) {
@@ -802,13 +802,13 @@ PHP_FUNCTION(pcntl_exec)
convert_to_string_ex(element);
- /* Length of element + equal sign + length of key + null */
+ /* Length of element + equal sign + length of key + null */
pair_length = Z_STRLEN_PP(element) + key_length + 2;
*pair = emalloc(pair_length);
- strlcpy(*pair, key, key_length);
+ strlcpy(*pair, key, key_length);
strlcat(*pair, "=", pair_length);
strlcat(*pair, Z_STRVAL_PP(element), pair_length);
-
+
/* Cleanup */
if (return_val == HASH_KEY_IS_LONG) efree(key);
}
@@ -818,7 +818,7 @@ PHP_FUNCTION(pcntl_exec)
PCNTL_G(last_error) = errno;
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error has occurred: (errno %d) %s", errno, strerror(errno));
}
-
+
/* Cleanup */
for (pair = envp; *pair != NULL; pair++) efree(*pair);
efree(envp);
@@ -831,7 +831,7 @@ PHP_FUNCTION(pcntl_exec)
}
efree(argv);
-
+
RETURN_FALSE;
}
/* }}} */
@@ -881,7 +881,7 @@ PHP_FUNCTION(pcntl_signal)
zend_hash_index_del(&PCNTL_G(php_signal_table), signo);
RETURN_TRUE;
}
-
+
if (!zend_is_callable(handle, 0, &func_name TSRMLS_CC)) {
PCNTL_G(last_error) = EINVAL;
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a callable function name error", func_name);
@@ -889,11 +889,11 @@ PHP_FUNCTION(pcntl_signal)
RETURN_FALSE;
}
efree(func_name);
-
+
/* Add the function name to our signal table */
zend_hash_index_update(&PCNTL_G(php_signal_table), signo, (void **) &handle, sizeof(zval *), (void **) &dest_handle);
if (dest_handle) zval_add_ref(dest_handle);
-
+
if (php_signal4(signo, pcntl_signal_handler, (int) restart_syscalls, 1) == SIG_ERR) {
PCNTL_G(last_error) = errno;
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error assigning signal");
@@ -1030,7 +1030,7 @@ static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait) /* {{
}
/*
- * sigtimedwait and sigwaitinfo can return 0 on success on some
+ * sigtimedwait and sigwaitinfo can return 0 on success on some
* platforms, e.g. NetBSD
*/
if (!signo && siginfo.si_signo) {
@@ -1078,7 +1078,7 @@ static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait) /* {{
EMPTY_SWITCH_DEFAULT_CASE();
}
}
-
+
RETURN_LONG(signo);
}
/* }}} */
@@ -1108,12 +1108,12 @@ PHP_FUNCTION(pcntl_getpriority)
long who = PRIO_PROCESS;
long pid = getpid();
int pri;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &pid, &who) == FAILURE) {
RETURN_FALSE;
}
- /* needs to be cleared, since any returned value is valid */
+ /* needs to be cleared, since any returned value is valid */
errno = 0;
pri = getpriority(who, pid);
@@ -1173,7 +1173,7 @@ PHP_FUNCTION(pcntl_setpriority)
}
RETURN_FALSE;
}
-
+
RETURN_TRUE;
}
/* }}} */
@@ -1206,7 +1206,7 @@ static void pcntl_signal_handler(int signo)
{
struct php_pcntl_pending_signal *psig;
TSRMLS_FETCH();
-
+
psig = PCNTL_G(spares);
if (!psig) {
/* oops, too many signals for us to track, so we'll forget about this one */
@@ -1255,7 +1255,7 @@ void pcntl_signal_dispatch()
queue = PCNTL_G(head);
PCNTL_G(head) = NULL; /* simple stores are atomic */
-
+
/* Allocate */
while (queue) {
@@ -1282,7 +1282,7 @@ void pcntl_signal_dispatch()
/* Re-enable queue */
PCNTL_G(processing_signal_queue) = 0;
-
+
/* return signal mask to previous state */
sigprocmask(SIG_SETMASK, &old_mask, NULL);
}
diff --git a/ext/phar/tar.c b/ext/phar/tar.c
index c4a81fb799..34ef0ef892 100644
--- a/ext/phar/tar.c
+++ b/ext/phar/tar.c
@@ -434,7 +434,7 @@ bail:
entry.filename_len = i;
entry.filename = pestrndup(hdr->name, i, myphar->is_persistent);
- if (entry.filename[entry.filename_len - 1] == '/') {
+ if (i > 0 && entry.filename[entry.filename_len - 1] == '/') {
/* some tar programs store directories with trailing slash */
entry.filename[entry.filename_len - 1] = '\0';
entry.filename_len--;
diff --git a/ext/phar/tests/bug69453.phpt b/ext/phar/tests/bug69453.phpt
new file mode 100644
index 0000000000..4a2a37f00a
--- /dev/null
+++ b/ext/phar/tests/bug69453.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Phar: bug #69453: Memory Corruption in phar_parse_tarfile when entry filename starts with null
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/bug69453.tar.phar';
+try {
+$r = new Phar($fname, 0);
+} catch(UnexpectedValueException $e) {
+ echo $e;
+}
+?>
+
+==DONE==
+--EXPECTF--
+exception 'UnexpectedValueException' with message 'phar error: "%s/bug69453.tar.phar" is a corrupted tar file (checksum mismatch of file "")' in %s:%d
+Stack trace:
+#0 %s/bug69453.php(%d): Phar->__construct('%s', 0)
+#1 {main}
+==DONE== \ No newline at end of file
diff --git a/ext/phar/tests/bug69453.tar.phar b/ext/phar/tests/bug69453.tar.phar
new file mode 100644
index 0000000000..655aa57e21
--- /dev/null
+++ b/ext/phar/tests/bug69453.tar.phar
Binary files differ
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index a3783e0712..98a5bb6db6 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -2127,7 +2127,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_stream_set_write_buffer, 0)
ZEND_ARG_INFO(0, fp)
ZEND_ARG_INFO(0, buffer)
ZEND_END_ARG_INFO()
-
+
ZEND_BEGIN_ARG_INFO(arginfo_stream_set_chunk_size, 0)
ZEND_ARG_INFO(0, fp)
ZEND_ARG_INFO(0, chunk_size)
@@ -2322,7 +2322,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_lcfirst, 0)
ZEND_ARG_INFO(0, str)
ZEND_END_ARG_INFO()
-
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ucwords, 0, 0, 1)
ZEND_ARG_INFO(0, str)
ZEND_ARG_INFO(0, delimiters)
@@ -3475,7 +3475,7 @@ static void basic_globals_ctor(php_basic_globals *basic_globals_p TSRMLS_DC) /*
BG(user_tick_functions) = NULL;
BG(user_filter_map) = NULL;
BG(serialize_lock) = 0;
-
+
memset(&BG(serialize), 0, sizeof(BG(serialize)));
memset(&BG(unserialize), 0, sizeof(BG(unserialize)));
@@ -4034,8 +4034,8 @@ PHP_FUNCTION(getenv)
int size;
SetLastError(0);
- /*If the given bugger is not large enough to hold the data, the return value is
- the buffer size, in characters, required to hold the string and its terminating
+ /*If the given bugger is not large enough to hold the data, the return value is
+ the buffer size, in characters, required to hold the string and its terminating
null character. We use this return value to alloc the final buffer. */
size = GetEnvironmentVariableA(str, &dummybuf, 0);
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
@@ -4087,7 +4087,7 @@ PHP_FUNCTION(putenv)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &setting, &setting_len) == FAILURE) {
return;
}
-
+
if(setting_len == 0 || setting[0] == '=') {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter syntax");
RETURN_FALSE;
@@ -4634,7 +4634,7 @@ PHP_FUNCTION(set_magic_quotes_runtime)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &new_setting) == FAILURE) {
return;
}
-
+
if (new_setting) {
php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "magic_quotes_runtime is not supported anymore");
}
@@ -4922,7 +4922,7 @@ PHP_FUNCTION(forward_static_call)
instanceof_function(EG(called_scope), fci_cache.calling_scope TSRMLS_CC)) {
fci_cache.called_scope = EG(called_scope);
}
-
+
if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && fci.retval_ptr_ptr && *fci.retval_ptr_ptr) {
COPY_PZVAL_TO_ZVAL(*return_value, *fci.retval_ptr_ptr);
}
@@ -5495,7 +5495,7 @@ PHP_FUNCTION(set_include_path)
int new_value_len;
char *old_value;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &new_value, &new_value_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &new_value, &new_value_len) == FAILURE) {
return;
}
@@ -5623,7 +5623,7 @@ PHP_FUNCTION(getservbyname)
}
-/* empty string behaves like NULL on windows implementation of
+/* empty string behaves like NULL on windows implementation of
getservbyname. Let be portable instead. */
#ifdef PHP_WIN32
if (proto_len == 0) {
@@ -6051,7 +6051,7 @@ PHP_FUNCTION(parse_ini_string)
/* }}} */
#if ZEND_DEBUG
-/* This function returns an array of ALL valid ini options with values and
+/* This function returns an array of ALL valid ini options with values and
* is not the same as ini_get_all() which returns only registered ini options. Only useful for devs to debug php.ini scanner/parser! */
PHP_FUNCTION(config_get_hash) /* {{{ */
{
diff --git a/ext/standard/dir.c b/ext/standard/dir.c
index 2ba4024a5b..ddf884f150 100644
--- a/ext/standard/dir.c
+++ b/ext/standard/dir.c
@@ -93,8 +93,8 @@ static zend_class_entry *dir_class_entry_ptr;
dirp = (php_stream *) zend_fetch_resource(&id TSRMLS_CC, -1, "Directory", NULL, 1, php_file_le_stream()); \
if (!dirp) \
RETURN_FALSE; \
- }
-
+ }
+
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX(arginfo_dir, 0, 0, 0)
ZEND_ARG_INFO(0, dir_handle)
@@ -118,7 +118,7 @@ static void php_set_default_dir(int id TSRMLS_DC)
if (id != -1) {
zend_list_addref(id);
}
-
+
DIRG(default_dir) = id;
}
@@ -168,25 +168,25 @@ PHP_MINIT_FUNCTION(dir)
#ifdef GLOB_NOSORT
REGISTER_LONG_CONSTANT("GLOB_NOSORT", GLOB_NOSORT, CONST_CS | CONST_PERSISTENT);
-#else
+#else
# define GLOB_NOSORT 0
#endif
#ifdef GLOB_NOCHECK
REGISTER_LONG_CONSTANT("GLOB_NOCHECK", GLOB_NOCHECK, CONST_CS | CONST_PERSISTENT);
-#else
+#else
# define GLOB_NOCHECK 0
#endif
#ifdef GLOB_NOESCAPE
REGISTER_LONG_CONSTANT("GLOB_NOESCAPE", GLOB_NOESCAPE, CONST_CS | CONST_PERSISTENT);
-#else
+#else
# define GLOB_NOESCAPE 0
#endif
#ifdef GLOB_ERR
REGISTER_LONG_CONSTANT("GLOB_ERR", GLOB_ERR, CONST_CS | CONST_PERSISTENT);
-#else
+#else
# define GLOB_ERR 0
#endif
@@ -219,12 +219,12 @@ static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
php_stream_context *context = NULL;
php_stream *dirp;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dirname, &dir_len, &zcontext) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|r", &dirname, &dir_len, &zcontext) == FAILURE) {
RETURN_NULL();
}
context = php_stream_context_from_zval(zcontext, 0);
-
+
dirp = php_stream_opendir(dirname, REPORT_ERRORS, context);
if (dirp == NULL) {
@@ -232,7 +232,7 @@ static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
}
dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
-
+
php_set_default_dir(dirp->rsrc_id TSRMLS_CC);
if (createobject) {
@@ -293,11 +293,11 @@ PHP_FUNCTION(chroot)
{
char *str;
int ret, str_len;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &str, &str_len) == FAILURE) {
RETURN_FALSE;
}
-
+
ret = chroot(str);
if (ret != 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
@@ -305,9 +305,9 @@ PHP_FUNCTION(chroot)
}
php_clear_stat_cache(1, NULL, 0 TSRMLS_CC);
-
+
ret = chdir("/");
-
+
if (ret != 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
RETURN_FALSE;
@@ -324,7 +324,7 @@ PHP_FUNCTION(chdir)
{
char *str;
int ret, str_len;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &str, &str_len) == FAILURE) {
RETURN_FALSE;
}
@@ -333,7 +333,7 @@ PHP_FUNCTION(chdir)
RETURN_FALSE;
}
ret = VCWD_CHDIR(str);
-
+
if (ret != 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
RETURN_FALSE;
@@ -358,7 +358,7 @@ PHP_FUNCTION(getcwd)
{
char path[MAXPATHLEN];
char *ret=NULL;
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -383,7 +383,7 @@ PHP_FUNCTION(rewinddir)
{
zval *id = NULL, **tmp, *myself;
php_stream *dirp;
-
+
FETCH_DIRP();
if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
@@ -450,9 +450,9 @@ PHP_FUNCTION(glob)
RETURN_FALSE;
}
-#ifdef ZTS
+#ifdef ZTS
if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
- result = VCWD_GETCWD(cwd, MAXPATHLEN);
+ result = VCWD_GETCWD(cwd, MAXPATHLEN);
if (!result) {
cwd[0] = '\0';
}
@@ -465,10 +465,10 @@ PHP_FUNCTION(glob)
snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
pattern = work_pattern;
- }
+ }
#endif
-
+
memset(&globbuf, 0, sizeof(glob_t));
globbuf.gl_offs = 0;
if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
@@ -477,7 +477,7 @@ PHP_FUNCTION(glob)
/* Some glob implementation simply return no data if no matches
were found, others return the GLOB_NOMATCH error code.
We don't want to treat GLOB_NOMATCH as an error condition
- so that PHP glob() behaves the same on both types of
+ so that PHP glob() behaves the same on both types of
implementations and so that 'foreach (glob() as ...'
can be used for simple glob() calls without further error
checking.
@@ -517,11 +517,11 @@ no_results:
}
/* we need to do this everytime since GLOB_ONLYDIR does not guarantee that
* all directories will be filtered. GNU libc documentation states the
- * following:
- * If the information about the type of the file is easily available
- * non-directories will be rejected but no extra work will be done to
- * determine the information for each file. I.e., the caller must still be
- * able to filter directories out.
+ * following:
+ * If the information about the type of the file is easily available
+ * non-directories will be rejected but no extra work will be done to
+ * determine the information for each file. I.e., the caller must still be
+ * able to filter directories out.
*/
if (flags & GLOB_ONLYDIR) {
struct stat s;
@@ -545,7 +545,7 @@ no_results:
}
}
/* }}} */
-#endif
+#endif
/* {{{ proto array scandir(string dir [, int sorting_order [, resource context]])
List files & directories inside the specified path */
@@ -583,7 +583,7 @@ PHP_FUNCTION(scandir)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "(errno %d): %s", errno, strerror(errno));
RETURN_FALSE;
}
-
+
array_init(return_value);
for (i = 0; i < n; i++) {
diff --git a/ext/standard/file.c b/ext/standard/file.c
index c2e71d1dea..0abc022ca6 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -814,7 +814,7 @@ PHP_FUNCTION(tempnam)
char *p;
int fd;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pp", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
return;
}
@@ -1343,7 +1343,7 @@ PHP_FUNCTION(rmdir)
zval *zcontext = NULL;
php_stream_context *context;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dir, &dir_len, &zcontext) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|r", &dir, &dir_len, &zcontext) == FAILURE) {
RETURN_FALSE;
}
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index a874b7ace9..69fa675193 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -148,7 +148,7 @@ PHP_FUNCTION(pack)
}
else if (c >= '0' && c <= '9') {
arg = atoi(&format[i]);
-
+
while (format[i] >= '0' && format[i] <= '9' && i < formatlen) {
i++;
}
@@ -158,8 +158,8 @@ PHP_FUNCTION(pack)
/* Handle special arg '*' for all codes and check argv overflows */
switch ((int) code) {
/* Never uses any args */
- case 'x':
- case 'X':
+ case 'x':
+ case 'X':
case '@':
if (arg < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: '*' ignored", code);
@@ -168,10 +168,10 @@ PHP_FUNCTION(pack)
break;
/* Always uses one arg */
- case 'a':
- case 'A':
- case 'Z':
- case 'h':
+ case 'a':
+ case 'A':
+ case 'Z':
+ case 'h':
case 'H':
if (currentarg >= num_args) {
efree(argv);
@@ -199,20 +199,20 @@ PHP_FUNCTION(pack)
break;
/* Use as many args as specified */
- case 'c':
- case 'C':
- case 's':
- case 'S':
- case 'i':
+ case 'c':
+ case 'C':
+ case 's':
+ case 'S':
+ case 'i':
case 'I':
- case 'l':
- case 'L':
- case 'n':
- case 'N':
- case 'v':
+ case 'l':
+ case 'L':
+ case 'n':
+ case 'N':
+ case 'v':
case 'V':
- case 'f':
- case 'd':
+ case 'f':
+ case 'd':
if (arg < 0) {
arg = num_args - currentarg;
}
@@ -250,35 +250,35 @@ PHP_FUNCTION(pack)
int arg = formatargs[i];
switch ((int) code) {
- case 'h':
- case 'H':
+ case 'h':
+ case 'H':
INC_OUTPUTPOS((arg + (arg % 2)) / 2,1) /* 4 bit per arg */
break;
- case 'a':
+ case 'a':
case 'A':
case 'Z':
- case 'c':
+ case 'c':
case 'C':
case 'x':
INC_OUTPUTPOS(arg,1) /* 8 bit per arg */
break;
- case 's':
- case 'S':
- case 'n':
+ case 's':
+ case 'S':
+ case 'n':
case 'v':
INC_OUTPUTPOS(arg,2) /* 16 bit per arg */
break;
- case 'i':
+ case 'i':
case 'I':
INC_OUTPUTPOS(arg,sizeof(int))
break;
- case 'l':
- case 'L':
- case 'N':
+ case 'l':
+ case 'L':
+ case 'N':
case 'V':
INC_OUTPUTPOS(arg,4) /* 32 bit per arg */
break;
@@ -321,8 +321,8 @@ PHP_FUNCTION(pack)
zval **val;
switch ((int) code) {
- case 'a':
- case 'A':
+ case 'a':
+ case 'A':
case 'Z': {
int arg_cp = (code != 'Z') ? arg : MAX(0, arg - 1);
memset(&output[outputpos], (code == 'a' || code == 'Z') ? '\0' : ' ', arg);
@@ -337,7 +337,7 @@ PHP_FUNCTION(pack)
break;
}
- case 'h':
+ case 'h':
case 'H': {
int nibbleshift = (code == 'h') ? 0 : 4;
int first = 1;
@@ -383,7 +383,7 @@ PHP_FUNCTION(pack)
break;
}
- case 'c':
+ case 'c':
case 'C':
while (arg-- > 0) {
php_pack(argv[currentarg++], 1, byte_map, &output[outputpos]);
@@ -391,9 +391,9 @@ PHP_FUNCTION(pack)
}
break;
- case 's':
- case 'S':
- case 'n':
+ case 's':
+ case 'S':
+ case 'n':
case 'v': {
int *map = machine_endian_short_map;
@@ -410,17 +410,17 @@ PHP_FUNCTION(pack)
break;
}
- case 'i':
- case 'I':
+ case 'i':
+ case 'I':
while (arg-- > 0) {
php_pack(argv[currentarg++], sizeof(int), int_map, &output[outputpos]);
outputpos += sizeof(int);
}
break;
- case 'l':
- case 'L':
- case 'N':
+ case 'l':
+ case 'L':
+ case 'N':
case 'V': {
int *map = machine_endian_long_map;
@@ -514,7 +514,7 @@ static long php_unpack(char *data, int size, int issigned, int *map)
/* unpack() is based on Perl's unpack(), but is modified a bit from there.
* Rather than depending on error-prone ordered lists or syntactically
- * unpleasant pass-by-reference, we return an object with named parameters
+ * unpleasant pass-by-reference, we return an object with named parameters
* (like *_fetch_object()). Syntax is "f[repeat]name/...", where "f" is the
* formatter char (like pack()), "[repeat]" is the optional repeater argument,
* and "name" is the name of the variable to use.
@@ -587,7 +587,7 @@ PHP_FUNCTION(unpack)
switch ((int) type) {
/* Never use any input */
- case 'X':
+ case 'X':
size = -1;
break;
@@ -595,44 +595,44 @@ PHP_FUNCTION(unpack)
size = 0;
break;
- case 'a':
+ case 'a':
case 'A':
case 'Z':
size = arg;
arg = 1;
break;
- case 'h':
- case 'H':
+ case 'h':
+ case 'H':
size = (arg > 0) ? (arg + (arg % 2)) / 2 : arg;
arg = 1;
break;
/* Use 1 byte of input */
- case 'c':
+ case 'c':
case 'C':
case 'x':
size = 1;
break;
/* Use 2 bytes of input */
- case 's':
- case 'S':
- case 'n':
+ case 's':
+ case 'S':
+ case 'n':
case 'v':
size = 2;
break;
/* Use sizeof(int) bytes of input */
- case 'i':
+ case 'i':
case 'I':
size = sizeof(int);
break;
/* Use 4 bytes of input */
- case 'l':
- case 'L':
- case 'N':
+ case 'l':
+ case 'L':
+ case 'N':
case 'V':
size = 4;
break;
@@ -654,6 +654,12 @@ PHP_FUNCTION(unpack)
break;
}
+ if (size != 0 && size != -1 && size < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: integer overflow", type);
+ zval_dtor(return_value);
+ RETURN_FALSE;
+ }
+
/* Do actual unpacking */
for (i = 0; i != arg; i++ ) {
/* Space for name + number, safe as namelen is ensured <= 200 */
@@ -669,7 +675,8 @@ PHP_FUNCTION(unpack)
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;
+ zval_dtor(return_value);
+ RETURN_FALSE;
}
if ((inputpos + size) <= inputlen) {
@@ -751,9 +758,9 @@ PHP_FUNCTION(unpack)
/* If size was given take minimum of len and size */
if (size >= 0 && len > (size * 2)) {
len = size * 2;
- }
+ }
- if (argb > 0) {
+ if (len > 0 && argb > 0) {
len -= argb % 2;
}
@@ -783,7 +790,7 @@ PHP_FUNCTION(unpack)
break;
}
- case 'c':
+ case 'c':
case 'C': {
int issigned = (type == 'c') ? (input[inputpos] & 0x80) : 0;
long v = php_unpack(&input[inputpos], 1, issigned, byte_map);
@@ -791,9 +798,9 @@ PHP_FUNCTION(unpack)
break;
}
- case 's':
- case 'S':
- case 'n':
+ case 's':
+ case 'S':
+ case 'n':
case 'v': {
long v;
int issigned = 0;
@@ -812,7 +819,7 @@ PHP_FUNCTION(unpack)
break;
}
- case 'i':
+ case 'i':
case 'I': {
long v;
int issigned = 0;
@@ -826,9 +833,9 @@ PHP_FUNCTION(unpack)
break;
}
- case 'l':
- case 'L':
- case 'N':
+ case 'l':
+ case 'L':
+ case 'N':
case 'V': {
int issigned = 0;
int *map = machine_endian_long_map;
@@ -851,7 +858,7 @@ PHP_FUNCTION(unpack)
v |= php_unpack(&input[inputpos], 4, issigned, map);
if (sizeof(long) > 4) {
if (type == 'l') {
- v = (signed int) v;
+ v = (signed int) v;
} else {
v = (unsigned int) v;
}
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 410535b41c..8c850512c7 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -13,7 +13,7 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Rasmus Lerdorf <rasmus@php.net> |
- | Stig Sæther Bakken <ssb@php.net> |
+ | Stig S�ther Bakken <ssb@php.net> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
@@ -1454,7 +1454,7 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen
}
#if defined(PHP_WIN32) || defined(NETWARE)
/* Catch relative paths in c:file.txt style. They're not to confuse
- with the NTFS streams. This part ensures also, that no drive
+ with the NTFS streams. This part ensures also, that no drive
letter traversing happens. */
} else if ((*c == ':' && (c - comp == 1))) {
if (state == 0) {
@@ -4910,6 +4910,10 @@ PHP_FUNCTION(str_repeat)
/* Initialize the result string */
result_len = input_len * mult;
+ if(result_len > INT_MAX) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, maximum %d allowed", INT_MAX);
+ RETURN_EMPTY_STRING();
+ }
result = (char *)safe_emalloc(input_len, mult, 1);
/* Heavy optimization for situations where input string is 1 byte long */
diff --git a/ext/standard/tests/dir/dir_variation1.phpt b/ext/standard/tests/dir/dir_variation1.phpt
index abb4719504..fff04ba8f9 100644
--- a/ext/standard/tests/dir/dir_variation1.phpt
+++ b/ext/standard/tests/dir/dir_variation1.phpt
@@ -8,7 +8,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') {
?>
--FILE--
<?php
-/*
+/*
* Prototype : object dir(string $directory[, resource $context])
* Description: Directory class with properties, handle and class and methods read, rewind and close
* Source code: ext/standard/dir.c
@@ -34,7 +34,7 @@ class A
}
// get a resource variable
-$fp = fopen(__FILE__, "r"); // get a file handle
+$fp = fopen(__FILE__, "r"); // get a file handle
$dfp = opendir( dirname(__FILE__) ); // get a dir handle
// unexpected values to be passed to $directory argument
@@ -92,27 +92,27 @@ echo "Done";
-- Iteration 1 --
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 2 --
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 3 --
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 4 --
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 5 --
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 6 --
@@ -151,16 +151,16 @@ bool(false)
-- Iteration 16 --
-Warning: dir() expects parameter 1 to be string, resource given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, resource given in %s on line %d
NULL
-- Iteration 17 --
-Warning: dir() expects parameter 1 to be string, resource given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, resource given in %s on line %d
NULL
-- Iteration 18 --
-Warning: dir() expects parameter 1 to be string, object given in %s on line %d
+Warning: dir() expects parameter 1 to be a valid path, object given in %s on line %d
NULL
-Done \ No newline at end of file
+Done
diff --git a/ext/standard/tests/dir/opendir_variation1.phpt b/ext/standard/tests/dir/opendir_variation1.phpt
index 8d195e1e62..cb4d543f72 100644
--- a/ext/standard/tests/dir/opendir_variation1.phpt
+++ b/ext/standard/tests/dir/opendir_variation1.phpt
@@ -9,7 +9,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') {
--FILE--
<?php
/* Prototype : mixed opendir(string $path[, resource $context])
- * Description: Open a directory and return a dir_handle
+ * Description: Open a directory and return a dir_handle
* Source code: ext/standard/dir.c
*/
@@ -30,7 +30,7 @@ unset ($unset_var);
// get a class
class classA {
-
+
var $path;
function __construct($path) {
$this->path = $path;
@@ -73,7 +73,7 @@ $inputs = array(
false,
TRUE,
FALSE,
-
+
// empty data
/*16*/ "",
'',
@@ -83,7 +83,7 @@ $inputs = array(
/*19*/ "$path",
'string',
$heredoc,
-
+
// object data
/*22*/ new classA($path),
@@ -194,7 +194,7 @@ bool(false)
-- Iteration 18 --
-Warning: opendir() expects parameter 1 to be string, array given in %s on line %d
+Warning: opendir() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-- Iteration 19 --
@@ -219,6 +219,6 @@ bool(false)
-- Iteration 25 --
-Warning: opendir() expects parameter 1 to be string, resource given in %s on line %d
+Warning: opendir() expects parameter 1 to be a valid path, resource given in %s on line %d
NULL
===DONE===
diff --git a/ext/standard/tests/file/mkdir_rmdir_variation2.phpt b/ext/standard/tests/file/mkdir_rmdir_variation2.phpt
index 14dd361e07..24dfc96ac9 100644
--- a/ext/standard/tests/file/mkdir_rmdir_variation2.phpt
+++ b/ext/standard/tests/file/mkdir_rmdir_variation2.phpt
@@ -68,7 +68,7 @@ bool(false)
Warning: mkdir() expects parameter 1 to be a valid path, string given in %s on line %d
bool(false)
-Warning: rmdir(%s): No such file or directory in %s on line %d
+Warning: rmdir() expects parameter 1 to be a valid path, string given in %s on line %d
bool(false)
*** Testing mkdir() with miscelleneous input ***
diff --git a/ext/standard/tests/file/tempnam_variation3-win32.phpt b/ext/standard/tests/file/tempnam_variation3-win32.phpt
index fb457cb6ab..cc8194afa3 100644
--- a/ext/standard/tests/file/tempnam_variation3-win32.phpt
+++ b/ext/standard/tests/file/tempnam_variation3-win32.phpt
@@ -22,9 +22,9 @@ if (!mkdir($file_path)) {
$file_path = realpath($file_path);
-/* An array of prefixes */
+/* An array of prefixes */
$names_arr = array(
- /* Valid args (casting)*/
+ /* Valid args (casting)*/
-1,
TRUE,
FALSE,
@@ -32,17 +32,17 @@ $names_arr = array(
"",
" ",
"\0",
- /* Invalid args */
+ /* Invalid args */
array(),
- /* Valid args*/
+ /* Valid args*/
/* prefix with path separator of a non existing directory*/
- "/no/such/file/dir",
+ "/no/such/file/dir",
"php/php"
);
$res_arr = array(
- /* Invalid args */
+ /* Invalid args */
true,
true,
true,
@@ -53,7 +53,7 @@ $res_arr = array(
false,
/* prefix with path separator of a non existing directory*/
- true,
+ true,
true
);
@@ -72,7 +72,7 @@ for( $i=0; $i<count($names_arr); $i++ ) {
} else {
echo "Failed, not created in the correct directory " . realpath($file_dir) . ' vs ' . $file_path ."\n";
}
-
+
if (!is_writable($file_name)) {
printf("%o\n", fileperms($file_name) );
@@ -105,7 +105,7 @@ Failed, not created in the correct directory %s vs %s
OK
-- Iteration 7 --
-Warning: tempnam() expects parameter 2 to be string, array given in %s\ext\standard\tests\file\tempnam_variation3-win32.php on line %d
+Warning: tempnam() expects parameter 2 to be a valid path, array given in %s\ext\standard\tests\file\tempnam_variation3-win32.php on line %d
OK
-- Iteration 8 --
OK
diff --git a/ext/standard/tests/file/tempnam_variation3.phpt b/ext/standard/tests/file/tempnam_variation3.phpt
index 69ab16c896..11b87809fc 100644
--- a/ext/standard/tests/file/tempnam_variation3.phpt
+++ b/ext/standard/tests/file/tempnam_variation3.phpt
@@ -17,9 +17,9 @@ echo "*** Testing tempnam() with obscure prefixes ***\n";
$file_path = dirname(__FILE__)."/tempnamVar3";
mkdir($file_path);
-/* An array of prefixes */
+/* An array of prefixes */
$names_arr = array(
- /* Invalid args */
+ /* Invalid args */
-1,
TRUE,
FALSE,
@@ -30,7 +30,7 @@ $names_arr = array(
array(),
/* prefix with path separator of a non existing directory*/
- "/no/such/file/dir",
+ "/no/such/file/dir",
"php/php"
);
@@ -48,10 +48,10 @@ for( $i=0; $i<count($names_arr); $i++ ) {
echo "File permissions are => ";
printf("%o", fileperms($file_name) );
echo "\n";
-
+
echo "File created in => ";
$file_dir = dirname($file_name);
-
+
if ($file_dir == sys_get_temp_dir()) {
echo "temp dir\n";
}
@@ -61,7 +61,7 @@ for( $i=0; $i<count($names_arr); $i++ ) {
else {
echo "unknown location\n";
}
-
+
}
else {
echo "-- File is not created --\n";
@@ -100,12 +100,14 @@ File name is => %s/%s
File permissions are => 100600
File created in => directory specified
-- Iteration 6 --
-File name is => %s/%s
-File permissions are => 100600
-File created in => directory specified
+
+Warning: tempnam() expects parameter 2 to be a valid path, string given in %s on line %d
+-- File is not created --
+
+Warning: unlink(): %s in %s on line %d
-- Iteration 7 --
-Warning: tempnam() expects parameter 2 to be string, array given in %s on line %d
+Warning: tempnam() expects parameter 2 to be a valid path, array given in %s on line %d
-- File is not created --
Warning: unlink(): %s in %s on line %d
diff --git a/ext/standard/tests/general_functions/include_path.phpt b/ext/standard/tests/general_functions/include_path.phpt
index 039230784d..8b6626fbc8 100644
--- a/ext/standard/tests/general_functions/include_path.phpt
+++ b/ext/standard/tests/general_functions/include_path.phpt
@@ -41,7 +41,7 @@ var_dump(get_include_path());
echo "Done\n";
?>
---EXPECTF--
+--EXPECTF--
string(1) "."
Warning: get_include_path() expects exactly 0 parameters, 1 given in %s on line %d
@@ -67,7 +67,7 @@ string(1) "."
NULL
string(1) "."
-Warning: set_include_path() expects parameter 1 to be string, array given in %s on line %d
+Warning: set_include_path() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
string(1) "."
NULL
diff --git a/ext/standard/tests/strings/bug69522.phpt b/ext/standard/tests/strings/bug69522.phpt
new file mode 100644
index 0000000000..fc86d409c6
--- /dev/null
+++ b/ext/standard/tests/strings/bug69522.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Bug #69522 (heap buffer overflow in unpack())
+--FILE--
+<?php
+$a = pack("AAAAAAAAAAAA", 1,2,3,4,5,6,7,8,9,10,11,12);
+$b = unpack('h2147483648', $a);
+?>
+===DONE===
+--EXPECTF--
+Warning: unpack(): Type h: integer overflow in %s on line %d
+===DONE===
diff --git a/main/rfc1867.c b/main/rfc1867.c
index 2c182025a2..86101dc817 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -33,6 +33,7 @@
#include "php_variables.h"
#include "rfc1867.h"
#include "ext/standard/php_string.h"
+#include "ext/standard/php_smart_str.h"
#define DEBUG_FILE_UPLOAD ZEND_DEBUG
@@ -398,8 +399,9 @@ static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC)
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC)
{
char *line;
- mime_header_entry prev_entry = {0}, entry;
- int prev_len, cur_len;
+ mime_header_entry entry = {0};
+ smart_str buf_value = {0};
+ char *key = NULL;
/* didn't find boundary, abort */
if (!find_boundary(self, self->boundary TSRMLS_CC)) {
@@ -411,11 +413,10 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T
while( (line = get_line(self TSRMLS_CC)) && line[0] != '\0' )
{
/* add header to table */
- char *key = line;
char *value = NULL;
if (php_rfc1867_encoding_translation(TSRMLS_C)) {
- self->input_encoding = zend_multibyte_encoding_detector(line, strlen(line), self->detect_order, self->detect_order_size TSRMLS_CC);
+ self->input_encoding = zend_multibyte_encoding_detector((unsigned char *)line, strlen(line), self->detect_order, self->detect_order_size TSRMLS_CC);
}
/* space in the beginning means same header */
@@ -424,31 +425,33 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T
}
if (value) {
- *value = 0;
- do { value++; } while(isspace(*value));
-
- entry.value = estrdup(value);
- entry.key = estrdup(key);
-
- } else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */
-
- prev_len = strlen(prev_entry.value);
- cur_len = strlen(line);
-
- entry.value = emalloc(prev_len + cur_len + 1);
- memcpy(entry.value, prev_entry.value, prev_len);
- memcpy(entry.value + prev_len, line, cur_len);
- entry.value[cur_len + prev_len] = '\0';
+ if(buf_value.c && key) {
+ /* new entry, add the old one to the list */
+ smart_str_0(&buf_value);
+ entry.key = key;
+ entry.value = buf_value.c;
+ zend_llist_add_element(header, &entry);
+ buf_value.c = NULL;
+ key = NULL;
+ }
- entry.key = estrdup(prev_entry.key);
+ *value = '\0';
+ do { value++; } while(isspace(*value));
- zend_llist_remove_tail(header);
+ key = estrdup(line);
+ smart_str_appends(&buf_value, value);
+ } else if (buf_value.c) { /* If no ':' on the line, add to previous line */
+ smart_str_appends(&buf_value, line);
} else {
continue;
}
-
+ }
+ if(buf_value.c && key) {
+ /* add the last one to the list */
+ smart_str_0(&buf_value);
+ entry.key = key;
+ entry.value = buf_value.c;
zend_llist_add_element(header, &entry);
- prev_entry = entry;
}
return 1;
@@ -884,7 +887,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
if (count == PG(max_input_vars) + 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
}
-
+
if (php_rfc1867_callback != NULL) {
multipart_event_formdata event_formdata;