Skip to content

Commit 053a5fc

Browse files
committed
Promote E_NOTICE to Value/TypeError in PostgreSQL extension
Add some tests to cover related codepaths. With the small caveat that the ones in build_assignment_string() still don't seem to be tested as it looks the condtions are checked beforehand, might need some more investigation. Closes GH-6226
1 parent 5dd5569 commit 053a5fc

6 files changed

+234
-46
lines changed

ext/pgsql/pgsql.c

+59-46
Original file line numberDiff line numberDiff line change
@@ -2300,6 +2300,7 @@ PHP_FUNCTION(pg_lo_create)
23002300
RETURN_THROWS();
23012301
}
23022302

2303+
/* Overloaded method uses default link if arg 1 is not a resource, set oid pointer */
23032304
if ((argc == 1) && (Z_TYPE_P(pgsql_link) != IS_RESOURCE)) {
23042305
oid = pgsql_link;
23052306
pgsql_link = NULL;
@@ -2322,25 +2323,26 @@ PHP_FUNCTION(pg_lo_create)
23222323
switch (Z_TYPE_P(oid)) {
23232324
case IS_STRING:
23242325
{
2326+
/* TODO: Use subroutine? */
23252327
char *end_ptr;
23262328
wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10);
23272329
if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) {
2328-
/* wrong integer format */
2329-
php_error_docref(NULL, E_NOTICE, "Invalid OID value passed");
2330-
RETURN_FALSE;
2330+
/* wrong integer format */
2331+
zend_value_error("Invalid OID value passed");
2332+
RETURN_THROWS();
23312333
}
23322334
}
23332335
break;
23342336
case IS_LONG:
23352337
if (Z_LVAL_P(oid) < (zend_long)InvalidOid) {
2336-
php_error_docref(NULL, E_NOTICE, "Invalid OID value passed");
2337-
RETURN_FALSE;
2338+
zend_value_error("Invalid OID value passed");
2339+
RETURN_THROWS();
23382340
}
23392341
wanted_oid = (Oid)Z_LVAL_P(oid);
23402342
break;
23412343
default:
2342-
php_error_docref(NULL, E_NOTICE, "Invalid OID value passed");
2343-
RETURN_FALSE;
2344+
zend_type_error("OID value must be of type string|int, %s given", zend_zval_type_name(oid));
2345+
RETURN_THROWS();
23442346
}
23452347
if ((pgsql_oid = lo_create(pgsql, wanted_oid)) == InvalidOid) {
23462348
php_error_docref(NULL, E_WARNING, "Unable to create PostgreSQL large object");
@@ -2374,39 +2376,41 @@ PHP_FUNCTION(pg_lo_unlink)
23742376
/* accept string type since Oid type is unsigned int */
23752377
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
23762378
"rs", &pgsql_link, &oid_string, &oid_strlen) == SUCCESS) {
2379+
/* TODO: Use subroutine? */
23772380
oid = (Oid)strtoul(oid_string, &end_ptr, 10);
23782381
if ((oid_string+oid_strlen) != end_ptr) {
23792382
/* wrong integer format */
2380-
php_error_docref(NULL, E_NOTICE, "Wrong OID value passed");
2381-
RETURN_FALSE;
2383+
zend_value_error("Invalid OID value passed");
2384+
RETURN_THROWS();
23822385
}
23832386
link = Z_RES_P(pgsql_link);
23842387
}
23852388
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
23862389
"rl", &pgsql_link, &oid_long) == SUCCESS) {
23872390
if (oid_long <= (zend_long)InvalidOid) {
2388-
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
2389-
RETURN_FALSE;
2391+
zend_value_error("Invalid OID value passed");
2392+
RETURN_THROWS();
23902393
}
23912394
oid = (Oid)oid_long;
23922395
link = Z_RES_P(pgsql_link);
23932396
}
23942397
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
23952398
"s", &oid_string, &oid_strlen) == SUCCESS) {
2399+
/* TODO: subroutine? */
23962400
oid = (Oid)strtoul(oid_string, &end_ptr, 10);
23972401
if ((oid_string+oid_strlen) != end_ptr) {
23982402
/* wrong integer format */
2399-
php_error_docref(NULL, E_NOTICE, "Wrong OID value passed");
2400-
RETURN_FALSE;
2403+
zend_value_error("Invalid OID value passed");
2404+
RETURN_THROWS();
24012405
}
24022406
link = FETCH_DEFAULT_LINK();
24032407
CHECK_DEFAULT_LINK(link);
24042408
}
24052409
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
24062410
"l", &oid_long) == SUCCESS) {
24072411
if (oid_long <= (zend_long)InvalidOid) {
2408-
php_error_docref(NULL, E_NOTICE, "Invalid OID is specified");
2409-
RETURN_FALSE;
2412+
zend_value_error("Invalid OID value passed");
2413+
RETURN_THROWS();
24102414
}
24112415
oid = (Oid)oid_long;
24122416
link = FETCH_DEFAULT_LINK();
@@ -2447,39 +2451,41 @@ PHP_FUNCTION(pg_lo_open)
24472451
/* accept string type since Oid is unsigned int */
24482452
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
24492453
"rss", &pgsql_link, &oid_string, &oid_strlen, &mode_string, &mode_strlen) == SUCCESS) {
2454+
/* TODO: Use subroutine? */
24502455
oid = (Oid)strtoul(oid_string, &end_ptr, 10);
24512456
if ((oid_string+oid_strlen) != end_ptr) {
24522457
/* wrong integer format */
2453-
php_error_docref(NULL, E_NOTICE, "Wrong OID value passed");
2454-
RETURN_FALSE;
2458+
zend_value_error("Invalid OID value passed");
2459+
RETURN_THROWS();
24552460
}
24562461
link = Z_RES_P(pgsql_link);
24572462
}
24582463
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
24592464
"rls", &pgsql_link, &oid_long, &mode_string, &mode_strlen) == SUCCESS) {
24602465
if (oid_long <= (zend_long)InvalidOid) {
2461-
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
2462-
RETURN_FALSE;
2466+
zend_value_error("Invalid OID value passed");
2467+
RETURN_THROWS();
24632468
}
24642469
oid = (Oid)oid_long;
24652470
link = Z_RES_P(pgsql_link);
24662471
}
24672472
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
24682473
"ss", &oid_string, &oid_strlen, &mode_string, &mode_strlen) == SUCCESS) {
2474+
/* TODO: Use subroutine? */
24692475
oid = (Oid)strtoul(oid_string, &end_ptr, 10);
24702476
if ((oid_string+oid_strlen) != end_ptr) {
24712477
/* wrong integer format */
2472-
php_error_docref(NULL, E_NOTICE, "Wrong OID value passed");
2473-
RETURN_FALSE;
2478+
zend_value_error("Invalid OID value passed");
2479+
RETURN_THROWS();
24742480
}
24752481
link = FETCH_DEFAULT_LINK();
24762482
CHECK_DEFAULT_LINK(link);
24772483
}
24782484
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
24792485
"ls", &oid_long, &mode_string, &mode_strlen) == SUCCESS) {
24802486
if (oid_long <= (zend_long)InvalidOid) {
2481-
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
2482-
RETURN_FALSE;
2487+
zend_value_error("Invalid OID value passed");
2488+
RETURN_THROWS();
24832489
}
24842490
oid = (Oid)oid_long;
24852491
link = FETCH_DEFAULT_LINK();
@@ -2717,25 +2723,26 @@ PHP_FUNCTION(pg_lo_import)
27172723
switch (Z_TYPE_P(oid)) {
27182724
case IS_STRING:
27192725
{
2726+
/* TODO: Use subroutine? */
27202727
char *end_ptr;
27212728
wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10);
27222729
if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) {
2723-
/* wrong integer format */
2724-
php_error_docref(NULL, E_NOTICE, "Invalid OID value passed");
2725-
RETURN_FALSE;
2730+
/* wrong integer format */
2731+
zend_value_error("Invalid OID value passed");
2732+
RETURN_THROWS();
27262733
}
27272734
}
27282735
break;
27292736
case IS_LONG:
27302737
if (Z_LVAL_P(oid) < (zend_long)InvalidOid) {
2731-
php_error_docref(NULL, E_NOTICE, "Invalid OID value passed");
2732-
RETURN_FALSE;
2738+
zend_value_error("Invalid OID value passed");
2739+
RETURN_THROWS();
27332740
}
27342741
wanted_oid = (Oid)Z_LVAL_P(oid);
27352742
break;
27362743
default:
2737-
php_error_docref(NULL, E_NOTICE, "Invalid OID value passed");
2738-
RETURN_FALSE;
2744+
zend_type_error("OID value must be of type string|int, %s given", zend_zval_type_name(oid));
2745+
RETURN_THROWS();
27392746
}
27402747

