From 8be94d46f836a886d85b9a813b241a7f26649020 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Fri, 25 Nov 2016 15:30:20 -0800 Subject: [PATCH] Fix more size_t/int implicit conversions Now the conversions are explicit and do checks. Not sure it's the best way but at least we can see them now in the open. --- ext/phar/phar_object.c | 215 ++++++++++++++++++++++++++++------------- 1 file changed, 149 insertions(+), 66 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 6998a4db91..fc31a7e536 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -61,8 +61,8 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char HashTable *_SERVER; zval *stuff; char *path_info; - int basename_len = strlen(basename); - int code; + size_t basename_len = strlen(basename); + size_t code; zval temp; /* "tweak" $_SERVER variables requested in earlier call to Phar::mungServer() */ @@ -150,7 +150,7 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char sapi_header_line ctr = {0}; size_t got; zval dummy; - int name_len; + size_t name_len; zend_file_handle file_handle; zend_op_array *new_op_array; zval result; @@ -162,9 +162,9 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char efree(basename); /* highlight source */ if (entry[0] == '/') { - name_len = spprintf(&name, 4096, "phar://%s%s", arch, entry); + spprintf(&name, 4096, "phar://%s%s", arch, entry); } else { - name_len = spprintf(&name, 4096, "phar://%s/%s", arch, entry); + spprintf(&name, 4096, "phar://%s/%s", arch, entry); } php_get_highlight_struct(&syntax_highlighter_ini); @@ -248,10 +248,10 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char PHAR_G(cwd_len) = 0; PHAR_G(cwd) = NULL; } else if (entry[0] == '/') { - PHAR_G(cwd_len) = cwd - (entry + 1); + PHAR_G(cwd_len) = (int)(cwd - (entry + 1)); PHAR_G(cwd) = estrndup(entry + 1, PHAR_G(cwd_len)); } else { - PHAR_G(cwd_len) = cwd - entry; + PHAR_G(cwd_len) = (int)(cwd - entry); PHAR_G(cwd) = estrndup(entry, PHAR_G(cwd_len)); } } @@ -322,7 +322,7 @@ static void phar_do_403(char *entry, int entry_len) /* {{{ */ } /* }}} */ -static void phar_do_404(phar_archive_data *phar, char *fname, int fname_len, char *f404, size_t f404_len, char *entry, size_t entry_len) /* {{{ */ +static void phar_do_404(phar_archive_data *phar, char *fname, int fname_len, char *f404, int f404_len, char *entry, size_t entry_len) /* {{{ */ { sapi_header_line ctr = {0}; phar_entry_info *info; @@ -398,7 +398,7 @@ static void phar_postprocess_ru_web(char *fname, int fname_len, char **entry, in } u[0] = '\0'; - u_len = strlen(u + 1); + u_len = (int)strlen(u + 1); e_len -= u_len + 1; if (e_len < 0) { @@ -426,7 +426,7 @@ PHP_METHOD(Phar, running) } fname = (char*)zend_get_executed_filename(); - fname_len = strlen(fname); + fname_len = (int)strlen(fname); if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { efree(entry); @@ -463,8 +463,12 @@ PHP_METHOD(Phar, mount) return; } + if (ZEND_SIZE_T_INT_OVFL(path_len) || ZEND_SIZE_T_INT_OVFL(actual_len)) { + RETURN_FALSE; + } + fname = (char*)zend_get_executed_filename(); - fname_len = strlen(fname); + fname_len = (int)strlen(fname); #ifdef PHP_WIN32 phar_unixify_path_separators(fname, fname_len); @@ -495,7 +499,7 @@ carry_on2: return; } carry_on: - if (SUCCESS != phar_mount_entry(pphar, actual, actual_len, path, path_len)) { + if (SUCCESS != phar_mount_entry(pphar, actual, (int)actual_len, path, (int)path_len)) { zend_throw_exception_ex(phar_ce_PharException, 0, "Mounting of %s to %s within phar %s failed", path, actual, arch); if (path && path == entry) { efree(entry); @@ -525,7 +529,7 @@ carry_on: } goto carry_on; - } else if (SUCCESS == phar_split_fname(path, path_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { + } else if (SUCCESS == phar_split_fname(path, (int)path_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { path = entry; path_len = entry_len; goto carry_on2; @@ -564,7 +568,12 @@ PHP_METHOD(Phar, webPhar) fname = (char*)zend_get_executed_filename(); fname_len = strlen(fname); - if (phar_open_executed_filename(alias, alias_len, &error) != SUCCESS) { + if (ZEND_SIZE_T_INT_OVFL(alias_len) + || ZEND_SIZE_T_INT_OVFL(f404_len) || ZEND_SIZE_T_INT_OVFL(index_php_len)) { + RETURN_FALSE; + } + + if (phar_open_executed_filename(alias, (int)alias_len, &error) != SUCCESS) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); efree(error); @@ -605,7 +614,7 @@ PHP_METHOD(Phar, webPhar) if (NULL != (z_path_info = zend_hash_str_find(_server, "PATH_INFO", sizeof("PATH_INFO")-1)) && IS_STRING == Z_TYPE_P(z_path_info)) { - entry_len = Z_STRLEN_P(z_path_info); + entry_len = (int)Z_STRLEN_P(z_path_info); entry = estrndup(Z_STRVAL_P(z_path_info), entry_len); path_info = emalloc(Z_STRLEN_P(z_script_name) + entry_len + 1); memcpy(path_info, Z_STRVAL_P(z_script_name), Z_STRLEN_P(z_script_name)); @@ -632,7 +641,7 @@ PHP_METHOD(Phar, webPhar) if (path_info) { entry = path_info; - entry_len = strlen(entry); + entry_len = (int)strlen(entry); spprintf(&path_info, 0, "%s%s", testit, path_info); free_pathinfo = 1; } else { @@ -653,7 +662,7 @@ PHP_METHOD(Phar, webPhar) return; } - entry_len = strlen(path_info); + entry_len = (int)strlen(path_info); entry_len -= (pt - path_info) + (fname_len - (basename - fname)); entry = estrndup(pt + (fname_len - (basename - fname)), entry_len); @@ -706,8 +715,12 @@ PHP_METHOD(Phar, webPhar) switch (Z_TYPE(retval)) { case IS_STRING: efree(entry); + if (ZEND_SIZE_T_INT_OVFL(Z_STRLEN_P(fci.retval))) { + zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: rewrite callback returned oversized value"); + return; + } entry = estrndup(Z_STRVAL_P(fci.retval), Z_STRLEN_P(fci.retval)); - entry_len = Z_STRLEN_P(fci.retval); + entry_len = (int)Z_STRLEN_P(fci.retval); break; case IS_TRUE: case IS_FALSE: @@ -730,7 +743,7 @@ PHP_METHOD(Phar, webPhar) } if (entry_len) { - phar_postprocess_ru_web(fname, fname_len, &entry, &entry_len, &ru, &ru_len); + phar_postprocess_ru_web(fname, (int)fname_len, &entry, &entry_len, &ru, &ru_len); } if (!entry_len || (entry_len == 1 && entry[0] == '/')) { @@ -738,7 +751,7 @@ PHP_METHOD(Phar, webPhar) /* direct request */ if (index_php_len) { entry = index_php; - entry_len = index_php_len; + entry_len = (int)index_php_len; if (entry[0] != '/') { spprintf(&entry, 0, "/%s", index_php); ++entry_len; @@ -749,9 +762,9 @@ PHP_METHOD(Phar, webPhar) entry_len = sizeof("/index.php")-1; } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || + if (FAILURE == phar_get_archive(&phar, fname, (int)fname_len, NULL, 0, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, 0)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); + phar_do_404(phar, fname, (int)fname_len, f404, (int)f404_len, entry, entry_len); if (free_pathinfo) { efree(path_info); @@ -795,9 +808,9 @@ PHP_METHOD(Phar, webPhar) } } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || + if (FAILURE == phar_get_archive(&phar, fname, (int)fname_len, NULL, 0, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, 0)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); + phar_do_404(phar, fname, (int)fname_len, f404, (int)f404_len, entry, entry_len); #ifdef PHP_WIN32 efree(fname); #endif @@ -816,7 +829,7 @@ PHP_METHOD(Phar, webPhar) case IS_LONG: if (Z_LVAL_P(val) == PHAR_MIME_PHP || Z_LVAL_P(val) == PHAR_MIME_PHPS) { mime_type = ""; - code = Z_LVAL_P(val); + code = (int)Z_LVAL_P(val); } else { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed"); if (free_pathinfo) { @@ -965,9 +978,12 @@ PHP_METHOD(Phar, mapPhar) return; } + if (ZEND_SIZE_T_INT_OVFL(alias_len)) { + RETURN_FALSE; + } phar_request_initialize(); - RETVAL_BOOL(phar_open_executed_filename(alias, alias_len, &error) == SUCCESS); + RETVAL_BOOL(phar_open_executed_filename(alias, (int)alias_len, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -986,9 +1002,12 @@ PHP_METHOD(Phar, loadPhar) return; } + if (ZEND_SIZE_T_INT_OVFL(alias_len) || ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } phar_request_initialize(); - RETVAL_BOOL(phar_open_from_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, &error) == SUCCESS); + RETVAL_BOOL(phar_open_from_filename(fname, (int)fname_len, alias, (int)alias_len, REPORT_ERRORS, NULL, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -1071,7 +1090,7 @@ PHP_METHOD(Phar, isValidPharFilename) } is_executable = executable; - RETVAL_BOOL(phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, is_executable, 2, 1) == SUCCESS); + RETVAL_BOOL(phar_detect_phar_fname_ext(fname, (int)fname_len, &ext_str, &ext_len, is_executable, 2, 1) == SUCCESS); } /* }}} */ @@ -1147,6 +1166,9 @@ PHP_METHOD(Phar, __construct) } } + if (ZEND_SIZE_T_INT_OVFL(alias_len) || ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } if (phar_obj->archive) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot call constructor twice"); return; @@ -1170,7 +1192,7 @@ PHP_METHOD(Phar, __construct) #endif } - if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, is_data, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + if (phar_open_or_create_filename(fname, (int)fname_len, alias, (int)alias_len, is_data, REPORT_ERRORS, &phar_data, &error) == FAILURE) { if (fname == arch && fname != save_fname) { efree(arch); @@ -1315,12 +1337,15 @@ PHP_METHOD(Phar, unlinkArchive) RETURN_FALSE; } + if (ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } if (!fname_len) { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"\""); return; } - if (FAILURE == phar_open_from_filename(fname, fname_len, NULL, 0, REPORT_ERRORS, &phar, &error)) { + if (FAILURE == phar_open_from_filename(fname, (int)fname_len, NULL, 0, REPORT_ERRORS, &phar, &error)) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\": %s", fname, error); efree(error); @@ -1331,7 +1356,7 @@ PHP_METHOD(Phar, unlinkArchive) } zname = (char*)zend_get_executed_filename(); - zname_len = strlen(zname); + zname_len = (int)strlen(zname); if (zname_len > 7 && !memcmp(zname, "phar://", 7) && SUCCESS == phar_split_fname(zname, zname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) { @@ -1407,9 +1432,10 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ zval *value; zend_bool close_fp = 1; struct _phar_t *p_obj = (struct _phar_t*) puser; - uint str_key_len, base_len = p_obj->l, fname_len; + uint base_len = p_obj->l, str_key_len; phar_entry_data *data; php_stream *fp; + php_stat_len fname_len; size_t contents_len; char *fname, *error = NULL, *base = p_obj->b, *save = NULL, *temp = NULL; zend_string *opened; @@ -1454,7 +1480,13 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } - str_key_len = Z_STRLEN(key); + if (ZEND_SIZE_T_INT_OVFL(Z_STRLEN(key))) { + zval_dtor(&key); + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Iterator %v returned an invalid key (too long)", ZSTR_VAL(ce->name)); + return ZEND_HASH_APPLY_STOP; + } + + str_key_len = (int)Z_STRLEN(key); str_key = estrndup(Z_STRVAL(key), str_key_len); save = str_key; @@ -1481,7 +1513,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ switch (intern->type) { case SPL_FS_DIR: test = spl_filesystem_object_get_path(intern, NULL); - fname_len = spprintf(&fname, 0, "%s%c%s", test, DEFAULT_SLASH, intern->u.dir.entry.d_name); + fname_len = (php_stat_len)spprintf(&fname, 0, "%s%c%s", test, DEFAULT_SLASH, intern->u.dir.entry.d_name); php_stat(fname, fname_len, FS_IS_DIR, &dummy); if (Z_TYPE(dummy) == IS_TRUE) { @@ -1495,7 +1527,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ if (test) { fname = test; - fname_len = strlen(fname); + fname_len = (php_stat_len)strlen(fname); } else { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Could not resolve file path"); return ZEND_HASH_APPLY_STOP; @@ -1511,7 +1543,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } - fname_len = strlen(fname); + fname_len = (php_stat_len)strlen(fname); save = fname; goto phar_spl_fileinfo; } @@ -1523,7 +1555,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ } fname = Z_STRVAL_P(value); - fname_len = Z_STRLEN_P(value); + fname_len = (php_stat_len)Z_STRLEN_P(value); phar_spl_fileinfo: if (base_len) { @@ -1537,7 +1569,7 @@ phar_spl_fileinfo: } base = temp; - base_len = strlen(base); + base_len = (int)strlen(base); if (strstr(fname, base)) { str_key_len = fname_len - base_len; @@ -1582,7 +1614,13 @@ phar_spl_fileinfo: return ZEND_HASH_APPLY_STOP; } - str_key_len = Z_STRLEN(key); + if (ZEND_SIZE_T_INT_OVFL(Z_STRLEN(key))) { + zval_dtor(&key); + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Iterator %v returned an invalid key (too long)", ZSTR_VAL(ce->name)); + return ZEND_HASH_APPLY_STOP; + } + + str_key_len = (int)Z_STRLEN(key); str_key = estrndup(Z_STRVAL(key), str_key_len); save = str_key; @@ -1747,6 +1785,10 @@ PHP_METHOD(Phar, buildFromDirectory) RETURN_FALSE; } + if (ZEND_SIZE_T_UINT_OVFL(dir_len)) { + RETURN_FALSE; + } + if (SUCCESS != object_init_ex(&iter, spl_ce_RecursiveDirectoryIterator)) { zval_ptr_dtor(&iter); zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to instantiate directory iterator for %s", phar_obj->archive->fname); @@ -1805,7 +1847,7 @@ PHP_METHOD(Phar, buildFromDirectory) pass.c = apply_reg ? Z_OBJCE(regexiter) : Z_OBJCE(iteriter); pass.p = phar_obj; pass.b = dir; - pass.l = dir_len; + pass.l = (uint)dir_len; pass.count = 0; pass.ret = return_value; pass.fp = php_stream_fopen_tmpfile(); @@ -1879,6 +1921,10 @@ PHP_METHOD(Phar, buildFromIterator) RETURN_FALSE; } + if (ZEND_SIZE_T_UINT_OVFL(base_len)) { + RETURN_FALSE; + } + if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); return; @@ -1889,7 +1935,7 @@ PHP_METHOD(Phar, buildFromIterator) pass.c = Z_OBJCE_P(obj); pass.p = phar_obj; pass.b = base; - pass.l = base_len; + pass.l = (uint)base_len; pass.ret = return_value; pass.count = 0; pass.fp = php_stream_fopen_tmpfile(); @@ -2012,7 +2058,7 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext, ze char *error; const char *pcr_error; int ext_len = ext ? strlen(ext) : 0; - int oldname_len; + size_t new_len, oldname_len; phar_archive_data *pphar = NULL; php_stream_statbuf ssb; @@ -2088,10 +2134,16 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext, ze spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext); efree(basename); - - basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); - phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname); + new_len = spprintf(&newpath, 0, "%s%s", basepath, newname); + if (ZEND_SIZE_T_INT_OVFL(new_len)) { + efree(oldpath); + efree(basepath); + efree(newpath); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "New name is too long"); + return NULL; + } + phar->fname_len = (int)new_len; phar->fname = newpath; phar->ext = newpath + phar->fname_len - strlen(ext) - 1; efree(basepath); @@ -2144,7 +2196,7 @@ its_ok: phar->alias_len = 0; } else { phar->alias = estrndup(newpath, strlen(newpath)); - phar->alias_len = strlen(newpath); + phar->alias_len = (int)strlen(newpath); phar->is_temporary_alias = 1; zend_hash_str_update_ptr(&(PHAR_G(phar_alias_map)), newpath, phar->fname_len, phar); } @@ -2407,7 +2459,7 @@ PHP_METHOD(Phar, convertToExecutable) is_data = phar_obj->archive->is_data; phar_obj->archive->is_data = 0; - ret = phar_convert_to_other(phar_obj->archive, format, ext, flags); + ret = phar_convert_to_other(phar_obj->archive, (int)format, ext, flags); phar_obj->archive->is_data = is_data; if (ret) { @@ -2510,7 +2562,7 @@ PHP_METHOD(Phar, convertToData) is_data = phar_obj->archive->is_data; phar_obj->archive->is_data = 1; - ret = phar_convert_to_other(phar_obj->archive, format, ext, flags); + ret = phar_convert_to_other(phar_obj->archive, (int)format, ext, flags); phar_obj->archive->is_data = is_data; if (ret) { @@ -2691,12 +2743,15 @@ PHP_METHOD(Phar, setAlias) } if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &alias, &alias_len) == SUCCESS) { + if (ZEND_SIZE_T_INT_OVFL(alias_len)) { + RETURN_FALSE; + } if (alias_len == phar_obj->archive->alias_len && memcmp(phar_obj->archive->alias, alias, alias_len) == 0) { RETURN_TRUE; } if (alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", alias, fd_ptr->fname); - if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) { + if (SUCCESS == phar_free_alias(fd_ptr, alias, (int)alias_len)) { efree(error); goto valid_alias; } @@ -2704,7 +2759,7 @@ PHP_METHOD(Phar, setAlias) efree(error); RETURN_FALSE; } - if (!phar_validate_alias(alias, alias_len)) { + if (!phar_validate_alias(alias, (int)alias_len)) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Invalid alias \"%s\" specified for phar \"%s\"", alias, phar_obj->archive->fname); RETURN_FALSE; @@ -2729,13 +2784,13 @@ valid_alias: phar_obj->archive->alias = NULL; } - phar_obj->archive->alias_len = alias_len; + phar_obj->archive->alias_len = (int)alias_len; phar_obj->archive->is_temporary_alias = 0; phar_flush(phar_obj->archive, NULL, 0, 0, &error); if (error) { phar_obj->archive->alias = oldalias; - phar_obj->archive->alias_len = oldalias_len; + phar_obj->archive->alias_len = (int)oldalias_len; phar_obj->archive->is_temporary_alias = old_temp; zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); if (readd) { @@ -3007,6 +3062,11 @@ PHP_METHOD(Phar, setSignatureAlgorithm) if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "l|s", &algo, &key, &key_len) != SUCCESS) { return; } + if (ZEND_SIZE_T_INT_OVFL(key_len)) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, + "Cannot set signature algorithm, key too long"); + return; + } switch (algo) { case PHAR_SIG_SHA256: @@ -3023,10 +3083,10 @@ PHP_METHOD(Phar, setSignatureAlgorithm) zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); return; } - phar_obj->archive->sig_flags = algo; + phar_obj->archive->sig_flags = (php_uint32)algo; phar_obj->archive->is_modified = 1; PHAR_G(openssl_privatekey) = key; - PHAR_G(openssl_privatekey_len) = key_len; + PHAR_G(openssl_privatekey_len) = (int)key_len; phar_flush(phar_obj->archive, 0, 0, 0, &error); if (error) { @@ -3407,7 +3467,9 @@ PHP_METHOD(Phar, copy) if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &oldfile, &oldfile_len, &newfile, &newfile_len) == FAILURE) { return; } - + if (ZEND_SIZE_T_INT_OVFL(newfile_len)) { + RETURN_FALSE; + } if (PHAR_G(readonly) && !phar_obj->archive->is_data) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Cannot copy \"%s\" to \"%s\", phar is read-only", oldfile, newfile); @@ -3467,7 +3529,7 @@ PHP_METHOD(Phar, copy) } newentry.filename = estrndup(newfile, newfile_len); - newentry.filename_len = newfile_len; + newentry.filename_len = (int)newfile_len; newentry.fp_refcount = 0; if (oldentry->fp_type != PHAR_FP) { @@ -3507,6 +3569,9 @@ PHP_METHOD(Phar, offsetExists) if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { return; } + if (ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, (uint) fname_len)) { if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint) fname_len))) { @@ -3546,8 +3611,12 @@ PHP_METHOD(Phar, offsetGet) return; } + if (ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } + /* security is 0 here so that we can get a better error message than "entry doesn't exist" */ - if (!(entry = phar_get_entry_info_dir(phar_obj->archive, fname, fname_len, 1, &error, 0))) { + if (!(entry = phar_get_entry_info_dir(phar_obj->archive, fname, (int)fname_len, 1, &error, 0))) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist%s%s", fname, error?", ":"", error?error:""); } else { if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) { @@ -3693,7 +3762,9 @@ PHP_METHOD(Phar, offsetSet) && zend_parse_parameters(ZEND_NUM_ARGS(), "ps", &fname, &fname_len, &cont_str, &cont_len) == FAILURE) { return; } - + if (ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", phar_obj->archive->fname); return; @@ -3709,7 +3780,7 @@ PHP_METHOD(Phar, offsetSet) return; } - phar_add_file(&(phar_obj->archive), fname, fname_len, cont_str, cont_len, zresource); + phar_add_file(&(phar_obj->archive), fname, (int)fname_len, cont_str, cont_len, zresource); } /* }}} */ @@ -3731,6 +3802,9 @@ PHP_METHOD(Phar, offsetUnset) if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { return; } + if (ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } if (zend_hash_str_exists(&phar_obj->archive->manifest, fname, (uint) fname_len)) { if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->archive->manifest, fname, (uint) fname_len))) { @@ -3778,13 +3852,16 @@ PHP_METHOD(Phar, addEmptyDir) if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &dirname, &dirname_len) == FAILURE) { return; } + if (ZEND_SIZE_T_INT_OVFL(dirname_len)) { + RETURN_FALSE; + } if (dirname_len >= sizeof(".phar")-1 && !memcmp(dirname, ".phar", sizeof(".phar")-1)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); return; } - phar_mkdir(&phar_obj->archive, dirname, dirname_len); + phar_mkdir(&phar_obj->archive, dirname, (int)dirname_len); } /* }}} */ @@ -3803,6 +3880,9 @@ PHP_METHOD(Phar, addFile) if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s", &fname, &fname_len, &localname, &localname_len) == FAILURE) { return; } + if (ZEND_SIZE_T_INT_OVFL(fname_len)) { + RETURN_FALSE; + } #if PHP_API_VERSION < 20100412 if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) { @@ -3827,7 +3907,7 @@ PHP_METHOD(Phar, addFile) } php_stream_to_zval(resource, &zresource); - phar_add_file(&(phar_obj->archive), fname, fname_len, NULL, 0, &zresource); + phar_add_file(&(phar_obj->archive), fname, (int)fname_len, NULL, 0, &zresource); zval_ptr_dtor(&zresource); } /* }}} */ @@ -3845,8 +3925,11 @@ PHP_METHOD(Phar, addFromString) if (zend_parse_parameters(ZEND_NUM_ARGS(), "ps", &localname, &localname_len, &cont_str, &cont_len) == FAILURE) { return; } + if (ZEND_SIZE_T_INT_OVFL(localname_len)) { + RETURN_FALSE; + } - phar_add_file(&(phar_obj->archive), localname, localname_len, cont_str, cont_len, NULL); + phar_add_file(&(phar_obj->archive), localname, (int)localname_len, cont_str, cont_len, NULL); } /* }}} */ @@ -4067,7 +4150,7 @@ PHP_METHOD(Phar, delMetadata) static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char *dest, int dest_len, char **error) /* {{{ */ { php_stream_statbuf ssb; - int len; + size_t len; php_stream *fp; char *fullpath; const char *slash; @@ -4337,7 +4420,7 @@ PHP_METHOD(Phar, extractTo) zend_throw_exception_ex(phar_ce_PharException, 0, "Phar Error: attempted to extract non-existent file \"%s\" from phar \"%s\"", Z_STRVAL_P(zval_file), phar_obj->archive->fname); } - if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, &error)) { + if (FAILURE == phar_extract_file(overwrite, entry, pathto, (int)pathto_len, &error)) { zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s", phar_obj->archive->fname, error); efree(error); @@ -4358,7 +4441,7 @@ PHP_METHOD(Phar, extractTo) return; } - if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, &error)) { + if (FAILURE == phar_extract_file(overwrite, entry, pathto, (int)pathto_len, &error)) { zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s", phar_obj->archive->fname, error); efree(error); @@ -4374,7 +4457,7 @@ all_files: } ZEND_HASH_FOREACH_PTR(&phar->manifest, entry) { - if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, &error)) { + if (FAILURE == phar_extract_file(overwrite, entry, pathto, (int)pathto_len, &error)) { zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s", phar->fname, error); efree(error); -- 2.40.0