diff --git a/NEWS b/NEWS index 3da5464750cc..3144cdf88c59 100644 --- a/NEWS +++ b/NEWS @@ -104,6 +104,10 @@ PHP NEWS - PGSQL: . Enabled 64 bits support for pg_lo_truncate()/pg_lo_tell() if the server supports it. (KentarouTakeda) + . pg_fetch_object() now surfaces non-instantiable class errors + before fetching, resolves the constructor via the get_constructor + handler, and reports the empty-constructor ValueError on the + $constructor_args argument. (David Carlier) - Phar: . Support reference values in Phar::mungServer(). (ndossche) diff --git a/UPGRADING b/UPGRADING index 56049f30cf93..6777820642f6 100644 --- a/UPGRADING +++ b/UPGRADING @@ -47,6 +47,13 @@ PHP 8.6 UPGRADE NOTES . Phar::mungServer() now raises a ValueError when an invalid argument value is passed instead of being silently ignored. +- PGSQL: + . pg_fetch_object() now reports the ValueError for a non-empty + $constructor_args on a class without a constructor on the + $constructor_args argument instead of $class. Errors raised when + the requested class is not instantiable (abstract, interface, enum) + now surface before the row is fetched. + - Posix: . posix_access() now raises a ValueError when an invalid $flags argument value is passed. diff --git a/ext/odbc/odbc_utils.c b/ext/odbc/odbc_utils.c index 742bf54bb292..8468fa9a06c1 100644 --- a/ext/odbc/odbc_utils.c +++ b/ext/odbc/odbc_utils.c @@ -57,7 +57,7 @@ PHP_FUNCTION(odbc_connection_string_quote) Z_PARAM_STR(str) ZEND_PARSE_PARAMETERS_END(); - size_t new_size = php_odbc_connstr_estimate_quote_length(ZSTR_VAL(str)); + size_t new_size = php_odbc_connstr_get_quoted_length(ZSTR_VAL(str)); zend_string *new_string = zend_string_alloc(new_size, 0); php_odbc_connstr_quote(ZSTR_VAL(new_string), ZSTR_VAL(str), new_size); /* reset length */ diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 2d6331b0f544..c9f1b3f2e147 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -1951,9 +1951,9 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool if (use_uid_arg) { should_quote_uid = !php_odbc_connstr_is_quoted(uid) && php_odbc_connstr_should_quote(uid); if (should_quote_uid) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(uid); - uid_quoted = emalloc(estimated_length); - php_odbc_connstr_quote(uid_quoted, uid, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(uid); + uid_quoted = emalloc(quoted_length); + php_odbc_connstr_quote(uid_quoted, uid, quoted_length); } else { uid_quoted = uid; } @@ -1966,9 +1966,9 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool if (use_pwd_arg) { should_quote_pwd = !php_odbc_connstr_is_quoted(pwd) && php_odbc_connstr_should_quote(pwd); if (should_quote_pwd) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(pwd); - pwd_quoted = emalloc(estimated_length); - php_odbc_connstr_quote(pwd_quoted, pwd, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(pwd); + pwd_quoted = emalloc(quoted_length); + php_odbc_connstr_quote(pwd_quoted, pwd, quoted_length); } else { pwd_quoted = pwd; } diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 4c627419d18e..3c8afe2d4215 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -548,9 +548,9 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ if (use_uid_arg) { should_quote_uid = !php_odbc_connstr_is_quoted(dbh->username) && php_odbc_connstr_should_quote(dbh->username); if (should_quote_uid) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->username); - uid = emalloc(estimated_length); - php_odbc_connstr_quote(uid, dbh->username, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(dbh->username); + uid = emalloc(quoted_length); + php_odbc_connstr_quote(uid, dbh->username, quoted_length); } else { uid = dbh->username; } @@ -565,9 +565,9 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ if (use_pwd_arg) { should_quote_pwd = !php_odbc_connstr_is_quoted(dbh->password) && php_odbc_connstr_should_quote(dbh->password); if (should_quote_pwd) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->password); - pwd = emalloc(estimated_length); - php_odbc_connstr_quote(pwd, dbh->password, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(dbh->password); + pwd = emalloc(quoted_length); + php_odbc_connstr_quote(pwd, dbh->password, quoted_length); } else { pwd = dbh->password; } diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 1674625429ad..8cb022c79cd1 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -2129,26 +2129,17 @@ PHP_FUNCTION(pg_fetch_object) ce = zend_standard_class_def; } - if (!ce->constructor && ctor_params && zend_hash_num_elements(ctor_params) > 0) { - zend_argument_value_error(3, - "must be empty when the specified class (%s) does not have a constructor", - ZSTR_VAL(ce->name) - ); + if (UNEXPECTED(object_init_ex(return_value, ce) == FAILURE)) { RETURN_THROWS(); } zval dataset; if (UNEXPECTED(!php_pgsql_fetch_hash(&dataset, result, row, row_is_null, PGSQL_ASSOC))) { /* Either an exception is thrown, or we return false */ + zval_ptr_dtor(return_value); RETURN_FALSE; } - // TODO: Check CE is an instantiable class earlier? - zend_result obj_initialized = object_init_ex(return_value, ce); - if (UNEXPECTED(obj_initialized == FAILURE)) { - zval_ptr_dtor(&dataset); - RETURN_THROWS(); - } if (!ce->default_properties_count && !ce->__set) { Z_OBJ_P(return_value)->properties = Z_ARR(dataset); } else { @@ -2156,10 +2147,32 @@ PHP_FUNCTION(pg_fetch_object) zval_ptr_dtor(&dataset); } - // TODO: Need to grab constructor via object handler as this allows instantiating internal objects with overridden get_constructor - if (ce->constructor) { - zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value), + zend_object *obj = Z_OBJ_P(return_value); + const zend_class_entry *old = EG(fake_scope); + EG(fake_scope) = ce; + zend_function *constructor = obj->handlers->get_constructor(obj); + EG(fake_scope) = old; + + if (UNEXPECTED(EG(exception))) { + /* visibility error or override refused - VM dtors return_value */ + return; + } + + if (UNEXPECTED(!constructor && ctor_params && zend_hash_num_elements(ctor_params) > 0)) { + zend_argument_value_error(4, + "must be empty when the specified class (%s) does not have a constructor", + ZSTR_VAL(ce->name) + ); + RETURN_THROWS(); + } + + if (constructor) { + zend_call_known_function(constructor, obj, ce, /* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params); + if (EG(exception)) { + zend_object_store_ctor_failed(obj); + RETURN_THROWS(); + } } } /* }}} */ diff --git a/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt b/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt new file mode 100644 index 000000000000..bd3df73acba4 --- /dev/null +++ b/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt @@ -0,0 +1,69 @@ +--TEST-- +pg_fetch_object() constructor handling: ctor_params validation, throwing constructor, property visibility +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- +num}, str={$this->str}\n"; + } + public function __destruct() { + echo "SeesProps::__destruct called\n"; + } +} + +$table_name = "pg_fetch_object_ctor_paths"; +$db = pg_connect($conn_str); +pg_query($db, "CREATE TABLE {$table_name} (num int, str text)"); +pg_query($db, "INSERT INTO {$table_name} VALUES(1, 'hello')"); + +$sql = "SELECT * FROM {$table_name} WHERE num = 1"; + +// 1) ctor_params on a class with no constructor must throw ValueError +try { + pg_fetch_object(pg_query($db, $sql), null, 'NoCtor', [1, 2]); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +// 2) Constructor that throws: __destruct must NOT run on the partially constructed object +try { + pg_fetch_object(pg_query($db, $sql), null, 'ThrowingCtor'); +} catch (RuntimeException $e) { + echo "caught: ", $e->getMessage(), "\n"; +} + +// 3) Constructor sees row properties already merged onto $this +$obj = pg_fetch_object(pg_query($db, $sql), null, 'SeesProps'); +unset($obj); + +echo "Ok\n"; +?> +--CLEAN-- + +--EXPECT-- +pg_fetch_object(): Argument #4 ($constructor_args) must be empty when the specified class (NoCtor) does not have a constructor +caught: boom +ctor sees: num=1, str=hello +SeesProps::__destruct called +Ok diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 2b74a566411f..6c356c04e5e1 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -19,8 +19,6 @@ #include "phar_internal.h" #include "dirstream.h" -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, bool is_dir); - static const php_stream_ops phar_dir_ops = { phar_dir_write, /* write */ phar_dir_read, /* read */ @@ -300,7 +298,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ size_t internal_file_len = ZSTR_LEN(resource->path) - 1; - phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); + const phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); php_stream *ret; if (NULL != entry && !entry->is_dir) { diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 6d9dd5324945..cd363fbd88ee 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -484,7 +484,7 @@ ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **err /** * Open an already loaded phar */ -static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { #ifdef PHP_WIN32 char *save_fname; @@ -720,7 +720,7 @@ void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker * This is used by phar_open_from_filename to process the manifest, but can be called * directly. */ -static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ +static zend_result phar_parse_pharfile(php_stream *fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { char b32[4], *buffer, *endbuffer, *savebuf; phar_archive_data *mydata = NULL; @@ -1302,7 +1302,7 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname /** * Create or open a phar for writing */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { const char *ext_str, *z; char *my_error; @@ -1366,9 +1366,9 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(ze } /* }}} */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +static zend_result phar_open_from_fp(php_stream* fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { php_stream *fp; zend_string *actual = NULL; @@ -1507,7 +1507,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(z * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_from_filename(char *fname, size_t fname_len, const char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { php_stream *fp; zend_string *actual; @@ -1564,7 +1564,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_from_fp(php_stream* fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { static const char token[] = "__HALT_COMPILER();"; static const char zip_magic[] = "PK\x03\x04"; @@ -2252,7 +2252,7 @@ zend_string* phar_split_fname(const char *filename, size_t filename_len, zend_st * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(const char *alias, size_t alias_len, char **error) /* {{{ */ { *error = NULL; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index b45fb2d2a13a..7a923fd15e18 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -406,10 +406,10 @@ void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error); +zend_result phar_open_from_filename(char *fname, size_t fname_len, const char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(const char *alias, size_t alias_len, char **error); zend_result phar_free_alias(const phar_archive_data *phar); phar_archive_data* phar_get_archive(const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error); zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, const char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error); @@ -423,7 +423,7 @@ const char *phar_compress_filter(const phar_entry_info *entry, bool return_unkno /* void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); */ void phar_add_virtual_dirs(phar_archive_data *phar, const char *filename, size_t filename_len); zend_result phar_mount_entry(phar_archive_data *phar, const char *filename, size_t filename_len, char *path, size_t path_len); -zend_string *phar_find_in_include_path(zend_string *file, phar_archive_data **pphar); +zend_string *phar_find_in_include_path(const zend_string *file, phar_archive_data **pphar); zend_string* phar_fix_filepath(const char *path, size_t path_length, bool use_cwd); ZEND_ATTRIBUTE_NONNULL phar_entry_info * phar_open_jit(const phar_archive_data *phar, phar_entry_info *entry, char **error); void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent); @@ -446,12 +446,12 @@ zend_result phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ bool phar_is_tar(const char *buf, const char *fname); zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_tar(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_tar(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error); /* zip functions in zip.c */ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_zip(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_zip(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); #ifdef PHAR_MAIN diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 1766d9f778eb..00a5ebf3058f 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -349,9 +349,10 @@ static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, /* post-process REQUEST_URI and retrieve the actual request URI. This is for cases like http://localhost/blah.phar/path/to/file.php/extra/stuff which calls "blah.phar" file "path/to/file.php" with PATH_INFO "/extra/stuff" */ -static void phar_postprocess_ru_web(const char *fname, size_t fname_len, char *entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ +static void phar_postprocess_ru_web(const char *fname, size_t fname_len, const char *entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ { - char *e = entry + 1, *u1 = NULL, *u = NULL, *saveu = NULL; + const char *e = entry + 1; + char *u1 = NULL, *u = NULL, *saveu = NULL; size_t e_len = *entry_len - 1, u_len = 0; phar_archive_data *pphar; diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 9d24fa64d75c..f9d19a04122a 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -364,7 +364,7 @@ static ssize_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* { phar_entry_data *data = (phar_entry_data *)stream->abstract; ssize_t got; - phar_entry_info *entry; + const phar_entry_info *entry; if (data->internal_file->symlink) { entry = phar_get_link_source(data->internal_file); @@ -394,7 +394,7 @@ static ssize_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* static int phar_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) /* {{{ */ { phar_entry_data *data = (phar_entry_data *)stream->abstract; - phar_entry_info *entry; + const phar_entry_info *entry; int res; zend_ulong temp; @@ -462,7 +462,7 @@ static int phar_stream_flush(php_stream *stream) /* {{{ */ { char *error; int ret; - phar_entry_data *data = (phar_entry_data *) stream->abstract; + const phar_entry_data *data = stream->abstract; if (data->internal_file->is_modified) { data->internal_file->timestamp = time(0); @@ -482,7 +482,7 @@ static int phar_stream_flush(php_stream *stream) /* {{{ */ /** * stat an opened phar file handle stream, used by phar_stat() */ -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, bool is_temp_dir) +static void phar_dostat(const phar_archive_data *phar, const phar_entry_info *data, php_stream_statbuf *ssb, bool is_temp_dir) { memset(ssb, 0, sizeof(php_stream_statbuf)); @@ -536,7 +536,7 @@ void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_stat */ static int phar_stream_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */ { - phar_entry_data *data = (phar_entry_data *)stream->abstract; + const phar_entry_data *data = stream->abstract; /* If ssb is NULL then someone is misbehaving */ if (!ssb) { @@ -659,7 +659,6 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int char *internal_file, *error; size_t internal_file_len; phar_entry_data *idata; - phar_archive_data *pphar; php_url *resource = phar_parse_url(wrapper, url, "rb", options); if (!resource) { @@ -682,7 +681,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int phar_request_initialize(); - pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); + const phar_archive_data *pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); if (PHAR_G(readonly) && (!pphar || !pphar->is_data)) { php_url_free(resource); php_stream_wrapper_log_error(wrapper, options, "phar error: write operations disabled by the php.ini setting phar.readonly"); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 761246000dd2..edb0707a6ff7 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -126,7 +126,7 @@ bool phar_is_tar(const char *buf, const char *fname) /* {{{ */ } /* }}} */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_tar(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_tar(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; zend_result ret = phar_create_or_parse_filename(fname, alias, alias_len, is_data, options, &phar, error); @@ -802,7 +802,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* /* write header */ entry->header_offset = php_stream_tell(fp->new); - if (sizeof(header) != php_stream_write(fp->new, (char *) &header, sizeof(header))) { + if (sizeof(header) != php_stream_write(fp->new, (const char *) &header, sizeof(header))) { if (fp->error) { spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, header for file \"%s\" could not be written", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } @@ -906,7 +906,7 @@ ZEND_ATTRIBUTE_NONNULL static int phar_tar_setmetadata(const phar_metadata_track ZEND_ATTRIBUTE_NONNULL static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */ { - struct _phar_pass_tar_info *i = (struct _phar_pass_tar_info *)argument; + const struct _phar_pass_tar_info *i = (struct _phar_pass_tar_info *)argument; char **error = i->error; phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv), newentry = {0}; diff --git a/ext/phar/util.c b/ext/phar/util.c index 331bbf6511ba..e501ccfaceba 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -264,7 +264,7 @@ zend_result phar_mount_entry(phar_archive_data *phar, const char *filename, size } /* }}} */ -zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar) /* {{{ */ +zend_string *phar_find_in_include_path(const zend_string *filename, phar_archive_data **pphar) /* {{{ */ { zend_string *ret; char *path; diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 8f61977a3835..900b41f9c794 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -794,7 +794,7 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l /** * Create or open a zip-based phar for writing */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_zip(zend_string *fname, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_zip(zend_string *fname, const char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; zend_result ret = phar_create_or_parse_filename(fname, alias, alias_len, is_data, options, &phar, error); diff --git a/main/php_odbc_utils.c b/main/php_odbc_utils.c index d3b18f2bd642..797a4ac04be1 100644 --- a/main/php_odbc_utils.c +++ b/main/php_odbc_utils.c @@ -71,12 +71,20 @@ PHPAPI bool php_odbc_connstr_should_quote(const char *str) } /** - * Estimates the worst-case scenario for a quoted version of a string's size. + * Gets the length of a string after it has been quoted. */ -PHPAPI size_t php_odbc_connstr_estimate_quote_length(const char *in_str) +PHPAPI size_t php_odbc_connstr_get_quoted_length(const char *in_str) { - /* Assume all '}'. Include '{,' '}', and the null terminator too */ - return (strlen(in_str) * 2) + 3; + /* Start with including the quotes ({}) and the null terminator */ + size_t size = 3; + /* Scan the string like strlen, doubling each } character. */ + while (*in_str) { + size++; + if (*in_str++ == '}') { + size++; + } + } + return size; } /** diff --git a/main/php_odbc_utils.h b/main/php_odbc_utils.h index 78353b49a814..f2bc46ebc5ba 100644 --- a/main/php_odbc_utils.h +++ b/main/php_odbc_utils.h @@ -16,5 +16,5 @@ PHPAPI bool php_odbc_connstr_is_quoted(const char *str); PHPAPI bool php_odbc_connstr_should_quote(const char *str); -PHPAPI size_t php_odbc_connstr_estimate_quote_length(const char *in_str); +PHPAPI size_t php_odbc_connstr_get_quoted_length(const char *in_str); PHPAPI size_t php_odbc_connstr_quote(char *out_str, const char *in_str, size_t out_str_size);