Fixes GHSA-3qrf-m4j2-pcrr.
To parse a document with libxml2, you first need to create a parsing context.
The parsing context contains parsing options (e.g. XML_NOENT to substitute
entities) that the application (in this case PHP) can set.
Unfortunately, libxml2 also supports providing default set options.
For example, if you call xmlSubstituteEntitiesDefault(1) then the XML_NOENT
option will be added to the parsing options every time you create a parsing
context **even if the application never requested XML_NOENT**.
Third party extensions can override these globals, in particular the
substitute entity global. This causes entity substitution to be
unexpectedly active.
Fix it by setting the parsing options to a sane known value.
For API calls that depend on global state we introduce
PHP_LIBXML_SANITIZE_GLOBALS() and PHP_LIBXML_RESTORE_GLOBALS().
For other APIs that work directly with a context we introduce
php_libxml_sanitize_parse_ctxt_options().
It's possible to categorise the failures into 2 categories:
- Changed error message. In this case we either duplicate the test and
modify the error message. Or if the change in error message is
small, we use the EXPECTF matchers to make the test compatible with both
old and new versions of libxml2.
- Missing warnings. This is caused by a change in libxml2 where the
parser started using SAX APIs internally [1]. In this case the
error_type passed to php_libxml_internal_error_handler() changed from
PHP_LIBXML_ERROR to PHP_LIBXML_CTX_WARNING because it internally
started to use the SAX handlers instead of the generic handlers.
However, for the SAX handlers the current input stack is empty, so
nothing is actually printed. I fixed this by falling back to a
regular warning without a filename & line number reference, which
mimicks the old behaviour. Furthermore, this change now also shows
an additional warning in a test which was previously hidden.
[1] 9a82b94a94
Closes GH-11162.
This reverts commit 94ee4f9834.
The commit was a bit too late to be included in PHP 8.2 RC1. Given it's a massive ABI break, we decide to postpone the change to PHP 8.3.
Add a family of upper case conversion functions to zend_operators.c,
by analogy with the lower case functions.
Move the single-character conversion macros to the header so that they
can be used as a locale-independent replacement for tolower() and
toupper().
Factor out the ugly bits of the SSE2 case conversion so that the four
functions that use it are easy to read and processor-independent.
Use the new ASCII upper case functions in ext/xml, ext/pdo_dblib and as
an optimization for strtoupper() when the locale is "C".
We must never strip embedded whitespace; we only need to skip values
when that option is set, and make sure that we keep BC regarding the
different behavior for "cdata" and "complete" elements (for the former,
the whole element is skipped; for the latter only the "value" key).
We also fix erroneous `int` types which should actually be `size_t`.
Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de>
Closes GH-7493.
This API had rather peculiar behavior in case the provided function
is not callable. For some types of failures, it would silently
return FAILURE (e.g. a function does not exist), while for others
(e.g. a class does not exist) it would generate a warning. Depending
on what the calling code does, this can either result in silent
failure or duplicate errors.
This commit switches the contract such that zend_call_function()
always (*) succeeds, though that success might be in the form of
throwing an exception. Calling a non-callable will now consistently
throw an exception.
There are some rare callers that do want to ignore missing methods,
for legacy APIs that are specific with optional methods. For these
use cases a new zend_call_method_if_exists() API is provided.
Calling code generally does not need to explicitly check for and
report zend_call_function() failures -- it can rely on
zend_call_function() having already done so. However, existing
code that does check for failure should continue to work fine.
(*) The only exception to this is if EG(active) being false during
late engine shutdown. This is not relevant to most code, but code
running in destructors and similar may need to be aware of the
possibility.
As of PHP 8.0.0, these functions are supposed to return int, so we
cannot return `false`. Since calling the parser recursively is a
programmer error, we throw an `Error` in this case.
Cf. <https://github.com/php/php-src/pull/7363>.
The fix for bug #73151[1] cured the symptoms, but not the root cause,
namely xmlParse() must not be called recursively. Since that bugfix
also messed up the error handling, we basically revert it (but also
simplify the return), and then prevent calling the parser recursively.
[1] <f2a8a8c068>
Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
Closes GH-7363.
1. Update: http://www.php.net/license/3_01.txt to https, as there is anyway server header "Location:" to https.
2. Update few license 3.0 to 3.01 as 3.0 states "php 5.1.1, 4.1.1, and earlier".
3. In some license comments is "at through the world-wide-web" while most is without "at", so deleted.
4. fixed indentation in some files before |