Created
March 21, 2017 13:30
-
-
Save weltling/aa8dddab3867248df333b24ed3e72398 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c | |
index 394819cf34..d57002a592 100644 | |
--- a/ext/zip/php_zip.c | |
+++ b/ext/zip/php_zip.c | |
@@ -138,7 +138,8 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil | |
struct zip_file *zf; | |
struct zip_stat sb; | |
char b[8192]; | |
- int n, len, ret; | |
+ zip_int64_t n; | |
+ int len, ret; | |
php_stream *stream; | |
char *fullpath; | |
char *file_dirname_fullpath; | |
@@ -255,7 +256,20 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil | |
n = 0; | |
while ((n=zip_fread(zf, b, sizeof(b))) > 0) { | |
+#if ZEND_ENABLE_ZVAL_LONG64 | |
php_stream_write(stream, b, n); | |
+#else | |
+ size_t k, l; | |
+ zip_int64_t m = n; | |
+ | |
+ do { | |
+ k = m > SIZE_MAX ? SIZE_MAX : (size_t)m; | |
+ | |
+ l = php_stream_write(stream, b, k); | |
+ | |
+ m -= l; | |
+ } while (m > 0); | |
+#endif | |
} | |
php_stream_close(stream); | |
@@ -1292,7 +1306,7 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_read) | |
zend_long len = 0; | |
zip_read_rsrc * zr_rsrc; | |
zend_string *buffer; | |
- int n = 0; | |
+ zip_int64_t n = 0; | |
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &zip_entry, &len) == FAILURE) { | |
return; | |
@@ -1311,7 +1325,8 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_read) | |
n = zip_fread(zr_rsrc->zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); | |
if (n > 0) { | |
ZSTR_VAL(buffer)[n] = '\0'; | |
- ZSTR_LEN(buffer) = n; | |
+ /* On 32-bit, we couldn't read more than were requested, cast should be safe. */ | |
+ ZSTR_LEN(buffer) = (size_t)n; | |
RETURN_NEW_STR(buffer); | |
} else { | |
zend_string_free(buffer); | |
@@ -1808,7 +1823,7 @@ static ZIPARCHIVE_METHOD(addFromString) | |
ze_zip_object *ze_obj; | |
struct zip_source *zs; | |
int pos = 0; | |
- int cur_idx; | |
+ zip_int64_t cur_idx; | |
if (!self) { | |
RETURN_FALSE; | |
@@ -1994,7 +2009,11 @@ static ZIPARCHIVE_METHOD(setArchiveComment) | |
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &comment, &comment_len) == FAILURE) { | |
return; | |
} | |
- if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) { | |
+ if (comment_len > UINT16_MAX) { | |
+ php_error_docref(NULL, E_WARNING, "Invalid argument, comment is too long, expect a string of max length %u", UINT16_MAX); | |
+ RETURN_FALSE; | |
+ } | |
+ if (zip_set_archive_comment(intern, (const char *)comment, (zip_uint16_t)comment_len)) { | |
RETURN_FALSE; | |
} else { | |
RETURN_TRUE; | |
@@ -2038,7 +2057,7 @@ static ZIPARCHIVE_METHOD(setCommentName) | |
zval *self = getThis(); | |
size_t comment_len, name_len; | |
char * comment, *name; | |
- int idx; | |
+ zip_int64_t idx; | |
if (!self) { | |
RETURN_FALSE; | |
@@ -2315,7 +2334,7 @@ static ZIPARCHIVE_METHOD(getCommentName) | |
struct zip *intern; | |
zval *self = getThis(); | |
size_t name_len; | |
- int idx; | |
+ zip_int64_t idx; | |
zend_long flags = 0; | |
int comment_len = 0; | |
const char * comment; | |
@@ -2335,14 +2354,18 @@ static ZIPARCHIVE_METHOD(getCommentName) | |
php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); | |
RETURN_FALSE; | |
} | |
+ if (ZEND_LONG_INT_OVFL(flags)) { | |
+ php_error_docref(NULL, E_NOTICE, "Invalid flags"); | |
+ RETURN_FALSE; | |
+ } | |
idx = zip_name_locate(intern, name, 0); | |
if (idx < 0) { | |
RETURN_FALSE; | |
} | |
- comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags); | |
- RETURN_STRINGL((char *)comment, (zend_long)comment_len); | |
+ comment = zip_get_file_comment(intern, idx, &comment_len, flags); | |
+ RETURN_STRINGL((char *)comment, comment_len); | |
} | |
/* }}} */ | |
@@ -2781,11 +2804,12 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ | |
zend_long index = -1; | |
zend_long flags = 0; | |
zend_long len = 0; | |
+ size_t alloc_len = 0; | |
zend_string *filename; | |
zend_string *buffer; | |
- int n = 0; | |
+ zip_int64_t n = 0; | |
if (!self) { | |
RETURN_FALSE; | |
@@ -2810,7 +2834,10 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ | |
} | |
if (len < 1) { | |
- len = sb.size; | |
+ /* FIXME not safe on 32-bit. */ | |
+ alloc_len = sb.size; | |
+ } else { | |
+ alloc_len = len; | |
} | |
if (index >= 0) { | |
zf = zip_fopen_index(intern, index, flags); | |
@@ -2822,7 +2849,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ | |
RETURN_FALSE; | |
} | |
- buffer = zend_string_safe_alloc(1, len, 0, 0); | |
+ buffer = zend_string_safe_alloc(1, alloc_len, 0, 0); | |
n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); | |
if (n < 1) { | |
zend_string_free(buffer); | |
@@ -2831,7 +2858,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ | |
zip_fclose(zf); | |
ZSTR_VAL(buffer)[n] = '\0'; | |
- ZSTR_LEN(buffer) = n; | |
+ ZSTR_LEN(buffer) = (size_t)n; | |
RETURN_NEW_STR(buffer); | |
} | |
/* }}} */ | |
diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h | |
index 327ad54262..c1a6815f2d 100644 | |
--- a/ext/zip/php_zip.h | |
+++ b/ext/zip/php_zip.h | |
@@ -43,8 +43,8 @@ extern zend_module_entry zip_module_entry; | |
typedef struct _ze_zip_rsrc { | |
struct zip *za; | |
- int index_current; | |
- int num_files; | |
+ zip_uint64_t index_current; | |
+ zip_uint64_t num_files; | |
} zip_rsrc; | |
typedef zip_rsrc * zip_rsrc_ptr; | |
diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c | |
index 2ed584021d..5cad2d7bce 100644 | |
--- a/ext/zip/zip_stream.c | |
+++ b/ext/zip/zip_stream.c | |
@@ -44,7 +44,7 @@ struct php_zip_stream_data_t { | |
/* {{{ php_zip_ops_read */ | |
static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count) | |
{ | |
- ssize_t n = 0; | |
+ zip_int64_t n = 0; | |
STREAM_DATA_FROM_STREAM(); | |
if (self->za && self->zf) { | |
@@ -66,10 +66,11 @@ static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count) | |
} | |
/* cast count to signed value to avoid possibly negative n | |
* being cast to unsigned value */ | |
- if (n == 0 || n < (ssize_t)count) { | |
+ if (n == 0 || n < count) { | |
stream->eof = 1; | |
} else { | |
- self->cursor += n; | |
+ /* On 32-bit, only SIZE_MAX bytes can be read, so it is safe to cast. */ | |
+ self->cursor += (size_t)n; | |
} | |
} | |
return (n < 1 ? 0 : (size_t)n); | |
@@ -173,6 +174,7 @@ static int php_zip_ops_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ | |
zip_close(za); | |
if (path[path_len-1] != '/') { | |
+ /* FIXME not safe on 32-bit. */ | |
ssb->sb.st_size = sb.size; | |
ssb->sb.st_mode |= S_IFREG; /* regular file */ | |
} else { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment