Skip to content

Commit dabaffb

Browse files
committed
ext/phar: assert function are not passed NULL pointers
This simplifies some of the logic and makes the assumptions clear
1 parent a66b631 commit dabaffb

File tree

10 files changed

+366
-421
lines changed

10 files changed

+366
-421
lines changed

ext/phar/phar.c

Lines changed: 75 additions & 135 deletions
Large diffs are not rendered by default.

ext/phar/phar_internal.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,11 @@ void phar_request_initialize(void);
404404
void phar_object_init(void);
405405
void phar_destroy_phar_data(phar_archive_data *phar);
406406

407-
zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip);
407+
ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip);
408408
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);
409-
zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error);
409+
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error);
410410
zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error);
411-
zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error);
411+
ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error);
412412
zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len);
413413
zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error);
414414
zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error);
@@ -424,7 +424,7 @@ void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filen
424424
zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len);
425425
zend_string *phar_find_in_include_path(zend_string *file, phar_archive_data **pphar);
426426
char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd);
427-
phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error);
427+
ZEND_ATTRIBUTE_NONNULL phar_entry_info * phar_open_jit(const phar_archive_data *phar, phar_entry_info *entry, char **error);
428428
void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent);
429429
bool phar_metadata_tracker_has_data(const phar_metadata_tracker* tracker, bool persistent);
430430
/* If this has data, free it and set all values to undefined. */
@@ -436,22 +436,22 @@ zend_result phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker* tra
436436
void destroy_phar_manifest_entry(zval *zv);
437437
int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links);
438438
php_stream *phar_get_efp(phar_entry_info *entry, int follow_links);
439-
zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error);
440-
zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links);
439+
ZEND_ATTRIBUTE_NONNULL zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error);
440+
ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links);
441441
phar_entry_info *phar_get_link_source(phar_entry_info *entry);
442442
zend_result phar_open_archive_fp(phar_archive_data *phar);
443443
zend_result phar_copy_on_write(phar_archive_data **pphar);
444444

445445
/* tar functions in tar.c */
446446
bool phar_is_tar(char *buf, char *fname);
447447
zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error);
448-
zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error);
449-
void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error);
448+
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error);
449+
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error);
450450

451451
/* zip functions in zip.c */
452452
int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, char **error);
453-
int phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error);
454-
void phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error);
453+
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error);
454+
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) void phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error);
455455

456456
#ifdef PHAR_MAIN
457457
extern const php_stream_wrapper php_stream_phar_wrapper;
@@ -465,10 +465,10 @@ void phar_entry_delref(phar_entry_data *idata);
465465

466466
phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security);
467467
phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security);
468-
phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security);
469-
zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security);
470-
void phar_flush_ex(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error);
471-
void phar_flush(phar_archive_data *archive, char **error);
468+
ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security);
469+
ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security);
470+
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) void phar_flush_ex(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error);
471+
ZEND_ATTRIBUTE_NONNULL void phar_flush(phar_archive_data *archive, char **error);
472472
zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete);
473473
zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create);
474474

ext/phar/phar_object.c

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,7 +2184,7 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /*
21842184
goto err_oldpath;
21852185
}
21862186

2187-
phar_flush_ex(phar, NULL, 1, &error);
2187+
phar_flush_ex(phar, NULL, true, &error);
21882188

21892189
if (error) {
21902190
zend_hash_str_del(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len);
@@ -4133,7 +4133,7 @@ PHP_METHOD(Phar, delMetadata)
41334133
}
41344134
/* }}} */
41354135

