diff options
author | Anatol Belski <ab@php.net> | 2018-04-17 15:09:31 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2018-04-18 20:15:05 +0200 |
commit | 2e5ac355b9b578e5d1e460f2b2f4205f8a7c87b3 (patch) | |
tree | 4e889adcbc69cf8c3a1f3ad2210dac034995e496 /ext/phar/tar.c | |
parent | 8327c4c3bd8844f3b312ac9d72cb940e73e48109 (diff) | |
download | php-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.c | 23 |
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); |