diff options
author | Antony Dovgal <tony2001@php.net> | 2005-10-11 13:50:52 +0000 |
---|---|---|
committer | Antony Dovgal <tony2001@php.net> | 2005-10-11 13:50:52 +0000 |
commit | ad73bdcbe06c4c4ed8cf64623de6f443589c165b (patch) | |
tree | 00b4f26999b4dd225811c91c06ce75bbd540692c | |
parent | bb8e5de1817b4c001394124635f77a7c91a3a568 (diff) | |
download | php-git-ad73bdcbe06c4c4ed8cf64623de6f443589c165b.tar.gz |
fix #34757 (iconv_substr() gives "Unknown error" when offset > string length)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/iconv/iconv.c | 42 |
2 files changed, 29 insertions, 15 deletions
@@ -62,6 +62,8 @@ PHP NEWS - Fixed bug #34785 (subclassing of mysqli_stmt does not work). (Georg) - Fixed bug #34777 (Crash in dblib when fetching non-existent error info). (Ilia) - Fixed bug #34771 (strtotime() fails with 1-12am/pm). (Derick) +- Fixed bug #34757 (iconv_substr() gives "Unknown error" when offset > string + length). (Tony) - Fixed bug #34723 (array_count_values() strips leading zeroes). (Tony) - Fixed bug #34704 (Infinite recursion due to corrupt JPEG). (Marcus) - Fixed bug #34678 (__call(), is_callable() and static methods). (Dmitry) diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 92e6a2e0df..5b8b60d175 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -583,26 +583,38 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval, size_t out_left; unsigned int cnt; - + unsigned int total_len; + + err = _php_iconv_strlen(&total_len, str, nbytes, enc); + if (err != PHP_ICONV_ERR_SUCCESS) { + return err; + } + /* normalize the offset and the length */ - if (offset < 0 || len < 0) { - unsigned int total_len; - err = _php_iconv_strlen(&total_len, str, nbytes, enc); - if (err != PHP_ICONV_ERR_SUCCESS) { - return err; - } - if (offset < 0) { - if ((offset += total_len) < 0) { - offset = 0; - } + if (offset < 0) { + if ((offset += total_len) < 0) { + offset = 0; } - if (len < 0) { - if ((len += (total_len - offset)) < 0) { - len = 0; - } + } + if (len < 0) { + if ((len += (total_len - offset)) < 0) { + len = 0; } } + if (offset >= total_len) { + return PHP_ICONV_ERR_SUCCESS; + } + + if ((offset + len) > total_len) { + /* trying to compute the length */ + len = total_len - offset; + } + + if (len == 0) { + return PHP_ICONV_ERR_SUCCESS; + } + cd1 = iconv_open(GENERIC_SUPERSET_NAME, enc); if (cd1 == (iconv_t)(-1)) { |