diff --git a/NEWS b/NEWS index f3c9b6ee73b0..98c8d3b3106b 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,15 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.6.0beta3 +- BCMath: + . Fixed out-of-bounds read in bc_is_zero_for_scale() when scale exceeds + n_scale. (Ilia Alshanetsky) + - Core: . Calling is_a() or is_subclass_of() with a string as the first argument when $allow_string is false is now deprecated. (Daniel Scherzer) + . Fixed bug GH-23232 (lone namespace separator asks the autoloader for an + empty class name). (spawnia) - CLI: . Fixed bug GH-23242 (PHP development server does not support Expect @@ -71,6 +77,10 @@ PHP NEWS . Fixed WSDL cache corruption when a soap:header defines headerfaults. (Ilia Alshanetsky) +- Sodium: + . Added support for the libsodium 1.0.22 KEM APIs (X-Wing and ML-KEM768). + (Zachary DuBois) + - Standard: . Fixed a segfault when a stream filter callback unsets StreamBucket::$data before re-attaching the bucket. (iliaal) @@ -79,6 +89,8 @@ PHP NEWS . Fixed read buffer compaction in php_stream_filter_flush(). (crystarm) . Io\Poll\Context::wait() now rejects a $maxEvents value greater than INT_MAX instead of truncating it. (marc-mabe) + . Fixed GH-23338 (fsockopen()/pfsockopen() ValueError reported wrong + argument number for $timeout). (lacatoire) - SimpleXML: . Fixed writing to a dimension of the object returned by attributes() not @@ -346,6 +358,10 @@ PHP NEWS (Girgias) - Standard: + . Passing an object as the $data argument to http_build_query() is now + deprecated. The interpretation of object values within $data as arrays + is also deprecated. Convert objects to arrays with get_object_vars() + before calling the function. (Girgias) . Added the "filter.max_filter_count" stream context option for php://filter URLs. Using more than 16 filters without configuring this option is now deprecated. (Sjoerd Langkemper) diff --git a/UPGRADING b/UPGRADING index fe6395dad746..c795bc347dfd 100644 --- a/UPGRADING +++ b/UPGRADING @@ -624,6 +624,11 @@ PHP 8.6 UPGRADE NOTES . Passing an object to array_walk{_recursive} is now deprecated. Use get_object_vars() on the object instead. RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_array_parameter_of_array_walk_and_array_walk_recursive + . Passing an object as the $data argument to http_build_query() is now + deprecated. The interpretation of object values within $data as arrays + is also deprecated. Convert objects to arrays with get_object_vars() + before calling the function. + RFC: https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_data_parameter_of_http_build_query . The is_double() function is now deprecated. Use is_float() instead. RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_is_double . The is_long() and is_integer() functions are now deprecated. Use is_int() @@ -763,6 +768,20 @@ PHP 8.6 UPGRADE NOTES . snmp_set_output_option() . snmp_set_string_output_format() +- Sodium: + . sodium_crypto_kem_keypair(), sodium_crypto_kem_seed_keypair(), + sodium_crypto_kem_secretkey(), sodium_crypto_kem_publickey(), + sodium_crypto_kem_enc() and sodium_crypto_kem_dec() expose the X-Wing + KEM (hybrid ML-KEM768+X25519, libsodium's recommended KEM). + Available when PHP is built against libsodium >= 1.0.22. + . sodium_crypto_kem_mlkem768_keypair(), + sodium_crypto_kem_mlkem768_seed_keypair(), + sodium_crypto_kem_mlkem768_secretkey(), + sodium_crypto_kem_mlkem768_publickey(), + sodium_crypto_kem_mlkem768_enc() and sodium_crypto_kem_mlkem768_dec() + expose the ML-KEM768 (FIPS 203) KEM. + Available when PHP is built against libsodium >= 1.0.22. + - Standard: . clamp() returns the given value if in range, else returns the nearest bound. @@ -917,6 +936,18 @@ PHP 8.6 UPGRADE NOTES . SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES. . SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES. . SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES. + . SODIUM_CRYPTO_KEM_PUBLICKEYBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_SECRETKEYBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_SHAREDSECRETBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_SEEDBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_KEYPAIRBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_MLKEM768_SECRETKEYBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_MLKEM768_CIPHERTEXTBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_MLKEM768_SHAREDSECRETBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES (libsodium >= 1.0.22). + . SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES (libsodium >= 1.0.22). - Standard: . ARRAY_FILTER_USE_VALUE. diff --git a/Zend/tests/gh23232.phpt b/Zend/tests/gh23232.phpt new file mode 100644 index 000000000000..57a2e0135e8e --- /dev/null +++ b/Zend/tests/gh23232.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-23232 (lone namespace separator asks the autoloader for an empty class name) +--FILE-- + +--EXPECT-- +is_callable("::a") +bool(false) +is_callable("\::a") +bool(false) +is_callable("\Foo::a") +autoload: 'Foo' +bool(false) +is_callable("Foo::a") +autoload: 'Foo' +bool(false) +bool(false) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index b48352a5aaf3..c67a31fd8de2 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1221,6 +1221,10 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * } if (ZSTR_VAL(name)[0] == '\\') { + if (ZSTR_LEN(name) == 1) { + /* A lone namespace separator names no class, e.g. is_callable('\::method'). */ + return NULL; + } lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0); zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1); } else { diff --git a/ext/bcmath/libbcmath/src/zero.c b/ext/bcmath/libbcmath/src/zero.c index 550ea97df674..e488069bae17 100644 --- a/ext/bcmath/libbcmath/src/zero.c +++ b/ext/bcmath/libbcmath/src/zero.c @@ -45,6 +45,10 @@ bool bc_is_zero_for_scale(bc_num num, size_t scale) return true; } + if (scale > num->n_scale) { + scale = num->n_scale; + } + /* Initialize */ count = num->n_len + scale; nptr = num->n_value; diff --git a/ext/bcmath/tests/bc_is_zero_for_scale_clamp.phpt b/ext/bcmath/tests/bc_is_zero_for_scale_clamp.phpt new file mode 100644 index 000000000000..887fabb92916 --- /dev/null +++ b/ext/bcmath/tests/bc_is_zero_for_scale_clamp.phpt @@ -0,0 +1,12 @@ +--TEST-- +bc_is_zero_for_scale clamps scale to n_scale (Number::compare opposite signs) +--EXTENSIONS-- +bcmath +--FILE-- +sub('1.0'); +$longNegative = new BcMath\Number('-0.' . str_repeat('0', 64) . '1'); +var_dump($shortZero->compare($longNegative, 64)); +?> +--EXPECT-- +int(0) diff --git a/ext/openssl/tests/bug38261.phpt b/ext/openssl/tests/bug38261.phpt index 6064380c8bca..582ebac054a8 100644 --- a/ext/openssl/tests/bug38261.phpt +++ b/ext/openssl/tests/bug38261.phpt @@ -16,28 +16,28 @@ var_dump(openssl_x509_parse("foo")); try { var_dump(openssl_x509_parse($t)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { openssl_x509_parse([]); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(openssl_x509_parse($cert)); try { openssl_x509_parse(new stdClass); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- bool(false) bool(false) -openssl_x509_parse(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given +TypeError: openssl_x509_parse(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given bool(false) -openssl_x509_parse(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, stdClass given +TypeError: openssl_x509_parse(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, stdClass given diff --git a/ext/openssl/tests/bug60632.phpt b/ext/openssl/tests/bug60632.phpt index 7be90bd4ab43..0c0135621c35 100644 --- a/ext/openssl/tests/bug60632.phpt +++ b/ext/openssl/tests/bug60632.phpt @@ -20,9 +20,9 @@ $ekeys = array(); try { $result = openssl_seal('test phrase', $encrypted, $ekeys, array($pubkey), 'AES-256-CBC'); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -openssl_seal(): Argument #6 ($iv) cannot be null for the chosen cipher algorithm +ValueError: openssl_seal(): Argument #6 ($iv) cannot be null for the chosen cipher algorithm diff --git a/ext/openssl/tests/bug68912.phpt b/ext/openssl/tests/bug68912.phpt index 7bb8c9e5032b..b9b2c29c8785 100644 --- a/ext/openssl/tests/bug68912.phpt +++ b/ext/openssl/tests/bug68912.phpt @@ -15,9 +15,9 @@ $var3=3; try { openssl_spki_new($var1, $var2, $var3); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -openssl_spki_new(): Argument #1 ($private_key) must be of type OpenSSLAsymmetricKey, resource given +TypeError: openssl_spki_new(): Argument #1 ($private_key) must be of type OpenSSLAsymmetricKey, resource given diff --git a/ext/openssl/tests/bug71475.phpt b/ext/openssl/tests/bug71475.phpt index 354d0b4de27d..31b02cfd1efc 100644 --- a/ext/openssl/tests/bug71475.phpt +++ b/ext/openssl/tests/bug71475.phpt @@ -7,11 +7,11 @@ openssl $_ = str_repeat("A", 512); try { openssl_seal($_, $_, $_, array_fill(0,64,0)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> DONE --EXPECT-- -openssl_seal() expects at least 5 arguments, 4 given +ArgumentCountError: openssl_seal() expects at least 5 arguments, 4 given DONE diff --git a/ext/openssl/tests/bug81713.phpt b/ext/openssl/tests/bug81713.phpt index 9e3ab5d5e2f3..35b8f0444feb 100644 --- a/ext/openssl/tests/bug81713.phpt +++ b/ext/openssl/tests/bug81713.phpt @@ -129,8 +129,8 @@ foreach ($tests as $test) { $key = call_user_func_array($test[0], array_slice($test, 1)); var_dump($key); } - catch (ValueError $e) { - echo $e->getMessage() . PHP_EOL; + catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } } ?> @@ -142,98 +142,98 @@ $outfile = __DIR__ . '/bug81713.out'; --EXPECTF-- object(OpenSSLAsymmetricKey)#1 (0) { } -openssl_pkey_get_public(): Argument #1 ($public_key) must not contain any null bytes -openssl_pkey_get_private(): Argument #1 ($private_key) must not contain any null bytes -openssl_pkey_export_to_file(): Argument #1 ($key) must not contain any null bytes -openssl_pkey_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes -openssl_pkey_export(): Argument #1 ($key) must not contain any null bytes -openssl_pkey_derive(): Argument #1 ($public_key) must not contain any null bytes -openssl_pkey_derive(): Argument #2 ($private_key) must not contain any null bytes -openssl_private_encrypt(): Argument #3 ($private_key) must not contain any null bytes -openssl_private_decrypt(): Argument #3 ($private_key) must not contain any null bytes -openssl_public_encrypt(): Argument #3 ($public_key) must not contain any null bytes -openssl_public_decrypt(): Argument #3 ($public_key) must not contain any null bytes -openssl_sign(): Argument #3 ($private_key) must not contain any null bytes -openssl_verify(): Argument #3 ($public_key) must not contain any null bytes -openssl_seal(): Argument #4 ($public_key) must not contain any null bytes -openssl_open(): Argument #4 ($private_key) must not contain any null bytes -openssl_csr_new(): Argument #2 ($private_key) must not contain any null bytes -openssl_csr_get_subject(): Argument #1 ($csr) must not contain any null bytes -openssl_csr_get_public_key(): Argument #1 ($csr) must not contain any null bytes +ValueError: openssl_pkey_get_public(): Argument #1 ($public_key) must not contain any null bytes +ValueError: openssl_pkey_get_private(): Argument #1 ($private_key) must not contain any null bytes +ValueError: openssl_pkey_export_to_file(): Argument #1 ($key) must not contain any null bytes +ValueError: openssl_pkey_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_pkey_export(): Argument #1 ($key) must not contain any null bytes +ValueError: openssl_pkey_derive(): Argument #1 ($public_key) must not contain any null bytes +ValueError: openssl_pkey_derive(): Argument #2 ($private_key) must not contain any null bytes +ValueError: openssl_private_encrypt(): Argument #3 ($private_key) must not contain any null bytes +ValueError: openssl_private_decrypt(): Argument #3 ($private_key) must not contain any null bytes +ValueError: openssl_public_encrypt(): Argument #3 ($public_key) must not contain any null bytes +ValueError: openssl_public_decrypt(): Argument #3 ($public_key) must not contain any null bytes +ValueError: openssl_sign(): Argument #3 ($private_key) must not contain any null bytes +ValueError: openssl_verify(): Argument #3 ($public_key) must not contain any null bytes +ValueError: openssl_seal(): Argument #4 ($public_key) must not contain any null bytes +ValueError: openssl_open(): Argument #4 ($private_key) must not contain any null bytes +ValueError: openssl_csr_new(): Argument #2 ($private_key) must not contain any null bytes +ValueError: openssl_csr_get_subject(): Argument #1 ($csr) must not contain any null bytes +ValueError: openssl_csr_get_public_key(): Argument #1 ($csr) must not contain any null bytes Warning: openssl_x509_fingerprint(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_x509_fingerprint(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_x509_fingerprint(): Argument #1 ($certificate) must not contain any null bytes Warning: openssl_x509_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_x509_export_to_file(): Argument #1 ($certificate) must not contain any null bytes -openssl_x509_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_x509_export_to_file(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_x509_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes Warning: openssl_x509_export(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_x509_export(): Argument #1 ($certificate) must not contain any null bytes -openssl_x509_checkpurpose(): Argument #1 ($certificate) must not contain any null bytes -openssl_x509_checkpurpose(): Argument #3 ($ca_info) array item must not contain any null bytes -openssl_x509_check_private_key(): Argument #1 ($certificate) must not contain any null bytes -openssl_x509_check_private_key(): Argument #2 ($private_key) must not contain any null bytes -openssl_x509_verify(): Argument #1 ($certificate) must not contain any null bytes -openssl_x509_verify(): Argument #2 ($public_key) must not contain any null bytes -openssl_x509_parse(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_x509_export(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_x509_checkpurpose(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_x509_checkpurpose(): Argument #3 ($ca_info) array item must not contain any null bytes +ValueError: openssl_x509_check_private_key(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_x509_check_private_key(): Argument #2 ($private_key) must not contain any null bytes +ValueError: openssl_x509_verify(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_x509_verify(): Argument #2 ($public_key) must not contain any null bytes +ValueError: openssl_x509_parse(): Argument #1 ($certificate) must not contain any null bytes Warning: openssl_x509_read(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_x509_read(): Argument #1 ($certificate) must not contain any null bytes -openssl_cms_encrypt(): Argument #1 ($input_filename) must not contain any null bytes -openssl_cms_encrypt(): Argument #2 ($output_filename) must not contain any null bytes -openssl_cms_encrypt(): Argument #3 ($certificate) must not contain any null bytes -openssl_cms_encrypt(): Argument #3 ($certificate) array item must not contain any null bytes -openssl_cms_decrypt(): Argument #1 ($input_filename) must not contain any null bytes -openssl_cms_decrypt(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_x509_read(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_cms_encrypt(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_cms_encrypt(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_cms_encrypt(): Argument #3 ($certificate) must not contain any null bytes +ValueError: openssl_cms_encrypt(): Argument #3 ($certificate) array item must not contain any null bytes +ValueError: openssl_cms_decrypt(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_cms_decrypt(): Argument #2 ($output_filename) must not contain any null bytes Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_cms_decrypt(): Argument #3 ($certificate) must not contain any null bytes -openssl_cms_decrypt(): Argument #4 ($private_key) must not contain any null bytes -openssl_cms_sign(): Argument #1 ($input_filename) must not contain any null bytes -openssl_cms_sign(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_cms_decrypt(): Argument #3 ($certificate) must not contain any null bytes +ValueError: openssl_cms_decrypt(): Argument #4 ($private_key) must not contain any null bytes +ValueError: openssl_cms_sign(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_cms_sign(): Argument #2 ($output_filename) must not contain any null bytes Warning: openssl_cms_sign(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_cms_sign(): Argument #3 ($certificate) must not contain any null bytes -openssl_cms_sign(): Argument #4 ($private_key) must not contain any null bytes -openssl_cms_sign(): Argument #8 ($untrusted_certificates_filename) must not contain any null bytes -openssl_cms_verify(): Argument #1 ($input_filename) must not contain any null bytes -openssl_cms_verify(): Argument #3 ($certificates) must not contain any null bytes -openssl_cms_verify(): Argument #4 ($ca_info) array item must not contain any null bytes -openssl_cms_verify(): Argument #5 ($untrusted_certificates_filename) must not contain any null bytes -openssl_cms_verify(): Argument #6 ($content) must not contain any null bytes -openssl_cms_verify(): Argument #7 ($pk7) must not contain any null bytes -openssl_pkcs7_encrypt(): Argument #1 ($input_filename) must not contain any null bytes -openssl_pkcs7_encrypt(): Argument #2 ($output_filename) must not contain any null bytes -openssl_pkcs7_encrypt(): Argument #3 ($certificate) must not contain any null bytes -openssl_pkcs7_encrypt(): Argument #3 ($certificate) array item must not contain any null bytes -openssl_pkcs7_decrypt(): Argument #1 ($input_filename) must not contain any null bytes -openssl_pkcs7_decrypt(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_cms_sign(): Argument #3 ($certificate) must not contain any null bytes +ValueError: openssl_cms_sign(): Argument #4 ($private_key) must not contain any null bytes +ValueError: openssl_cms_sign(): Argument #8 ($untrusted_certificates_filename) must not contain any null bytes +ValueError: openssl_cms_verify(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_cms_verify(): Argument #3 ($certificates) must not contain any null bytes +ValueError: openssl_cms_verify(): Argument #4 ($ca_info) array item must not contain any null bytes +ValueError: openssl_cms_verify(): Argument #5 ($untrusted_certificates_filename) must not contain any null bytes +ValueError: openssl_cms_verify(): Argument #6 ($content) must not contain any null bytes +ValueError: openssl_cms_verify(): Argument #7 ($pk7) must not contain any null bytes +ValueError: openssl_pkcs7_encrypt(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_pkcs7_encrypt(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_pkcs7_encrypt(): Argument #3 ($certificate) must not contain any null bytes +ValueError: openssl_pkcs7_encrypt(): Argument #3 ($certificate) array item must not contain any null bytes +ValueError: openssl_pkcs7_decrypt(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_pkcs7_decrypt(): Argument #2 ($output_filename) must not contain any null bytes Warning: openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_pkcs7_decrypt(): Argument #3 ($certificate) must not contain any null bytes -openssl_pkcs7_decrypt(): Argument #4 ($private_key) must not contain any null bytes -openssl_pkcs7_sign(): Argument #1 ($input_filename) must not contain any null bytes -openssl_pkcs7_sign(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_pkcs7_decrypt(): Argument #3 ($certificate) must not contain any null bytes +ValueError: openssl_pkcs7_decrypt(): Argument #4 ($private_key) must not contain any null bytes +ValueError: openssl_pkcs7_sign(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_pkcs7_sign(): Argument #2 ($output_filename) must not contain any null bytes Warning: openssl_pkcs7_sign(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_pkcs7_sign(): Argument #3 ($certificate) must not contain any null bytes -openssl_pkcs7_sign(): Argument #4 ($private_key) must not contain any null bytes -openssl_pkcs7_sign(): Argument #7 ($untrusted_certificates_filename) must not contain any null bytes -openssl_pkcs7_verify(): Argument #1 ($input_filename) must not contain any null bytes -openssl_pkcs7_verify(): Argument #3 ($signers_certificates_filename) must not contain any null bytes -openssl_pkcs7_verify(): Argument #4 ($ca_info) array item must not contain any null bytes -openssl_pkcs7_verify(): Argument #5 ($untrusted_certificates_filename) must not contain any null bytes -openssl_pkcs7_verify(): Argument #6 ($content) must not contain any null bytes -openssl_pkcs7_verify(): Argument #7 ($output_filename) must not contain any null bytes +ValueError: openssl_pkcs7_sign(): Argument #3 ($certificate) must not contain any null bytes +ValueError: openssl_pkcs7_sign(): Argument #4 ($private_key) must not contain any null bytes +ValueError: openssl_pkcs7_sign(): Argument #7 ($untrusted_certificates_filename) must not contain any null bytes +ValueError: openssl_pkcs7_verify(): Argument #1 ($input_filename) must not contain any null bytes +ValueError: openssl_pkcs7_verify(): Argument #3 ($signers_certificates_filename) must not contain any null bytes +ValueError: openssl_pkcs7_verify(): Argument #4 ($ca_info) array item must not contain any null bytes +ValueError: openssl_pkcs7_verify(): Argument #5 ($untrusted_certificates_filename) must not contain any null bytes +ValueError: openssl_pkcs7_verify(): Argument #6 ($content) must not contain any null bytes +ValueError: openssl_pkcs7_verify(): Argument #7 ($output_filename) must not contain any null bytes Warning: openssl_pkcs12_export(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_pkcs12_export(): Argument #1 ($certificate) must not contain any null bytes -openssl_pkcs12_export(): Argument #3 ($private_key) must not contain any null bytes -openssl_pkcs12_export(): Argument #5 ($options) option extracerts array item must not contain any null bytes +ValueError: openssl_pkcs12_export(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_pkcs12_export(): Argument #3 ($private_key) must not contain any null bytes +ValueError: openssl_pkcs12_export(): Argument #5 ($options) option extracerts array item must not contain any null bytes Warning: openssl_pkcs12_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d -openssl_pkcs12_export_to_file(): Argument #1 ($certificate) must not contain any null bytes -openssl_pkcs12_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes -openssl_pkcs12_export_to_file(): Argument #3 ($private_key) must not contain any null bytes -openssl_pkcs12_export_to_file(): Argument #5 ($options) option extracerts array item must not contain any null bytes +ValueError: openssl_pkcs12_export_to_file(): Argument #1 ($certificate) must not contain any null bytes +ValueError: openssl_pkcs12_export_to_file(): Argument #2 ($output_filename) must not contain any null bytes +ValueError: openssl_pkcs12_export_to_file(): Argument #3 ($private_key) must not contain any null bytes +ValueError: openssl_pkcs12_export_to_file(): Argument #5 ($options) option extracerts array item must not contain any null bytes diff --git a/ext/openssl/tests/gh22081.phpt b/ext/openssl/tests/gh22081.phpt index 17f74be7584c..f8069bc180f7 100644 --- a/ext/openssl/tests/gh22081.phpt +++ b/ext/openssl/tests/gh22081.phpt @@ -73,4 +73,3 @@ ok 1 ok 2 ok 3 ok 4 - diff --git a/ext/openssl/tests/memory_leak_x509_store.phpt b/ext/openssl/tests/memory_leak_x509_store.phpt index bc9b113602a3..253283107033 100644 --- a/ext/openssl/tests/memory_leak_x509_store.phpt +++ b/ext/openssl/tests/memory_leak_x509_store.phpt @@ -13,10 +13,10 @@ class MyStringable{ try { openssl_pkcs7_verify("does not matter", 0, "does not matter", [new MyStringable]); -} catch (Error $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -stop +Error: stop diff --git a/ext/openssl/tests/openssl_cipher_iv_length_error.phpt b/ext/openssl/tests/openssl_cipher_iv_length_error.phpt index cdd5f3616fb2..1464b7b75770 100644 --- a/ext/openssl/tests/openssl_cipher_iv_length_error.phpt +++ b/ext/openssl/tests/openssl_cipher_iv_length_error.phpt @@ -9,13 +9,12 @@ var_dump(openssl_cipher_iv_length('unknown')); try { var_dump(openssl_cipher_iv_length('')); -} catch (ValueError $e) { - echo $e->getMessage() . "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- - Warning: openssl_cipher_iv_length(): Unknown cipher algorithm in %s on line %d bool(false) -openssl_cipher_iv_length(): Argument #1 ($cipher_algo) must not be empty +ValueError: openssl_cipher_iv_length(): Argument #1 ($cipher_algo) must not be empty diff --git a/ext/openssl/tests/openssl_cipher_key_length_error.phpt b/ext/openssl/tests/openssl_cipher_key_length_error.phpt index a4e4e8e6bfcf..5cf147acd628 100644 --- a/ext/openssl/tests/openssl_cipher_key_length_error.phpt +++ b/ext/openssl/tests/openssl_cipher_key_length_error.phpt @@ -9,13 +9,12 @@ var_dump(openssl_cipher_key_length('unknown')); try { var_dump(openssl_cipher_key_length('')); -} catch (ValueError $e) { - echo $e->getMessage() . "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- - Warning: openssl_cipher_key_length(): Unknown cipher algorithm in %s on line %d bool(false) -openssl_cipher_key_length(): Argument #1 ($cipher_algo) must not be empty +ValueError: openssl_cipher_key_length(): Argument #1 ($cipher_algo) must not be empty diff --git a/ext/openssl/tests/openssl_cms_decrypt_error.phpt b/ext/openssl/tests/openssl_cms_decrypt_error.phpt index 3c128be64d09..78cf4e4c9d4b 100644 --- a/ext/openssl/tests/openssl_cms_decrypt_error.phpt +++ b/ext/openssl/tests/openssl_cms_decrypt_error.phpt @@ -17,8 +17,8 @@ $d = new stdclass; try { var_dump(openssl_cms_decrypt($a, $b, $c, $d)); -} catch (Error $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump($c); @@ -30,7 +30,7 @@ var_dump(openssl_cms_decrypt($a, $b, 0, 0)); echo "Done\n"; ?> --EXPECT-- -Object of class stdClass could not be converted to string +Error: Object of class stdClass could not be converted to string object(stdClass)#1 (0) { } string(60) "openssl_cms_decrypt(): X.509 Certificate cannot be retrieved" diff --git a/ext/openssl/tests/openssl_cms_encrypt_der.phpt b/ext/openssl/tests/openssl_cms_encrypt_der.phpt index 2f26428c2a64..11985a367ae4 100644 --- a/ext/openssl/tests/openssl_cms_encrypt_der.phpt +++ b/ext/openssl/tests/openssl_cms_encrypt_der.phpt @@ -46,4 +46,3 @@ bool(true) Now is the winter of our discontent. true true - diff --git a/ext/openssl/tests/openssl_csr_export_basic.phpt b/ext/openssl/tests/openssl_csr_export_basic.phpt index f64271ffd971..8188e29cbf21 100644 --- a/ext/openssl/tests/openssl_csr_export_basic.phpt +++ b/ext/openssl/tests/openssl_csr_export_basic.phpt @@ -33,13 +33,13 @@ $csr = openssl_csr_new($dn, $privkey, $args); var_dump(openssl_csr_export($csr, $output)); try { var_dump(openssl_csr_export($wrong, $output)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { var_dump(openssl_csr_export($privkey, $output)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(openssl_csr_export($csr, $output, false)); ?> @@ -48,5 +48,5 @@ bool(true) Warning: openssl_csr_export(): X.509 Certificate Signing Request cannot be retrieved in %s on line %d bool(false) -openssl_csr_export(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, OpenSSLAsymmetricKey given +TypeError: openssl_csr_export(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, OpenSSLAsymmetricKey given bool(true) diff --git a/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt b/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt index 4a6a393a6ba2..f90ebf3563fd 100644 --- a/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt @@ -45,8 +45,8 @@ var_dump(openssl_csr_export_to_file($wrong, $csrfile)); try { openssl_csr_export_to_file($dh, $csrfile); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(openssl_csr_export_to_file($csr, $csrfile, false)); ?> @@ -81,5 +81,5 @@ f1JMPX0/eHrKvG9wBZu28FdS54xoWGeD1NGraW24 Warning: openssl_csr_export_to_file(): X.509 Certificate Signing Request cannot be retrieved in %s on line %d bool(false) -openssl_csr_export_to_file(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, OpenSSLAsymmetricKey given +TypeError: openssl_csr_export_to_file(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, OpenSSLAsymmetricKey given bool(true) diff --git a/ext/openssl/tests/openssl_csr_new_array_dn_entry.phpt b/ext/openssl/tests/openssl_csr_new_array_dn_entry.phpt index 7184c9af48d5..0f8f3540fa53 100644 --- a/ext/openssl/tests/openssl_csr_new_array_dn_entry.phpt +++ b/ext/openssl/tests/openssl_csr_new_array_dn_entry.phpt @@ -56,4 +56,4 @@ array(7) { string(12) "test.php.net" ["emailAddress"]=> string(20) "php.test@example.com" -} \ No newline at end of file +} diff --git a/ext/openssl/tests/openssl_csr_new_basic.phpt b/ext/openssl/tests/openssl_csr_new_basic.phpt index 66a30584e5a7..ed51b928eabc 100644 --- a/ext/openssl/tests/openssl_csr_new_basic.phpt +++ b/ext/openssl/tests/openssl_csr_new_basic.phpt @@ -12,8 +12,8 @@ $conf = array('config' => __DIR__ . DIRECTORY_SEPARATOR . 'openssl.cnf'); try { var_dump(openssl_csr_new(array(), $a, $conf, array())); var_dump($keyFailed); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } // this leaks @@ -28,7 +28,7 @@ var_dump(openssl_csr_new(["countryName" => "DE"], $x, $conf + ["x509_extensions" ?> --EXPECTF-- Warning: openssl_csr_new(): add1_attr_by_txt challengePassword_min -> 4 (failed; check error queue and value of string_mask OpenSSL option if illegal characters are reported) in %s on line %d -Key array must be of the form array(0 => key, 1 => phrase) +ValueError: Key array must be of the form array(0 => key, 1 => phrase) object(OpenSSLCertificateSigningRequest)#%d (0) { } object(OpenSSLCertificateSigningRequest)#%d (0) { diff --git a/ext/openssl/tests/openssl_csr_new_with_attribs.phpt b/ext/openssl/tests/openssl_csr_new_with_attribs.phpt index a031b9d4a661..f8d4b2fc3c15 100644 --- a/ext/openssl/tests/openssl_csr_new_with_attribs.phpt +++ b/ext/openssl/tests/openssl_csr_new_with_attribs.phpt @@ -91,4 +91,4 @@ UeEz+fvmQ4L+sc3RE8u+M8g31LM= Warning: openssl_csr_new(): attributes: wrong is not a recognized attribute name in %s on line %d object(OpenSSLCertificateSigningRequest)#%d (0) { -} \ No newline at end of file +} diff --git a/ext/openssl/tests/openssl_csr_sign_basic.phpt b/ext/openssl/tests/openssl_csr_sign_basic.phpt index 852b296b9e04..cdcb48529581 100644 --- a/ext/openssl/tests/openssl_csr_sign_basic.phpt +++ b/ext/openssl/tests/openssl_csr_sign_basic.phpt @@ -44,20 +44,20 @@ var_dump(openssl_csr_sign($wrong, null, $privkey, 365)); try { openssl_csr_sign(array(), null, $privkey, 365); -} catch (TypeError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } try { var_dump(openssl_csr_sign($csr, array(), $privkey, 365)); -} catch (TypeError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } try { var_dump(openssl_csr_sign($csr, null, array(), 365)); -} catch (ValueError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } var_dump(openssl_csr_sign($csr, null, $privkey, 365, $config_arg)); ?> @@ -79,8 +79,8 @@ bool(false) Warning: openssl_csr_sign(): X.509 Certificate Signing Request cannot be retrieved in %s on line %d bool(false) -openssl_csr_sign(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, array given -openssl_csr_sign(): Argument #2 ($ca_certificate) must be of type OpenSSLCertificate|string|null, array given -Key array must be of the form array(0 => key, 1 => phrase) +TypeError: openssl_csr_sign(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, array given +TypeError: openssl_csr_sign(): Argument #2 ($ca_certificate) must be of type OpenSSLCertificate|string|null, array given +ValueError: Key array must be of the form array(0 => key, 1 => phrase) object(OpenSSLCertificate)#%d (0) { } diff --git a/ext/openssl/tests/openssl_csr_sign_with_serial_hex.phpt b/ext/openssl/tests/openssl_csr_sign_with_serial_hex.phpt index eec1bbdcfc4c..56084838b10a 100644 --- a/ext/openssl/tests/openssl_csr_sign_with_serial_hex.phpt +++ b/ext/openssl/tests/openssl_csr_sign_with_serial_hex.phpt @@ -62,4 +62,4 @@ string(6) "12D687" string(10) "3735928559" string(8) "DEADBEEF" string(42) "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" -string(40) "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" \ No newline at end of file +string(40) "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" diff --git a/ext/openssl/tests/openssl_pkcs12_export_basic.phpt b/ext/openssl/tests/openssl_pkcs12_export_basic.phpt index 458f365fc14b..3db9b860095d 100644 --- a/ext/openssl/tests/openssl_pkcs12_export_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs12_export_basic.phpt @@ -32,8 +32,8 @@ var_dump(openssl_pkcs12_export($invalid, $output, $invalid, $pass)); var_dump(openssl_pkcs12_export($invalid_path, $output, $invalid_path, $pass)); try { var_dump(openssl_pkcs12_export($priv_res, $output, $cert_res, $pass)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } //var_dump(openssl_pkcs12_export($cert, $output, $priv, $pass, array("foo"))); ?> @@ -53,4 +53,4 @@ bool(false) Warning: openssl_pkcs12_export(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -openssl_pkcs12_export(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given +TypeError: openssl_pkcs12_export(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given diff --git a/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt b/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt index 0938921a8ff5..82e07f5a4c4e 100644 --- a/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt @@ -32,8 +32,8 @@ var_dump(openssl_pkcs12_export_to_file($invalid, $pkcsfile, $invalid, $pass)); var_dump(openssl_pkcs12_export_to_file($invalid_path, $pkcsfile, $invalid_path, $pass)); try { var_dump(openssl_pkcs12_export_to_file($priv_res, $pkcsfile, $cert_res, $pass)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --CLEAN-- @@ -58,4 +58,4 @@ bool(false) Warning: openssl_pkcs12_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -openssl_pkcs12_export_to_file(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given +TypeError: openssl_pkcs12_export_to_file(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given diff --git a/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt b/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt index 480e662e4145..ed70c27f1a0a 100644 --- a/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt +++ b/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt @@ -17,8 +17,8 @@ $d = new stdclass; try { var_dump(openssl_pkcs7_decrypt($a, $b, $c, $d)); -} catch (Error $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump($c); @@ -30,7 +30,7 @@ var_dump(openssl_pkcs7_decrypt($a, $b, 0, 0)); echo "Done\n"; ?> --EXPECT-- -Object of class stdClass could not be converted to string +Error: Object of class stdClass could not be converted to string object(stdClass)#1 (0) { } string(62) "openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved" diff --git a/ext/openssl/tests/openssl_pkey_new_error.phpt b/ext/openssl/tests/openssl_pkey_new_error.phpt index f32292677bac..764c4547e4fe 100644 --- a/ext/openssl/tests/openssl_pkey_new_error.phpt +++ b/ext/openssl/tests/openssl_pkey_new_error.phpt @@ -13,21 +13,21 @@ $dh = array("dh" => array()); try { openssl_pkey_get_details(openssl_pkey_new($rsa)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { openssl_pkey_get_details(openssl_pkey_new($dsa)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { openssl_pkey_get_details(openssl_pkey_new($dh)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, false given -openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, false given -openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, false given +TypeError: openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, false given +TypeError: openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, false given +TypeError: openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, false given diff --git a/ext/openssl/tests/openssl_private_decrypt_basic.phpt b/ext/openssl/tests/openssl_private_decrypt_basic.phpt index 44101d580c02..97250254085d 100644 --- a/ext/openssl/tests/openssl_private_decrypt_basic.phpt +++ b/ext/openssl/tests/openssl_private_decrypt_basic.phpt @@ -20,8 +20,8 @@ var_dump($output3); try { var_dump(openssl_private_decrypt($encrypted, $output4, array($privkey), OPENSSL_PKCS1_OAEP_PADDING)); var_dump($output4); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(openssl_private_decrypt($encrypted, $output5, array($privkey, ""), OPENSSL_PKCS1_OAEP_PADDING)); @@ -36,6 +36,6 @@ bool(false) NULL bool(false) NULL -Key array must be of the form array(0 => key, 1 => phrase) +ValueError: Key array must be of the form array(0 => key, 1 => phrase) bool(true) string(32) "Testing openssl_public_decrypt()" diff --git a/ext/openssl/tests/openssl_private_decrypt_digest.phpt b/ext/openssl/tests/openssl_private_decrypt_digest.phpt index 9bb07ba71eac..d90860aa3a77 100644 --- a/ext/openssl/tests/openssl_private_decrypt_digest.phpt +++ b/ext/openssl/tests/openssl_private_decrypt_digest.phpt @@ -33,8 +33,8 @@ var_dump($output_invalid); try { var_dump(openssl_private_decrypt($encrypted_sha256, $output_invalid, $privkey, OPENSSL_PKCS1_OAEP_PADDING, "sha256\0extra")); var_dump($output_invalid); -} catch (\ValueError $e) { - var_dump($e->getMessage()); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } openssl_public_encrypt($data, $encrypted_pkcs1, $pubkey, OPENSSL_PKCS1_PADDING); @@ -52,6 +52,6 @@ NULL Warning: openssl_private_decrypt(): Unknown digest algorithm: invalid_hash in %s on line %d bool(false) NULL -string(85) "openssl_private_decrypt(): Argument #5 ($digest_algo) must not contain any null bytes" +ValueError: openssl_private_decrypt(): Argument #5 ($digest_algo) must not contain any null bytes bool(true) string(56) "Testing openssl_private_decrypt() with digest algorithms" diff --git a/ext/openssl/tests/openssl_public_decrypt_basic.phpt b/ext/openssl/tests/openssl_public_decrypt_basic.phpt index 8a3f0f2c58d7..f021758dc205 100644 --- a/ext/openssl/tests/openssl_public_decrypt_basic.phpt +++ b/ext/openssl/tests/openssl_public_decrypt_basic.phpt @@ -20,15 +20,15 @@ var_dump($output3); try { var_dump(openssl_public_decrypt($encrypted, $output4, array())); var_dump($output4); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { var_dump(openssl_public_decrypt($encrypted, $output5, array($pubkey))); var_dump($output5); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(openssl_public_decrypt($encrypted, $output6, array($pubkey, ""))); var_dump($output6); @@ -42,7 +42,7 @@ bool(false) NULL bool(false) NULL -Key array must be of the form array(0 => key, 1 => phrase) -Key array must be of the form array(0 => key, 1 => phrase) +ValueError: Key array must be of the form array(0 => key, 1 => phrase) +ValueError: Key array must be of the form array(0 => key, 1 => phrase) bool(true) string(32) "Testing openssl_public_decrypt()" diff --git a/ext/openssl/tests/openssl_random_pseudo_bytes_error.phpt b/ext/openssl/tests/openssl_random_pseudo_bytes_error.phpt index 9f905e6a3510..18ba07aeb35f 100644 --- a/ext/openssl/tests/openssl_random_pseudo_bytes_error.phpt +++ b/ext/openssl/tests/openssl_random_pseudo_bytes_error.phpt @@ -6,9 +6,9 @@ openssl getMessage().PHP_EOL; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -openssl_random_pseudo_bytes(): Argument #1 ($length) must be greater than 0 +ValueError: openssl_random_pseudo_bytes(): Argument #1 ($length) must be greater than 0 diff --git a/ext/openssl/tests/openssl_seal_basic.phpt b/ext/openssl/tests/openssl_seal_basic.phpt index 6c08efa6d70d..37a15f27081b 100644 --- a/ext/openssl/tests/openssl_seal_basic.phpt +++ b/ext/openssl/tests/openssl_seal_basic.phpt @@ -15,8 +15,8 @@ var_dump(openssl_seal($a, $b, $c, $d, $method)); try { var_dump(openssl_seal($a, $a, $a, array(), $method)); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } // tests with cert @@ -30,8 +30,8 @@ var_dump(openssl_seal($data, $sealed, $ekeys, array($pub_key, $wrong), $method)) try { var_dump(openssl_seal($data, $sealed, $ekeys, array(), $method)); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(openssl_seal($data, $sealed, $ekeys, array($wrong), $method)); @@ -40,13 +40,13 @@ var_dump(openssl_seal($data, $sealed, $ekeys, array($wrong), $method)); --EXPECTF-- Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($public_key) must not be empty +ValueError: openssl_seal(): Argument #4 ($public_key) must not be empty int(32) int(32) Warning: openssl_seal(): Not a public key (2th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($public_key) must not be empty +ValueError: openssl_seal(): Argument #4 ($public_key) must not be empty Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_x509_export_basic.phpt b/ext/openssl/tests/openssl_x509_export_basic.phpt index f4b96fb9df24..86f039d5fb50 100644 --- a/ext/openssl/tests/openssl_x509_export_basic.phpt +++ b/ext/openssl/tests/openssl_x509_export_basic.phpt @@ -19,8 +19,8 @@ var_dump(openssl_x509_export($d, $output4)); // read cert from a resource try { openssl_x509_export($e, $output5); // read an array, fails -} catch (TypeError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } if (PHP_EOL !== "\n") { @@ -40,7 +40,7 @@ bool(true) Warning: openssl_x509_export(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(true) -openssl_x509_export(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given +TypeError: openssl_x509_export(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given int(0) int(0) int(%d) diff --git a/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt b/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt index 9fe8abfa4569..0fa60fe046c0 100644 --- a/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt @@ -19,8 +19,8 @@ var_dump(openssl_x509_export_to_file($c, $outfilename)); // read an invalid cert var_dump(openssl_x509_export_to_file($d, $outfilename)); // read cert from a resource try { openssl_x509_export_to_file($e, $outfilename); // read an array, fails -} catch (TypeError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } echo "---\n"; var_dump($exists = file_exists($outfilename)); @@ -39,6 +39,6 @@ bool(true) Warning: openssl_x509_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(true) -openssl_x509_export_to_file(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given +TypeError: openssl_x509_export_to_file(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given --- bool(true) diff --git a/ext/openssl/tests/openssl_x509_read_basic.phpt b/ext/openssl/tests/openssl_x509_read_basic.phpt index 5eaf4ce8eb63..4e99aaede058 100644 --- a/ext/openssl/tests/openssl_x509_read_basic.phpt +++ b/ext/openssl/tests/openssl_x509_read_basic.phpt @@ -21,14 +21,14 @@ var_dump(openssl_x509_read($d)); // read cert from a resource try { openssl_x509_read($e); // read an array -} catch (TypeError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } try { openssl_x509_read($f); // read an array with the filename -} catch (TypeError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } ?> @@ -42,5 +42,5 @@ Warning: openssl_x509_read(): X.509 Certificate cannot be retrieved in %s on lin bool(false) object(OpenSSLCertificate)#%d (0) { } -openssl_x509_read(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given -openssl_x509_read(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given +TypeError: openssl_x509_read(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given +TypeError: openssl_x509_read(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given diff --git a/ext/openssl/tests/php_openssl_pkey_from_zval_leak.phpt b/ext/openssl/tests/php_openssl_pkey_from_zval_leak.phpt index 2b19dd311150..fbabc3aefca8 100644 --- a/ext/openssl/tests/php_openssl_pkey_from_zval_leak.phpt +++ b/ext/openssl/tests/php_openssl_pkey_from_zval_leak.phpt @@ -14,10 +14,10 @@ class StrFail { $key = ["", new StrFail]; try { openssl_pkey_export_to_file($key, "doesnotmatter"); -} catch (Error $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -create a leak +Error: create a leak diff --git a/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt b/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt index f87f831a7859..74db2f3474ba 100644 --- a/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt +++ b/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt @@ -76,4 +76,3 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECT-- SERVER_EXCEPTION: Session tickets cannot be enabled when session_get_cb is setConnection failed as expected - diff --git a/ext/openssl/tests/session_resumption_invalid_session_import.phpt b/ext/openssl/tests/session_resumption_invalid_session_import.phpt index efd49e7c693b..582761e7561e 100644 --- a/ext/openssl/tests/session_resumption_invalid_session_import.phpt +++ b/ext/openssl/tests/session_resumption_invalid_session_import.phpt @@ -11,9 +11,9 @@ if (!function_exists("proc_open")) die("skip no proc_open"); try { Openssl\Session::import('invalid'); -} catch (Openssl\OpensslException $e) { - echo $e->getMessage() . "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -Failed to import session data +Openssl\OpensslException: Failed to import session data diff --git a/ext/openssl/tests/tls_psk_callback_not_callable.phpt b/ext/openssl/tests/tls_psk_callback_not_callable.phpt index 29382e2a13ab..14b2a0508e51 100644 --- a/ext/openssl/tests/tls_psk_callback_not_callable.phpt +++ b/ext/openssl/tests/tls_psk_callback_not_callable.phpt @@ -43,4 +43,3 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECTF-- caught: psk_client_cb must be a valid callback, %s - diff --git a/ext/openssl/tests/tls_psk_client_callback_null.phpt b/ext/openssl/tests/tls_psk_client_callback_null.phpt index 92d970908c8e..e7acdf77094b 100644 --- a/ext/openssl/tests/tls_psk_client_callback_null.phpt +++ b/ext/openssl/tests/tls_psk_client_callback_null.phpt @@ -42,4 +42,3 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECT-- bool(false) - diff --git a/ext/openssl/tests/tls_psk_client_callback_throws.phpt b/ext/openssl/tests/tls_psk_client_callback_throws.phpt index 13b2d71476c2..350756130b14 100644 --- a/ext/openssl/tests/tls_psk_client_callback_throws.phpt +++ b/ext/openssl/tests/tls_psk_client_callback_throws.phpt @@ -45,4 +45,3 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECT-- caught: callback boom - diff --git a/ext/openssl/tests/tls_psk_client_no_identity.phpt b/ext/openssl/tests/tls_psk_client_no_identity.phpt index bfc8d078ceff..8a84d822b4c1 100644 --- a/ext/openssl/tests/tls_psk_client_no_identity.phpt +++ b/ext/openssl/tests/tls_psk_client_no_identity.phpt @@ -46,4 +46,3 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECT-- caught: Client PSK callback must return Openssl\Psk with a non-null identity - diff --git a/ext/openssl/tests/tls_psk_mismatch.phpt b/ext/openssl/tests/tls_psk_mismatch.phpt index 8fa90d115c5a..ada49402bbde 100644 --- a/ext/openssl/tests/tls_psk_mismatch.phpt +++ b/ext/openssl/tests/tls_psk_mismatch.phpt @@ -41,4 +41,3 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECT-- bool(false) - diff --git a/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt b/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt index 830c02449dc9..ddd05fd37ab4 100644 --- a/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt +++ b/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt @@ -41,4 +41,3 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> --EXPECT-- bool(false) - diff --git a/ext/sockets/tests/gh16267.phpt b/ext/sockets/tests/gh16267.phpt index de3e1b657fbc..f6e18148cffa 100644 --- a/ext/sockets/tests/gh16267.phpt +++ b/ext/sockets/tests/gh16267.phpt @@ -9,10 +9,10 @@ sockets var_dump(socket_strerror(-2147483648)); try { socket_strerror(2147483648); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- string(%d) "%S" -socket_strerror(): Argument #1 ($error_code) must be between %i and %d +ValueError: socket_strerror(): Argument #1 ($error_code) must be between %i and %d diff --git a/ext/sockets/tests/gh20532.phpt b/ext/sockets/tests/gh20532.phpt index 360f9e7e11a8..2bec6953dac4 100644 --- a/ext/sockets/tests/gh20532.phpt +++ b/ext/sockets/tests/gh20532.phpt @@ -13,4 +13,3 @@ var_dump(socket_addrinfo_lookup("example.com", "http", ['ai_socktype' => SOCK_RA bool(true) bool(true) bool(true) - diff --git a/ext/sockets/tests/mcast_ipv4_send_error.phpt b/ext/sockets/tests/mcast_ipv4_send_error.phpt index 94148df1c4cb..c19264f0dcc9 100644 --- a/ext/sockets/tests/mcast_ipv4_send_error.phpt +++ b/ext/sockets/tests/mcast_ipv4_send_error.phpt @@ -42,8 +42,8 @@ echo "Setting IP_MULTICAST_TTL with 256\n"; try { $r = socket_set_option($s, $level, IP_MULTICAST_TTL, 256); var_dump($r); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } $r = socket_get_option($s, $level, IP_MULTICAST_TTL); var_dump($r); @@ -61,8 +61,8 @@ echo "Setting IP_MULTICAST_TTL with -1\n"; try { $r = socket_set_option($s, $level, IP_MULTICAST_TTL, -1); var_dump($r); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } $r = socket_get_option($s, $level, IP_MULTICAST_TTL); var_dump($r); @@ -78,7 +78,7 @@ bool(true) int(0) Setting IP_MULTICAST_TTL with 256 -socket_set_option(): Argument #4 ($value) must be between 0 and 255 +ValueError: socket_set_option(): Argument #4 ($value) must be between 0 and 255 int(1) Setting IP_MULTICAST_TTL with "254" @@ -86,5 +86,5 @@ bool(true) int(254) Setting IP_MULTICAST_TTL with -1 -socket_set_option(): Argument #4 ($value) must be between 0 and 255 +ValueError: socket_set_option(): Argument #4 ($value) must be between 0 and 255 int(254) diff --git a/ext/sockets/tests/mcast_sockettype_error.phpt b/ext/sockets/tests/mcast_sockettype_error.phpt index 56308534ebc4..7747e7435221 100644 --- a/ext/sockets/tests/mcast_sockettype_error.phpt +++ b/ext/sockets/tests/mcast_sockettype_error.phpt @@ -22,9 +22,9 @@ try { "group" => '127.0.0.1', "interface" => "lo", )); -} catch (\ValueError $e) { - echo $e->getMessage(), PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -IP address used in the context of an unexpected type of socket +ValueError: IP address used in the context of an unexpected type of socket diff --git a/ext/sockets/tests/socket_addrinfo_lookup.phpt b/ext/sockets/tests/socket_addrinfo_lookup.phpt index 42745f36978d..5dfcd809acc2 100644 --- a/ext/sockets/tests/socket_addrinfo_lookup.phpt +++ b/ext/sockets/tests/socket_addrinfo_lookup.phpt @@ -11,9 +11,9 @@ try { 'invalid' => null, )); var_dump($addrinfo[0]); -} catch (\ValueError $e) { - echo $e->getMessage(), \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -socket_addrinfo_lookup(): Argument #3 ($hints) must only contain array keys "ai_flags", "ai_socktype", "ai_protocol", or "ai_family" +ValueError: socket_addrinfo_lookup(): Argument #3 ($hints) must only contain array keys "ai_flags", "ai_socktype", "ai_protocol", or "ai_family" diff --git a/ext/sockets/tests/socket_bind_invalid_port.phpt b/ext/sockets/tests/socket_bind_invalid_port.phpt index b70900f68620..3bf3bd8789ac 100644 --- a/ext/sockets/tests/socket_bind_invalid_port.phpt +++ b/ext/sockets/tests/socket_bind_invalid_port.phpt @@ -8,16 +8,16 @@ sockets try { socket_bind($s_c, '0.0.0.0', -1); - } catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; + } catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_bind($s_c, '0.0.0.0', 65536); - } catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; + } catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -socket_bind(): Argument #3 ($port) must be between 0 and 65535 -socket_bind(): Argument #3 ($port) must be between 0 and 65535 +ValueError: socket_bind(): Argument #3 ($port) must be between 0 and 65535 +ValueError: socket_bind(): Argument #3 ($port) must be between 0 and 65535 diff --git a/ext/sockets/tests/socket_cmsg_udp_segment.phpt b/ext/sockets/tests/socket_cmsg_udp_segment.phpt index 38a914066510..24e9e731d1dd 100644 --- a/ext/sockets/tests/socket_cmsg_udp_segment.phpt +++ b/ext/sockets/tests/socket_cmsg_udp_segment.phpt @@ -12,15 +12,15 @@ $src = socket_create(AF_UNIX, SOCK_DGRAM, 0); try { socket_setopt($src, SOL_UDP, UDP_SEGMENT, -1); -} catch (\ValueError $e) { - echo $e->getMessage(), PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_setopt($src, SOL_UDP, UDP_SEGMENT, 65536); -} catch (\ValueError $e) { - echo $e->getMessage(), PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -socket_setopt(): Argument #4 ($value) must be between 0 and 65535 -socket_setopt(): Argument #4 ($value) must be between 0 and 65535 +ValueError: socket_setopt(): Argument #4 ($value) must be between 0 and 65535 +ValueError: socket_setopt(): Argument #4 ($value) must be between 0 and 65535 diff --git a/ext/sockets/tests/socket_connect_params.phpt b/ext/sockets/tests/socket_connect_params.phpt index 683b8e9d919f..6e79bb89df01 100644 --- a/ext/sockets/tests/socket_connect_params.phpt +++ b/ext/sockets/tests/socket_connect_params.phpt @@ -14,20 +14,20 @@ socket_getsockname($s_c, $addr, $port); // wrong parameter count try { socket_connect($s_c); -} catch (\ArgumentCountError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_connect($s_c, '0.0.0.0'); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } $s_w = socket_connect($s_c, '0.0.0.0', $port); socket_close($s_c); ?> --EXPECTF-- -socket_connect() expects at least 2 arguments, 1 given -socket_connect(): Argument #3 ($port) cannot be null when the socket type is AF_INET +ArgumentCountError: socket_connect() expects at least 2 arguments, 1 given +ValueError: socket_connect(): Argument #3 ($port) cannot be null when the socket type is AF_INET Warning: socket_connect(): unable to connect [%i]: %a in %s on line %d diff --git a/ext/sockets/tests/socket_create_listen_invalid_port.phpt b/ext/sockets/tests/socket_create_listen_invalid_port.phpt index 35182139ee6f..8aa577b1de12 100644 --- a/ext/sockets/tests/socket_create_listen_invalid_port.phpt +++ b/ext/sockets/tests/socket_create_listen_invalid_port.phpt @@ -8,17 +8,17 @@ var_dump(socket_create_listen(0)); try { socket_create_listen(-1); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_create_listen(65536); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- object(Socket)#1 (0) { } -socket_create_listen(): Argument #1 ($port) must be between 0 and 65535 -socket_create_listen(): Argument #1 ($port) must be between 0 and 65535 +ValueError: socket_create_listen(): Argument #1 ($port) must be between 0 and 65535 +ValueError: socket_create_listen(): Argument #1 ($port) must be between 0 and 65535 diff --git a/ext/sockets/tests/socket_create_pair-wrongparams.phpt b/ext/sockets/tests/socket_create_pair-wrongparams.phpt index 1d0a6540841d..957828ddfc01 100644 --- a/ext/sockets/tests/socket_create_pair-wrongparams.phpt +++ b/ext/sockets/tests/socket_create_pair-wrongparams.phpt @@ -15,22 +15,22 @@ var_dump(socket_create_pair(AF_INET, 0, 0, $sockets)); try { var_dump(socket_create_pair(31337, 0, 0, $sockets)); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { var_dump(socket_create_pair(AF_INET, 31337, 0, $sockets)); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- Warning: socket_create_pair(): Unable to create socket pair [%d]: %s %r(not supported|wrong type for socket)%r in %s on line %d bool(false) -socket_create_pair(): Argument #1 ($domain) must be one of AF_UNIX, AF_INET6, or AF_INET -socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A +ValueError: socket_create_pair(): Argument #1 ($domain) must be one of AF_UNIX, AF_INET6, or AF_INET +ValueError: socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A --CREDITS-- Till Klampaeckel, till@php.net Berlin TestFest 2009 diff --git a/ext/sockets/tests/socket_create_pair_sockexec.phpt b/ext/sockets/tests/socket_create_pair_sockexec.phpt index 5e31b1550340..9e4ff0e76fa7 100644 --- a/ext/sockets/tests/socket_create_pair_sockexec.phpt +++ b/ext/sockets/tests/socket_create_pair_sockexec.phpt @@ -12,23 +12,23 @@ if (!defined('SOCK_NONBLOCK')) die("skip SOCK_NONBLOCK"); $sockets = array(); try { socket_create_pair(AF_UNIX, 11 | SOCK_CLOEXEC, 0, $sockets); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_create_pair(AF_UNIX, 11 | SOCK_NONBLOCK, 0, $sockets); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_create_pair(AF_UNIX, 11 | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, $sockets); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(socket_create_pair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, $sockets)); ?> --EXPECTF-- -socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A -socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A -socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A +ValueError: socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A +ValueError: socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A +ValueError: socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A bool(true) diff --git a/ext/sockets/tests/socket_export_stream-2.phpt b/ext/sockets/tests/socket_export_stream-2.phpt index 0a83ef485ba8..638b17ed41cd 100644 --- a/ext/sockets/tests/socket_export_stream-2.phpt +++ b/ext/sockets/tests/socket_export_stream-2.phpt @@ -7,13 +7,13 @@ sockets try { socket_export_stream(fopen(__FILE__, "rb")); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_export_stream(stream_socket_server("udp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); var_dump($s); @@ -21,16 +21,16 @@ socket_close($s); try { var_dump(socket_export_stream($s)); -} catch (Error $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "Done."; ?> --EXPECTF-- -socket_export_stream(): Argument #1 ($socket) must be of type Socket, resource given -socket_export_stream(): Argument #1 ($socket) must be of type Socket, resource given +TypeError: socket_export_stream(): Argument #1 ($socket) must be of type Socket, resource given +TypeError: socket_export_stream(): Argument #1 ($socket) must be of type Socket, resource given object(Socket)#%d (0) { } -socket_export_stream(): Argument #1 ($socket) has already been closed +Error: socket_export_stream(): Argument #1 ($socket) has already been closed Done. diff --git a/ext/sockets/tests/socket_export_stream-4.phpt b/ext/sockets/tests/socket_export_stream-4.phpt index 168671138680..4512ea837b58 100644 --- a/ext/sockets/tests/socket_export_stream-4.phpt +++ b/ext/sockets/tests/socket_export_stream-4.phpt @@ -17,8 +17,8 @@ function test($stream, $sock) { echo "stream_set_blocking "; try { print_r(stream_set_blocking($stream, false)); - } catch (Error $e) { - echo get_class($e), ": ", $e->getMessage(), "\n"; + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "\n"; } @@ -26,8 +26,8 @@ function test($stream, $sock) { echo "socket_set_block "; try { print_r(socket_set_block($sock)); - } catch (Error $e) { - echo get_class($e), ": ", $e->getMessage(), "\n"; + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "\n"; echo "socket_get_option "; @@ -35,8 +35,8 @@ function test($stream, $sock) { // Solaris uses different numeric values for SOCK_* constants $opt = socket_get_option($sock, SOL_SOCKET, SO_TYPE); print_r($opt === SOCK_DGRAM ? "DGRAM" : $opt); - } catch (Error $e) { - echo get_class($e), ": ", $e->getMessage(), "\n"; + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "\n"; } diff --git a/ext/sockets/tests/socket_getaddrinfo_error.phpt b/ext/sockets/tests/socket_getaddrinfo_error.phpt index a2455821e70e..9875e1894d3e 100644 --- a/ext/sockets/tests/socket_getaddrinfo_error.phpt +++ b/ext/sockets/tests/socket_getaddrinfo_error.phpt @@ -11,8 +11,8 @@ try { 'ai_flags' => 0, 'ai_protocol' => 0, )); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -21,8 +21,8 @@ try { 'ai_flags' => 0, 'ai_protocol' => 0, )); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -31,8 +31,8 @@ try { 'ai_flags' => new stdClass(), 'ai_protocol' => 0, )); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -41,8 +41,8 @@ try { 'ai_flags' => 0, 'ai_protocol' => new stdClass(), )); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -51,8 +51,8 @@ try { 'ai_flags' => 0, 'ai_protocol' => 0, )); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -61,8 +61,8 @@ try { 'ai_flags' => 0, 'ai_protocol' => 0, )); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -71,8 +71,8 @@ try { 'ai_flags' => -256, 'ai_protocol' => 0, )); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -81,8 +81,8 @@ try { 'ai_flags' => 0, 'ai_protocol' => PHP_INT_MIN, )); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, [ @@ -91,8 +91,8 @@ try { 0, 0, ]); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_addrinfo_lookup('127.0.0.1', 2000, array( @@ -101,18 +101,18 @@ try { 0, 0, )); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be of type int, stdClass given -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be of type int, stdClass given -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be of type int, stdClass given -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be of type int, stdClass given -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be AF_INET%A -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be between 0 and %d -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be between 0 and %d -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be between 0 and %d -socket_addrinfo_lookup(): Argument #3 ($hints) must only contain array keys "ai_flags", "ai_socktype", "ai_protocol", or "ai_family" -socket_addrinfo_lookup(): Argument #3 ($hints) must only contain array keys "ai_flags", "ai_socktype", "ai_protocol", or "ai_family" +TypeError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be of type int, stdClass given +TypeError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be of type int, stdClass given +TypeError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be of type int, stdClass given +TypeError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be of type int, stdClass given +ValueError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be AF_INET%A +ValueError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be between 0 and %d +ValueError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be between 0 and %d +ValueError: socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be between 0 and %d +ValueError: socket_addrinfo_lookup(): Argument #3 ($hints) must only contain array keys "ai_flags", "ai_socktype", "ai_protocol", or "ai_family" +ValueError: socket_addrinfo_lookup(): Argument #3 ($hints) must only contain array keys "ai_flags", "ai_socktype", "ai_protocol", or "ai_family" diff --git a/ext/sockets/tests/socket_import_stream-2.phpt b/ext/sockets/tests/socket_import_stream-2.phpt index 7d3b492a85e1..271aab935922 100644 --- a/ext/sockets/tests/socket_import_stream-2.phpt +++ b/ext/sockets/tests/socket_import_stream-2.phpt @@ -8,16 +8,16 @@ sockets var_dump(socket_import_stream(fopen(__FILE__, "rb"))); try { socket_import_stream(socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } $s = stream_socket_server("udp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND); var_dump($s); var_dump(fclose($s)); try { socket_import_stream($s); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "Done."; @@ -25,8 +25,8 @@ echo "Done."; --EXPECTF-- Warning: socket_import_stream(): Cannot represent a stream of type STDIO as a Socket Descriptor in %s on line %d bool(false) -socket_import_stream(): Argument #1 ($stream) must be of type resource, Socket given +TypeError: socket_import_stream(): Argument #1 ($stream) must be of type resource, Socket given resource(%d) of type (stream) bool(true) -socket_import_stream(): supplied resource is not a valid stream resource +TypeError: socket_import_stream(): supplied resource is not a valid stream resource Done. diff --git a/ext/sockets/tests/socket_import_stream-4.phpt b/ext/sockets/tests/socket_import_stream-4.phpt index 87ca608b862b..585c18285b6d 100644 --- a/ext/sockets/tests/socket_import_stream-4.phpt +++ b/ext/sockets/tests/socket_import_stream-4.phpt @@ -16,8 +16,8 @@ function test($stream, $sock) { echo "stream_set_blocking "; try { print_r(stream_set_blocking($stream, false)); - } catch (Error $e) { - echo get_class($e), ": ", $e->getMessage(), "\n"; + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "\n"; } @@ -25,8 +25,8 @@ function test($stream, $sock) { echo "socket_set_block "; try { print_r(socket_set_block($sock)); - } catch (Error $e) { - echo get_class($e), ": ", $e->getMessage(), "\n"; + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "\n"; echo "socket_get_option "; @@ -34,8 +34,8 @@ function test($stream, $sock) { // Solaris uses different numeric values for SOCK_* constants $opt = socket_get_option($sock, SOL_SOCKET, SO_TYPE); print_r($opt === SOCK_DGRAM ? "DGRAM" : $opt); - } catch (Error $e) { - echo get_class($e), ": ", $e->getMessage(), "\n"; + } catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } echo "\n"; } diff --git a/ext/sockets/tests/socket_reuseport_cbpf.phpt b/ext/sockets/tests/socket_reuseport_cbpf.phpt index a9b8d5c731ff..11792b1b8124 100644 --- a/ext/sockets/tests/socket_reuseport_cbpf.phpt +++ b/ext/sockets/tests/socket_reuseport_cbpf.phpt @@ -20,7 +20,7 @@ var_dump(socket_set_option( $socket, SOL_SOCKET, SO_REUSEADDR, true)); var_dump(socket_set_option( $socket, SOL_SOCKET, SO_REUSEPORT, true)); try { socket_set_option( $socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, []); -} catch (\TypeError $e) { +} catch (\Throwable $e) { echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump(socket_set_option( $socket, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, SKF_AD_CPU)); diff --git a/ext/sockets/tests/socket_select-wrongparams-2.phpt b/ext/sockets/tests/socket_select-wrongparams-2.phpt index f2d3799e7570..0e86e924f019 100644 --- a/ext/sockets/tests/socket_select-wrongparams-2.phpt +++ b/ext/sockets/tests/socket_select-wrongparams-2.phpt @@ -11,12 +11,12 @@ $time = 0; try { socket_select($sockets, $write, $except, $time); -} catch (ValueError $exception) { - echo $exception->getMessage() . "\n"; +} catch (Throwable $exception) { + echo $exception::class, ': ', $exception->getMessage(), "\n"; } ?> --EXPECT-- -socket_select(): At least one array argument must be passed +ValueError: socket_select(): At least one array argument must be passed --CREDITS-- Till Klampaeckel, till@php.net Berlin TestFest 2009 diff --git a/ext/sockets/tests/socket_select_error.phpt b/ext/sockets/tests/socket_select_error.phpt index 143351dd427d..d9c103b1d353 100644 --- a/ext/sockets/tests/socket_select_error.phpt +++ b/ext/sockets/tests/socket_select_error.phpt @@ -7,9 +7,9 @@ sockets $r = $w = $e = ['no resource']; try { socket_select($r, $w, $e, 1); -} catch (TypeError $ex) { - echo $ex->getMessage(), PHP_EOL; +} catch (Throwable $ex) { + echo $ex::class, ': ', $ex->getMessage(), "\n"; } ?> --EXPECT-- -socket_select(): Argument #1 ($read) must only have elements of type Socket, string given +TypeError: socket_select(): Argument #1 ($read) must only have elements of type Socket, string given diff --git a/ext/sockets/tests/socket_send_params.phpt b/ext/sockets/tests/socket_send_params.phpt index d6294c490105..c3171ebc566c 100644 --- a/ext/sockets/tests/socket_send_params.phpt +++ b/ext/sockets/tests/socket_send_params.phpt @@ -7,10 +7,10 @@ sockets $s_c = socket_create_listen(0); try { $s_w = socket_send($s_c, "foo", -1, MSG_OOB); - } catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; + } catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } socket_close($s_c); ?> --EXPECT-- -socket_send(): Argument #3 ($length) must be greater than or equal to 0 +ValueError: socket_send(): Argument #3 ($length) must be greater than or equal to 0 diff --git a/ext/sockets/tests/socket_sendto_invalid_port.phpt b/ext/sockets/tests/socket_sendto_invalid_port.phpt index 9ff81ff5e15b..d0778ca9817a 100644 --- a/ext/sockets/tests/socket_sendto_invalid_port.phpt +++ b/ext/sockets/tests/socket_sendto_invalid_port.phpt @@ -7,16 +7,16 @@ sockets $s_c = socket_create_listen(0); try { $s_w = socket_sendto($s_c, "foo", 0, MSG_OOB, '127.0.0.1', 65536); - } catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; + } catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $s_w = socket_sendto($s_c, "foo", 0, MSG_OOB, '127.0.0.1', -1); - } catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; + } catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } socket_close($s_c); ?> --EXPECT-- -socket_sendto(): Argument #6 ($port) must be between 0 and 65535 -socket_sendto(): Argument #6 ($port) must be between 0 and 65535 +ValueError: socket_sendto(): Argument #6 ($port) must be between 0 and 65535 +ValueError: socket_sendto(): Argument #6 ($port) must be between 0 and 65535 diff --git a/ext/sockets/tests/socket_sendto_params.phpt b/ext/sockets/tests/socket_sendto_params.phpt index ed805ee9be7d..78db7cb95dce 100644 --- a/ext/sockets/tests/socket_sendto_params.phpt +++ b/ext/sockets/tests/socket_sendto_params.phpt @@ -7,10 +7,10 @@ sockets $s_c = socket_create_listen(0); try { $s_w = socket_sendto($s_c, "foo", -1, MSG_OOB, '127.0.0.1'); - } catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; + } catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } socket_close($s_c); ?> --EXPECT-- -socket_sendto(): Argument #3 ($length) must be greater than or equal to 0 +ValueError: socket_sendto(): Argument #3 ($length) must be greater than or equal to 0 diff --git a/ext/sockets/tests/socket_sendto_unix_addr_too_long.phpt b/ext/sockets/tests/socket_sendto_unix_addr_too_long.phpt index f2b62527e337..7203308d742b 100644 --- a/ext/sockets/tests/socket_sendto_unix_addr_too_long.phpt +++ b/ext/sockets/tests/socket_sendto_unix_addr_too_long.phpt @@ -19,11 +19,11 @@ $long_addr = str_repeat('a', 512); try { socket_sendto($socket, "data", 4, 0, $long_addr); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } socket_close($socket); ?> --EXPECTF-- -socket_sendto(): Argument #5 ($address) must be less than %d +ValueError: socket_sendto(): Argument #5 ($address) must be less than %d diff --git a/ext/sockets/tests/socket_set_block-retval.phpt b/ext/sockets/tests/socket_set_block-retval.phpt index 04f980416835..648847b539b3 100644 --- a/ext/sockets/tests/socket_set_block-retval.phpt +++ b/ext/sockets/tests/socket_set_block-retval.phpt @@ -13,11 +13,11 @@ $socket2 = socket_create_listen(0); socket_close($socket2); try { var_dump(socket_set_block($socket2)); -} catch (Error $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- bool(true) -socket_set_block(): Argument #1 ($socket) has already been closed +Error: socket_set_block(): Argument #1 ($socket) has already been closed diff --git a/ext/sockets/tests/socket_set_nonblock-retval.phpt b/ext/sockets/tests/socket_set_nonblock-retval.phpt index b92a75e17c2c..bc32f79782b0 100644 --- a/ext/sockets/tests/socket_set_nonblock-retval.phpt +++ b/ext/sockets/tests/socket_set_nonblock-retval.phpt @@ -13,11 +13,11 @@ $socket2 = socket_create_listen(0); socket_close($socket2); try { var_dump(socket_set_nonblock($socket2)); -} catch (Error $e) { - echo $e->getMessage(), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- bool(true) -socket_set_nonblock(): Argument #1 ($socket) has already been closed +Error: socket_set_nonblock(): Argument #1 ($socket) has already been closed diff --git a/ext/sockets/tests/socket_set_option_mcast_error.phpt b/ext/sockets/tests/socket_set_option_mcast_error.phpt index 0d7630fb279c..0fdb4ed8f5ba 100644 --- a/ext/sockets/tests/socket_set_option_mcast_error.phpt +++ b/ext/sockets/tests/socket_set_option_mcast_error.phpt @@ -21,16 +21,16 @@ $iwanttoleavenow = true; try { socket_set_option($s, $level, MCAST_LEAVE_GROUP, $iwanttoleavenow); -} catch (\TypeError $e) { - echo $e->getMessage(), PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option($s, $level, MCAST_LEAVE_SOURCE_GROUP, $iwanttoleavenow); -} catch (\TypeError $e) { - echo $e->getMessage(); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is MCAST_LEAVE_GROUP, true given -socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is MCAST_LEAVE_SOURCE_GROUP, true given +TypeError: socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is MCAST_LEAVE_GROUP, true given +TypeError: socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is MCAST_LEAVE_SOURCE_GROUP, true given diff --git a/ext/sockets/tests/socket_set_option_rcvtimeo.phpt b/ext/sockets/tests/socket_set_option_rcvtimeo.phpt index ef75ee025378..411f6da2af39 100644 --- a/ext/sockets/tests/socket_set_option_rcvtimeo.phpt +++ b/ext/sockets/tests/socket_set_option_rcvtimeo.phpt @@ -16,8 +16,8 @@ socket_set_block($socket); //wrong params try { $retval_1 = socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, []); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } //set/get comparison @@ -30,6 +30,6 @@ var_dump($retval_3 === $options); socket_close($socket); ?> --EXPECT-- -socket_set_option(): Argument #4 ($value) must have key "sec" +ValueError: socket_set_option(): Argument #4 ($value) must have key "sec" bool(true) bool(true) diff --git a/ext/sockets/tests/socket_set_option_seolinger.phpt b/ext/sockets/tests/socket_set_option_seolinger.phpt index 0450c7525099..62b79629c3cf 100644 --- a/ext/sockets/tests/socket_set_option_seolinger.phpt +++ b/ext/sockets/tests/socket_set_option_seolinger.phpt @@ -16,8 +16,8 @@ if (!$socket) { // wrong params try { $retval_1 = socket_set_option( $socket, SOL_SOCKET, SO_LINGER, []); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } // set/get comparison @@ -29,8 +29,8 @@ $retval_3 = socket_get_option( $socket, SOL_SOCKET, SO_LINGER); $options_2 = array("l_onoff" => 1); try { var_dump(socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_2)); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump($retval_2); @@ -41,8 +41,8 @@ var_dump((bool)$retval_3["l_onoff"] === (bool)$options["l_onoff"]); socket_close($socket); ?> --EXPECT-- -socket_set_option(): Argument #4 ($value) must have key "l_onoff" -socket_set_option(): Argument #4 ($value) must have key "l_linger" +ValueError: socket_set_option(): Argument #4 ($value) must have key "l_onoff" +ValueError: socket_set_option(): Argument #4 ($value) must have key "l_linger" bool(true) bool(true) bool(true) diff --git a/ext/sockets/tests/socket_set_option_sndtimeo.phpt b/ext/sockets/tests/socket_set_option_sndtimeo.phpt index e7487f75b05c..ec162b4dbd78 100644 --- a/ext/sockets/tests/socket_set_option_sndtimeo.phpt +++ b/ext/sockets/tests/socket_set_option_sndtimeo.phpt @@ -16,8 +16,8 @@ socket_set_block($socket); //wrong params try { $retval_1 = socket_set_option( $socket, SOL_SOCKET, SO_SNDTIMEO, []); -} catch (\ValueError $e) { - echo $e->getMessage() . \PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } //set/get comparison @@ -30,6 +30,6 @@ var_dump($retval_3 === $options); socket_close($socket); ?> --EXPECT-- -socket_set_option(): Argument #4 ($value) must have key "sec" +ValueError: socket_set_option(): Argument #4 ($value) must have key "sec" bool(true) bool(true) diff --git a/ext/sockets/tests/socket_set_option_timeo_error.phpt b/ext/sockets/tests/socket_set_option_timeo_error.phpt index befdfb095855..5e95dd65a811 100644 --- a/ext/sockets/tests/socket_set_option_timeo_error.phpt +++ b/ext/sockets/tests/socket_set_option_timeo_error.phpt @@ -17,57 +17,57 @@ $options_6 = array("l_onoff" => "1", "l_linger" => PHP_INT_MAX); try { socket_set_option( $socket, SOL_SOCKET, SO_RCVTIMEO, new stdClass); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_RCVTIMEO, $options_1); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_SNDTIMEO, $options_2); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_RCVTIMEO, "not good"); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_LINGER, "not good neither"); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_3); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_4); -} catch (\TypeError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_5); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_6); -} catch (\ValueError $e) { - echo $e->getMessage() . PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- -socket_set_option(): Argument #4 ($value) must have key "sec" +ValueError: socket_set_option(): Argument #4 ($value) must have key "sec" Warning: Object of class stdClass could not be converted to int in %s on line %d -socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is SO_RCVTIMEO, string given -socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is SO_LINGER, string given -socket_set_option(): Argument #4 ($value) "l_onoff" must be between 0 and %d -socket_set_option(): Argument #4 ($value) "l_linger" must be between 0 and %d +TypeError: socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is SO_RCVTIMEO, string given +TypeError: socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is SO_LINGER, string given +ValueError: socket_set_option(): Argument #4 ($value) "l_onoff" must be between 0 and %d +ValueError: socket_set_option(): Argument #4 ($value) "l_linger" must be between 0 and %d diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt index 894a24d2a49b..624911545230 100644 --- a/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt @@ -17,14 +17,14 @@ socket_set_block($socket); try { socket_setopt($socket, SOL_TCP, TCP_USER_TIMEOUT, -1); -} catch (\ValueError $e) { - echo $e->getMessage(), PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { socket_setopt($socket, SOL_TCP, TCP_USER_TIMEOUT, PHP_INT_MAX); -} catch (\ValueError $e) { - echo $e->getMessage(), PHP_EOL; +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } $timeout = 200; @@ -35,7 +35,7 @@ var_dump($retval_3 === $timeout); socket_close($socket); ?> --EXPECTF-- -socket_setopt(): Argument #4 ($value) must be between 0 and %d -socket_setopt(): Argument #4 ($value) must be between 0 and %d +ValueError: socket_setopt(): Argument #4 ($value) must be between 0 and %d +ValueError: socket_setopt(): Argument #4 ($value) must be between 0 and %d bool(true) bool(true) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 7b8f41f2f4bb..814258d6a84f 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -4830,3 +4830,311 @@ PHP_FUNCTION(sodium_crypto_xof_turboshake256_squeeze) RETURN_NEW_STR(out); } #endif + +#ifdef crypto_kem_PUBLICKEYBYTES +PHP_FUNCTION(sodium_crypto_kem_keypair) +{ + zend_string *keypair; + size_t keypair_len; + + ZEND_PARSE_PARAMETERS_NONE(); + + keypair_len = crypto_kem_SECRETKEYBYTES + crypto_kem_PUBLICKEYBYTES; + keypair = zend_string_alloc(keypair_len, 0); + if (crypto_kem_keypair((unsigned char *) ZSTR_VAL(keypair) + + crypto_kem_SECRETKEYBYTES, + (unsigned char *) ZSTR_VAL(keypair)) != 0) { + sodium_memzero(ZSTR_VAL(keypair), keypair_len); + zend_string_efree(keypair); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(keypair)[keypair_len] = 0; + + RETURN_NEW_STR(keypair); +} + +PHP_FUNCTION(sodium_crypto_kem_seed_keypair) +{ + zend_string *keypair; + unsigned char *seed; + size_t keypair_len; + size_t seed_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &seed, &seed_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (seed_len != crypto_kem_SEEDBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_SEEDBYTES bytes long"); + RETURN_THROWS(); + } + keypair_len = crypto_kem_SECRETKEYBYTES + crypto_kem_PUBLICKEYBYTES; + keypair = zend_string_alloc(keypair_len, 0); + if (crypto_kem_seed_keypair((unsigned char *) ZSTR_VAL(keypair) + + crypto_kem_SECRETKEYBYTES, + (unsigned char *) ZSTR_VAL(keypair), + seed) != 0) { + sodium_memzero(ZSTR_VAL(keypair), keypair_len); + zend_string_efree(keypair); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(keypair)[keypair_len] = 0; + + RETURN_NEW_STR(keypair); +} + +PHP_FUNCTION(sodium_crypto_kem_secretkey) +{ + unsigned char *keypair; + size_t keypair_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &keypair, &keypair_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (keypair_len != + crypto_kem_SECRETKEYBYTES + crypto_kem_PUBLICKEYBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_KEYPAIRBYTES bytes long"); + RETURN_THROWS(); + } + RETURN_STRINGL((const char *) keypair, crypto_kem_SECRETKEYBYTES); +} + +PHP_FUNCTION(sodium_crypto_kem_publickey) +{ + unsigned char *keypair; + size_t keypair_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &keypair, &keypair_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (keypair_len != + crypto_kem_SECRETKEYBYTES + crypto_kem_PUBLICKEYBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_KEYPAIRBYTES bytes long"); + RETURN_THROWS(); + } + RETURN_STRINGL((const char *) keypair + crypto_kem_SECRETKEYBYTES, crypto_kem_PUBLICKEYBYTES); +} + +PHP_FUNCTION(sodium_crypto_kem_enc) +{ + unsigned char ciphertext[crypto_kem_CIPHERTEXTBYTES]; + unsigned char shared_secret[crypto_kem_SHAREDSECRETBYTES]; + unsigned char *publickey; + size_t publickey_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &publickey, &publickey_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (publickey_len != crypto_kem_PUBLICKEYBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_PUBLICKEYBYTES bytes long"); + RETURN_THROWS(); + } + if (crypto_kem_enc(ciphertext, shared_secret, publickey) != 0) { + sodium_memzero(shared_secret, sizeof shared_secret); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + array_init(return_value); + add_next_index_stringl(return_value, (const char *) ciphertext, sizeof ciphertext); + add_next_index_stringl(return_value, (const char *) shared_secret, sizeof shared_secret); + sodium_memzero(shared_secret, sizeof shared_secret); +} + +PHP_FUNCTION(sodium_crypto_kem_dec) +{ + zend_string *shared_secret; + unsigned char *ciphertext; + unsigned char *secretkey; + size_t ciphertext_len; + size_t secretkey_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ciphertext, &ciphertext_len, + &secretkey, &secretkey_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (ciphertext_len != crypto_kem_CIPHERTEXTBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES bytes long"); + RETURN_THROWS(); + } + if (secretkey_len != crypto_kem_SECRETKEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_KEM_SECRETKEYBYTES bytes long"); + RETURN_THROWS(); + } + shared_secret = zend_string_alloc(crypto_kem_SHAREDSECRETBYTES, 0); + if (crypto_kem_dec((unsigned char *) ZSTR_VAL(shared_secret), + ciphertext, secretkey) != 0) { + sodium_memzero(ZSTR_VAL(shared_secret), crypto_kem_SHAREDSECRETBYTES); + zend_string_efree(shared_secret); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(shared_secret)[crypto_kem_SHAREDSECRETBYTES] = 0; + + RETURN_NEW_STR(shared_secret); +} +#endif + +#ifdef crypto_kem_mlkem768_PUBLICKEYBYTES +PHP_FUNCTION(sodium_crypto_kem_mlkem768_keypair) +{ + zend_string *keypair; + size_t keypair_len; + + ZEND_PARSE_PARAMETERS_NONE(); + + keypair_len = crypto_kem_mlkem768_SECRETKEYBYTES + crypto_kem_mlkem768_PUBLICKEYBYTES; + keypair = zend_string_alloc(keypair_len, 0); + if (crypto_kem_mlkem768_keypair((unsigned char *) ZSTR_VAL(keypair) + + crypto_kem_mlkem768_SECRETKEYBYTES, + (unsigned char *) ZSTR_VAL(keypair)) != 0) { + sodium_memzero(ZSTR_VAL(keypair), keypair_len); + zend_string_efree(keypair); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(keypair)[keypair_len] = 0; + + RETURN_NEW_STR(keypair); +} + +PHP_FUNCTION(sodium_crypto_kem_mlkem768_seed_keypair) +{ + zend_string *keypair; + unsigned char *seed; + size_t keypair_len; + size_t seed_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &seed, &seed_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (seed_len != crypto_kem_mlkem768_SEEDBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES bytes long"); + RETURN_THROWS(); + } + keypair_len = crypto_kem_mlkem768_SECRETKEYBYTES + crypto_kem_mlkem768_PUBLICKEYBYTES; + keypair = zend_string_alloc(keypair_len, 0); + if (crypto_kem_mlkem768_seed_keypair((unsigned char *) ZSTR_VAL(keypair) + + crypto_kem_mlkem768_SECRETKEYBYTES, + (unsigned char *) ZSTR_VAL(keypair), + seed) != 0) { + sodium_memzero(ZSTR_VAL(keypair), keypair_len); + zend_string_efree(keypair); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(keypair)[keypair_len] = 0; + + RETURN_NEW_STR(keypair); +} + +PHP_FUNCTION(sodium_crypto_kem_mlkem768_secretkey) +{ + unsigned char *keypair; + size_t keypair_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &keypair, &keypair_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (keypair_len != + crypto_kem_mlkem768_SECRETKEYBYTES + crypto_kem_mlkem768_PUBLICKEYBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES bytes long"); + RETURN_THROWS(); + } + RETURN_STRINGL((const char *) keypair, crypto_kem_mlkem768_SECRETKEYBYTES); +} + +PHP_FUNCTION(sodium_crypto_kem_mlkem768_publickey) +{ + unsigned char *keypair; + size_t keypair_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &keypair, &keypair_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (keypair_len != + crypto_kem_mlkem768_SECRETKEYBYTES + crypto_kem_mlkem768_PUBLICKEYBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES bytes long"); + RETURN_THROWS(); + } + RETURN_STRINGL((const char *) keypair + crypto_kem_mlkem768_SECRETKEYBYTES, crypto_kem_mlkem768_PUBLICKEYBYTES); +} + +PHP_FUNCTION(sodium_crypto_kem_mlkem768_enc) +{ + unsigned char ciphertext[crypto_kem_mlkem768_CIPHERTEXTBYTES]; + unsigned char shared_secret[crypto_kem_mlkem768_SHAREDSECRETBYTES]; + unsigned char *publickey; + size_t publickey_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &publickey, &publickey_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (publickey_len != crypto_kem_mlkem768_PUBLICKEYBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES bytes long"); + RETURN_THROWS(); + } + if (crypto_kem_mlkem768_enc(ciphertext, shared_secret, publickey) != 0) { + sodium_memzero(shared_secret, sizeof shared_secret); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + array_init(return_value); + add_next_index_stringl(return_value, (const char *) ciphertext, sizeof ciphertext); + add_next_index_stringl(return_value, (const char *) shared_secret, sizeof shared_secret); + sodium_memzero(shared_secret, sizeof shared_secret); +} + +PHP_FUNCTION(sodium_crypto_kem_mlkem768_dec) +{ + zend_string *shared_secret; + unsigned char *ciphertext; + unsigned char *secretkey; + size_t ciphertext_len; + size_t secretkey_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ciphertext, &ciphertext_len, + &secretkey, &secretkey_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (ciphertext_len != crypto_kem_mlkem768_CIPHERTEXTBYTES) { + zend_argument_error(sodium_exception_ce, 1, "must be SODIUM_CRYPTO_KEM_MLKEM768_CIPHERTEXTBYTES bytes long"); + RETURN_THROWS(); + } + if (secretkey_len != crypto_kem_mlkem768_SECRETKEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_KEM_MLKEM768_SECRETKEYBYTES bytes long"); + RETURN_THROWS(); + } + shared_secret = zend_string_alloc(crypto_kem_mlkem768_SHAREDSECRETBYTES, 0); + if (crypto_kem_mlkem768_dec((unsigned char *) ZSTR_VAL(shared_secret), + ciphertext, secretkey) != 0) { + sodium_memzero(ZSTR_VAL(shared_secret), crypto_kem_mlkem768_SHAREDSECRETBYTES); + zend_string_efree(shared_secret); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(shared_secret)[crypto_kem_mlkem768_SHAREDSECRETBYTES] = 0; + + RETURN_NEW_STR(shared_secret); +} +#endif diff --git a/ext/sodium/libsodium.stub.php b/ext/sodium/libsodium.stub.php index 9fda5f4ddd73..80d8de2c0b29 100644 --- a/ext/sodium/libsodium.stub.php +++ b/ext/sodium/libsodium.stub.php @@ -967,4 +967,94 @@ function sodium_crypto_xof_turboshake256_update(string &$state, string $message) function sodium_crypto_xof_turboshake256_squeeze(string &$state, int $length): string {} #endif +#ifdef crypto_kem_PUBLICKEYBYTES +/** + * @var int + * @cvalue crypto_kem_PUBLICKEYBYTES + */ +const SODIUM_CRYPTO_KEM_PUBLICKEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_SECRETKEYBYTES + */ +const SODIUM_CRYPTO_KEM_SECRETKEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_CIPHERTEXTBYTES + */ +const SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_SHAREDSECRETBYTES + */ +const SODIUM_CRYPTO_KEM_SHAREDSECRETBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_SEEDBYTES + */ +const SODIUM_CRYPTO_KEM_SEEDBYTES = UNKNOWN; +/** + * @var int + * @cvalue SODIUM_CRYPTO_KEM_KEYPAIRBYTES() + */ +const SODIUM_CRYPTO_KEM_KEYPAIRBYTES = UNKNOWN; + +function sodium_crypto_kem_keypair(): string {} + +function sodium_crypto_kem_seed_keypair(#[\SensitiveParameter] string $seed): string {} + +function sodium_crypto_kem_secretkey(#[\SensitiveParameter] string $key_pair): string {} + +function sodium_crypto_kem_publickey(#[\SensitiveParameter] string $key_pair): string {} + +function sodium_crypto_kem_enc(string $public_key): array {} + +function sodium_crypto_kem_dec(string $ciphertext, #[\SensitiveParameter] string $secret_key): string {} +#endif + +#ifdef crypto_kem_mlkem768_PUBLICKEYBYTES +/** + * @var int + * @cvalue crypto_kem_mlkem768_PUBLICKEYBYTES + */ +const SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_mlkem768_SECRETKEYBYTES + */ +const SODIUM_CRYPTO_KEM_MLKEM768_SECRETKEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_mlkem768_CIPHERTEXTBYTES + */ +const SODIUM_CRYPTO_KEM_MLKEM768_CIPHERTEXTBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_mlkem768_SHAREDSECRETBYTES + */ +const SODIUM_CRYPTO_KEM_MLKEM768_SHAREDSECRETBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_kem_mlkem768_SEEDBYTES + */ +const SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES = UNKNOWN; +/** + * @var int + * @cvalue SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES() + */ +const SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES = UNKNOWN; + +function sodium_crypto_kem_mlkem768_keypair(): string {} + +function sodium_crypto_kem_mlkem768_seed_keypair(#[\SensitiveParameter] string $seed): string {} + +function sodium_crypto_kem_mlkem768_secretkey(#[\SensitiveParameter] string $key_pair): string {} + +function sodium_crypto_kem_mlkem768_publickey(#[\SensitiveParameter] string $key_pair): string {} + +function sodium_crypto_kem_mlkem768_enc(string $public_key): array {} + +function sodium_crypto_kem_mlkem768_dec(string $ciphertext, #[\SensitiveParameter] string $secret_key): string {} +#endif + class SodiumException extends Exception {} diff --git a/ext/sodium/libsodium_arginfo.h b/ext/sodium/libsodium_arginfo.h index 1b291e9a2330..548cd132c555 100644 --- a/ext/sodium/libsodium_arginfo.h +++ b/ext/sodium/libsodium_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit libsodium.stub.php instead. - * Stub hash: 7b337a297ae333dd8d0c232979b770332c9e7eb6 */ + * Stub hash: 82dc3f80ea85b0c71ed9db9b111097f3eb49d71d */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_aead_aes256gcm_is_available, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -572,6 +572,54 @@ ZEND_END_ARG_INFO() #define arginfo_sodium_crypto_xof_turboshake256_squeeze arginfo_sodium_crypto_xof_shake128_squeeze #endif +#if defined(crypto_kem_PUBLICKEYBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_keypair, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_seed_keypair, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, seed, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_secretkey, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, key_pair, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_sodium_crypto_kem_publickey arginfo_sodium_crypto_kem_secretkey + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_enc, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, public_key, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_dec, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, ciphertext, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, secret_key, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_kem_mlkem768_PUBLICKEYBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_mlkem768_keypair, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_mlkem768_seed_keypair, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, seed, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_mlkem768_secretkey, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, key_pair, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_sodium_crypto_kem_mlkem768_publickey arginfo_sodium_crypto_kem_mlkem768_secretkey + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_mlkem768_enc, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, public_key, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_kem_mlkem768_dec, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, ciphertext, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, secret_key, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_is_available); #if defined(HAVE_AESGCM) ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_decrypt); @@ -739,6 +787,22 @@ ZEND_FUNCTION(sodium_crypto_xof_turboshake256_init); ZEND_FUNCTION(sodium_crypto_xof_turboshake256_update); ZEND_FUNCTION(sodium_crypto_xof_turboshake256_squeeze); #endif +#if defined(crypto_kem_PUBLICKEYBYTES) +ZEND_FUNCTION(sodium_crypto_kem_keypair); +ZEND_FUNCTION(sodium_crypto_kem_seed_keypair); +ZEND_FUNCTION(sodium_crypto_kem_secretkey); +ZEND_FUNCTION(sodium_crypto_kem_publickey); +ZEND_FUNCTION(sodium_crypto_kem_enc); +ZEND_FUNCTION(sodium_crypto_kem_dec); +#endif +#if defined(crypto_kem_mlkem768_PUBLICKEYBYTES) +ZEND_FUNCTION(sodium_crypto_kem_mlkem768_keypair); +ZEND_FUNCTION(sodium_crypto_kem_mlkem768_seed_keypair); +ZEND_FUNCTION(sodium_crypto_kem_mlkem768_secretkey); +ZEND_FUNCTION(sodium_crypto_kem_mlkem768_publickey); +ZEND_FUNCTION(sodium_crypto_kem_mlkem768_enc); +ZEND_FUNCTION(sodium_crypto_kem_mlkem768_dec); +#endif static const zend_function_entry ext_functions[] = { ZEND_FE(sodium_crypto_aead_aes256gcm_is_available, arginfo_sodium_crypto_aead_aes256gcm_is_available) @@ -908,6 +972,22 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(sodium_crypto_xof_turboshake256_init, arginfo_sodium_crypto_xof_turboshake256_init) ZEND_FE(sodium_crypto_xof_turboshake256_update, arginfo_sodium_crypto_xof_turboshake256_update) ZEND_FE(sodium_crypto_xof_turboshake256_squeeze, arginfo_sodium_crypto_xof_turboshake256_squeeze) +#endif +#if defined(crypto_kem_PUBLICKEYBYTES) + ZEND_FE(sodium_crypto_kem_keypair, arginfo_sodium_crypto_kem_keypair) + ZEND_FE(sodium_crypto_kem_seed_keypair, arginfo_sodium_crypto_kem_seed_keypair) + ZEND_FE(sodium_crypto_kem_secretkey, arginfo_sodium_crypto_kem_secretkey) + ZEND_FE(sodium_crypto_kem_publickey, arginfo_sodium_crypto_kem_publickey) + ZEND_FE(sodium_crypto_kem_enc, arginfo_sodium_crypto_kem_enc) + ZEND_FE(sodium_crypto_kem_dec, arginfo_sodium_crypto_kem_dec) +#endif +#if defined(crypto_kem_mlkem768_PUBLICKEYBYTES) + ZEND_FE(sodium_crypto_kem_mlkem768_keypair, arginfo_sodium_crypto_kem_mlkem768_keypair) + ZEND_FE(sodium_crypto_kem_mlkem768_seed_keypair, arginfo_sodium_crypto_kem_mlkem768_seed_keypair) + ZEND_FE(sodium_crypto_kem_mlkem768_secretkey, arginfo_sodium_crypto_kem_mlkem768_secretkey) + ZEND_FE(sodium_crypto_kem_mlkem768_publickey, arginfo_sodium_crypto_kem_mlkem768_publickey) + ZEND_FE(sodium_crypto_kem_mlkem768_enc, arginfo_sodium_crypto_kem_mlkem768_enc) + ZEND_FE(sodium_crypto_kem_mlkem768_dec, arginfo_sodium_crypto_kem_mlkem768_dec) #endif ZEND_FE_END }; @@ -1064,6 +1144,22 @@ static void register_libsodium_symbols(int module_number) REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES", crypto_xof_turboshake256_BLOCKBYTES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES", crypto_xof_turboshake256_STATEBYTES, CONST_PERSISTENT); #endif +#if defined(crypto_kem_PUBLICKEYBYTES) + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_PUBLICKEYBYTES", crypto_kem_PUBLICKEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_SECRETKEYBYTES", crypto_kem_SECRETKEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES", crypto_kem_CIPHERTEXTBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_SHAREDSECRETBYTES", crypto_kem_SHAREDSECRETBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_SEEDBYTES", crypto_kem_SEEDBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_KEYPAIRBYTES", SODIUM_CRYPTO_KEM_KEYPAIRBYTES(), CONST_PERSISTENT); +#endif +#if defined(crypto_kem_mlkem768_PUBLICKEYBYTES) + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES", crypto_kem_mlkem768_PUBLICKEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_MLKEM768_SECRETKEYBYTES", crypto_kem_mlkem768_SECRETKEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_MLKEM768_CIPHERTEXTBYTES", crypto_kem_mlkem768_CIPHERTEXTBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_MLKEM768_SHAREDSECRETBYTES", crypto_kem_mlkem768_SHAREDSECRETBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES", crypto_kem_mlkem768_SEEDBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES", SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES(), CONST_PERSISTENT); +#endif #if defined(HAVE_AESGCM) @@ -1259,6 +1355,26 @@ static void register_libsodium_symbols(int module_number) zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_pfx_decrypt", sizeof("sodium_crypto_ipcrypt_pfx_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); #endif +#if defined(crypto_kem_PUBLICKEYBYTES) + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_seed_keypair", sizeof("sodium_crypto_kem_seed_keypair") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_secretkey", sizeof("sodium_crypto_kem_secretkey") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_publickey", sizeof("sodium_crypto_kem_publickey") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_dec", sizeof("sodium_crypto_kem_dec") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#endif +#if defined(crypto_kem_mlkem768_PUBLICKEYBYTES) + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_mlkem768_seed_keypair", sizeof("sodium_crypto_kem_mlkem768_seed_keypair") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_mlkem768_secretkey", sizeof("sodium_crypto_kem_mlkem768_secretkey") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_mlkem768_publickey", sizeof("sodium_crypto_kem_mlkem768_publickey") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_kem_mlkem768_dec", sizeof("sodium_crypto_kem_mlkem768_dec") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#endif } static zend_class_entry *register_class_SodiumException(zend_class_entry *class_entry_Exception) diff --git a/ext/sodium/php_libsodium.h b/ext/sodium/php_libsodium.h index 8132472d684f..ed070df7744a 100644 --- a/ext/sodium/php_libsodium.h +++ b/ext/sodium/php_libsodium.h @@ -34,6 +34,14 @@ extern zend_module_entry sodium_module_entry; #define SODIUM_CRYPTO_SIGN_KEYPAIRBYTES() crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES +#ifdef crypto_kem_PUBLICKEYBYTES +#define SODIUM_CRYPTO_KEM_KEYPAIRBYTES() crypto_kem_SECRETKEYBYTES + crypto_kem_PUBLICKEYBYTES +#endif + +#ifdef crypto_kem_mlkem768_PUBLICKEYBYTES +#define SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES() crypto_kem_mlkem768_SECRETKEYBYTES + crypto_kem_mlkem768_PUBLICKEYBYTES +#endif + #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6) /** diff --git a/ext/sodium/tests/crypto_kem.phpt b/ext/sodium/tests/crypto_kem.phpt new file mode 100644 index 000000000000..4a3036a98b64 --- /dev/null +++ b/ext/sodium/tests/crypto_kem.phpt @@ -0,0 +1,135 @@ +--TEST-- +Check for libsodium crypto_kem (X-Wing) +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.22)"; +?> +--FILE-- + extractors -> enc -> dec */ +$keypair = sodium_crypto_kem_keypair(); +var_dump(strlen($keypair) === SODIUM_CRYPTO_KEM_KEYPAIRBYTES); +$secret_key = sodium_crypto_kem_secretkey($keypair); +$public_key = sodium_crypto_kem_publickey($keypair); +var_dump(strlen($secret_key) === SODIUM_CRYPTO_KEM_SECRETKEYBYTES); +var_dump(strlen($public_key) === SODIUM_CRYPTO_KEM_PUBLICKEYBYTES); + +[$ciphertext, $shared_secret] = sodium_crypto_kem_enc($public_key); +var_dump(strlen($ciphertext) === SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES); +var_dump(strlen($shared_secret) === SODIUM_CRYPTO_KEM_SHAREDSECRETBYTES); +var_dump(sodium_crypto_kem_dec($ciphertext, $secret_key) === $shared_secret); + +/* Encapsulation is randomized: same public key, fresh ciphertext and secret */ +[$ciphertext2, $shared_secret2] = sodium_crypto_kem_enc($public_key); +var_dump($ciphertext2 !== $ciphertext); +var_dump($shared_secret2 !== $shared_secret); +var_dump(sodium_crypto_kem_dec($ciphertext2, $secret_key) === $shared_secret2); + +/* Key generation is randomized */ +var_dump(sodium_crypto_kem_keypair() !== $keypair); + +/* seed_keypair is deterministic and round-trips */ +$seed = random_bytes(SODIUM_CRYPTO_KEM_SEEDBYTES); +$seeded_keypair = sodium_crypto_kem_seed_keypair($seed); +var_dump(strlen($seeded_keypair) === SODIUM_CRYPTO_KEM_KEYPAIRBYTES); +var_dump(sodium_crypto_kem_seed_keypair($seed) === $seeded_keypair); +[$seeded_ciphertext, $seeded_shared_secret] = + sodium_crypto_kem_enc(sodium_crypto_kem_publickey($seeded_keypair)); +var_dump(sodium_crypto_kem_dec($seeded_ciphertext, + sodium_crypto_kem_secretkey($seeded_keypair)) === $seeded_shared_secret); + +/* Implicit rejection: a tampered ciphertext still decapsulates to a + * shared secret of the right length, but not the original one */ +$tampered_ciphertext = $ciphertext; +$tampered_ciphertext[0] = $tampered_ciphertext[0] === "\x00" ? "\x01" : "\x00"; +$tampered_shared_secret = sodium_crypto_kem_dec($tampered_ciphertext, $secret_key); +var_dump(strlen($tampered_shared_secret) === SODIUM_CRYPTO_KEM_SHAREDSECRETBYTES); +var_dump($tampered_shared_secret !== $shared_secret); + +/* Error: truncated public key */ +try { + sodium_crypto_kem_enc(substr($public_key, 0, -1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: truncated ciphertext */ +try { + sodium_crypto_kem_dec(substr($ciphertext, 0, -1), $secret_key); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: truncated secret key */ +try { + sodium_crypto_kem_dec($ciphertext, substr($secret_key, 0, -1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: truncated keypair */ +try { + sodium_crypto_kem_secretkey(substr($keypair, 0, -1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: overlong keypair */ +try { + sodium_crypto_kem_publickey($keypair . 'x'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: wrong-length seed */ +try { + sodium_crypto_kem_seed_keypair(random_bytes(SODIUM_CRYPTO_KEM_SEEDBYTES - 1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: a public key with an invalid ML-KEM encoding is rejected */ +try { + sodium_crypto_kem_enc(str_repeat("\xff", SODIUM_CRYPTO_KEM_PUBLICKEYBYTES)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: a ciphertext whose X25519 component is a small-order point is rejected */ +$small_order_ciphertext = substr($ciphertext, 0, SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES - 32) + . str_repeat("\0", 32); +try { + sodium_crypto_kem_dec($small_order_ciphertext, $secret_key); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +?> +--EXPECT-- +crypto_kem (X-Wing): +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +SodiumException: sodium_crypto_kem_enc(): Argument #1 ($public_key) must be SODIUM_CRYPTO_KEM_PUBLICKEYBYTES bytes long +SodiumException: sodium_crypto_kem_dec(): Argument #1 ($ciphertext) must be SODIUM_CRYPTO_KEM_CIPHERTEXTBYTES bytes long +SodiumException: sodium_crypto_kem_dec(): Argument #2 ($secret_key) must be SODIUM_CRYPTO_KEM_SECRETKEYBYTES bytes long +SodiumException: sodium_crypto_kem_secretkey(): Argument #1 ($key_pair) must be SODIUM_CRYPTO_KEM_KEYPAIRBYTES bytes long +SodiumException: sodium_crypto_kem_publickey(): Argument #1 ($key_pair) must be SODIUM_CRYPTO_KEM_KEYPAIRBYTES bytes long +SodiumException: sodium_crypto_kem_seed_keypair(): Argument #1 ($seed) must be SODIUM_CRYPTO_KEM_SEEDBYTES bytes long +SodiumException: internal error +SodiumException: internal error diff --git a/ext/sodium/tests/crypto_kem_mlkem768.phpt b/ext/sodium/tests/crypto_kem_mlkem768.phpt new file mode 100644 index 000000000000..2898eebb69c2 --- /dev/null +++ b/ext/sodium/tests/crypto_kem_mlkem768.phpt @@ -0,0 +1,126 @@ +--TEST-- +Check for libsodium crypto_kem_mlkem768 +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.22)"; +?> +--FILE-- + extractors -> enc -> dec */ +$keypair = sodium_crypto_kem_mlkem768_keypair(); +var_dump(strlen($keypair) === SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES); +$secret_key = sodium_crypto_kem_mlkem768_secretkey($keypair); +$public_key = sodium_crypto_kem_mlkem768_publickey($keypair); +var_dump(strlen($secret_key) === SODIUM_CRYPTO_KEM_MLKEM768_SECRETKEYBYTES); +var_dump(strlen($public_key) === SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES); + +[$ciphertext, $shared_secret] = sodium_crypto_kem_mlkem768_enc($public_key); +var_dump(strlen($ciphertext) === SODIUM_CRYPTO_KEM_MLKEM768_CIPHERTEXTBYTES); +var_dump(strlen($shared_secret) === SODIUM_CRYPTO_KEM_MLKEM768_SHAREDSECRETBYTES); +var_dump(sodium_crypto_kem_mlkem768_dec($ciphertext, $secret_key) === $shared_secret); + +/* Encapsulation is randomized: same public key, fresh ciphertext and secret */ +[$ciphertext2, $shared_secret2] = sodium_crypto_kem_mlkem768_enc($public_key); +var_dump($ciphertext2 !== $ciphertext); +var_dump($shared_secret2 !== $shared_secret); +var_dump(sodium_crypto_kem_mlkem768_dec($ciphertext2, $secret_key) === $shared_secret2); + +/* Key generation is randomized */ +var_dump(sodium_crypto_kem_mlkem768_keypair() !== $keypair); + +/* seed_keypair is deterministic and round-trips */ +$seed = random_bytes(SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES); +$seeded_keypair = sodium_crypto_kem_mlkem768_seed_keypair($seed); +var_dump(strlen($seeded_keypair) === SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES); +var_dump(sodium_crypto_kem_mlkem768_seed_keypair($seed) === $seeded_keypair); +[$seeded_ciphertext, $seeded_shared_secret] = + sodium_crypto_kem_mlkem768_enc(sodium_crypto_kem_mlkem768_publickey($seeded_keypair)); +var_dump(sodium_crypto_kem_mlkem768_dec($seeded_ciphertext, + sodium_crypto_kem_mlkem768_secretkey($seeded_keypair)) === $seeded_shared_secret); + +/* Implicit rejection: a tampered ciphertext still decapsulates to a + * shared secret of the right length, but not the original one */ +$tampered_ciphertext = $ciphertext; +$tampered_ciphertext[0] = $tampered_ciphertext[0] === "\x00" ? "\x01" : "\x00"; +$tampered_shared_secret = sodium_crypto_kem_mlkem768_dec($tampered_ciphertext, $secret_key); +var_dump(strlen($tampered_shared_secret) === SODIUM_CRYPTO_KEM_MLKEM768_SHAREDSECRETBYTES); +var_dump($tampered_shared_secret !== $shared_secret); + +/* Error: truncated public key */ +try { + sodium_crypto_kem_mlkem768_enc(substr($public_key, 0, -1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: truncated ciphertext */ +try { + sodium_crypto_kem_mlkem768_dec(substr($ciphertext, 0, -1), $secret_key); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: truncated secret key */ +try { + sodium_crypto_kem_mlkem768_dec($ciphertext, substr($secret_key, 0, -1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: truncated keypair */ +try { + sodium_crypto_kem_mlkem768_secretkey(substr($keypair, 0, -1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: overlong keypair */ +try { + sodium_crypto_kem_mlkem768_publickey($keypair . 'x'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: wrong-length seed */ +try { + sodium_crypto_kem_mlkem768_seed_keypair(random_bytes(SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES - 1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +/* Error: a public key with an invalid ML-KEM encoding is rejected */ +try { + sodium_crypto_kem_mlkem768_enc(str_repeat("\xff", SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +?> +--EXPECT-- +crypto_kem_mlkem768: +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +SodiumException: sodium_crypto_kem_mlkem768_enc(): Argument #1 ($public_key) must be SODIUM_CRYPTO_KEM_MLKEM768_PUBLICKEYBYTES bytes long +SodiumException: sodium_crypto_kem_mlkem768_dec(): Argument #1 ($ciphertext) must be SODIUM_CRYPTO_KEM_MLKEM768_CIPHERTEXTBYTES bytes long +SodiumException: sodium_crypto_kem_mlkem768_dec(): Argument #2 ($secret_key) must be SODIUM_CRYPTO_KEM_MLKEM768_SECRETKEYBYTES bytes long +SodiumException: sodium_crypto_kem_mlkem768_secretkey(): Argument #1 ($key_pair) must be SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES bytes long +SodiumException: sodium_crypto_kem_mlkem768_publickey(): Argument #1 ($key_pair) must be SODIUM_CRYPTO_KEM_MLKEM768_KEYPAIRBYTES bytes long +SodiumException: sodium_crypto_kem_mlkem768_seed_keypair(): Argument #1 ($seed) must be SODIUM_CRYPTO_KEM_MLKEM768_SEEDBYTES bytes long +SodiumException: internal error diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 79d45b76396a..42115fed5379 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -98,7 +98,7 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) efree(hashkey); } - zend_argument_value_error(6, "must be -1 or between 0 and " ZEND_ULONG_FMT, ((double) PHP_TIMEOUT_ULL_MAX / 1000000.0)); + zend_argument_value_error(5, "must be -1 or between 0 and %" PRIu64, (uint64_t) ((double) PHP_TIMEOUT_ULL_MAX / 1000000.0)); RETURN_THROWS(); } else { #ifndef PHP_WIN32 diff --git a/ext/standard/tests/http/http_auto_decode.phpt b/ext/standard/tests/http/http_auto_decode.phpt new file mode 100644 index 000000000000..c1fa2a64011e --- /dev/null +++ b/ext/standard/tests/http/http_auto_decode.phpt @@ -0,0 +1,61 @@ +--TEST-- +http.auto_decode stream context option controls chunked response decoding +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses); + +function test_auto_decode($auto_decode) { + global $uri; + $ctx = null; + if ($auto_decode !== null) { + $ctx = stream_context_create(['http' => ['auto_decode' => $auto_decode]]); + } + $body = file_get_contents($uri, false, $ctx); + + $has_te = false; + foreach (http_get_last_response_headers() as $h) { + if (stripos($h, 'Transfer-Encoding:') === 0) { + $has_te = true; + break; + } + } + + return [addcslashes($body, "\r\n"), $has_te]; +} + +var_dump(test_auto_decode(null)); +var_dump(test_auto_decode(true)); +var_dump(test_auto_decode(false)); + +http_server_kill($pid); +?> +--EXPECT-- +array(2) { + [0]=> + string(4) "abcd" + [1]=> + bool(false) +} +array(2) { + [0]=> + string(4) "abcd" + [1]=> + bool(false) +} +array(2) { + [0]=> + string(31) "2\r\nab\r\n2\r\ncd\r\n0\r\n\r\n" + [1]=> + bool(true) +} diff --git a/ext/standard/tests/http/http_location_realloc.phpt b/ext/standard/tests/http/http_location_realloc.phpt new file mode 100644 index 000000000000..df4e1057c337 --- /dev/null +++ b/ext/standard/tests/http/http_location_realloc.phpt @@ -0,0 +1,35 @@ +--TEST-- +HTTP response with two Location headers (second longer) triggers erealloc +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +$ctx = stream_context_create(['http' => ['follow_location' => 0]]); +$result = file_get_contents("$uri/", false, $ctx); +var_dump($result); +var_dump(http_get_last_response_headers()); + +http_server_kill($pid); +?> +--EXPECT-- +string(0) "" +array(4) { + [0]=> + string(30) "HTTP/1.1 301 Moved Permanently" + [1]=> + string(16) "Location: /short" + [2]=> + string(40) "Location: /a_much_longer_path_than_short" + [3]=> + string(17) "Content-Length: 0" +} diff --git a/ext/standard/tests/http/http_proxy_auth_removed.phpt b/ext/standard/tests/http/http_proxy_auth_removed.phpt new file mode 100644 index 000000000000..5c541e299505 --- /dev/null +++ b/ext/standard/tests/http/http_proxy_auth_removed.phpt @@ -0,0 +1,72 @@ +--TEST-- +Proxy-Authorization header removed from request after CONNECT tunnel +--EXTENSIONS-- +openssl +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + [ + 'proxy' => "tcp://$host:$port", + 'header' => [ + "Proxy-Authorization: Basic Zm9vOmJhcg==", + ], + ], + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + ], +]); + +file_get_contents("https://www.php.net/", false, $ctx); + +http_server_kill($server['pid']); +?> +--EXPECT-- +CONNECT contains Proxy-Authorization: bool(true) +Proxied request contains Proxy-Authorization: bool(false) diff --git a/ext/standard/tests/http/http_proxy_ssl_connect_01.phpt b/ext/standard/tests/http/http_proxy_ssl_connect_01.phpt new file mode 100644 index 000000000000..0d647b79d02f --- /dev/null +++ b/ext/standard/tests/http/http_proxy_ssl_connect_01.phpt @@ -0,0 +1,48 @@ +--TEST-- +HTTP proxy SSL CONNECT with Proxy-Authorization header (string, multi-line) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +$host = parse_url($uri, PHP_URL_HOST); +$port = parse_url($uri, PHP_URL_PORT); + +$ctx = stream_context_create([ + 'http' => [ + 'proxy' => "tcp://$host:$port", + 'header' => "X-Custom: test\r\nProxy-Authorization: Basic dXNlcjpwYXNz", + ], + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + ], +]); +@$result = file_get_contents("https://www.php.net/test", false, $ctx); +var_dump($result); + +http_server_kill($pid); + +rewind($output); +$request = stream_get_contents($output); +var_dump(str_contains($request, 'CONNECT www.php.net:443 HTTP/1.0')); +var_dump(str_contains($request, 'Proxy-Authorization: Basic dXNlcjpwYXNz')); +var_dump(str_contains($request, 'X-Custom: test')); +?> +--EXPECT-- +bool(false) +bool(true) +bool(true) +bool(false) diff --git a/ext/standard/tests/http/http_proxy_ssl_connect_02.phpt b/ext/standard/tests/http/http_proxy_ssl_connect_02.phpt new file mode 100644 index 000000000000..bff063e2a0ae --- /dev/null +++ b/ext/standard/tests/http/http_proxy_ssl_connect_02.phpt @@ -0,0 +1,46 @@ +--TEST-- +HTTP proxy SSL CONNECT without Proxy-Authorization header (FAILURE path) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +$host = parse_url($uri, PHP_URL_HOST); +$port = parse_url($uri, PHP_URL_PORT); + +$ctx = stream_context_create([ + 'http' => [ + 'proxy' => "tcp://$host:$port", + 'header' => "X-Custom: test\r\nX-Other: value", + ], + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + ], +]); +@$result = file_get_contents("https://www.php.net/test", false, $ctx); +var_dump($result); + +http_server_kill($pid); + +rewind($output); +$request = stream_get_contents($output); +var_dump(str_contains($request, 'CONNECT www.php.net:443 HTTP/1.0')); +var_dump(str_contains($request, 'Proxy-Authorization')); +?> +--EXPECT-- +bool(false) +bool(true) +bool(false) diff --git a/ext/standard/tests/http/http_proxy_ssl_connect_03.phpt b/ext/standard/tests/http/http_proxy_ssl_connect_03.phpt new file mode 100644 index 000000000000..90a19798f6df --- /dev/null +++ b/ext/standard/tests/http/http_proxy_ssl_connect_03.phpt @@ -0,0 +1,48 @@ +--TEST-- +HTTP proxy SSL CONNECT with Proxy-Authorization header (array) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +$host = parse_url($uri, PHP_URL_HOST); +$port = parse_url($uri, PHP_URL_PORT); + +$ctx = stream_context_create([ + 'http' => [ + 'proxy' => "tcp://$host:$port", + 'header' => ["X-Custom: test", "Proxy-Authorization: Basic abc123"], + ], + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + ], +]); +@$result = file_get_contents("https://www.php.net/test", false, $ctx); +var_dump($result); + +http_server_kill($pid); + +rewind($output); +$request = stream_get_contents($output); +var_dump(str_contains($request, 'CONNECT www.php.net:443 HTTP/1.0')); +var_dump(str_contains($request, 'Proxy-Authorization: Basic abc123')); +var_dump(str_contains($request, 'X-Custom')); +?> +--EXPECT-- +bool(false) +bool(true) +bool(true) +bool(false) diff --git a/ext/standard/tests/http/http_redirect_removes_post_headers.phpt b/ext/standard/tests/http/http_redirect_removes_post_headers.phpt new file mode 100644 index 000000000000..6e0927016ec6 --- /dev/null +++ b/ext/standard/tests/http/http_redirect_removes_post_headers.phpt @@ -0,0 +1,74 @@ +--TEST-- +POST Content-Type and Content-Length headers removed on redirect except for 307/308 +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + [ + 'method' => 'POST', + 'content' => 'test=data', + 'follow_location' => 1, + 'max_redirects' => 3, + 'header' => + "Content-Type: application/x-www-form-urlencoded\r\n" . + "Content-Length: 9\r\n", + ], +]); + +foreach ($status_codes as $code) { + file_get_contents($server['uri'], false, $context); +} + +http_server_kill($server['pid']); + +rewind($output); +$contents = stream_get_contents($output); + +foreach ($status_codes as $code) { + if (!preg_match("~(GET|POST) /$code-redirected .*?\r\n\r\n~s", $contents, $matches)) { + die("fail redirect request for $code not found\n"); + } + echo "Redirect request for $code has Content-Type: "; + var_dump(stripos($matches[0], 'content-type') !== false); + echo "Redirect request for $code has Content-Length: "; + var_dump(stripos($matches[0], 'content-length') !== false); +} + +?> +--EXPECT-- +Redirect request for 301 has Content-Type: bool(false) +Redirect request for 301 has Content-Length: bool(false) +Redirect request for 302 has Content-Type: bool(false) +Redirect request for 302 has Content-Length: bool(false) +Redirect request for 303 has Content-Type: bool(false) +Redirect request for 303 has Content-Length: bool(false) +Redirect request for 307 has Content-Type: bool(true) +Redirect request for 307 has Content-Length: bool(true) +Redirect request for 308 has Content-Type: bool(true) +Redirect request for 308 has Content-Length: bool(true) diff --git a/ext/standard/tests/http/http_relative_redirect.phpt b/ext/standard/tests/http/http_relative_redirect.phpt new file mode 100644 index 000000000000..9c3036da5a11 --- /dev/null +++ b/ext/standard/tests/http/http_relative_redirect.phpt @@ -0,0 +1,186 @@ +--TEST-- +http wrapper resolves a relative redirect Location against the request path +--DESCRIPTION-- +This test tests the current behavior, which is clearly not the correct behavior in some cases. +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +foreach ($uri_parsers as $uri_parser) { + echo "# URI parser: $uri_parser\n"; + foreach ($froms as $from) { + foreach ($tos as $to) { + ftruncate($output, 0); + + $ctx = stream_context_create(['http' => [ + 'follow_location' => true, + 'uri_parser_class' => $uri_parser, + ]]); + $body = @file_get_contents($uri . $from, false, $ctx); + rewind($output); + + if ($body === false) { + $result = "failed"; + // Remove request from responses queue + file_get_contents($uri); + } else { + $requests = stream_get_contents($output); + preg_match_all('~GET (.*) HTTP/1.~', $requests, $matches); + $result = $matches[1][1]; + } + echo "Redirect from '$from' to '$to': $result\n"; + } + } +} + +http_server_kill($pid); +?> +--EXPECT-- +# URI parser: +Redirect from '/dir/page' to '/dir/page': /dir/page +Redirect from '/dir/page' to 'dir/page': /dir//dir/page +Redirect from '/dir/page' to 'a': /a +Redirect from '/dir/page' to 'other': /dir//other +Redirect from '/dir/page' to '': / +Redirect from '/dir/page' to '../../../foo': /dir//../../../foo +Redirect from '/dir/page' to 'space bar': /dir//space bar +Redirect from '/a' to '/dir/page': /dir/page +Redirect from '/a' to 'dir/page': /dir/page +Redirect from '/a' to 'a': /a +Redirect from '/a' to 'other': /other +Redirect from '/a' to '': / +Redirect from '/a' to '../../../foo': /../../../foo +Redirect from '/a' to 'space bar': /space bar +Redirect from '/other' to '/dir/page': /dir/page +Redirect from '/other' to 'dir/page': /dir/page +Redirect from '/other' to 'a': /a +Redirect from '/other' to 'other': /other +Redirect from '/other' to '': / +Redirect from '/other' to '../../../foo': /../../../foo +Redirect from '/other' to 'space bar': /space bar +Redirect from '' to '/dir/page': /dir/page +Redirect from '' to 'dir/page': /dir/page +Redirect from '' to 'a': /a +Redirect from '' to 'other': /other +Redirect from '' to '': / +Redirect from '' to '../../../foo': /../../../foo +Redirect from '' to 'space bar': /space bar +Redirect from '/../../../foo' to '/dir/page': /dir/page +Redirect from '/../../../foo' to 'dir/page': /../../..//dir/page +Redirect from '/../../../foo' to 'a': /a +Redirect from '/../../../foo' to 'other': /../../..//other +Redirect from '/../../../foo' to '': / +Redirect from '/../../../foo' to '../../../foo': /../../..//../../../foo +Redirect from '/../../../foo' to 'space bar': /../../..//space bar +Redirect from '/space bar' to '/dir/page': /dir/page +Redirect from '/space bar' to 'dir/page': /dir/page +Redirect from '/space bar' to 'a': /a +Redirect from '/space bar' to 'other': /other +Redirect from '/space bar' to '': / +Redirect from '/space bar' to '../../../foo': /../../../foo +Redirect from '/space bar' to 'space bar': /space bar +# URI parser: Uri\Rfc3986\Uri +Redirect from '/dir/page' to '/dir/page': /dir/page +Redirect from '/dir/page' to 'dir/page': /dir//dir/page +Redirect from '/dir/page' to 'a': /a +Redirect from '/dir/page' to 'other': /dir//other +Redirect from '/dir/page' to '': / +Redirect from '/dir/page' to '../../../foo': /dir//../../../foo +Redirect from '/dir/page' to 'space bar': failed +Redirect from '/a' to '/dir/page': /dir/page +Redirect from '/a' to 'dir/page': /dir/page +Redirect from '/a' to 'a': /a +Redirect from '/a' to 'other': /other +Redirect from '/a' to '': / +Redirect from '/a' to '../../../foo': /../../../foo +Redirect from '/a' to 'space bar': failed +Redirect from '/other' to '/dir/page': /dir/page +Redirect from '/other' to 'dir/page': /dir/page +Redirect from '/other' to 'a': /a +Redirect from '/other' to 'other': /other +Redirect from '/other' to '': / +Redirect from '/other' to '../../../foo': /../../../foo +Redirect from '/other' to 'space bar': failed +Redirect from '' to '/dir/page': /dir/page +Redirect from '' to 'dir/page': /dir/page +Redirect from '' to 'a': /a +Redirect from '' to 'other': /other +Redirect from '' to '': / +Redirect from '' to '../../../foo': /../../../foo +Redirect from '' to 'space bar': failed +Redirect from '/../../../foo' to '/dir/page': /dir/page +Redirect from '/../../../foo' to 'dir/page': /../../..//dir/page +Redirect from '/../../../foo' to 'a': /a +Redirect from '/../../../foo' to 'other': /../../..//other +Redirect from '/../../../foo' to '': / +Redirect from '/../../../foo' to '../../../foo': /../../..//../../../foo +Redirect from '/../../../foo' to 'space bar': failed +Redirect from '/space bar' to '/dir/page': failed +Redirect from '/space bar' to 'dir/page': failed +Redirect from '/space bar' to 'a': failed +Redirect from '/space bar' to 'other': failed +Redirect from '/space bar' to '': failed +Redirect from '/space bar' to '../../../foo': failed +Redirect from '/space bar' to 'space bar': failed +# URI parser: Uri\WhatWg\Url +Redirect from '/dir/page' to '/dir/page': /dir/page +Redirect from '/dir/page' to 'dir/page': /dir//dir/page +Redirect from '/dir/page' to 'a': /a +Redirect from '/dir/page' to 'other': /dir//other +Redirect from '/dir/page' to '': / +Redirect from '/dir/page' to '../../../foo': /foo +Redirect from '/dir/page' to 'space bar': /dir//space%20bar +Redirect from '/a' to '/dir/page': /dir/page +Redirect from '/a' to 'dir/page': /dir/page +Redirect from '/a' to 'a': /a +Redirect from '/a' to 'other': /other +Redirect from '/a' to '': / +Redirect from '/a' to '../../../foo': /foo +Redirect from '/a' to 'space bar': /space%20bar +Redirect from '/other' to '/dir/page': /dir/page +Redirect from '/other' to 'dir/page': /dir/page +Redirect from '/other' to 'a': /a +Redirect from '/other' to 'other': /other +Redirect from '/other' to '': / +Redirect from '/other' to '../../../foo': /foo +Redirect from '/other' to 'space bar': /space%20bar +Redirect from '' to '/dir/page': /dir/page +Redirect from '' to 'dir/page': /dir/page +Redirect from '' to 'a': /a +Redirect from '' to 'other': /other +Redirect from '' to '': / +Redirect from '' to '../../../foo': /foo +Redirect from '' to 'space bar': /space%20bar +Redirect from '/../../../foo' to '/dir/page': /dir/page +Redirect from '/../../../foo' to 'dir/page': /dir/page +Redirect from '/../../../foo' to 'a': /a +Redirect from '/../../../foo' to 'other': /other +Redirect from '/../../../foo' to '': / +Redirect from '/../../../foo' to '../../../foo': /foo +Redirect from '/../../../foo' to 'space bar': /space%20bar +Redirect from '/space bar' to '/dir/page': /dir/page +Redirect from '/space bar' to 'dir/page': /dir/page +Redirect from '/space bar' to 'a': /a +Redirect from '/space bar' to 'other': /other +Redirect from '/space bar' to '': / +Redirect from '/space bar' to '../../../foo': /foo +Redirect from '/space bar' to 'space bar': /space%20bar diff --git a/ext/standard/tests/http/http_sets_default_request_headers.phpt b/ext/standard/tests/http/http_sets_default_request_headers.phpt new file mode 100644 index 000000000000..c86cea6cfae1 --- /dev/null +++ b/ext/standard/tests/http/http_sets_default_request_headers.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test from and user-agent headers are set from ini and ctx +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +from=ini_from@php.net +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +$ctx = stream_context_create([ + 'http' => [ + 'user_agent' => 'SomeAgent', + 'content' => 'payload', + ], +]); +file_get_contents($uri, false, $ctx); + +http_server_kill($pid); + +rewind($output); +$request = stream_get_contents($output); + +var_dump(str_contains($request, 'User-Agent: SomeAgent')); +var_dump(str_contains($request, 'From: ini_from@php.net')); +var_dump(str_contains($request, 'Content-Type: application/x-www-form-urlencoded')); +var_dump(str_contains($request, 'Content-Length: 7')); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/http/http_user_header_precedence.phpt b/ext/standard/tests/http/http_user_header_precedence.phpt new file mode 100644 index 000000000000..b5e562972bb4 --- /dev/null +++ b/ext/standard/tests/http/http_user_header_precedence.phpt @@ -0,0 +1,54 @@ +--TEST-- +Header precedence when headers are supplied in multiple ways +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +from=ini_from@example.com +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +$ctx = stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => "User-Agent: MyCustomUA\r\n" + . "From: me@example.com\r\n" + . "Content-Length: 5\r\n" + . "Content-Type: application/json\r\n" + . "X-Custom: test", + 'user_agent' => 'AutoGeneratedUA', + 'content' => '0123456789', + ], +]); +file_get_contents($uri, false, $ctx); + +http_server_kill($pid); + +rewind($output); +$request = stream_get_contents($output); + +var_dump(str_contains($request, 'User-Agent: MyCustomUA')); +var_dump(str_contains($request, 'AutoGeneratedUA')); +var_dump(substr_count($request, 'User-Agent:')); +var_dump(str_contains($request, 'From: me@example.com')); +var_dump(str_contains($request, 'ini_from@example.com')); +var_dump(substr_count($request, 'From:')); +var_dump(str_contains($request, 'Content-Length: 5')); +var_dump(substr_count($request, 'Content-Length:')); +?> +--EXPECT-- +bool(true) +bool(false) +int(1) +bool(true) +bool(false) +int(1) +bool(true) +int(1) diff --git a/ext/standard/tests/network/fsockopen_timeout_out_of_range.phpt b/ext/standard/tests/network/fsockopen_timeout_out_of_range.phpt new file mode 100644 index 000000000000..575db4690fb9 --- /dev/null +++ b/ext/standard/tests/network/fsockopen_timeout_out_of_range.phpt @@ -0,0 +1,19 @@ +--TEST-- +fsockopen() and pfsockopen(): ValueError for $timeout reports correct argument number and name +--FILE-- +getMessage(), "\n"; +} + +try { + pfsockopen('localhost', 80, $errno, $errstr, -2.0); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +ValueError: fsockopen(): Argument #5 ($timeout) must be -1 or between 0 and %s +ValueError: pfsockopen(): Argument #5 ($timeout) must be -1 or between 0 and %s diff --git a/ext/standard/tests/streams/gh14780.phpt b/ext/standard/tests/streams/gh14780.phpt index 064e496b1753..c0fc4e621a9d 100644 --- a/ext/standard/tests/streams/gh14780.phpt +++ b/ext/standard/tests/streams/gh14780.phpt @@ -31,8 +31,8 @@ try { } ?> --EXPECTF-- -pfsockopen(): Argument #6 must be -1 or between 0 and %s -pfsockopen(): Argument #6 must be -1 or between 0 and %s +pfsockopen(): Argument #5 ($timeout) must be -1 or between 0 and %s +pfsockopen(): Argument #5 ($timeout) must be -1 or between 0 and %s resource(%d) of type (persistent stream) -pfsockopen(): Argument #6 must be -1 or between 0 and %s -pfsockopen(): Argument #6 must be -1 or between 0 and %s +pfsockopen(): Argument #5 ($timeout) must be -1 or between 0 and %s +pfsockopen(): Argument #5 ($timeout) must be -1 or between 0 and %s diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c index 4e6c1a54c0f9..a597a9b391cc 100644 --- a/ext/zlib/zlib_filter.c +++ b/ext/zlib/zlib_filter.c @@ -24,9 +24,9 @@ typedef struct _php_zlib_filter_data { size_t inbuf_len; unsigned char *outbuf; size_t outbuf_len; - int persistent; - bool finished; /* for zlib.deflate: signals that no flush is pending */ int windowBits; + bool persistent; + bool finished; /* for zlib.deflate: signals that no flush is pending */ } php_zlib_filter_data; /* }}} */ diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index d6249ae068da..88afd1b3752e 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1192,7 +1192,7 @@ static const char *phpdbg_load_module_or_extension(zend_string **path, const cha phpdbg_error("extension_dir ini setting contains a nul byte"); return NULL; } - if (memchr(ZSTR_VAL(*path), '/', ZSTR_LEN(*path)) != NULL || memchr(ZSTR_VAL(*path), '/', ZSTR_LEN(*path)) != NULL) { + if (memchr(ZSTR_VAL(*path), '/', ZSTR_LEN(*path)) != NULL || memchr(ZSTR_VAL(*path), DEFAULT_SLASH, ZSTR_LEN(*path)) != NULL) { /* path is fine */ } else if (extension_dir && ZSTR_LEN(extension_dir) > 0) { zend_string *libpath;