The `encoding` attribute of the XML declaration is optional; it is good
practice to use external encoding information where available if it is
missing. Thus, we check for `charset` info of `Content-Type` headers,
and see whether the encoding is supported.
We cater to trailing parameters and quoted-strings, but not to escaped
backslashes and quotes in quoted-strings, since no known character
encoding contains these anyway.
Co-authored-by: Michael Wallner <mike@php.net>
Closes GH-6747.
When opening HTTP streams, and reading the headers, we currently
discard header lines longer than `HTTP_HEADER_BLOCK_SIZE` (1024 bytes).
While this is not generally forbidden by RFC 7230, section 3.2.5, it
is not generally allowed either, since that may change the "message
framing or response semantics".
We thus fix this by allowing arbitrarily long header lines.
Closes GH-6720.
First, the `bzip2.compress` filter has the same issue as `zlib.deflate`
so we port the respective fix[1] to ext/bz2.
Second, there is still an issue, if a stream with an attached
compression filter is flushed before it is closed, without any writes
in between. In that case, the compression is never finalized. We fix
this by enforcing a `_php_stream_flush()` with the `closing` flag set
in `_php_stream_free()`, whenever a write filter is attached. This
call is superfluous for most write filters, but does not hurt, even
when it is unnecessary.
[1] <http://git.php.net/?p=php-src.git;a=commit;h=20e75329f2adb11dd231852c061926d0e4080929>
Closes GH-6703.
zend_find_array_dim_slow() may throw, make sure to handle this.
This backports the code we already use for this on PHP-8.0,
and also backports an exception check that makes this easier to
catch.
Rather than segfaulting because sname is missing lateron, report
a FAIL here. As this indicates a server bug, the errors is reported
as an out of band warning, rather than a client error.
This fixes the PHP side of bug #80713.
The PAM service requires the terminating null to be part
of the communication.
Tested with MariaDB-10.4(pam) and Percona Server 5.7.32(auth_pam_compat).
Also changed MySQL Enterprise test to the server side plugin, authentication_pam
as opposed to the client plugin mysql_clear_password.
Add additional check for pamtest user and pam service file as
all are required for the test.
More importantly, test result should actually succeed.
Thanks Geoff Montee for bug report.
Closes GH-78680.
We need to handle the case where a CRLF after a Bcc header is not the
beginning of a folding marker, because in that case the Bcc header was
not the last "thing".
Closes GH-6666.
We must not use the locale dependent `atof()`, but instead use the
(hopefully) locale independent `zend_strtod()`, when converting string
representations of floating point numbers which are sent by the server.
Closes GH-6665.
When Phars are flushed, a new temporary file is created for each entry
which should be compressed, and the `compressed_filesize` is retrieved.
Afterwards, the Phar manifest is written, and only after that the files
are copied to the actual Phar. So for each such entry there is an open
temp file, what easily exceeds the limit.
Therefore, we use a single temporary file for all entries, and store
the start offset in the otherwise unused `header_offset` member. We
ensure that the `cfp` members are properly set to NULL even if flushing
fails, to avoid use after free scenarios.
This solution is based on a suggestion by @lserni[1].
Closes GH-6643.
[1] <https://github.com/box-project/box2/issues/80#issuecomment-77147371>
We remove the arbitrary restriction to `INT_MAX`; it is superfluous on
32bit systems where `ZEND_LONG_MAX == INT_MAX` anyway, and not useful
on 64bit systems, where larger files should be readable, if the
`memory_limit` is large enough.
Closes GH-6648.
The default encoding of filenames in a ZIP archive is IBM Code Page
437. Phar, however, only supports UTF-8 filenames. Therefore we have
to mark filenames as being stored in UTF-8 by setting the general
purpose bit 11 (the language encoding flag).
The effect of not setting this bit for non ASCII filenames can be seen
in popular tools like 7-Zip and UnZip, but not when extracting the
archives via ext/phar (which is agnostic to the filename encoding), or
via ext/zip (which guesses the encoding). Thus we add a somewhat
brittle low-level test case.
Closes GH-6630.
When extracting compressed files from an uncompressed Phar, we must not
use the direct file pointer, but rather get an uncompressed file
pointer.
We also add a test to show that deflated and stored entries are
properly extracted.
This also fixes#79912, which appears to be a duplicate of #69279.
Co-authored-by: Anna Filina <afilina@gmail.com>
Closes GH-6599.
This is mainly to work around https://github.com/curl/curl/issues/6455,
but not building the mime structure for empty hashtables is a general
performance optimization, so we do not restrict it to affected cURL
versions (7.56.0 to 7.75.0).
The minor change to bug79033.phpt is unexpected, but should not matter
in practice.
Closes GH-6606.
We must not assume that the first end of central dir signature in a ZIP
archive actually designates the end of central directory record, since
the data in the archive may contain arbitrary byte patterns. Thus, we
better search from the end of the data, what is also slightly more
efficient.
There is, however, no way to detect the end of central directory
signature by searching from the end of the ZIP archive with absolute
certainty, since the signature could be part of the trailing comment.
To mitigate, we check that the comment length fits to the found
position, but that might still not be the correct position in rare
cases.
Closes GH-6507.
In the case of a stream with no filters, php_stream_fill_read_buffer
only reads stream->chunk_size into the read buffer. If the stream has
filters attached, it could unnecessarily buffer a large amount of data.
With this change, php_stream_fill_read_buffer only proceeds until either
the requested size or stream->chunk_size is available in the read buffer.
Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de>
Closes GH-6444.
This fixes two related issues:
1. When a PS with cursor is used in store_result/get_result,
perform a COM_FETCH with maximum number of rows rather than
silently switching to an unbuffered result set (in the case of
store_result) or erroring (in the case of get_result).
In the future, we might want to make get_result unbuffered for
PS with cursors, as using cursors with buffered result sets
doesn't really make sense. Unlike store_result, get_result
isn't very explicit about what kind of result set is desired.
2. If the client did not request a cursor, but the server reports
that a cursor exists, ignore this and treat the PS as if it
has no cursor (i.e. to not use COM_FETCH). It appears to be a
server side bug that a cursor used inside an SP will be reported
to the client, even though the client cannot use the cursor.
Fixes bug #64638, bug #72862, bug #77935.
Closes GH-6518.
Don't truncate the file length to unsigned int...
I have no idea whether that fully fixes the problem because the
process gets OOM killed before finishing, but at least the
immediate parse error is gone now.
`phar_path_check()` already strips a leading slash, so we must not
attempt to strip the trailing slash from an now empty directory name.
Closes GH-6508.
When we receive an error while reading a result set, we should
assume that no more result sets are available. libmysqlclient
implements the same behavior.
When `php_zlib_deflate_filter()` is called with `PSFS_FLAG_FLUSH_INC`
but without new buckets being available (e.g. because a user calls
`rewind()` after writing to the stream), we have to make sure that any
pending data are flushed. This could basically be done like in the
attached patch[1], but that could cause unnessary flushes, which can be
harmful for compression, and adds unnecessary flush markers to the
stream. Thus, we use the `php_zlib_filter_data.finished` field, which
has not been used for `zlib.deflate` filters, and properly keep track
of the need to flush.
[1] <https://bugs.php.net/patch-display.php?bug_id=48725&patch=zlib-filter-flush-fix.patch&revision=latest>
Closes GH-6019.
Reading from a stream may return greater than zero, but nonetheless the
stream's EOF flag may have been set. We have to cater to this
condition by setting the close flag for filters.
We also have to cater to that change in the zlib.inflate filter:
If `inflate()` is called with flush mode `Z_FINISH`, but the output
buffer is not large enough to inflate all available data, it fails with
`Z_BUF_ERROR`. However, `Z_BUF_ERROR` is not fatal; in fact, the zlib
manual states: "If deflate returns with Z_OK or Z_BUF_ERROR, this
function must be called again with Z_FINISH and more output space
(updated avail_out) but no more input data, until it returns with
Z_STREAM_END or an error." Hence, we do so.
Closes GH-6001.
If there is no result set (e.g. for upsert queries), still allow
fetching to occur without error, i.e. treat it the same way as
an empty result set.
This normalizes behavior between native and emulated prepared
statements and addresses a regression in PHP 7.4.13.
Apparently, there are broken tarballs out there which are actually in
ustar format, but did not write the `ustar` marker. Since popular tar
tools like GNU tar and 7zip have no issues dealing with such tarballs,
Phar should also be more resilient.
Thus, when the first checksum check of a tarball in (presumed) in old-
style format fails, we check whether the checksum would be suitable for
ustar format; if so, we treat the tarball as being in ustar format.
Closes GH-6479.
Phar signatures practically are of limited size; for the MD5 and SHA
hashes the size is fixed (at most 64 bytes for SHA512); for OpenSSL
public keys there is no size limit in theory, but "64 KiB ought to be
good enough for anybody". So we check for that limit, to avoid fatal
errors due to out of memory conditions.
Since it is neither possible to have the signature compressed in the
ZIP archive, nor is it possible to manually add a signature via Phar,
we use ZipArchive to create a suitable archive for the test on the fly.
Closes GH-6474.
We avoid `YYCURSOR` becoming `NULL` by initializing `YYMARKER`, and add
a default rule for `<NORMAL>` where we catch unexpected input.
We also fix the only superficially related issue regarding empty input
followed by `T_SEPARATOR` and command, which caused another segfault.
Closes GH-6464.
Rename the methods in MessageFormatAdapter to make sure they don't
clash with anything defined by icu itself, which may be a problem
if icu is linked statically.
The current behavior has been introduced 20 years ago in
f9e375f493 as part of a larger change.
It's not clear to me why special treatement of -lpthread is necessary
here.
References to null-serializations are stored as null, and as such
are part of the reference count.
Reminds me that we really need to deprecate the mess that is
Serializable.
In the somewhat unlikely case that `zend_fstat()` fails, we must not
proceed executing the function, but return `false` instead.
Patch based on the patch contributed by sagpant at microsoft dot com.
Closes GH-6432.
`\r\n` does only terminate a header, if not followed by `\t` or ` `.
We have to cater to that when determining the end position of the
respective headers.
Closes GH-6420.
We must not redefine the version "constants" for phpize builds, because
these have already generated in phpize.js, from where we pass these
variables forward to configure.js.
We also add `PHP_EXTRA_VERSION` and `PHP_VERSION_STRING` to the files
for completeness.
Closes GH-6419.
Failure to rebind such closures is not necessarily related to them
being created by `ReflectionFunctionAbstract::getClosure()`, so we fix
the error message.
Closes GH-6424.
As of commit 81b2f3e[1], `parse_url()` accepts URLs with a zero port,
but does not report that port, what is wrong in hindsight.
Since the port number is stored as `unsigned short` there is no way to
distinguish between port zero and no port. For BC reasons, we thus
introduce `parse_url_ex2()` which accepts an output parameter that
allows that distinction, and use the new function to fix the behavior.
The introduction of `parse_url_ex2()` has been suggested by Nikita.
[1] <http://git.php.net/?p=php-src.git;a=commit;h=81b2f3e5d9fcdffd87a4fcd12bd8c708a97091e1>
Closes GH-6399.
We cannot simply switch to use_result here, because the fetch_row
methods in get_result mode and in use_result/store_result mode
are different: In one case it accepts a statement, in the other
a return value zval. Thus, doing a switch to use_result results
in a segfault when trying to fetch a row.
Actually supporting get_result with cursors would require adding
cursor support in mysqlnd_result, not just mysqlnd_ps. That would
be a significant amount of effort and, given the age of the issue,
does not appear to be particularly likely to happen soon.
As such, we simply generate an error when using get_result()
with cursors, which is much better than causing a segfault.
Instead, parameter binding needs to be used.
Unless `SQLGetData()` returns `SQL_SUCCESS` or `SQL_SUCCESS_WITH_INFO`,
the `StrLen_or_IndPtr` output argument is not guaranteed to be properly
set. Thus we handle retrieval failure other than `SQL_ERROR` by
yielding `false` for those column values and raising a warning.
Closes GH-6281.
Set error_info when we fail to read a packet, instead of throwing
a warning. Additionally we also need to populate the right
error_info in rowp_read -- we'll later take the error from the
packet, not the connection.
No test case, as this is hard to reliably test. I'm using the
test case from:
https://github.com/php/php-src/pull/2131#issuecomment-538374838
We have to error on unhandled exceptions in FFI callbacks, to avoid
passing back undefined values.
This has been discussed and agreed upon in a previous PR[1].
[1] <https://github.com/php/php-src/pull/5120>
Closes GH-6366.
Make sure deadlock errors are properly propagated and reports in
a number of places in mysqli and PDO MySQL.
This also fixes a memory and a segfault that can occur under these
conditions.
libxml2 has no particular issues parsing HTML strings with NUL bytes;
these just cause truncation of the current text content, but parsing
continues generally. Since `::loadHTMLFile()` already supports NUL
bytes, `::loadHTML()` should as well.
Note that this is different from XML, which does not allow any NUL
bytes.
Closes GH-6368.
A recent bug fix regarding symlinks claimed:
> After resolving reparse points, the path still may be a reparse
> point; in that case we have to resolve that reparse point as well.
While that is basically correct, some reparse points may point to
inaccessible system folders (e.g. `IO_REPARSE_TAG_DEDUP` points to
"\System Volume Information"). Since we don't know details about
arbitrary reparse points, and are mainly interested in nested symlinks,
we take a step back, and only resolve `IO_REPARSE_TAG_SYMLINK` for now.
Close GH-6354.
`ADD_EXTENSION_DEP()` relies on the `PHP_<extname>` config variables to
be set to `"yes"`, and since the standard and date extension are always
enabled, we define the respective variables uncoditionally.
Closes GH-6383.
libc-client expects `TYPEMESSAGE` with an explicit subtype of `RFC822`
to have a `nested.msg` (otherwise there will be a segfault during
free), but not to have any `contents.text.data` (this will leak
otherwise).
Closes GH-6345.
The original fix for that bug[1] broke the formerly working composition
of message/rfc822 messages, which results in a segfault when freeing
the message body now. While `imap_mail_compose()` does not really
support composition of meaningful message/rfc822 messages (although
libc-client appears to support that), some code may still use this to
compose partial messages, and using string manipulation to create the
final message.
The point is that libc-client expects `TYPEMESSAGE` with an explicit
subtype of `RFC822` to have a `nested.msg` (otherwise there will be a
segfault during free), but not to have any `contents.text.data` (this
will leak otherwise).
[1] <http://git.php.net/?p=php-src.git;a=commit;h=0d022ddf03c5fabaaa22e486d1e4a367ed9170a7>
Closes GH-6343.
OCB mode ciphers were already exposed to openssl_encrypt/decrypt,
but misbehaved, because they were not treated as AEAD ciphers.
From that perspective, OCB should be treated the same way as GCM.
In OpenSSL 1.1 the necessary controls were unified under
EVP_CTRL_AEAD_* (and OCB is only supported since OpenSSL 1.1).
Closes GH-6337.
If unsupported `$search_criteria` are passed to `imap_sort()`, the
function returns an empty array, but there is also an error on the
libc-client error stack ("Unknown search criterion: UNSUPPORTED
(errflg=2)"). If, on the other hand, unsupported `$criteria` or
unsupported `$flags` are passed, the function returns `false`. We
solve this inconsistency by returning `false` for unsupported
`$search_criteria` as well.
Closes GH-6332.
Unless `topbod` is of `TYPEMULTIPART`, `mail_free_body()` does not free
the `nested.part`; while we could do this ourselves, instead we just
ignore additional bodies in this case, i.e. we don't attach them in the
first place.
Closes GH-6321.
We separate the input arrays and all sub-arrays to avoid modification
of the passed parameters.
This should be rewritten to use `zend_string`s for the "master" branch.
Closes GH-6316.
The documentation of `tidyNode::isHtml()` states that this method
"checks if a node is part of a HTML document". That is, of course,
nonsense, since a tidyNode is "an HTML node in an HTML file, as
detected by tidy."
What this method is actually supposed to do is to check whether a node
is an element (unless it is the root element). This has been broken by
commit d8eeb8e[1], which assumed that `enum TidyNodeType` would
represent flags of a bitmask, what it does not.
[1] <http://git.php.net/?p=php-src.git;a=commit;h=d8eeb8e28673236bca3f066ded75037a5bdf6378>
Closes GH-6290.
There is no such thing as the "end of the unix epoch", and if it was,
it would certainly not be 2037-10-11T02:00:00. There is, however,
potential integer overflow which we need to avoid.
Closes GH-6288.
It is mandatory to pass either `SQL_NO_NULLS` or `SQL_NULLABLE` as
tenth parameter to `SQLSpecialColumns()`; otherwise the function call
fails. Therefore the user must be allowed to pass the desired value
as parameter to `odbc_specialcolumns()` again.
Closes GH-6200.
We have to log errors in `stream_opener` callbacks to the wrapper's
error log, because otherwise we may pick up an unrelated `errno` or a
most generic message.
Closes GH-6187.
If restoring of any not registered built-in wrapper is requested, the
function is supposed to fail with a warning, so we have to check this
condition first.
Furthermore, to be able to detect whether a built-in wrapper has been
changed, it is not sufficient to check whether *any* userland wrapper
has been registered, but rather whether the specific wrapper has been
modified.
Closes GH-6183.
Passing `NULL` as `lpFileSizeHigh` to `GetFileSize()` gives wrong
results for files larger than 0xFFFFFFFF bytes. We fix this by using
`GetFileSizeEx()`, and let the mapping fail, if the file size is too
large for the architecture.
Closes GH-5319.
Instead of attempting to map large files into memory at once, we map
chunks of at most `PHP_STREAM_MMAP_MAX` bytes, and repeat that until we
hit the point where `php_stream_seek()` fails (see bug 54902), and copy
the rest of the file by reading and writing small chunks.
We also fix the mapping behavior for zero bytes on Windows, which did
not error (as with `mmap()`), but would have mapped the remaining file.
URIs with a 0 port are generally valid, so `parse_url()` should
recognize such URIs, but still report the port as missing.
Co-authored-by: twosee <twose@qq.com>
Closes GH-6152.
* PHP-7.3:
Fix bug #80107: Handling of large compressed packets
Bug #80107 Add test for mysqli_query() fails for ~16 MB long query when compression is enabled
There's two layers of packet splitting going on. First, packets
need to be split into having a payload of exactly 2^24-1 bytes or
being the last packet. If the split packet has size between 2^24-5
and 2^24-1 bytes, the compressed packets also needs to be split,
though the choice of split doesn't matter here. I'm splitting off
the first 8192 bytes, as that's what I observe libmysqlclient to be
doing.
Add db2_execute() to the list of functions accessing the local
scope. Ideally the API wouldn't do that, but it seems most
pragmatic to address this on the opcache side at this point.
A recent commit[1] which fixed a memory leak introduced a regression
regarding the formerly liberal handling of IP addresses to bind to. We
fix this by reverting that commit, and fix the memory leak where it
actually occurs. In other words, this fix is less intrusive than the
former fix.
[1] <http://git.php.net/?p=php-src.git;a=commit;h=0b8c83f5936581942715d14883cdebddc18bad30>
Closes GH-6104.
Modules may have changed after restart which can cause dangling pointers from custom opcode handlers in the second-level cache files. This fix includes the installed module names and versions in the accel_system_id hash as entropy. Closes GH-5836
Quoting from the bug report:
> The domain names passed to getmxrr() do not contain a trailing dot.
> DNS lookups which do not find records will (depending on the local
> resolver config) try again by adding the local domain to the end of
> the searched host/domain. In many environments there's an mx record
> for any subdomain of the local domain and the MX query will return
> a hit. But the test expects no hit. So the test fails when checking
> that "qa.php.net" does not have an MX record in DNS. In our local
> environment the resolver falls back to also check qa.php.net.kippdata.de
> which does have an MX record. Using "qa.php.net." instead of "qa.php.net"
> should fix this for everyone.
If we're accessing an uninitialized typed property and __get is
defined, don't perform a read_property callback, as __get is
supposed to have no effect on uninitialized typed properties.
Usually it doesn't, but by-reference assignments cannot be
performed through read_property.
I'm deleting the test for bug #80039 again, as it doesn't really
make sense anymore with this fix.
Added new flags that allow skipping param_evt(s) that are not used by drivers,
in a backwards and forward compatible manner. Updated the pgsql, mysql, sqlite
and oci drivers to properly use the new flags. I've left out pdo_dblib, which
doesn't have a param_hook, and pdo_firebird, which seems to be using
PARAM_EVT_NORMALIZE in a wrong context (param type vs event type).
`ITypeInfo_GetIDsOfNames()` is supposed to fail with `E_NOTIMPL` for
out-of-process servers, thus we should not remove the already available
typeinfo of the object in this case.
We also properly free the `byref_vals`.
`tolower()` returns an `int`, so we must not convert to `char` which
may be `signed` and as such may be subject to overflow (actually,
implementation defined behavior).
Closes GH-6007
PDO driver constructors are throwing PdoException without setting
errorInfo, so create a new reusable function that throws exceptions
for PDO and will also set the errorInfo. Use this function in
pdo_mysql, pdo_sqlite, and pdo_pgsql.
Different manufacturer models may come with a
different endianness (motorola/intel) format. In
order to avoid a big refactor and a gigantic lookup
table, this commit simply attempts to switch the
endianness and proceed when values are acceptable.
Closes GH-5849.
op_arrays can be shared on two levels: Either the op_array is
completely shared, or it is distinct but shares all members
(apart from static_variables).
The the op_array is distinct, we need to make sure to properly
initialize the MAP_PTR structures.
Whether the type library is cached is actually irrelevant here; what
matters is that the symbols are imported, and since these are not
cached, we have to import them for every request. And we cannot cache
the symbols, because the import depends on the current codepage, but
the codepage is a `PHP_INI_ALL` setting.