We have to free the retrieved text content; to keep the code readable,
we extract a helper function to check for empty nodes. Unfortunately,
we cannot use xmlIsBlankNode(), because that also recognizes whitespace
only text content.
We also make sure to properly handle NULL returns from
xmlNodeGetContent().
Qianqian Bu [Fri, 3 Apr 2020 07:44:41 +0000 (15:44 +0800)]
Fix incorrect free for last_message
In commit a7305eb539596e175bd6c3ae9a20953358c5d677 the last_message
field of the connection object was changed to be always non-persistent.
But there is a place on change_user path that still treats it
depending on conn->persistent flag. This will cause PHP crash after
com_change_user success when there is last_message set
Fix #79413: session_create_id() fails for active sessions
The comment on `PS_VALIDATE_SID_FUNC(files)` is very clear that the
function is supposed to return `SUCCESS` if the session already exists.
So to detect a collision, we have to check for `SUCCESS`, not
`FAILURE`.
We also fix the wrong condition in session_regenerate_id() as well.
Lukas Berger [Thu, 26 Mar 2020 17:39:39 +0000 (10:39 -0700)]
Add missing 'skip' to bug79332.phpt skip message
The skip message must start with the word 'skip', otherwise the test will not be skipped.
*Before:*
Running selected tests.
TEST 1/1 [ext/com_dotnet/tests/bug79332.phpt]
========DIFF========
001+ Fatal error: Uncaught Error: Class 'COMPersistHelper' not found in /srv/php/ext/com_dotnet/tests/bug79332.php:2
001- A com_exception has been thrown
002+ Stack trace:
003+ #0 {main}
004+ thrown in /srv/php/ext/com_dotnet/tests/bug79332.php on line 2
========DONE========
FAIL Bug #79332 (php_istreams are never freed) [ext/com_dotnet/tests/bug79332.phpt]
*After:*
Running selected tests.
SKIP Bug #79332 (php_istreams are never freed) [ext/com_dotnet/tests/bug79332.phpt] reason: com_dotnet extension not available
To cater to potentially state-dependent encodings, we have to reset the
conversion descriptor into its initial shift state to properly finish
the conversion. Furthermore, state-dependent encodings may not show
progress when comparing `in_left` before and after the conversion; we
rather have to see whether `out_left` has decreased. Also we have to
cater to the fact that the final potentially state resetting call does
not signal failure, but we still have to break respective loops
afterwards.
* If an empty string is passed as $address to `stream_socket_sendto()`,
the `sa` is not initialized, so we must not pass it as `addr` to
`php_stream_xport_sendto()`.
* On POSIX, `recvfrom()` truncates messages which are too long to fit
into the specified buffer (unless `MSG_PEEK` is given), discards the
excessive bytes, and returns the buffer length. On Windows, the same
happens, but `recvfrom()` returns `SOCKET_ERROR` with the error code
`WSAEMSGSIZE`. We have to catch this for best POSIX compatibility.
* In `php_network_parse_network_address_with_port()`, we have to zero
`in6` (not only its alias `sa`) to properly support IPv6.
Even though `SplStack::unserialize()` is not supposed to be called on
an already constructed instance, it is probably better if the method
clears the stack before actually unserializing.
Releasing the `com_dotnet_istream_wrapper` in `istream_destructor()` is
pointless, since `istream_destructor()` is only called when the
resource is going to be released. This recursion is not a real issue,
though, since the resource is never exposed to userland, and has at
most refcount 1, so due to well defined unsigned integer underflow, it
never is released twice. However, returning early in this case causes
a memory leak which needs to be fixed.
Fix #79311: enchant_dict_suggest() fails on big endian architecture
For obvious reasons, we must not assign a `size_t` value to an `int`
variable using memcpy(). However, there is actually no need for the
intermediate `n_sugg_st` here, if we use the proper types in the first
place.
A regression test is not necessary, because dict_suggest.phpt already
exhibits the erroneous behavior on big endian architectures.
Fix #64032: mysqli reports different client_version
While `mysqli_get_client_version()` calls `mysql_get_client_version()`
to retrieve the client version, `mysql::$client_version` is initialized
to `MYSQL_VERSION_ID`. Both should match though, and since the former
is the more useful information, we fix `mysql::$client_version`.
We do not add a regression test, because it would usually succeed
anyway, and we already have several tests with respective `assert()`s.
Fix #79294: ::columnType() may fail after SQLite3Stmt::reset()
The fix for feature request #53466 did not properly handle resetting of
the corresponding statement; the problem with this is that the
statement does not know about its result sets. But even if we could
fix this, the `complete` handling still appears to be brittle, since
the `sqlite3_column_type()`docs[1] state:
| If the SQL statement does not currently point to a valid row, or if
| the column index is out of range, the result is undefined.
Fortunately, we can use `sqlite3_data_count()` instead, since[2]:
| If prepared statement P does not have results ready to return (via
| calls to the sqlite3_column() family of interfaces) then
| sqlite3_data_count(P) returns 0.
Thus, we guard `SQLite3::columnType()` with `sqlite3_data_count()`, and
completely drop updating the `php_sqlite3_result_object.complete`
field, but keep it for ABI BC purposes.
Firstly, we must not rely on `stmt->column_count` when freeing the
driver specific column values, but rather store the column count in
the driver data. Since the column count is a `short`, 16 bit are
sufficient, so we can store it in reserved bits of `pdo_odbc_stmt`.
Furthermore, we must not allocate new column value storage when the
statement is not executed, but rather when the column value storage has
not been allocated.
Finally, we have to introduce a driver specific `cursor_closer` to
avoid that `::closeCursor()` calls `odbc_stmt_next_rowset()` which then
frees the column value storage, because it may be still needed for
bound columns.
* PHP-7.2:
Mark bug76348.phpt as online test
Fix bug #79082 - Files added to tar with Phar::buildFromIterator have all-access permissions
Fix bug #79221 - Null Pointer Dereference in PHP Session Upload Progress
Fix #79254: getenv() w/o arguments not showing changes
To be able to see changes done only with `SetEnvironmentVariable()`, we
have to use `GetEnvironmentStrings()` instead of `environ`, because the
latter sees only changes done with `putenv()`.
For best backward compatibility we're using `GetEnvironmentStringsA()`;
switching to the wide string version likely makes sense for master,
though.
If the `VT_ARRAY` is empty, i.e. its upperbound is less than its lower
bound, we must not call `php_com_safearray_get_elem()`, because that
function throws in this case.