. Fixed bug #69566 (Conditional jump or move depends on uninitialised value
in extension trait). (jbboehr at gmail dot com)
+- Iconv:
+ . Fixed bug #48147 (iconv with //IGNORE cuts the string). (Stas)
+
- Opcache
. Fixed bug #69549 (Memory leak with opcache.optimization_level=0xFFFFFFFF).
(Laruence, Dmitry)
PHP_ICONV_H_PATH="$PHP_ICONV_PREFIX/include/giconv.h"
else
PHP_ICONV_H_PATH="$PHP_ICONV_PREFIX/include/iconv.h"
- fi
+ fi
AC_MSG_CHECKING([if iconv is glibc's])
AC_TRY_LINK([#include <gnu/libc-version.h>],[gnu_get_libc_version();],
AC_TRY_RUN([
#include <$PHP_ICONV_H_PATH>
int main() {
- printf("%d", _libiconv_version);
- return 0;
+ printf("%d", _libiconv_version);
+ return 0;
}
],[
AC_MSG_RESULT(yes)
if (cd == (iconv_t)(-1)) {
if (errno == EINVAL) {
return 0;
- } else {
+ } else {
return 1;
}
}
AC_DEFINE([ICONV_SUPPORTS_ERRNO],0,[Whether iconv supports error no or not])
])
+ AC_MSG_CHECKING([if iconv supports //IGNORE])
+ AC_TRY_RUN([
+#include <$PHP_ICONV_H_PATH>
+#include <stdlib.h>
+
+int main() {
+ iconv_t cd = iconv_open( "UTF-8//IGNORE", "UTF-8" );
+ char *in_p = "\xC3\xC3\xC3\xB8";
+ size_t in_left = 4, out_left = 4096;
+ char *out = malloc(out_left);
+ char *out_p = out;
+ size_t result = iconv(cd, (char **) &in_p, &in_left, (char **) &out_p, &out_left);
+ if(result == (size_t)-1) {
+ return 1;
+ }
+ return 0;
+}
+ ],[
+ AC_MSG_RESULT(yes)
+ PHP_DEFINE([ICONV_BROKEN_IGNORE],0,[ext/iconv])
+ AC_DEFINE([ICONV_BROKEN_IGNORE],0,[Whether iconv supports IGNORE])
+ ],[
+ AC_MSG_RESULT(no)
+ PHP_DEFINE([ICONV_BROKEN_IGNORE],1,[ext/iconv])
+ AC_DEFINE([ICONV_BROKEN_IGNORE],1,[Whether iconv supports IGNORE])
+ ],[
+ AC_MSG_RESULT(no, cross-compiling)
+ PHP_DEFINE([ICONV_SUPPORTS_ERRNO],0,[ext/iconv])
+ AC_DEFINE([ICONV_SUPPORTS_ERRNO],0,[Whether iconv supports IGNORE])
+ ])
+
AC_MSG_CHECKING([if your cpp allows macro usage in include lines])
AC_TRY_COMPILE([
#define FOO <$PHP_ICONV_H_PATH>
}
/* }}} */
+/* {{{ */
+#if ICONV_BROKEN_IGNORE
+static int _php_check_ignore(const char *charset)
+{
+ size_t clen = strlen(charset);
+ if (clen >= 9 && strcmp("//IGNORE", charset+clen-8) == 0) {
+ return 1;
+ }
+ if (clen >= 19 && strcmp("//IGNORE//TRANSLIT", charset+clen-18) == 0) {
+ return 1;
+ }
+ return 0;
+}
+#else
+#define _php_check_ignore(x) (0)
+#endif
+/* }}} */
+
/* {{{ php_iconv_string()
*/
PHP_ICONV_API php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len,
char *out_p, *out_buf, *tmp_buf;
size_t bsz, result = 0;
php_iconv_err_t retval = PHP_ICONV_ERR_SUCCESS;
+ int ignore_ilseq = _php_check_ignore(out_charset);
*out = NULL;
*out_len = 0;
result = iconv(cd, (char **) &in_p, &in_left, (char **) &out_p, &out_left);
out_size = bsz - out_left;
if (result == (size_t)(-1)) {
+ if (ignore_ilseq && errno == EILSEQ) {
+ if (in_left <= 1) {
+ result = 0;
+ } else {
+ errno = 0;
+ in_p++;
+ in_left--;
+ continue;
+ }
+ }
+
if (errno == E2BIG && in_left > 0) {
/* converted string is longer than out buffer */
bsz += in_len;
--- /dev/null
+--TEST--
+Bug #48147 (iconv with //IGNORE cuts the string)
+--SKIPIF--
+<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?>
+--FILE--
+<?php
+$text = "aa\xC3\xC3\xC3\xB8aa";
+var_dump(iconv("UTF-8", "UTF-8", $text));
+var_dump(urlencode(iconv("UTF-8", "UTF-8//IGNORE", $text)));
+// only invalid
+var_dump(urlencode(iconv("UTF-8", "UTF-8//IGNORE", "\xC3")));
+// start invalid
+var_dump(urlencode(iconv("UTF-8", "UTF-8//IGNORE", "\xC3\xC3\xC3\xB8aa")));
+// finish invalid
+var_dump(urlencode(iconv("UTF-8", "UTF-8//IGNORE", "aa\xC3\xC3\xC3")));
+?>
+--EXPECTF--
+Notice: iconv(): Detected an illegal character in input string in %s on line %d
+bool(false)
+string(10) "aa%C3%B8aa"
+
+Notice: iconv(): Detected an incomplete multibyte character in input string in %s on line %d
+string(0) ""
+string(8) "%C3%B8aa"
+
+Notice: iconv(): Detected an incomplete multibyte character in input string in %s on line %d
+string(0) ""