Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions ext/pgsql/pgsql.c
Original file line number Diff line number Diff line change
Expand Up @@ -4529,7 +4529,6 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
data_type = php_pgsql_get_data_type(Z_STR_P(type));
}

/* TODO: Should E_NOTICE be converted to type error if PHP type cannot be converted to field type? */
switch(data_type)
{
case PG_BOOL:
Expand All @@ -4554,7 +4553,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
ZVAL_STRINGL(&new_val, "'f'", sizeof("'f'")-1);
}
else {
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));
zend_value_error("%s(): Field \"%s\" must be of type bool, %s (%s) given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type), Z_STRVAL_P(val));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zend_value_error("%s(): Field \"%s\" must be of type bool, %s (%s) given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type), Z_STRVAL_P(val));
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));

Erf I don't know what to do with this error message as what it wants is a valid PostgreSQL bool and we are parsing the string here...

err = 1;
}
}
Expand Down Expand Up @@ -4586,7 +4585,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|bool, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|bool, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
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));

}
break;

Expand Down Expand Up @@ -4630,7 +4629,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for pgsql '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this field types just wants am int|null and does some type juggling to convert other types to int. however this maybe should follow the normal PHP semantics

}
break;

Expand Down Expand Up @@ -4679,7 +4678,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, it seems it only wants a float. But then this might require us to split the logic for NUMERIC and MONEY fields

}
break;

Expand Down Expand Up @@ -4740,7 +4739,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
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));

Similarly here, it does implicit type juggling to end up with a string.

}
break;

Expand Down Expand Up @@ -4782,7 +4781,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only just saw that "long" is used instead of the standard "int" PHP type.

Also it wants the time as an int so...

Moreover, there is the issue again about not actually providing the type of the actual passed value

Suggested change
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
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));

}
break;

Expand All @@ -4801,7 +4800,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
at all though and let the server side to handle it.*/
if (php_pgsql_convert_match(Z_STR_P(val), REGEX0, sizeof(REGEX0)-1, 0) == FAILURE
&& php_pgsql_convert_match(Z_STR_P(val), REGEX1, sizeof(REGEX1)-1, 0) == FAILURE) {
err = 1;
err = 2;
}
else {
ZVAL_STR(&new_val, php_pgsql_add_quotes(Z_STR_P(val)));
Expand All @@ -4820,7 +4819,11 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL or IPv4 or IPv6 address string for '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
if (err == 2) {
zend_value_error("%s(): Field \"%s\" must be of type IPv4|IPv6|null, given %s", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(val));
} else {
zend_type_error("%s(): Field \"%s\" must be of type IPv4|IPv6|null, given %s", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (err == 2) {
zend_value_error("%s(): Field \"%s\" must be of type IPv4|IPv6|null, given %s", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(val));
} else {
zend_type_error("%s(): Field \"%s\" must be of type IPv4|IPv6|null, given %s", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
}
if (err == 2) {
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));
} else {
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));
}

As far as I can see the "type" zval should have nothing to do here. I think ideally it would be good to have a new test that tries to hit everyone of these type errors and value errors as it would be easier to see and correct the error messages.

}
break;

Expand Down Expand Up @@ -4854,7 +4857,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
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));
}
break;

Expand Down Expand Up @@ -4886,7 +4889,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
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));
}
break;

Expand Down Expand Up @@ -4918,7 +4921,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
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));
}
break;

Expand Down Expand Up @@ -4996,7 +4999,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
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));
}
break;
case PG_BYTEA:
Expand Down Expand Up @@ -5037,7 +5040,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zend_type_error("%s(): Field \"%s\" must be of type string|null|long|float, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type));
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));

}
break;

Expand Down Expand Up @@ -5068,7 +5071,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *
}
PGSQL_CONV_CHECK_IGNORE();
if (err) {
php_error_docref(NULL, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
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));
}
break;

Expand Down
7 changes: 6 additions & 1 deletion ext/pgsql/tests/bug71998.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ $i = 0;
$errors = 0;
foreach ($ips as $ip) {
$data = array("id" => ++$i, "remote_addr" => $ip);
$r = @pg_insert($db, 'tmp_statistics', $data);
$r = true;
try {
@pg_insert($db, 'tmp_statistics', $data);
} catch (\ValueError $e) {
$r = false;
}

if (!$r && in_array($ip, $bad)) {
$errors++;
Expand Down
15 changes: 11 additions & 4 deletions ext/pgsql/tests/bug77047.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@ pg_query($db, "CREATE TABLE bug77047 (
t TIME WITHOUT TIME ZONE
)");

pg_insert($db, "bug77047", array("t" => "13:31"));
try {
pg_insert($db, "bug77047", array("t" => "13:31"));
Copy link
Member

@nielsdos nielsdos May 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're only testing one case now, because when pg_insert (expectedly) fails, it will execute the catch and not execute the other pg_insert calls.
I guess it doesn't really matter here, but maybe you want the test to check if there are no errors thrown that shouldn't be thrown after the first failure. In which case you might not want to put a big try-catch around all calls.

} catch (\TypeError $e) {
echo $e->getMessage();
}
pg_insert($db, "bug77047", array("t" => "13:31:13"));
pg_insert($db, "bug77047", array("t" => "1:2:3"));
pg_insert($db, "bug77047", array("t" => "xyz"));
try {
pg_insert($db, "bug77047", array("t" => "xyz"));
} catch (\TypeError $e) {
echo $e->getMessage() . PHP_EOL;
}
pg_insert($db, "bug77047", array("t" => NULL));
pg_insert($db, "bug77047", array("t" => ""));

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

?>
--EXPECTF--
Notice: pg_insert(): Expects NULL or string for PostgreSQL time field (t) in %s on line %d
pg_insert(): Field "t" must be of type string|null, time given
string(8) "13:31:00"
string(8) "13:31:13"
string(8) "01:02:03"
NULL
NULL