diff --git a/ext/bz2/tests/bzdecompress_input_too_large.phpt b/ext/bz2/tests/bzdecompress_input_too_large.phpt index 88c93d366c54..9774c6dbbfd6 100644 --- a/ext/bz2/tests/bzdecompress_input_too_large.phpt +++ b/ext/bz2/tests/bzdecompress_input_too_large.phpt @@ -10,6 +10,8 @@ if (!getenv('RUN_RESOURCE_HEAVY_TESTS')) die('skip resource-heavy test'); if (getenv('SKIP_SLOW_TESTS')) die('skip slow test'); if (PHP_INT_SIZE != 8) die('skip 64-bit only'); ?> +--CONFLICTS-- +all --FILE-- +--CONFLICTS-- +all --INI-- memory_limit=-1 --FILE-- diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 2b0696305d2b..0e24e4450641 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -5160,6 +5160,23 @@ PHP_METHOD(DatePeriod, createFromISO8601String) } } +static void date_period_reset(php_period_obj *period_obj) +{ + if (period_obj->start) { + timelib_time_dtor(period_obj->start); + } + if (period_obj->current) { + timelib_time_dtor(period_obj->current); + } + if (period_obj->end) { + timelib_time_dtor(period_obj->end); + } + if (period_obj->interval) { + timelib_rel_time_dtor(period_obj->interval); + } + memset(period_obj, 0, offsetof(php_period_obj, std)); +} + /* {{{ Creates new DatePeriod object. */ PHP_METHOD(DatePeriod, __construct) { @@ -5181,7 +5198,7 @@ PHP_METHOD(DatePeriod, __construct) } dpobj = Z_PHPPERIOD_P(ZEND_THIS); - dpobj->current = NULL; + date_period_reset(dpobj); if (isostr) { zend_error(E_DEPRECATED, "Calling DatePeriod::__construct(string $isostr, int $options = 0) is deprecated, " @@ -5199,6 +5216,7 @@ PHP_METHOD(DatePeriod, __construct) if (end) { DATE_CHECK_INITIALIZED(Z_PHPDATE_P(end)->time, date_ce_interface); } + DATE_CHECK_INITIALIZED(Z_PHPINTERVAL_P(interval)->initialized, Z_OBJCE_P(interval)); /* init */ php_interval_obj *intobj = Z_PHPINTERVAL_P(interval); diff --git a/ext/date/tests/DatePeriod_double_constructor_call.phpt b/ext/date/tests/DatePeriod_double_constructor_call.phpt new file mode 100644 index 000000000000..551d2727282d --- /dev/null +++ b/ext/date/tests/DatePeriod_double_constructor_call.phpt @@ -0,0 +1,14 @@ +--TEST-- +Double DatePeriod::__construct() call +--FILE-- +__construct($start, $interval, 1); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 31030e12fbf1..62dca4f5db43 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2215,7 +2215,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c switch (format) { case TAG_FMT_STRING: if (length > value_len) { - exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len); + exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %zu > %zu", length, value_len); value = NULL; } if (value) { @@ -2245,7 +2245,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c ZEND_FALLTHROUGH; case TAG_FMT_UNDEFINED: if (length > value_len) { - exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len); + exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %zu > %zu", length, value_len); value = NULL; } if (value) { @@ -3304,7 +3304,7 @@ static bool exif_process_IFD_TAG_impl(image_info_type *ImageInfo, char *dir_entr * relative to the start of the TIFF header in APP1 section. */ // TODO: Shouldn't we also be taking "displacement" into account here? if (byte_count > ImageInfo->FileSize || offset_val>ImageInfo->FileSize-byte_count || (ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_II && ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_MM && ImageInfo->FileType!=IMAGE_FILETYPE_JPEG)) { - exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal pointer offset(x%04X + x%04X = x%04X > x%04X)", tag, exif_get_tagname_debug(tag, tag_table), offset_val, byte_count, offset_val+byte_count, ImageInfo->FileSize); + exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal pointer offset(x%04zX + x%04zX = x%04zX > x%04zX)", tag, exif_get_tagname_debug(tag, tag_table), offset_val, byte_count, offset_val+byte_count, ImageInfo->FileSize); return false; } if (byte_count>sizeof(cbuf)) { @@ -3326,7 +3326,7 @@ static bool exif_process_IFD_TAG_impl(image_info_type *ImageInfo, char *dir_entr size_t fgot = php_stream_tell(ImageInfo->infile); if (fgot!=displacement+offset_val) { EFREE_IF(outside); - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Wrong file pointer: 0x%08X != 0x%08X", fgot, displacement+offset_val); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Wrong file pointer: 0x%08zX != 0x%08zX", fgot, displacement+offset_val); return false; } fgot = exif_read_from_stream_file_looped(ImageInfo->infile, value_ptr, byte_count); @@ -3866,7 +3866,7 @@ static bool exif_scan_JPEG_header(image_info_type *ImageInfo) got = exif_read_from_stream_file_looped(ImageInfo->infile, (char*)(Data+2), itemlen-2); /* Read the whole section. */ if (got != itemlen-2) { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error reading from file: got=x%04X(=%d) != itemlen-2=x%04X(=%d)", got, got, itemlen-2, itemlen-2); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error reading from file: got=x%04zX(=%zu) != itemlen-2=x%04zX(=%zu)", got, got, itemlen-2, itemlen-2); return false; } @@ -4150,7 +4150,7 @@ static bool exif_process_IFD_in_TIFF_impl(image_info_type *ImageInfo, size_t dir if (ImageInfo->FileSize >= ImageInfo->file.list[sn].size && ImageInfo->FileSize - ImageInfo->file.list[sn].size >= dir_offset) { if (ifd_size > dir_size) { if (ImageInfo->FileSize < ifd_size || dir_offset > ImageInfo->FileSize - ifd_size) { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, ifd_size); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than size of IFD(x%04zX + x%04zX)", ImageInfo->FileSize, dir_offset, ifd_size); return false; } if (exif_file_sections_realloc(ImageInfo, sn, ifd_size)) { @@ -4266,15 +4266,15 @@ static bool exif_process_IFD_in_TIFF_impl(image_info_type *ImageInfo, size_t dir } return true; } else { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD(x%04X)", ImageInfo->FileSize, dir_offset+ImageInfo->file.list[sn].size); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than size of IFD(x%04zX)", ImageInfo->FileSize, dir_offset+ImageInfo->file.list[sn].size); return false; } } else { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD dir(x%04X)", ImageInfo->FileSize, dir_offset+dir_size); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than size of IFD dir(x%04zX)", ImageInfo->FileSize, dir_offset+dir_size); return false; } } else { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than start of IFD dir(x%04X)", ImageInfo->FileSize, dir_offset+2); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04zX) less than start of IFD dir(x%04zX)", ImageInfo->FileSize, dir_offset+2); return false; } } @@ -4507,7 +4507,7 @@ static bool exif_scan_FILE_header(image_info_type *ImageInfo) ImageInfo->FileType = IMAGE_FILETYPE_UNKNOWN; if (UNEXPECTED(ImageInfo->FileSize < 2)) { - exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "File too small (%d)", ImageInfo->FileSize); + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "File too small (%zu)", ImageInfo->FileSize); return false; } @@ -4938,7 +4938,7 @@ PHP_FUNCTION(exif_read_data) exif_discard_imageinfo(&ImageInfo); #ifdef EXIF_DEBUG - php_error_docref1(NULL, (Z_TYPE_P(stream) == IS_RESOURCE ? "" : Z_STRVAL_P(stream)), E_NOTICE, "Done"); + php_error_docref(NULL, E_NOTICE, "Done"); #endif } /* }}} */ @@ -5026,7 +5026,7 @@ PHP_FUNCTION(exif_thumbnail) exif_discard_imageinfo(&ImageInfo); #ifdef EXIF_DEBUG - php_error_docref1(NULL, (Z_TYPE_P(stream) == IS_RESOURCE ? "" : Z_STRVAL_P(stream)), E_NOTICE, "Done"); + php_error_docref(NULL, E_NOTICE, "Done"); #endif } /* }}} */ diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index e628ce58086c..b7772ec3ac34 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -133,6 +133,11 @@ static void free_cols(pdo_stmt_t *stmt, pdo_odbc_stmt *S) } } +static void odbc_free_out_buffer(zval *el) +{ + efree(Z_PTR_P(el)); +} + static int odbc_stmt_dtor(pdo_stmt_t *stmt) { pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; @@ -149,11 +154,41 @@ static int odbc_stmt_dtor(pdo_stmt_t *stmt) if (S->convbuf) { efree(S->convbuf); } + if (S->out_buffers) { + zend_hash_destroy(S->out_buffers); + FREE_HASHTABLE(S->out_buffers); + } efree(S); return 1; } +static bool odbc_bind_param(pdo_stmt_t *stmt, struct pdo_bound_param_data *param) +{ + pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; + pdo_odbc_param *P = (pdo_odbc_param*)param->driver_data; + RETCODE rc; + + if (!P) { + return true; + } + + rc = SQLBindParameter(S->stmt, (SQLUSMALLINT) param->paramno+1, + P->paramtype, P->ctype, P->sqltype, P->precision, P->scale, + P->paramtype == SQL_PARAM_INPUT ? + (SQLPOINTER)param : + P->outbuf, + P->outbuf ? P->outbuflen : 0, + &P->len + ); + + if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { + return true; + } + pdo_odbc_stmt_error("SQLBindParameter"); + return false; +} + static int odbc_stmt_execute(pdo_stmt_t *stmt) { RETCODE rc, rc1; @@ -165,6 +200,24 @@ static int odbc_stmt_execute(pdo_stmt_t *stmt) SQLCloseCursor(S->stmt); } + if (S->params_dirty) { + rc = SQLFreeStmt(S->stmt, SQL_RESET_PARAMS); + if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + pdo_odbc_stmt_error("SQLFreeStmt: SQL_RESET_PARAMS"); + return 0; + } + if (stmt->bound_params) { + struct pdo_bound_param_data *param; + + ZEND_HASH_FOREACH_PTR(stmt->bound_params, param) { + if (!odbc_bind_param(stmt, param)) { + return 0; + } + } ZEND_HASH_FOREACH_END(); + } + S->params_dirty = false; + } + rc = SQLExecute(S->stmt); while (rc == SQL_NEED_DATA) { @@ -308,6 +361,7 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p if (P) { efree(P); } + S->params_dirty = true; break; case PDO_PARAM_EVT_ALLOC: @@ -382,6 +436,11 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p } P->outbuf = emalloc(P->len + (P->is_unicode ? 2:1)); P->outbuflen = P->len; + if (!S->out_buffers) { + ALLOC_HASHTABLE(S->out_buffers); + zend_hash_init(S->out_buffers, HT_MIN_SIZE, NULL, odbc_free_out_buffer, false); + } + zend_hash_next_index_insert_ptr(S->out_buffers, P->outbuf); } } @@ -390,20 +449,12 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p return 0; } - rc = SQLBindParameter(S->stmt, (SQLUSMALLINT) param->paramno+1, - P->paramtype, ctype, sqltype, precision, scale, - P->paramtype == SQL_PARAM_INPUT ? - (SQLPOINTER)param : - P->outbuf, - P->len, - &P->len - ); - - if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { - return 1; - } - pdo_odbc_stmt_error("SQLBindParameter"); - return 0; + P->sqltype = sqltype; + P->ctype = ctype; + P->precision = precision; + P->scale = scale; + S->params_dirty = true; + return 1; } case PDO_PARAM_EVT_EXEC_PRE: diff --git a/ext/pdo_odbc/php_pdo_odbc_int.h b/ext/pdo_odbc/php_pdo_odbc_int.h index 3ebfadb57523..52d66abfba01 100644 --- a/ext/pdo_odbc/php_pdo_odbc_int.h +++ b/ext/pdo_odbc/php_pdo_odbc_int.h @@ -143,16 +143,22 @@ typedef struct { pdo_odbc_errinfo einfo; char *convbuf; zend_ulong convbufsize; + HashTable *out_buffers; unsigned going_long:1; unsigned assume_utf8:1; + unsigned params_dirty:1; signed col_count:16; - unsigned _spare:14; + unsigned _spare:13; } pdo_odbc_stmt; typedef struct { SQLLEN len; SQLLEN outbuflen; SQLSMALLINT paramtype; + SQLSMALLINT sqltype; + SQLSMALLINT ctype; + SQLSMALLINT scale; + SQLULEN precision; char *outbuf; unsigned is_unicode:1; unsigned _spare:31; diff --git a/ext/pdo_odbc/tests/bound_param_rebind.phpt b/ext/pdo_odbc/tests/bound_param_rebind.phpt new file mode 100644 index 000000000000..1ae9651f3a7d --- /dev/null +++ b/ext/pdo_odbc/tests/bound_param_rebind.phpt @@ -0,0 +1,28 @@ +--TEST-- +pdo_odbc: a bound parameter does not leave a stale ODBC binding on re-execute +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +$stmt = $pdo->prepare('SELECT ? AS v'); +$v = 'bound'; +$stmt->bindParam(1, $v, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 256); +$stmt->execute(['from_array']); + +var_dump($stmt->fetch(PDO::FETCH_ASSOC)['v']); +?> +--EXPECT-- +string(10) "from_array" diff --git a/ext/pdo_odbc/tests/output_param_leak.phpt b/ext/pdo_odbc/tests/output_param_leak.phpt new file mode 100644 index 000000000000..f6d4aad5a8c6 --- /dev/null +++ b/ext/pdo_odbc/tests/output_param_leak.phpt @@ -0,0 +1,29 @@ +--TEST-- +pdo_odbc: bound output parameter buffer is released (no leak) +--EXTENSIONS-- +pdo_odbc +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +$stmt = $pdo->prepare('SELECT ? AS v'); +$var = 'seed'; +$stmt->bindParam(1, $var, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 256); +$stmt->execute(); +$row = $stmt->fetch(PDO::FETCH_ASSOC); + +var_dump($row['v']); +?> +--EXPECT-- +string(4) "seed" diff --git a/ext/standard/file.c b/ext/standard/file.c index 0bb00355744f..fd6f578e4ef0 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -822,7 +822,7 @@ PHP_FUNCTION(popen) fp = VCWD_POPEN(command, posix_mode); if (!fp) { - php_error_docref2(NULL, command, posix_mode, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); efree(posix_mode); RETURN_FALSE; } @@ -831,7 +831,7 @@ PHP_FUNCTION(popen) stream = php_stream_fopen_from_pipe(fp, mode); if (stream == NULL) { - php_error_docref2(NULL, command, mode, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); RETVAL_FALSE; } else { php_stream_to_zval(stream, return_value); diff --git a/ext/standard/tests/file/rename_variation.phpt b/ext/standard/tests/file/rename_variation.phpt index b86c5c80973d..88ad26080f4a 100644 --- a/ext/standard/tests/file/rename_variation.phpt +++ b/ext/standard/tests/file/rename_variation.phpt @@ -55,7 +55,7 @@ bool(false) bool(true) -- Iteration 2 -- -Warning: rename(%s,%s): Not a directory in %s on line %d +Warning: rename(): Not a directory in %s on line %d bool(false) bool(false) bool(false) diff --git a/ext/standard/tests/file/rename_variation12.phpt b/ext/standard/tests/file/rename_variation12.phpt index 8675b17aab5c..954c12427232 100644 --- a/ext/standard/tests/file/rename_variation12.phpt +++ b/ext/standard/tests/file/rename_variation12.phpt @@ -2,6 +2,9 @@ Test rename() function : variation - various relative, absolute paths --CREDITS-- Dave Kelsey +--INI-- +zend.exception_string_param_max_len=1000000 +error_include_args=On --SKIPIF-- +--INI-- +zend.exception_string_param_max_len=1000000 +error_include_args=On --SKIPIF--