Skip to content

Commit 54f03d3

Browse files
committed
Promote invalid field to ValueError in pgsql
The same error condition is a ValueError in mysqli, be consistent. Additionally, do not display the argument name for these errors. As the signatures are overloaded, the argument name may not match the meaning at all.
1 parent 68a9075 commit 54f03d3

File tree

5 files changed

+128
-53
lines changed

5 files changed

+128
-53
lines changed

ext/opcache/Optimizer/zend_func_info.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,16 +702,16 @@ static const func_info_t func_infos[] = {
702702
F1("pg_execute", MAY_BE_FALSE | MAY_BE_RESOURCE),
703703
FN("pg_last_notice", MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_STRING | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY ),
704704
F1("pg_field_table", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
705-
F1("pg_field_name", MAY_BE_FALSE | MAY_BE_STRING),
706-
F1("pg_field_type", MAY_BE_FALSE | MAY_BE_STRING),
707-
F1("pg_field_type_oid", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
705+
F1("pg_field_name", MAY_BE_STRING),
706+
F1("pg_field_type", MAY_BE_STRING),
707+
F1("pg_field_type_oid", MAY_BE_LONG | MAY_BE_STRING),
708708
F1("pg_fetch_result", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING),
709709
F1("pg_fetch_row", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_STRING),
710710
F1("pg_fetch_assoc", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_STRING),
711711
F1("pg_fetch_array", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_STRING),
712712
F1("pg_fetch_object", MAY_BE_FALSE | MAY_BE_OBJECT),
713713
F1("pg_fetch_all", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_ARRAY),
714-
F1("pg_fetch_all_columns", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_STRING),
714+
F1("pg_fetch_all_columns", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_STRING),
715715
F1("pg_last_oid", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
716716
F1("pg_lo_create", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
717717
F1("pg_lo_open", MAY_BE_FALSE | MAY_BE_RESOURCE),

ext/pgsql/pgsql.c

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,8 +1560,8 @@ PHP_FUNCTION(pg_field_table)
15601560
}
15611561

15621562
if (fnum >= PQnfields(pg_result->result)) {
1563-
php_error_docref(NULL, E_WARNING, "Bad field offset specified");
1564-
RETURN_FALSE;
1563+
zend_argument_value_error(2, "must be less than the number of fields for this result set");
1564+
RETURN_THROWS();
15651565
}
15661566

15671567
oid = PQftable(pg_result->result, (int)fnum);
@@ -1650,8 +1650,8 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ
16501650
pgsql_result = pg_result->result;
16511651

16521652
if (field >= PQnfields(pgsql_result)) {
1653-
php_error_docref(NULL, E_WARNING, "Bad field offset specified");
1654-
RETURN_FALSE;
1653+
zend_argument_value_error(2, "must be less than the number of fields for this result set");
1654+
RETURN_THROWS();
16551655
}
16561656

16571657
switch (entry_type) {
@@ -1728,6 +1728,29 @@ PHP_FUNCTION(pg_field_num)
17281728
}
17291729
/* }}} */
17301730

1731+
static zend_long field_arg_to_offset(
1732+
PGresult *result, zend_string *field_name, zend_long field_offset, int arg_num) {
1733+
if (field_name) {
1734+
field_offset = PQfnumber(result, ZSTR_VAL(field_name));
1735+
if (field_offset < 0) {
1736+
/* Avoid displaying the argument name, as the signature is overloaded and the name
1737+
* might not line up. */
1738+
zend_value_error("Argument #%d must be a field name from this result set", arg_num);
1739+
return -1;
1740+
}
1741+
} else {
1742+
if (field_offset < 0) {
1743+
zend_value_error("Argument #%d must be greater than or equal to 0", arg_num);
1744+
return -1;
1745+
}
1746+
if (field_offset >= PQnfields(result)) {
1747+
zend_value_error("Argument #%d must be less than the number of fields for this result set", arg_num);
1748+
return -1;
1749+
}
1750+
}
1751+
return field_offset;
1752+
}
1753+
17311754
/* {{{ Returns values from a result identifier */
17321755
PHP_FUNCTION(pg_fetch_result)
17331756
{
@@ -1777,21 +1800,10 @@ PHP_FUNCTION(pg_fetch_result)
17771800
}
17781801
pgsql_row = (int)row;
17791802
}
1780-
if (field_name) {
1781-
field_offset = PQfnumber(pgsql_result, ZSTR_VAL(field_name));
1782-
if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) {
1783-
php_error_docref(NULL, E_WARNING, "Bad column offset specified");
1784-
RETURN_FALSE;
1785-
}
1786-
} else {
1787-
if (field_offset < 0) {
1788-
zend_argument_value_error(argc, "must be greater than or equal to 0");
1789-
RETURN_THROWS();
1790-
}
1791-
if (field_offset >= PQnfields(pgsql_result)) {
1792-
php_error_docref(NULL, E_WARNING, "Bad column offset specified");
1793-
RETURN_FALSE;
1794-
}
1803+
1804+
field_offset = field_arg_to_offset(pgsql_result, field_name, field_offset, argc);
1805+
if (field_offset < 0) {
1806+
RETURN_THROWS();
17951807
}
17961808

17971809
if (PQgetisnull(pgsql_result, pgsql_row, field_offset)) {
@@ -2037,8 +2049,8 @@ PHP_FUNCTION(pg_fetch_all_columns)
20372049

20382050
num_fields = PQnfields(pgsql_result);
20392051
if (colno >= (zend_long)num_fields) {
2040-
php_error_docref(NULL, E_WARNING, "Invalid column number '" ZEND_LONG_FMT "'", colno);
2041-
RETURN_FALSE;
2052+
zend_argument_value_error(2, "must be less than the number of fields for this result set");
2053+
RETURN_THROWS();
20422054
}
20432055

20442056
array_init(return_value);
@@ -2134,20 +2146,9 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
21342146
pgsql_row = (int)row;
21352147
}
21362148

2137-
if (field_name) {
2138-
field_offset = PQfnumber(pgsql_result, ZSTR_VAL(field_name));
2139-
if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) {
2140-
php_error_docref(NULL, E_WARNING, "Bad column offset specified");
2141-
RETURN_FALSE;
2142-
}
2143-
} else {
2144-
if (field_offset < 0) {
2145-
zend_argument_value_error(argc, "must be greater than or equal to 0");
2146-
}
2147-
if (field_offset >= PQnfields(pgsql_result)) {
2148-
php_error_docref(NULL, E_WARNING, "Bad column offset specified");
2149-
RETURN_FALSE;
2150-
}
2149+
field_offset = field_arg_to_offset(pgsql_result, field_name, field_offset, argc);
2150+
if (field_offset < 0) {
2151+
RETURN_THROWS();
21512152
}
21522153

21532154
switch (entry_type) {

ext/pgsql/pgsql.stub.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,37 +118,37 @@ function pg_last_notice($connection, int $option = PGSQL_NOTICE_LAST): array|str
118118
function pg_field_table($result, int $field_number, bool $oid_only = false): string|int|false {}
119119

120120
/** @param resource $result */
121-
function pg_field_name($result, int $field_number): string|false {}
121+
function pg_field_name($result, int $field_number): string {}
122122

123123
/**
124124
* @param resource $result
125125
* @alias pg_field_name
126126
* @deprecated
127127
*/
128-
function pg_fieldname($result, int $field_number): string|false {}
128+
function pg_fieldname($result, int $field_number): string {}
129129

130130
/** @param resource $result */
131-
function pg_field_size($result, int $field_number): int|false {}
131+
function pg_field_size($result, int $field_number): int {}
132132

133133
/**
134134
* @param resource $result
135135
* @alias pg_field_size
136136
* @deprecated
137137
*/
138-
function pg_fieldsize($result, int $field_number): int|false {}
138+
function pg_fieldsize($result, int $field_number): int {}
139139

140140
/** @param resource $result */
141-
function pg_field_type($result, int $field_number): string|false {}
141+
function pg_field_type($result, int $field_number): string {}
142142

143143
/**
144144
* @param resource $result
145145
* @alias pg_field_type
146146
* @deprecated
147147
*/
148-
function pg_fieldtype($result, int $field_number): string|false {}
148+
function pg_fieldtype($result, int $field_number): string {}
149149

150150
/** @param resource $result */
151-
function pg_field_type_oid($result, int $field_number): string|int|false {}
151+
function pg_field_type_oid($result, int $field_number): string|int {}
152152

153153
/** @param resource $result */
154154
function pg_field_num($result, string $field_name): int {}
@@ -196,7 +196,7 @@ function pg_fetch_object($result, ?int $row_number = null, string $class_name =
196196
function pg_fetch_all($result, int $result_type = PGSQL_ASSOC): array|false {}
197197

198198
/** @param resource $result */
199-
function pg_fetch_all_columns($result, int $column_number = 0): array|false {}
199+
function pg_fetch_all_columns($result, int $field_number = 0): array {}
200200

201201
/** @param resource $result */
202202
function pg_result_seek($result, int $row_number): bool {}

ext/pgsql/pgsql_arginfo.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 87152e947ab7bfb3a9d7df30dd6fbccac504504e */
2+
* Stub hash: 3f5e097d572721b42f2ad438c2af8c0d1f9c9086 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0)
@@ -93,14 +93,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_table, 0, 2, MAY_BE_STR
9393
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, oid_only, _IS_BOOL, 0, "false")
9494
ZEND_END_ARG_INFO()
9595

96-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_name, 0, 2, MAY_BE_STRING|MAY_BE_FALSE)
96+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_name, 0, 2, IS_STRING, 0)
9797
ZEND_ARG_INFO(0, result)
9898
ZEND_ARG_TYPE_INFO(0, field_number, IS_LONG, 0)
9999
ZEND_END_ARG_INFO()
100100

101101
#define arginfo_pg_fieldname arginfo_pg_field_name
102102

103-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_size, 0, 2, MAY_BE_LONG|MAY_BE_FALSE)
103+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_size, 0, 2, IS_LONG, 0)
104104
ZEND_ARG_INFO(0, result)
105105
ZEND_ARG_TYPE_INFO(0, field_number, IS_LONG, 0)
106106
ZEND_END_ARG_INFO()
@@ -111,7 +111,7 @@ ZEND_END_ARG_INFO()
111111