4136-
static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, size_t dest_len, char **error) /* {{{ */
4136+
ZEND_ATTRIBUTE_NONNULL static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, const zend_string *dest, char **error) /* {{{ */
41374137
{
41384138
php_stream_statbuf ssb;
41394139
size_t len;
@@ -4161,7 +4161,7 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha
41614161
if (virtual_file_ex(&new_state, ZSTR_VAL(entry->filename), NULL, CWD_EXPAND) != 0 ||
41624162
new_state.cwd_length <= 1) {
41634163
if (EINVAL == errno && ZSTR_LEN(entry->filename) > 50) {
4164-
spprintf(error, 4096, "Cannot extract \"%.50s...\" to \"%s...\", extracted filename is too long for filesystem", ZSTR_VAL(entry->filename), dest);
4164+
spprintf(error, 4096, "Cannot extract \"%.50s...\" to \"%s...\", extracted filename is too long for filesystem", ZSTR_VAL(entry->filename), ZSTR_VAL(dest));
41654165
} else {
41664166
spprintf(error, 4096, "Cannot extract \"%s\", internal error", ZSTR_VAL(entry->filename));
41674167
}
@@ -4183,7 +4183,7 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha
41834183
}
41844184
#endif
41854185

4186-
len = spprintf(&fullpath, 0, "%s/%s", dest, filename);
4186+
len = spprintf(&fullpath, 0, "%s/%s", ZSTR_VAL(dest), filename);
41874187

41884188
if (len >= MAXPATHLEN) {
41894189
/* truncate for error message */
@@ -4224,9 +4224,9 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha
42244224
slash = zend_memrchr(filename, '/', filename_len);
42254225

42264226
if (slash) {
4227-
fullpath[dest_len + (slash - filename) + 1] = '\0';
4227+
fullpath[ZSTR_LEN(dest) + (slash - filename) + 1] = '\0';
42284228
} else {
4229-
fullpath[dest_len] = '\0';
4229+
fullpath[ZSTR_LEN(dest)] = '\0';
42304230
}
42314231

42324232
if (FAILURE == php_stream_stat_path(fullpath, &ssb)) {
@@ -4248,9 +4248,9 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha
42484248
}
42494249

42504250
if (slash) {
4251-
fullpath[dest_len + (slash - filename) + 1] = '/';
4251+
fullpath[ZSTR_LEN(dest) + (slash - filename) + 1] = '/';
42524252
} else {
4253-
fullpath[dest_len] = '/';
4253+
fullpath[ZSTR_LEN(dest)] = '/';
42544254
}
42554255

42564256
filename = NULL;
@@ -4270,9 +4270,10 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha
42704270
}
42714271

42724272
if ((phar_get_fp_type(entry) == PHAR_FP && (entry->flags & PHAR_ENT_COMPRESSION_MASK)) || !phar_get_efp(entry, 0)) {
4273-
if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
4274-
if (error) {
4275-
spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer: %s", ZSTR_VAL(entry->filename), fullpath, *error);
4273+
char *open_entry_error = NULL;
4274+
if (FAILURE == phar_open_entry_fp(entry, &open_entry_error, 1)) {
4275+
if (open_entry_error) {
4276+
spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer: %s", ZSTR_VAL(entry->filename), fullpath, open_entry_error);
42764277
} else {
42774278
spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer", ZSTR_VAL(entry->filename), fullpath);
42784279
}
@@ -4310,28 +4311,28 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha
43104311
}
43114312
/* }}} */
43124313

4313-
static int extract_helper(phar_archive_data *archive, zend_string *search, char *pathto, size_t pathto_len, bool overwrite, char **error) { /* {{{ */
4314+
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 3, 5) static int extract_helper(const phar_archive_data *archive, zend_string *search, const zend_string *pathto, bool overwrite, char **error) { /* {{{ */
43144315
int extracted = 0;
43154316
phar_entry_info *entry;
43164317

43174318
if (!search) {
43184319
/* nothing to match -- extract all files */
43194320
ZEND_HASH_MAP_FOREACH_PTR(&archive->manifest, entry) {
4320-
if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, error)) return -1;
4321+
if (FAILURE == phar_extract_file(overwrite, entry, pathto, error)) return -1;
43214322
extracted++;
43224323
} ZEND_HASH_FOREACH_END();
43234324
} else if (ZSTR_LEN(search) > 0 && '/' == ZSTR_VAL(search)[ZSTR_LEN(search) - 1]) {
43244325
/* ends in "/" -- extract all entries having that prefix */
43254326
ZEND_HASH_MAP_FOREACH_PTR(&archive->manifest, entry) {
43264327
if (!zend_string_starts_with(entry->filename, search)) continue;
4327-
if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, error)) return -1;
4328+
if (FAILURE == phar_extract_file(overwrite, entry, pathto, error)) return -1;
43284329
extracted++;
43294330
} ZEND_HASH_FOREACH_END();
43304331
} else {
43314332
/* otherwise, looking for an exact match */
43324333
entry = zend_hash_find_ptr(&archive->manifest, search);
43334334
if (NULL == entry) return 0;
4334-
if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, error)) return -1;
4335+
if (FAILURE == phar_extract_file(overwrite, entry, pathto, error)) return -1;
43354336
return 1;
43364337
}
43374338

