--- embedaddon/php/main/streams/streams.c 2012/05/29 12:34:35 1.1.1.2 +++ embedaddon/php/main/streams/streams.c 2013/10/14 08:02:43 1.1.1.4 @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.1.1.2 2012/05/29 12:34:35 misho Exp $ */ +/* $Id: streams.c,v 1.1.1.4 2013/10/14 08:02:43 misho Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -1028,8 +1028,8 @@ PHPAPI char *php_stream_get_record(php_stream *stream, char *ret_buf, /* returned buffer */ *found_delim = NULL; size_t buffered_len, - tent_ret_len; /* tentative returned length*/ - int has_delim = delim_len > 0 && delim[0] != '\0'; + tent_ret_len; /* tentative returned length */ + int has_delim = delim_len > 0; if (maxlen == 0) { return NULL; @@ -1060,9 +1060,17 @@ PHPAPI char *php_stream_get_record(php_stream *stream, if (has_delim) { /* search for delimiter, but skip buffered_len (the number of bytes * buffered before this loop iteration), as they have already been - * searched for the delimiter */ + * searched for the delimiter. + * The left part of the delimiter may still remain in the buffer, + * so subtract up to from buffered_len, which is + * the ammount of data we skip on this search as an optimization + */ found_delim = _php_stream_search_delim( - stream, maxlen, buffered_len, delim, delim_len TSRMLS_CC); + stream, maxlen, + buffered_len >= (delim_len - 1) + ? buffered_len - (delim_len - 1) + : 0, + delim, delim_len TSRMLS_CC); if (found_delim) { break; } @@ -1437,7 +1445,12 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, len += ret; ptr += ret; } - *ptr = '\0'; + if (len) { + *ptr = '\0'; + } else { + pefree(*buf, persistent); + *buf = NULL; + } return len; } @@ -1481,7 +1494,7 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *s char buf[CHUNK_SIZE]; size_t readchunk; size_t haveread = 0; - size_t didread; + size_t didread, didwrite, towrite; size_t dummy; php_stream_statbuf ssbuf; @@ -1516,16 +1529,16 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *s p = php_stream_mmap_range(src, php_stream_tell(src), maxlen, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped); if (p) { - mapped = php_stream_write(dest, p, mapped); + didwrite = php_stream_write(dest, p, mapped); php_stream_mmap_unmap_ex(src, mapped); - *len = mapped; + *len = didwrite; - /* we've got at least 1 byte to read. - * less than 1 is an error */ - - if (mapped > 0) { + /* we've got at least 1 byte to read + * less than 1 is an error + * AND read bytes match written */ + if (mapped > 0 && mapped == didwrite) { return SUCCESS; } return FAILURE; @@ -1543,7 +1556,6 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *s if (didread) { /* extra paranoid */ - size_t didwrite, towrite; char *writeptr; towrite = didread; @@ -2327,8 +2339,8 @@ PHPAPI int _php_stream_scandir(char *dirname, char **n php_stream *stream; php_stream_dirent sdp; char **vector = NULL; - int vector_size = 0; - int nfiles = 0; + unsigned int vector_size = 0; + unsigned int nfiles = 0; if (!namelist) { return FAILURE; @@ -2344,20 +2356,32 @@ PHPAPI int _php_stream_scandir(char *dirname, char **n if (vector_size == 0) { vector_size = 10; } else { + if(vector_size*2 < vector_size) { + /* overflow */ + php_stream_closedir(stream); + efree(vector); + return FAILURE; + } vector_size *= 2; } - vector = (char **) erealloc(vector, vector_size * sizeof(char *)); + vector = (char **) safe_erealloc(vector, vector_size, sizeof(char *), 0); } vector[nfiles] = estrdup(sdp.d_name); nfiles++; + if(vector_size < 10 || nfiles == 0) { + /* overflow */ + php_stream_closedir(stream); + efree(vector); + return FAILURE; + } } php_stream_closedir(stream); *namelist = vector; - if (compare) { + if (nfiles > 0 && compare) { qsort(*namelist, nfiles, sizeof(char *), (int(*)(const void *, const void *))compare); } return nfiles;