From c407243712c0086ee6db70f83d200a14e61f08dc Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 19 Mar 2023 22:11:09 +0100 Subject: [PATCH] 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. --- NEWS | 2 ++ ext/standard/browscap.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 01cf4ac6317..c3a3dfbbe2a 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 490acac2f99..53504098fb8 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -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 */