Skip to content

Commit 16a63d7

Browse files
committed
ext/pgsql: php_pgsql_convert converts E_NOTICE to TypeError/ValueError exceptions.
Close GH-11238
1 parent 9ce6980 commit 16a63d7

File tree

5 files changed

+47
-20
lines changed

5 files changed

+47
-20
lines changed

Diff for: NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ PHP NEWS
141141
. pg_trace new PGSQL_TRACE_SUPPRESS_TIMESTAMPS/PGSQL_TRACE_REGRESS_MODE
142142
contants support. (David Carlier)
143143
. pg_set_error_verbosity adding PGSQL_ERRORS_STATE constant. (David Carlier)
144+
. pg_convert/pg_insert E_WARNING on type errors had been converted to
145+
ValueError/TypeError exceptions. (David Carlier)
144146

145147
- Phar:
146148
. Fix memory leak in phar_rename_archive(). (stkeke)

Diff for: UPGRADING

+2
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ PHP 8.3 UPGRADE NOTES
146146
. pg_fetch_object now raises a ValueError instead of an Exception when the constructor_args
147147
argument is non empty with the class not having constructor.
148148
. pg_insert now raises a ValueError instead of a WARNING when the table specified is invalid.
149+
. pg_insert and pg_convert raises a ValueError or a TypeError instead of a WARNING when the
150+
value/type of a field does not match properly with a PostGreSQL's type.
149151

150152
- Standard:
151153
. E_NOTICEs emitted by unserialize() have been promoted to E_WARNING.

Diff for: ext/pgsql/pgsql.c

+18-15
Original file line numberDiff line numberDiff line change
@@ -4529,7 +4529,6 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
45294529
data_type = php_pgsql_get_data_type(Z_STR_P(type));
45304530
}
45314531

4532-
/* TODO: Should E_NOTICE be converted to type error if PHP type cannot be converted to field type? */
45334532
switch(data_type)
45344533
{
45354534
case PG_BOOL:
@@ -4554,7 +4553,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
45544553
ZVAL_STRINGL(&new_val, "'f'", sizeof("'f'")-1);
45554554
}
45564555
else {
4557-
php_error_docref(NULL, E_NOTICE, "Detected invalid value (%s) for PostgreSQL %s field (%s)", Z_STRVAL_P(val), Z_STRVAL_P(type), ZSTR_VAL(field));
4556+
zend_value_error("%s(): Field \"%s\" must be of type bool, invalid PostgreSQL string boolean value \"%s\" given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(val));
45584557
err = 1;
45594558
}
45604559
}
@@ -4586,7 +4585,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
45864585
}
45874586
PGSQL_CONV_CHECK_IGNORE();
45884587
if (err) {
4589-
php_error_docref(NULL, E_NOTICE, "Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4588+
zend_type_error("%s(): Field \"%s\" must be of type string|null|int|bool, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
45904589
}
45914590
break;
45924591

@@ -4630,7 +4629,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
46304629
}
46314630
PGSQL_CONV_CHECK_IGNORE();
46324631
if (err) {
4633-
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for pgsql '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4632+
zend_type_error("%s(): Field \"%s\" must be of type int|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
46344633
}
46354634
break;
46364635

@@ -4679,7 +4678,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
46794678
}
46804679
PGSQL_CONV_CHECK_IGNORE();
46814680
if (err) {
4682-
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4681+
zend_type_error("%s(): Field \"%s\" must be of type %s|int|null, %s given", get_active_function_name(), (data_type == PG_MONEY ? "money" : "float"), ZSTR_VAL(field), Z_STRVAL_P(type));
46834682
}
46844683
break;
46854684

@@ -4740,7 +4739,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
47404739
}
47414740
PGSQL_CONV_CHECK_IGNORE();
47424741
if (err) {
4743-
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4742+
zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
47444743
}
47454744
break;
47464745

@@ -4782,7 +4781,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
47824781
}
47834782
PGSQL_CONV_CHECK_IGNORE();
47844783
if (err) {
4785-
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4784+
zend_type_error("%s(): Field \"%s\" must be of type int|null, %s given", get_active_function_name(), ZSTR_VAL(field), zend_zval_value_name(val));
47864785
}
47874786
break;
47884787