112112
#define arginfo_pg_fieldtype arginfo_pg_field_name
113113

114-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_type_oid, 0, 2, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE)
114+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_type_oid, 0, 2, MAY_BE_STRING|MAY_BE_LONG)
115115
ZEND_ARG_INFO(0, result)
116116
ZEND_ARG_TYPE_INFO(0, field_number, IS_LONG, 0)
117117
ZEND_END_ARG_INFO()
@@ -160,9 +160,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_all, 0, 1, MAY_BE_ARRAY
160160
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_type, IS_LONG, 0, "PGSQL_ASSOC")
161161
ZEND_END_ARG_INFO()
162162

163-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_all_columns, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE)
163+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all_columns, 0, 1, IS_ARRAY, 0)
164164
ZEND_ARG_INFO(0, result)
165-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, column_number, IS_LONG, 0, "0")
165+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, field_number, IS_LONG, 0, "0")
166166
ZEND_END_ARG_INFO()
167167

168168
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_result_seek, 0, 2, _IS_BOOL, 0)

ext/pgsql/tests/03sync_query.phpt

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,32 @@ for ($i=0; $i < $rows; $i++)
3131
pg_fetch_result($result, $i, 0);
3232
}
3333

34+
try {
35+
pg_fetch_result($result, 0, -1);
36+
} catch (ValueError $e) {
37+
echo $e->getMessage(), "\n";
38+
}
39+
try {
40+
pg_fetch_result($result, 0, 3);
41+
} catch (ValueError $e) {
42+
echo $e->getMessage(), "\n";
43+
}
44+
try {
45+
pg_fetch_result($result, 0, "unknown");
46+
} catch (ValueError $e) {
47+
echo $e->getMessage(), "\n";
48+
}
49+
try {
50+
pg_fetch_all_columns($result, -1);
51+
} catch (ValueError $e) {
52+
echo $e->getMessage(), "\n";
53+
}
54+
try {
55+
pg_fetch_all_columns($result, 3);
56+
} catch (ValueError $e) {
57+
echo $e->getMessage(), "\n";
58+
}
59+
3460
pg_result_error($result);
3561
if (function_exists('pg_result_error_field')) {
3662
pg_result_error_field($result, PGSQL_DIAG_SEVERITY);
@@ -61,6 +87,42 @@ pg_field_type($result, 0);
6187
pg_field_prtlen($result, 0);
6288
pg_field_is_null($result, 0);
6389

90+
try {
91+
pg_field_is_null($result, -1);
92+
} catch (ValueError $e) {
93+
echo $e->getMessage(), "\n";
94+
}
95+
try {
96+
pg_field_is_null($result, 3);
97+
} catch (ValueError $e) {
98+
echo $e->getMessage(), "\n";
99+
}
100+
try {
101+
pg_field_is_null($result, "unknown");
102+
} catch (ValueError $e) {
103+
echo $e->getMessage(), "\n";
104+
}
105+
try {
106+
pg_field_name($result, -1);
107+
} catch (ValueError $e) {
108+
echo $e->getMessage(), "\n";
109+
}
110+
try {
111+
pg_field_name($result, 3);
112+
} catch (ValueError $e) {
113+
echo $e->getMessage(), "\n";
114+
}
115+
try {
116+
pg_field_table($result, -1);
117+
} catch (ValueError $e) {
118+
echo $e->getMessage(), "\n";
119+
}
120+
try {
121+
pg_field_table($result, 3);
122+
} catch (ValueError $e) {
123+
echo $e->getMessage(), "\n";
124+
}
125+
64126
$result = pg_query($db, "INSERT INTO ".$table_name." VALUES (9999, 'ABC');");
65127
pg_last_oid($result);
66128

@@ -70,4 +132,16 @@ pg_close($db);
70132
echo "OK";
71133
?>
72134
--EXPECT--
135+
Argument #3 must be greater than or equal to 0
136+
Argument #3 must be less than the number of fields for this result set
137+
Argument #3 must be a field name from this result set
138+
pg_fetch_all_columns(): Argument #2 ($field_number) must be greater than or equal to 0
139+
pg_fetch_all_columns(): Argument #2 ($field_number) must be less than the number of fields for this result set
140+
Argument #2 must be greater than or equal to 0
141+
Argument #2 must be less than the number of fields for this result set
142+
Argument #2 must be a field name from this result set
143+
pg_field_name(): Argument #2 ($field_number) must be greater than or equal to 0
144+
pg_field_name(): Argument #2 ($field_number) must be less than the number of fields for this result set
145+
pg_field_table(): Argument #2 ($field_number) must be greater than or equal to 0
146+
pg_field_table(): Argument #2 ($field_number) must be less than the number of fields for this result set
73147
OK

0 commit comments

Comments
 (0)