Fix GH-10052: Browscap crashes PHP 8.1.12 on request shutdown (apache2)

get_browser() implements a lazy parse system for the browscap
INI configuration. There are two possible moments when a browscap
configuration can be loaded: during module startup or during request.
In case of module startup, the strings are persistent strings, while for
the request they are not.

The INI parser must therefore know whether to create persistent or
non-persistent strings. It does this by looking at
CG(ini_parser_unbuffered_errors). If that value is 1 it's persistent,
otherwise non-persistent. Note that this also controls how the errors
are reported: if it's 1 then the errors are sent to stderr, otherwise we
get E_WARNINGs.

Currently, a hardcoded value of 1 is always used for that CG value in
browscap_read_file(). This means we'll always create persistent strings
*and* we'll not report parse errors correctly as E_WARNINGs.
We fix both the crash and the lack of warnings by passing the value of
persistent instead of a hardcoded 1.

This is also in line with how other INI parsing code is called in
ext/standard: they also make sure that during request a value of 0 is
passed.

Closes GH-10883.
This commit is contained in:
Niels Dossche 2023-03-19 22:11:09 +01:00
parent 122f1287a0
commit c407243712
2 changed files with 3 additions and 1 deletions

2
NEWS
View file

@ -51,6 +51,8 @@ PHP NEWS
- Standard:
. Fixed bug GH-10885 (stream_socket_server context leaks). (ilutov)
. Fixed bug GH-10052 (Browscap crashes PHP 8.1.12 on request shutdown
(apache2)). (nielsdos)
16 Mar 2023, PHP 8.1.17

View file

@ -432,7 +432,7 @@ static int browscap_read_file(char *filename, browser_data *browdata, int persis
ctx.current_section_name = NULL;
zend_hash_init(&ctx.str_interned, 8, NULL, str_interned_dtor, persistent);
zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_RAW,
zend_parse_ini_file(&fh, persistent, ZEND_INI_SCANNER_RAW,
(zend_ini_parser_cb_t) php_browscap_parser_cb, &ctx);
/* Destroy parser context */