From 4e26555fe1dba00591e62080eee781a0c91b0b74 Mon Sep 17 00:00:00 2001 From: Sergei Turchanov Date: Thu, 29 Aug 2019 17:29:19 +1000 Subject: [PATCH 1/2] 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. --- ext/fileinfo/libmagic/funcs.c | 5 +---- ext/fileinfo/libmagic/readcdf.c | 19 +++++++++++++++---- ext/fileinfo/libmagic/softmagic.c | 11 ++++------- ext/fileinfo/tests/bug74170.phpt | 22 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 ext/fileinfo/tests/bug74170.phpt diff --git a/ext/fileinfo/libmagic/funcs.c b/ext/fileinfo/libmagic/funcs.c index f49129e7d80bf..4b1964b574715 100644 --- a/ext/fileinfo/libmagic/funcs.c +++ b/ext/fileinfo/libmagic/funcs.c @@ -471,11 +471,9 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep) zend_string *repl; int rep_cnt = 0; - (void)setlocale(LC_CTYPE, "C"); - opts |= PCRE_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; @@ -497,7 +495,6 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep) zend_string_release(res); out: - (void)setlocale(LC_CTYPE, ""); return rep_cnt; } diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c index 5123f6f7e7492..36ee1c11611b7 100644 --- a/ext/fileinfo/libmagic/readcdf.c +++ b/ext/fileinfo/libmagic/readcdf.c @@ -120,14 +120,25 @@ 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 = 0; + + + 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 1f7c7db4836de..6329104844368 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -412,23 +412,20 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, private int check_fmt(struct magic_set *ms, struct magic *m) { - pcre *pce; - int re_options, rv = -1; - pcre_extra *re_extra; + pcre_cache_entry *pce; + int rv = -1; zend_string *pattern; if (strchr(m->desc, '%') == 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, &re_extra, &re_options)) == NULL) { + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) { rv = -1; } else { - rv = !pcre_exec(pce, re_extra, m->desc, strlen(m->desc), 0, re_options, NULL, 0); + rv = !pcre_exec(pce->re, pce->extra, m->desc, strlen(m->desc), 0, pce->preg_options, NULL, 0); } zend_string_release(pattern); - (void)setlocale(LC_CTYPE, ""); return rv; } diff --git a/ext/fileinfo/tests/bug74170.phpt b/ext/fileinfo/tests/bug74170.phpt new file mode 100644 index 0000000000000..9e3cbd982b4f1 --- /dev/null +++ b/ext/fileinfo/tests/bug74170.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #74170 locale information change after mime_content_type +--SKIPIF-- + +--FILE-- + Date: Thu, 10 Oct 2019 00:52:36 +1000 Subject: [PATCH 2/2] Cosmetic fixes: removed extra line break + no initialization is needed for variable. --- ext/fileinfo/libmagic/readcdf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c index 36ee1c11611b7..6255c6fb42b47 100644 --- a/ext/fileinfo/libmagic/readcdf.c +++ b/ext/fileinfo/libmagic/readcdf.c @@ -125,8 +125,7 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv) vbuf_lower = zend_str_tolower_dup(vbuf, strlen(vbuf)); for (i = 0; nv[i].pattern != NULL; i++) { char *pattern_lower; - int found = 0; - + int found; pattern_lower = zend_str_tolower_dup(nv[i].pattern, strlen(nv[i].pattern)); found = (strstr(vbuf_lower, pattern_lower) != NULL);