27412748
returned_oid = lo_import_with_oid(pgsql, file_in, wanted_oid);
@@ -2773,39 +2780,41 @@ PHP_FUNCTION(pg_lo_export)
27732780
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
27742781
"rlp", &pgsql_link, &oid_long, &file_out, &name_len) == SUCCESS) {
27752782
if (oid_long <= (zend_long)InvalidOid) {
2776-
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
2777-
RETURN_FALSE;
2783+
zend_value_error("Invalid OID value passed");
2784+
RETURN_THROWS();
27782785
}
27792786
oid = (Oid)oid_long;
27802787
link = Z_RES_P(pgsql_link);
27812788
}
27822789
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
27832790
"rsp", &pgsql_link, &oid_string, &oid_strlen, &file_out, &name_len) == SUCCESS) {
2791+
/* TODO: Use subroutine? */
27842792
oid = (Oid)strtoul(oid_string, &end_ptr, 10);
27852793
if ((oid_string+oid_strlen) != end_ptr) {
27862794
/* wrong integer format */
2787-
php_error_docref(NULL, E_NOTICE, "Wrong OID value passed");
2788-
RETURN_FALSE;
2795+
zend_value_error("Invalid OID value passed");
2796+
RETURN_THROWS();
27892797
}
27902798
link = Z_RES_P(pgsql_link);
27912799
}
27922800
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
27932801
"lp", &oid_long, &file_out, &name_len) == SUCCESS) {
27942802
if (oid_long <= (zend_long)InvalidOid) {
2795-
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
2796-
RETURN_FALSE;
2803+
zend_value_error("Invalid OID value passed");
2804+
RETURN_THROWS();
27972805
}
27982806
oid = (Oid)oid_long;
27992807
link = FETCH_DEFAULT_LINK();
28002808
CHECK_DEFAULT_LINK(link);
28012809
}
28022810
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
28032811
"sp", &oid_string, &oid_strlen, &file_out, &name_len) == SUCCESS) {
2812+
/* TODO: Use subroutine? */
28042813
oid = (Oid)strtoul(oid_string, &end_ptr, 10);
28052814
if ((oid_string+oid_strlen) != end_ptr) {
28062815
/* wrong integer format */
2807-
php_error_docref(NULL, E_NOTICE, "Wrong OID value passed");
2808-
RETURN_FALSE;
2816+
zend_value_error("Invalid OID value passed");
2817+
RETURN_THROWS();
28092818
}
28102819
link = FETCH_DEFAULT_LINK();
28112820
CHECK_DEFAULT_LINK(link);
@@ -4264,6 +4273,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
42644273
src = estrdup(table_name);
42654274
tmp_name = php_strtok_r(src, ".", &tmp_name2);
42664275
if (!tmp_name) {
4276+
// TODO ValueError (empty table name)?
42674277
efree(src);
42684278
php_error_docref(NULL, E_WARNING, "The table name must be specified");
42694279
return FAILURE;
@@ -4557,6 +4567,7 @@ static int php_pgsql_add_quotes(zval *src, zend_bool should_free)
45574567
}
45584568
/* }}} */
45594569

4570+
/* Raise E_NOTICE to E_WARNING or Error? */
45604571
#define PGSQL_CONV_CHECK_IGNORE() \
45614572
if (!err && Z_TYPE(new_val) == IS_STRING && !strcmp(Z_STRVAL(new_val), "NULL")) { \
45624573
/* if new_value is string "NULL" and field has default value, remove element to use default value */ \
@@ -4600,8 +4611,10 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
46004611
skip_field = 0;
46014612
ZVAL_NULL(&new_val);
46024613

4614+
/* TODO: Check when meta data can be broken and see if can use assertions instead */
4615+
46034616
if (!err && field == NULL) {
4604-
php_error_docref(NULL, E_WARNING, "Accepts only string key for values");
4617+
zend_value_error("Array of values must be an associative array with string keys");
46054618
err = 1;
46064619
}
46074620

@@ -4625,8 +4638,8 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
46254638
php_error_docref(NULL, E_NOTICE, "Detected broken meta data. Missing 'is enum'");
46264639
err = 1;
46274640
}
4628-
if (!err && (Z_TYPE_P(val) == IS_ARRAY || Z_TYPE_P(val) == IS_OBJECT)) {
4629-
php_error_docref(NULL, E_NOTICE, "Expects scalar values as field values");
4641+
if (!err && (Z_TYPE_P(val) == IS_ARRAY || Z_TYPE_P(val) == IS_OBJECT || Z_TYPE_P(val) == IS_RESOURCE)) {
4642+
zend_type_error("Values must be of type string|int|float|bool|null, %s given", zend_zval_type_name(val));
46304643
err = 1;
46314644
}
46324645
if (err) {
@@ -4641,6 +4654,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
46414654
data_type = php_pgsql_get_data_type(Z_STRVAL_P(type), Z_STRLEN_P(type));
46424655
}
46434656

4657+
/* TODO: Should E_NOTICE be converted to type error if PHP type cannot be converted to field type? */
46444658
switch(data_type)
46454659
{
46464660
case PG_BOOL:
@@ -5358,7 +5372,7 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
53585372

53595373
ZEND_HASH_FOREACH_STR_KEY(Z_ARRVAL_P(var_array), fld) {
53605374
if (fld == NULL) {
5361-
php_error_docref(NULL, E_NOTICE, "Expects associative array for values to be inserted");
5375+
zend_value_error("Array of values must be an associative array with string keys");
53625376
goto cleanup;
53635377
}
53645378
if (opt & PGSQL_DML_ESCAPE) {
@@ -5401,9 +5415,8 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
54015415
smart_str_appendl(&querystr, "NULL", sizeof("NULL")-1);
54025416
break;
54035417
default:
5404-
php_error_docref(NULL, E_WARNING, "Expects scaler values. type = %d", Z_TYPE_P(val));
5418+
zend_type_error("Value must be of type string|int|float|null, %s given", zend_zval_type_name(val));
54055419
goto cleanup;
5406-
break;
54075420
}
54085421
smart_str_appendc(&querystr, ',');
54095422
} ZEND_HASH_FOREACH_END();
@@ -5532,7 +5545,7 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
55325545

55335546
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, fld, val) {
55345547
if (fld == NULL) {
5535-
php_error_docref(NULL, E_NOTICE, "Expects associative array for values to be inserted");
5548+
zend_value_error("Array of values must be an associative array with string keys");
55365549
return -1;
55375550
}
55385551
if (opt & PGSQL_DML_ESCAPE) {
@@ -5573,7 +5586,7 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
55735586
smart_str_appendl(querystr, "NULL", sizeof("NULL")-1);
55745587
break;
55755588
default:
5576-
php_error_docref(NULL, E_WARNING, "Expects scaler values. type=%d", Z_TYPE_P(val));
5589+
zend_type_error("Value must be of type string|int|float|null, %s given", zend_zval_type_name(val));
55775590
return -1;
55785591
}
55795592
smart_str_appendl(querystr, pad, pad_len);

ext/pgsql/tests/05large_object.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,28 @@ if (!file_exists($path . 'php.gif.exported')) {
6868
@unlink($path . 'php.gif.exported');
6969
pg_query($db, 'commit');
7070

71+
/* invalid OID values */
72+
try {
73+
pg_lo_create(-15);
74+
} catch (\ValueError $e) {
75+
echo $e->getMessage(), \PHP_EOL;
76+
}
77+
try {
78+
pg_lo_create($db, -15);
79+
} catch (\ValueError $e) {
80+
echo $e->getMessage(), \PHP_EOL;
81+
}
82+
try {
83+
pg_lo_create('giberrish');
84+
} catch (\ValueError $e) {
85+
echo $e->getMessage(), \PHP_EOL;
86+
}
87+
try {
88+
pg_lo_create($db, 'giberrish');
89+
} catch (\ValueError $e) {
90+
echo $e->getMessage(), \PHP_EOL;
91+
}
92+
7193
echo "OK";
7294
?>
7395
--EXPECT--
@@ -79,4 +101,8 @@ unlink LO
79101
Test without connection
80102
Test with string oid value
81103
import/export LO
104+
Invalid OID value passed
105+
Invalid OID value passed
106+
Invalid OID value passed
107+
Invalid OID value passed
82108
OK

ext/pgsql/tests/10pg_convert_9.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,34 @@ $fields = array('num'=>'1234', 'str'=>'AAA', 'bin'=>'BBB');
1818
$converted = pg_convert($db, $table_name, $fields);
1919

2020
var_dump($converted);
21+
22+
/* Invalid values */
23+
try {
24+
$converted = pg_convert($db, $table_name, [5 => 'AAA']);
25+
} catch (\ValueError $e) {
26+
echo $e->getMessage(), \PHP_EOL;
27+
}
28+
try {
29+
$converted = pg_convert($db, $table_name, ['AAA']);
30+
} catch (\ValueError $e) {
31+
echo $e->getMessage(), \PHP_EOL;
32+
}
33+
try {
34+
$converted = pg_convert($db, $table_name, ['num' => []]);
35+
} catch (\TypeError $e) {
36+
echo $e->getMessage(), \PHP_EOL;
37+
}
38+
try {
39+
$converted = pg_convert($db, $table_name, ['num' => new stdClass()]);
40+
} catch (\TypeError $e) {
41+
echo $e->getMessage(), \PHP_EOL;
42+
}
43+
try {
44+
$converted = pg_convert($db, $table_name, ['num' => $db]);
45+
var_dump($converted);
46+
} catch (\TypeError $e) {
47+
echo $e->getMessage(), \PHP_EOL;
48+
}
2149
?>
2250
--EXPECT--
2351
array(3) {
@@ -28,3 +56,8 @@ array(3) {
2856
[""bin""]=>
2957
string(12) "E'\\x424242'"
3058
}
59+
Array of values must be an associative array with string keys
60+
Array of values must be an associative array with string keys
61+
Values must be of type string|int|float|bool|null, array given
62+
Values must be of type string|int|float|bool|null, stdClass given
63+
Values must be of type string|int|float|bool|null, resource given

0 commit comments

Comments
 (0)