diff options
author | Sergei Turchanov <turchanov@farpost.com> | 2019-08-29 17:29:19 +1000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-12-20 11:22:59 +0100 |
commit | c62cd9a43ad97aa279615b21f7cb5f1646f52d80 (patch) | |
tree | 2cf838ada7ac80c90d24f7337faedf1049287902 | |
parent | cbb0efaeeb265ff8026dee1d049d57a8d2b5c133 (diff) | |
download | php-git-c62cd9a43ad97aa279615b21f7cb5f1646f52d80.tar.gz |
Fix #74170: locale information change after mime_content_type
Some functions in libmagic (distributed with fileinfo extension) perform this sequence of calls:
func() {
setlocale(LC_TYPE, "C")
.. do some work ..
setlocale(LC_TYPE, "")
}
It effectively resets LC_TYPE if it that was set before the function call.
To avoid manipulations with current locale at all, the problematic functions
were modified to use locale-independent functions.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | ext/fileinfo/libmagic/funcs.c | 5 | ||||
-rw-r--r-- | ext/fileinfo/libmagic/readcdf.c | 18 | ||||
-rw-r--r-- | ext/fileinfo/libmagic/softmagic.c | 14 | ||||
-rw-r--r-- | ext/fileinfo/tests/bug74170.phpt | 22 |
5 files changed, 47 insertions, 16 deletions
@@ -9,6 +9,10 @@ PHP NEWS - CURL: . Implemented FR #77711 (CURLFile should support UNICODE filenames). (cmb) +- Fileinfo: + . Fixed bug #74170 (locale information change after mime_content_type). + (Sergei Turchanov) + - GD: . Fixed bug #78923 (Artifacts when convoluting image with transparency). (wilson chen) diff --git a/ext/fileinfo/libmagic/funcs.c b/ext/fileinfo/libmagic/funcs.c index 8377bcc6a5..027af0e516 100644 --- a/ext/fileinfo/libmagic/funcs.c +++ b/ext/fileinfo/libmagic/funcs.c @@ -477,11 +477,9 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep) zend_string *repl; size_t rep_cnt = 0; - (void)setlocale(LC_CTYPE, "C"); - opts |= PCRE2_MULTILINE; convert_libmagic_pattern(&patt, (char*)pat, strlen(pat), opts); - if ((pce = pcre_get_compiled_regex_cache(Z_STR(patt))) == NULL) { + if ((pce = pcre_get_compiled_regex_cache_ex(Z_STR(patt), 0)) == NULL) { zval_ptr_dtor(&patt); rep_cnt = -1; goto out; @@ -503,7 +501,6 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep) zend_string_release_ex(res, 0); out: - (void)setlocale(LC_CTYPE, ""); return rep_cnt; } diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c index 4a3ddc60ff..6e93db1ec3 100644 --- a/ext/fileinfo/libmagic/readcdf.c +++ b/ext/fileinfo/libmagic/readcdf.c @@ -116,14 +116,24 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv) { size_t i; const char *rv = NULL; + char *vbuf_lower; - (void)setlocale(LC_CTYPE, "C"); - for (i = 0; nv[i].pattern != NULL; i++) - if (strcasestr(vbuf, nv[i].pattern) != NULL) { + vbuf_lower = zend_str_tolower_dup(vbuf, strlen(vbuf)); + for (i = 0; nv[i].pattern != NULL; i++) { + char *pattern_lower; + int found; + + pattern_lower = zend_str_tolower_dup(nv[i].pattern, strlen(nv[i].pattern)); + found = (strstr(vbuf_lower, pattern_lower) != NULL); + efree(pattern_lower); + + if (found) { rv = nv[i].mime; break; } - (void)setlocale(LC_CTYPE, ""); + } + + efree(vbuf_lower); return rv; } diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index d37ce0d255..10f9aaaaa3 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -422,27 +422,25 @@ flush: private int check_fmt(struct magic_set *ms, const char *fmt) { - pcre2_code *pce; - uint32_t re_options, capture_count; + pcre_cache_entry *pce; int rv = -1; zend_string *pattern; if (strchr(fmt, '%') == NULL) return 0; - (void)setlocale(LC_CTYPE, "C"); pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0); - if ((pce = pcre_get_compiled_regex(pattern, &capture_count, &re_options)) == NULL) { + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) { rv = -1; } else { - pcre2_match_data *match_data = php_pcre_create_match_data(capture_count, pce); + pcre2_code *re = php_pcre_pce_re(pce); + pcre2_match_data *match_data = php_pcre_create_match_data(0, re); if (match_data) { - rv = pcre2_match(pce, (PCRE2_SPTR)fmt, strlen(fmt), 0, re_options, match_data, php_pcre_mctx()) > 0; + rv = pcre2_match(re, (PCRE2_SPTR)fmt, strlen(fmt), 0, 0, match_data, php_pcre_mctx()) > 0; php_pcre_free_match_data(match_data); } } - zend_string_release_ex(pattern, 0); - (void)setlocale(LC_CTYPE, ""); + zend_string_release(pattern); return rv; } diff --git a/ext/fileinfo/tests/bug74170.phpt b/ext/fileinfo/tests/bug74170.phpt new file mode 100644 index 0000000000..9e3cbd982b --- /dev/null +++ b/ext/fileinfo/tests/bug74170.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #74170 locale information change after mime_content_type +--SKIPIF-- +<?php +if (!class_exists('finfo')) + die('skip no fileinfo extension'); +if (!extension_loaded('intl')) + die('skip intl extension not enabled'); +if (setlocale(LC_CTYPE, 'ru_RU.koi8r') === false) + die('skip ru_RU.koi8r locale is not available'); +?> +--FILE-- +<?php +var_dump(setlocale(LC_CTYPE, 'ru_RU.koi8r')); +var_dump(nl_langinfo(CODESET)); +var_dump(mime_content_type(__DIR__ . '/resources/test.ppt')); +var_dump(nl_langinfo(CODESET)); +--EXPECT-- +string(11) "ru_RU.koi8r" +string(6) "KOI8-R" +string(29) "application/vnd.ms-powerpoint" +string(6) "KOI8-R" |