summaryrefslogtreecommitdiff
path: root/ext/phar/tar.c
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2018-04-17 15:09:31 +0200
committerAnatol Belski <ab@php.net>2018-04-18 20:15:05 +0200
commit2e5ac355b9b578e5d1e460f2b2f4205f8a7c87b3 (patch)
tree4e889adcbc69cf8c3a1f3ad2210dac034995e496 /ext/phar/tar.c
parent8327c4c3bd8844f3b312ac9d72cb940e73e48109 (diff)
downloadphp-git-2e5ac355b9b578e5d1e460f2b2f4205f8a7c87b3.tar.gz
Move to unsigned types in phar
Preventing integer overflows in principle, which allows to avoid additional range checks. The phar format is based on 32-bit lengths, so the storage sizes was kept same.
Diffstat (limited to 'ext/phar/tar.c')
-rw-r--r--ext/phar/tar.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/ext/phar/tar.c b/ext/phar/tar.c
index dd2b16af05..6385483914 100644
--- a/ext/phar/tar.c
+++ b/ext/phar/tar.c
@@ -19,7 +19,7 @@
#include "phar_internal.h"
-static uint32_t phar_tar_number(char *buf, int len) /* {{{ */
+static uint32_t phar_tar_number(char *buf, size_t len) /* {{{ */
{
uint32_t num = 0;
int i = 0;
@@ -84,7 +84,7 @@ static int phar_tar_octal(char *buf, uint32_t val, int len) /* {{{ */
}
/* }}} */
-static uint32_t phar_tar_checksum(char *buf, int len) /* {{{ */
+static uint32_t phar_tar_checksum(char *buf, size_t len) /* {{{ */
{
uint32_t sum = 0;
char *end = buf + len;
@@ -124,7 +124,7 @@ int phar_is_tar(char *buf, char *fname) /* {{{ */
}
/* }}} */
-int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error) /* {{{ */
+int 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) /* {{{ */
{
phar_archive_data *phar;
int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error);
@@ -202,7 +202,7 @@ static size_t strnlen(const char *s, size_t maxlen) {
}
#endif
-int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, int is_data, uint32_t compression, char **error) /* {{{ */
+int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, int is_data, uint32_t compression, char **error) /* {{{ */
{
char buf[512], *actual_alias = NULL, *p;
phar_entry_info entry = {0};
@@ -211,7 +211,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
uint32_t sum1, sum2, size, old;
phar_archive_data *myphar, *actual;
int last_was_longlink = 0;
- int linkname_len;
+ size_t linkname_len;
if (error) {
*error = NULL;
@@ -274,6 +274,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
if (((!old && hdr->prefix[0] == 0) || old) && strnlen(hdr->name, 100) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) {
zend_off_t curloc;
+ size_t sig_len;
if (size > 511) {
if (error) {
@@ -302,7 +303,7 @@ bail:
# define PHAR_GET_32(buffer) (uint32_t) *(buffer)
#endif
myphar->sig_flags = PHAR_GET_32(buf);
- if (FAILURE == phar_verify_signature(fp, php_stream_tell(fp) - size - 512, myphar->sig_flags, buf + 8, size - 8, fname, &myphar->signature, &myphar->sig_len, error)) {
+ if (FAILURE == phar_verify_signature(fp, php_stream_tell(fp) - size - 512, myphar->sig_flags, buf + 8, size - 8, fname, &myphar->signature, &sig_len, error)) {
if (error) {
char *save = *error;
spprintf(error, 4096, "phar error: tar-based phar \"%s\" signature cannot be verified: %s", fname, save);
@@ -310,6 +311,7 @@ bail:
}
goto bail;
}
+ myphar->sig_len = sig_len;
php_stream_seek(fp, curloc + 512, SEEK_SET);
/* signature checked out, let's ensure this is the last file in the phar */
if (((hdr->typeflag == '\0') || (hdr->typeflag == TAR_FILE)) && size > 0) {
@@ -486,7 +488,7 @@ bail:
if (entry.tar_type == TAR_LINK) {
if (!zend_hash_str_exists(&myphar->manifest, hdr->linkname, linkname_len)) {
if (error) {
- spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%.*s\"", fname, linkname_len, hdr->linkname);
+ spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%.*s\"", fname, (int)linkname_len, hdr->linkname);
}
pefree(entry.filename, entry.is_persistent);
php_stream_close(fp);
@@ -946,7 +948,8 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
phar_entry_info entry = {0};
static const char newstub[] = "<?php // tar-based phar archive stub file\n__HALT_COMPILER();";
php_stream *oldfile, *newfile, *stubfile;
- int closeoldfile, free_user_stub, signature_length;
+ int closeoldfile, free_user_stub;
+ size_t signature_length;
struct _phar_pass_tar_info pass;
char *buf, *signature, *tmp, sigbuf[8];
char halt_stub[] = "__HALT_COMPILER();";
@@ -983,7 +986,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
spprintf(error, 0, "phar error: unable to create temporary file");
return -1;
}
- if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
+ if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
if (error) {
spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
}
@@ -1249,7 +1252,7 @@ nostub:
PHAR_SET_32(sigbuf, phar->sig_flags);
PHAR_SET_32(sigbuf + 4, signature_length);
- if (8 != (int)php_stream_write(entry.fp, sigbuf, 8) || signature_length != (int)php_stream_write(entry.fp, signature, signature_length)) {
+ if (8 != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) {
efree(signature);
if (error) {
spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", phar->fname);