Skip to content

Commit c62cd9a

Browse files
turchanovnikic
authored andcommitted
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.
1 parent cbb0efa commit c62cd9a

File tree

5 files changed

+47
-16
lines changed

5 files changed

+47
-16
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ PHP NEWS
99
- CURL:
1010
. Implemented FR #77711 (CURLFile should support UNICODE filenames). (cmb)
1111

12+
- Fileinfo:
13+
. Fixed bug #74170 (locale information change after mime_content_type).
14+
(Sergei Turchanov)
15+
1216
- GD:
1317
. Fixed bug #78923 (Artifacts when convoluting image with transparency).
1418
(wilson chen)

ext/fileinfo/libmagic/funcs.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,11 +477,9 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
477477
zend_string *repl;
478478
size_t rep_cnt = 0;
479479

480-
(void)setlocale(LC_CTYPE, "C");
481-
482480
opts |= PCRE2_MULTILINE;
483481
convert_libmagic_pattern(&patt, (char*)pat, strlen(pat), opts);
484-
if ((pce = pcre_get_compiled_regex_cache(Z_STR(patt))) == NULL) {
482+
if ((pce = pcre_get_compiled_regex_cache_ex(Z_STR(patt), 0)) == NULL) {
485483
zval_ptr_dtor(&patt);
486484
rep_cnt = -1;
487485
goto out;
@@ -503,7 +501,6 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
503501
zend_string_release_ex(res, 0);
504502

505503
out:
506-
(void)setlocale(LC_CTYPE, "");
507504
return rep_cnt;
508505
}
509506

ext/fileinfo/libmagic/readcdf.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,24 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv)
116116
{
117117
size_t i;
118118
const char *rv = NULL;
119+
char *vbuf_lower;
119120

120-
(void)setlocale(LC_CTYPE, "C");
121-
for (i = 0; nv[i].pattern != NULL; i++)
122-
if (strcasestr(vbuf, nv[i].pattern) != NULL) {
121+
vbuf_lower = zend_str_tolower_dup(vbuf, strlen(vbuf));
122+
for (i = 0; nv[i].pattern != NULL; i++) {
123+
char *pattern_lower;
124+
int found;
125+
126+
pattern_lower = zend_str_tolower_dup(nv[i].pattern, strlen(nv[i].pattern));
127+
found = (strstr(vbuf_lower, pattern_lower) != NULL);
128+
efree(pattern_lower);
129+
130+
if (found) {
123131
rv = nv[i].mime;
124132
break;
125133
}
126-
(void)setlocale(LC_CTYPE, "");
134+
}
135+
136+
efree(vbuf_lower);
127137
return rv;
128138
}
129139

ext/fileinfo/libmagic/softmagic.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -422,27 +422,25 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
422422
private int
423423
check_fmt(struct magic_set *ms, const char *fmt)
424424
{
425-
pcre2_code *pce;
426-
uint32_t re_options, capture_count;
425+
pcre_cache_entry *pce;
427426
int rv = -1;
428427
zend_string *pattern;
429428

430429
if (strchr(fmt, '%') == NULL)
431430
return 0;
432431

433-
(void)setlocale(LC_CTYPE, "C");
434432
pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0);
435-
if ((pce = pcre_get_compiled_regex(pattern, &capture_count, &re_options)) == NULL) {
433+
if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) {
436434
rv = -1;
437435
} else {
438-
pcre2_match_data *match_data = php_pcre_create_match_data(capture_count, pce);
436+
pcre2_code *re = php_pcre_pce_re(pce);
437+
pcre2_match_data *match_data = php_pcre_create_match_data(0, re);
439438
if (match_data) {
440-
rv = pcre2_match(pce, (PCRE2_SPTR)fmt, strlen(fmt), 0, re_options, match_data, php_pcre_mctx()) > 0;
439+
rv = pcre2_match(re, (PCRE2_SPTR)fmt, strlen(fmt), 0, 0, match_data, php_pcre_mctx()) > 0;
441440
php_pcre_free_match_data(match_data);
442441
}
443442
}
444-
zend_string_release_ex(pattern, 0);
445-
(void)setlocale(LC_CTYPE, "");
443+
zend_string_release(pattern);
446444
return rv;
447445
}
448446

ext/fileinfo/tests/bug74170.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #74170 locale information change after mime_content_type
3+
--SKIPIF--
4+
<?php
5+
if (!class_exists('finfo'))
6+
die('skip no fileinfo extension');
7+
if (!extension_loaded('intl'))
8+
die('skip intl extension not enabled');
9+
if (setlocale(LC_CTYPE, 'ru_RU.koi8r') === false)
10+
die('skip ru_RU.koi8r locale is not available');
11+
?>
12+
--FILE--
13+
<?php
14+
var_dump(setlocale(LC_CTYPE, 'ru_RU.koi8r'));
15+
var_dump(nl_langinfo(CODESET));
16+
var_dump(mime_content_type(__DIR__ . '/resources/test.ppt'));
17+
var_dump(nl_langinfo(CODESET));
18+
--EXPECT--
19+
string(11) "ru_RU.koi8r"
20+
string(6) "KOI8-R"
21+
string(29) "application/vnd.ms-powerpoint"
22+
string(6) "KOI8-R"

0 commit comments

Comments
 (0)