@@ -4344,17 +4345,16 @@ PHP_METHOD(Phar, extractTo)
43444345
{
43454346
php_stream *fp;
43464347
php_stream_statbuf ssb;
4347-
char *pathto;
4348+
zend_string *path_to;
43484349
zend_string *filename = NULL;
4349-
size_t pathto_len;
43504350
int ret;
43514351
zval *zval_file;
43524352
HashTable *files_ht = NULL;
43534353
bool overwrite = 0;
43544354
char *error = NULL;
43554355

43564356
ZEND_PARSE_PARAMETERS_START(1, 3)
4357-
Z_PARAM_PATH(pathto, pathto_len)
4357+
Z_PARAM_PATH_STR(path_to)
43584358
Z_PARAM_OPTIONAL
43594359
Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(files_ht, filename)
43604360
Z_PARAM_BOOL(overwrite)
@@ -4372,30 +4372,30 @@ PHP_METHOD(Phar, extractTo)
43724372

43734373
php_stream_close(fp);
43744374

4375-
if (pathto_len < 1) {
4375+
if (ZSTR_LEN(path_to) < 1) {
43764376
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0,
43774377
"Invalid argument, extraction path must be non-zero length");
43784378
RETURN_THROWS();
43794379
}
43804380

4381-
if (pathto_len >= MAXPATHLEN) {
4382-
char *tmp = estrndup(pathto, 50);
4381+
if (ZSTR_LEN(path_to) >= MAXPATHLEN) {
4382+
char *tmp = estrndup(ZSTR_VAL(path_to), 50);
43834383
/* truncate for error message */
43844384
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Cannot extract to \"%s...\", destination directory is too long for filesystem", tmp);
43854385
efree(tmp);
43864386
RETURN_THROWS();
43874387
}
43884388

4389-
if (php_stream_stat_path(pathto, &ssb) < 0) {
4390-
ret = php_stream_mkdir(pathto, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL);
4389+
if (php_stream_stat_path(ZSTR_VAL(path_to), &ssb) < 0) {
4390+
ret = php_stream_mkdir(ZSTR_VAL(path_to), 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL);
43914391
if (!ret) {
43924392
zend_throw_exception_ex(spl_ce_RuntimeException, 0,
4393-
"Unable to create path \"%s\" for extraction", pathto);
4393+
"Unable to create path \"%s\" for extraction", ZSTR_VAL(path_to));
43944394
RETURN_THROWS();
43954395
}
43964396
} else if (!(ssb.sb.st_mode & S_IFDIR)) {
43974397
zend_throw_exception_ex(spl_ce_RuntimeException, 0,
4398-
"Unable to use path \"%s\" for extraction, it is a file, must be a directory", pathto);
4398+
"Unable to use path \"%s\" for extraction, it is a file, must be a directory", ZSTR_VAL(path_to));
43994399
RETURN_THROWS();
44004400
}
44014401

@@ -4411,7 +4411,7 @@ PHP_METHOD(Phar, extractTo)
44114411
"Invalid argument, array of filenames to extract contains non-string value");
44124412
RETURN_THROWS();
44134413
}
4414-
switch (extract_helper(phar_obj->archive, Z_STR_P(zval_file), pathto, pathto_len, overwrite, &error)) {
4414+
switch (extract_helper(phar_obj->archive, Z_STR_P(zval_file), path_to, overwrite, &error)) {
44154415
case -1:
44164416
zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s",
44174417
phar_obj->archive->fname, error);
@@ -4427,7 +4427,7 @@ PHP_METHOD(Phar, extractTo)
44274427
RETURN_TRUE;
44284428
}
44294429

4430-
ret = extract_helper(phar_obj->archive, filename, pathto, pathto_len, overwrite, &error);
4430+
ret = extract_helper(phar_obj->archive, filename, path_to, overwrite, &error);
44314431
if (-1 == ret) {
44324432
zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s",
44334433
phar_obj->archive->fname, error);

ext/phar/stream.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ BEGIN_EXTERN_C()
2121
#include "ext/standard/url.h"
2222

2323
php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options);
24-
void phar_entry_remove(phar_entry_data *idata, char **error);
24+
ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **error);
2525

2626
static php_stream* phar_wrapper_open_url(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC);
2727
static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context);

0 commit comments

Comments
 (0)