@@ -4801,7 +4800,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
48014800
at all though and let the server side to handle it.*/
48024801
if (php_pgsql_convert_match(Z_STR_P(val), REGEX0, sizeof(REGEX0)-1, 0) == FAILURE
48034802
&& php_pgsql_convert_match(Z_STR_P(val), REGEX1, sizeof(REGEX1)-1, 0) == FAILURE) {
4804-
err = 1;
4803+
err = 2;
48054804
}
48064805
else {
48074806
ZVAL_STR(&new_val, php_pgsql_add_quotes(Z_STR_P(val)));
@@ -4820,7 +4819,11 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
48204819
}
48214820
PGSQL_CONV_CHECK_IGNORE();
48224821
if (err) {
4823-
php_error_docref(NULL, E_NOTICE, "Expects NULL or IPv4 or IPv6 address string for '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4822+
if (err == 2) {
4823+
zend_value_error("%s(): Field \"%s\" must be a valid IPv4 or IPv6 address string, \"%s\" given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(val));
4824+
} else {
4825+
zend_type_error("%s(): Field \"%s\" must be of type string|null, given %s", get_active_function_name(), ZSTR_VAL(field), zend_zval_value_name(val));
4826+
}
48244827
}
48254828
break;
48264829

@@ -4854,7 +4857,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
48544857
}
48554858
PGSQL_CONV_CHECK_IGNORE();
48564859
if (err) {
4857-
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4860+
zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
48584861
}
48594862
break;
48604863

@@ -4886,7 +4889,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
48864889
}
48874890
PGSQL_CONV_CHECK_IGNORE();
48884891
if (err) {
4889-
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4892+
zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
48904893
}
48914894
break;
48924895

@@ -4918,7 +4921,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
49184921
}
49194922
PGSQL_CONV_CHECK_IGNORE();
49204923
if (err) {
4921-
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
4924+
zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
49224925
}
49234926
break;
49244927

@@ -4996,7 +4999,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
49964999
}
49975000
PGSQL_CONV_CHECK_IGNORE();
49985001
if (err) {
4999-
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
5002+
zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
50005003
}
50015004
break;
50025005
case PG_BYTEA:
@@ -5037,7 +5040,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
50375040
}
50385041
PGSQL_CONV_CHECK_IGNORE();
50395042
if (err) {
5040-
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
5043+
zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
50415044
}
50425045
break;
50435046

@@ -5068,7 +5071,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
50685071
}
50695072
PGSQL_CONV_CHECK_IGNORE();
50705073
if (err) {
5071-
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
5074+
zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
50725075
}
50735076
break;
50745077

Diff for: ext/pgsql/tests/bug71998.phpt

+14-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@ $i = 0;
5757
$errors = 0;
5858
foreach ($ips as $ip) {
5959
$data = array("id" => ++$i, "remote_addr" => $ip);
60-
$r = @pg_insert($db, 'tmp_statistics', $data);
60+
$r = true;
61+
try {
62+
@pg_insert($db, 'tmp_statistics', $data);
63+
} catch (\ValueError $e) {
64+
echo $e->getMessage() . PHP_EOL;
65+
$r = false;
66+
}
6167

6268
if (!$r && in_array($ip, $bad)) {
6369
$errors++;
@@ -79,6 +85,13 @@ pg_close($db);
7985

8086
?>
8187
--EXPECT--
88+
pg_insert(): Field "remote_addr" must be a valid IPv4 or IPv6 address string, "256.257.258.259" given
89+
pg_insert(): Field "remote_addr" must be a valid IPv4 or IPv6 address string, "fe08::7:8interface" given
90+
pg_insert(): Field "remote_addr" must be a valid IPv4 or IPv6 address string, "schnitzel" given
91+
pg_insert(): Field "remote_addr" must be a valid IPv4 or IPv6 address string, "10002.3.4" given
92+
pg_insert(): Field "remote_addr" must be a valid IPv4 or IPv6 address string, "1.2.3.4.5" given
93+
pg_insert(): Field "remote_addr" must be a valid IPv4 or IPv6 address string, "256.0.0.0" given
94+
pg_insert(): Field "remote_addr" must be a valid IPv4 or IPv6 address string, "260.0.0.0" given
8295
array(2) {
8396
[0]=>
8497
string(1) "1"

Diff for: ext/pgsql/tests/bug77047.phpt

+11-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,18 @@ pg_query($db, "CREATE TABLE bug77047 (
1919
t TIME WITHOUT TIME ZONE
2020
)");
2121

22-
pg_insert($db, "bug77047", array("t" => "13:31"));
22+
try {
23+
pg_insert($db, "bug77047", array("t" => "13:31"));
24+
} catch (\TypeError $e) {
25+
echo $e->getMessage();
26+
}
2327
pg_insert($db, "bug77047", array("t" => "13:31:13"));
2428
pg_insert($db, "bug77047", array("t" => "1:2:3"));
25-
pg_insert($db, "bug77047", array("t" => "xyz"));
29+
try {
30+
pg_insert($db, "bug77047", array("t" => "xyz"));
31+
} catch (\TypeError $e) {
32+
echo $e->getMessage() . PHP_EOL;
33+
}
2634
pg_insert($db, "bug77047", array("t" => NULL));
2735
pg_insert($db, "bug77047", array("t" => ""));
2836

@@ -33,10 +41,9 @@ while (false !== ($row = pg_fetch_row($res))) {
3341

3442
?>
3543
--EXPECTF--
36-
Notice: pg_insert(): Expects NULL or string for PostgreSQL time field (t) in %s on line %d
44+
pg_insert(): Field "t" must be of type string|null, time given
3745
string(8) "13:31:00"
3846
string(8) "13:31:13"
3947
string(8) "01:02:03"
4048
NULL
4149
NULL
42-

0 commit comments

Comments
 (0)