From: George Peter Banyard Date: Sun, 3 May 2020 12:09:37 +0000 (+0200) Subject: Use ZPP int|string and add ValueError for Windows codepages X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8d346f767944a8a2e166d1b6cc13b94fbdd3a88e;p=php Use ZPP int|string and add ValueError for Windows codepages Closes GH-5517 --- diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 09c3513b68..e750d2229c 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1534,11 +1534,7 @@ function sapi_windows_cp_set(int $cp): bool {} function sapi_windows_cp_get(string $kind = UNKNOWN): int {} -/** - * @param int|string $in_codepage - * @param int|string $out_codepage - */ -function sapi_windows_cp_conv($in_codepage, $out_codepage, string $subject): ?string {} +function sapi_windows_cp_conv(int|string $in_codepage, int|string $out_codepage, string $subject): ?string {} function sapi_windows_cp_is_utf8(): bool {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index bc26e4ad97..f7c9805683 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -2213,8 +2213,8 @@ ZEND_END_ARG_INFO() #if defined(PHP_WIN32) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sapi_windows_cp_conv, 0, 3, IS_STRING, 1) - ZEND_ARG_INFO(0, in_codepage) - ZEND_ARG_INFO(0, out_codepage) + ZEND_ARG_TYPE_MASK(0, in_codepage, MAY_BE_LONG|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_MASK(0, out_codepage, MAY_BE_LONG|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0) ZEND_END_ARG_INFO() #endif diff --git a/win32/codepage.c b/win32/codepage.c index 0f90c534b8..5ed0fd50a5 100644 --- a/win32/codepage.c +++ b/win32/codepage.c @@ -567,8 +567,8 @@ PHP_FUNCTION(sapi_windows_cp_set) } if (ZEND_LONG_UINT_OVFL(id)) { - php_error_docref(NULL, E_WARNING, "Argument %d is out of range", id); - RETURN_FALSE; + zend_argument_value_error(1, "must be between 0 and %u", UINT_MAX); + RETURN_THROWS(); } if (php_win32_console_is_cli_sapi()) { @@ -624,68 +624,66 @@ PHP_FUNCTION(sapi_windows_cp_is_utf8) * Convert string from one codepage to another. */ PHP_FUNCTION(sapi_windows_cp_conv) { - char *subj, *ret; - size_t subj_len, ret_len, tmpw_len; + char *ret; + size_t ret_len, tmpw_len; wchar_t *tmpw; const struct php_win32_cp *in_cp, *out_cp; - zval *z_in_cp, *z_out_cp; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzs", &z_in_cp, &z_out_cp, &subj, &subj_len) == FAILURE) { + zend_string *string_in_codepage = NULL; + zend_long int_in_codepage = 0; + zend_string *string_out_codepage = NULL; + zend_long int_out_codepage = 0; + zend_string *subject; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_STR_OR_LONG(string_in_codepage, int_in_codepage) + Z_PARAM_STR_OR_LONG(string_out_codepage, int_out_codepage) + Z_PARAM_STR(subject) + ZEND_PARSE_PARAMETERS_END(); + + if (ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(subject))) { + zend_argument_value_error(1, "is too long"); RETURN_THROWS(); } - if (ZEND_SIZE_T_INT_OVFL(subj_len)) { - php_error_docref(NULL, E_WARNING, "String is too long"); - RETURN_NULL(); - } - - if (IS_LONG == Z_TYPE_P(z_in_cp)) { - if (ZEND_LONG_UINT_OVFL(Z_LVAL_P(z_in_cp))) { - php_error_docref(NULL, E_WARNING, "Argument %d is out of range", Z_LVAL_P(z_in_cp)); - RETURN_NULL(); - } - - in_cp = php_win32_cp_get_by_id((DWORD)Z_LVAL_P(z_in_cp)); + if (string_in_codepage != NULL) { + in_cp = php_win32_cp_get_by_enc(ZSTR_VAL(string_in_codepage)); if (!in_cp) { - php_error_docref(NULL, E_WARNING, "Invalid codepage %d", Z_LVAL_P(z_in_cp)); - RETURN_NULL(); + zend_argument_value_error(1, "must be a valid charset"); + RETURN_THROWS(); } } else { - if (!try_convert_to_string(z_in_cp)) { - return; + if (ZEND_LONG_UINT_OVFL(int_in_codepage)) { + zend_argument_value_error(1, "must be between 0 and %u", UINT_MAX); + RETURN_THROWS(); } - in_cp = php_win32_cp_get_by_enc(Z_STRVAL_P(z_in_cp)); + in_cp = php_win32_cp_get_by_id((DWORD)int_in_codepage); if (!in_cp) { - php_error_docref(NULL, E_WARNING, "Invalid charset %s", Z_STRVAL_P(z_in_cp)); - RETURN_NULL(); + zend_argument_value_error(1, "must be a valid codepage"); + RETURN_THROWS(); } } - if (IS_LONG == Z_TYPE_P(z_out_cp)) { - if (ZEND_LONG_UINT_OVFL(Z_LVAL_P(z_out_cp))) { - php_error_docref(NULL, E_WARNING, "Argument %d is out of range", Z_LVAL_P(z_out_cp)); - RETURN_NULL(); - } - - out_cp = php_win32_cp_get_by_id((DWORD)Z_LVAL_P(z_out_cp)); + if (string_out_codepage != NULL) { + out_cp = php_win32_cp_get_by_enc(ZSTR_VAL(string_out_codepage)); if (!out_cp) { - php_error_docref(NULL, E_WARNING, "Invalid codepage %d", Z_LVAL_P(z_out_cp)); - RETURN_NULL(); + zend_argument_value_error(2, "must be a valid charset"); + RETURN_THROWS(); } } else { - if (!try_convert_to_string(z_out_cp)) { - return; + if (ZEND_LONG_UINT_OVFL(int_out_codepage)) { + zend_argument_value_error(2, "must be between 0 and %u", UINT_MAX); + RETURN_THROWS(); } - out_cp = php_win32_cp_get_by_enc(Z_STRVAL_P(z_out_cp)); + out_cp = php_win32_cp_get_by_id((DWORD)int_out_codepage); if (!out_cp) { - php_error_docref(NULL, E_WARNING, "Invalid charset %s", Z_STRVAL_P(z_out_cp)); - RETURN_NULL(); + zend_argument_value_error(2, "must be a valid codepage"); + RETURN_THROWS(); } } - tmpw = php_win32_cp_conv_to_w(in_cp->id, in_cp->to_w_fl, subj, subj_len, &tmpw_len); + tmpw = php_win32_cp_conv_to_w(in_cp->id, in_cp->to_w_fl, ZSTR_VAL(subject), ZSTR_LEN(subject), &tmpw_len); if (!tmpw) { php_error_docref(NULL, E_WARNING, "Wide char conversion failed"); RETURN_NULL();