Almost every character set can be given a number N such that a multibyte
sequence starts with a byte higher than that number N. This allows us to
skip a lot of work. To ensure the correctness of this, a sanity check is
implemented that exhaustively tries every 4-byte sequence for every
character set and checks for consistency issues.
This finally gives:
Time (mean ± σ): 120.2 ms ± 1.2 ms [User: 116.9 ms, System: 2.8 ms]
Range (min … max): 118.0 ms … 122.9 ms 24 runs
We allocate twice the input length, and every input character results in
either 1 or 2 output bytes, so we cannot overflow.
By using an enum, and a switch table (which will be efficiently compiled
into a jump table), we can avoid the pessimistic code generation of the
indirect calls.
With this I get the following runtime for the test script in GH-13466 on
my i7-4790, which is around 1.25x faster.
Time (mean ± σ): 250.9 ms ± 1.6 ms [User: 248.4 ms, System: 2.0 ms]
Range (min … max): 248.9 ms … 254.4 ms 11 runs
The character set ID included in the handshake data at the time of connection
actually only includes the lower 8 bits of the ID, so if try to use this to specify
a character set, the corresponding character set may not exist.
In case of an invalid character set, the default character set is now used
without an error.
Fixes#13452Closes#13470
* PHP-8.3:
Fix GH-13177: PHP 8.3.2: final private constructor not allowed when used in trait
Fix GH-12107: When running a stored procedure (that returns a result set) twice, PHP crashes
While __php_mempcpy is only used by ext/standard/crypt_sha*, the
mempcpy "pattern" is used everywhere.
This commit removes __php_mempcpy, adds zend_mempcpy and transforms
open-coded parts into function calls.
This was once used by the ext/mysqli when building without ext/mysqlnd
and the ext/mysqlnd/php_mysqlnd_config.h file was created in the build
directory.
* PHP-8.2:
Fix GH-11997: ctype_alnum 5 times slower in PHP 8.1 or greater
Fix GH-12297: PHP Startup: Invalid library (maybe not a PHP library) 'mysqlnd.so' in Unknown on line
* PHP-8.1:
Fix GH-11997: ctype_alnum 5 times slower in PHP 8.1 or greater
Fix GH-12297: PHP Startup: Invalid library (maybe not a PHP library) 'mysqlnd.so' in Unknown on line
On some configurations, the COMPILE_DL_MYSQLND must come from config.h.
If it isn't set, the get_module function won't be exposed, resulting in
a failure when trying to load the library.
It's the same issue ext/fileinfo had a while back that was fixed in
b0ba368d5.
Closes GH-12299.
This syncs the style of the --enable-mysqlnd-compression-support option
name, otherwise in Autoconf both --enable-foo_bar and --enable-foo-bar
work.
Also the configure output message is synced to match the check
information.
* PHP-8.2:
Fix GH-10964: Improve `man` page about the built-in server
Fix GH-11438: mysqlnd fails to authenticate with sha256_password accounts using passwords longer than 19 characters
* PHP-8.1:
Fix GH-10964: Improve `man` page about the built-in server
Fix GH-11438: mysqlnd fails to authenticate with sha256_password accounts using passwords longer than 19 characters
https://dev.mysql.com/doc/dev/mysql-server/latest/page_caching_sha2_authentication_exchanges.html
tells us that the nonce used in this authentication method is 20 bytes
long. However, we might receive additional scramble data in
php_mysqlnd_greet_read not used in this method.
On my test setup, I received 21 bytes (20 bytes + '\0'). This resulted
in the xor computation to incorrectly include the NUL byte. Every
password of at least 20 characters therefore failed to authenticate
using this method.
Looking at mysql-server source code also seems to reveal that it always
uses a fixed number of scramble bytes [1].
[1] ea7087d885/sql/auth/sha2_password.cc (L1078-L1079)
Closes GH-11445.
Co-authored-by: Kamil Tekiela <tekiela246@gmail.com>
* PHP-8.2:
Fix GH-10907: Unable to serialize processed SplFixedArrays in PHP 8.2.4
Fix GH-8979: Possible Memory Leak with SSL-enabled MySQL connections
The stream context inside `mysqlnd_vio::enable_ssl()` is leaking.
In particular: when `php_stream_context_set()` get called the refcount
of `context` is increased by 1, which means that `context` will now
have a refcount of 2. Later on we remove the context from the stream
by calling `php_stream_context_set(stream, NULL)` but that leaves our
`context` with a refcount of 1, and therefore it's never destroyed.
In my test case this yielded a leak of 1456 bytes per connection
(but could be more depending on your settings ofc).
Annoyingly, Valgrind doesn't find it because the context is still
in the `EG(regular_list)` and will thus be destroyed at the end of
the request. However, I still think this bug needs to be fixed because
as the users in the issue report already mentioned:
there can be long-running PHP scripts.
Fix it by decreasing the refcount to transfer the ownership.
Closes GH-10909.
These are mandatory in C99, so it's a pointless waste of time to check
for them.
(Actually, the fixed-size integer types are not mandatory, but if they
are really not available on some theoretical system, PHP's fallbacks
won't work either, so nothing is gained from this check.)