]> granicus.if.org Git - php/commitdiff
Promote invalid field to ValueError in pgsql
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 21 Sep 2020 14:11:50 +0000 (16:11 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 21 Sep 2020 15:00:23 +0000 (17:00 +0200)
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.

ext/opcache/Optimizer/zend_func_info.c
ext/pgsql/pgsql.c
ext/pgsql/pgsql.stub.php
ext/pgsql/pgsql_arginfo.h
ext/pgsql/tests/03sync_query.phpt

index 7471da8220b7639a9f68b8705cd667c7cf9b0de0..0d41c05f7adf4ec5ae7ae7cb8ff0f6ac78c21864 100644 (file)
@@ -702,16 +702,16 @@ static const func_info_t func_infos[] = {
        F1("pg_execute",                                                        MAY_BE_FALSE | MAY_BE_RESOURCE),
        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 ),
        F1("pg_field_table",                                            MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
-       F1("pg_field_name",                                                     MAY_BE_FALSE | MAY_BE_STRING),
-       F1("pg_field_type",                                                     MAY_BE_FALSE | MAY_BE_STRING),
-       F1("pg_field_type_oid",                                         MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
+       F1("pg_field_name",                                                     MAY_BE_STRING),
+       F1("pg_field_type",                                                     MAY_BE_STRING),
+       F1("pg_field_type_oid",                                         MAY_BE_LONG | MAY_BE_STRING),
        F1("pg_fetch_result",                                           MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING),
        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),
        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),
        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),
        F1("pg_fetch_object",                                           MAY_BE_FALSE | MAY_BE_OBJECT),
        F1("pg_fetch_all",                                                      MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_ARRAY),
-       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),
+       F1("pg_fetch_all_columns",                                      MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_NULL | MAY_BE_ARRAY_OF_STRING),
        F1("pg_last_oid",                                                       MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
        F1("pg_lo_create",                                                      MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING),
        F1("pg_lo_open",                                                        MAY_BE_FALSE | MAY_BE_RESOURCE),
index 779c1f444b93f0a1790706f4ebb762118d579c32..b2b08f7fc1619f14fef90092174ef0706c9285e2 100644 (file)
@@ -1560,8 +1560,8 @@ PHP_FUNCTION(pg_field_table)
        }
 
        if (fnum >= PQnfields(pg_result->result)) {
-               php_error_docref(NULL, E_WARNING, "Bad field offset specified");
-               RETURN_FALSE;
+               zend_argument_value_error(2, "must be less than the number of fields for this result set");
+               RETURN_THROWS();
        }
 
        oid = PQftable(pg_result->result, (int)fnum);
@@ -1650,8 +1650,8 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ
        pgsql_result = pg_result->result;
 
        if (field >= PQnfields(pgsql_result)) {
-               php_error_docref(NULL, E_WARNING, "Bad field offset specified");
-               RETURN_FALSE;
+               zend_argument_value_error(2, "must be less than the number of fields for this result set");
+               RETURN_THROWS();
        }
 
        switch (entry_type) {
@@ -1728,6 +1728,29 @@ PHP_FUNCTION(pg_field_num)
 }
 /* }}} */
 
+static zend_long field_arg_to_offset(
+               PGresult *result, zend_string *field_name, zend_long field_offset, int arg_num) {
+       if (field_name) {
+               field_offset = PQfnumber(result, ZSTR_VAL(field_name));
+               if (field_offset < 0) {
+                       /* Avoid displaying the argument name, as the signature is overloaded and the name
+                        * might not line up. */
+                       zend_value_error("Argument #%d must be a field name from this result set", arg_num);
+                       return -1;
+               }
+       } else {
+               if (field_offset < 0) {
+                       zend_value_error("Argument #%d must be greater than or equal to 0", arg_num);
+                       return -1;
+               }
+               if (field_offset >= PQnfields(result)) {
+                       zend_value_error("Argument #%d must be less than the number of fields for this result set", arg_num);
+                       return -1;
+               }
+       }
+       return field_offset;
+}
+
 /* {{{ Returns values from a result identifier */
 PHP_FUNCTION(pg_fetch_result)
 {
@@ -1777,21 +1800,10 @@ PHP_FUNCTION(pg_fetch_result)
                }
                pgsql_row = (int)row;
        }
-       if (field_name) {
-               field_offset = PQfnumber(pgsql_result, ZSTR_VAL(field_name));
-               if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) {
-                       php_error_docref(NULL, E_WARNING, "Bad column offset specified");
-                       RETURN_FALSE;
-               }
-       } else {
-               if (field_offset < 0) {
-                       zend_argument_value_error(argc, "must be greater than or equal to 0");
-                       RETURN_THROWS();
-               }
-               if (field_offset >= PQnfields(pgsql_result)) {
-                       php_error_docref(NULL, E_WARNING, "Bad column offset specified");
-                       RETURN_FALSE;
-               }
+
+       field_offset = field_arg_to_offset(pgsql_result, field_name, field_offset, argc);
+       if (field_offset < 0) {
+               RETURN_THROWS();
        }
 
        if (PQgetisnull(pgsql_result, pgsql_row, field_offset)) {
@@ -2037,8 +2049,8 @@ PHP_FUNCTION(pg_fetch_all_columns)
 
        num_fields = PQnfields(pgsql_result);
        if (colno >= (zend_long)num_fields) {
-               php_error_docref(NULL, E_WARNING, "Invalid column number '" ZEND_LONG_FMT "'", colno);
-               RETURN_FALSE;
+               zend_argument_value_error(2, "must be less than the number of fields for this result set");
+               RETURN_THROWS();
        }
 
        array_init(return_value);
@@ -2134,20 +2146,9 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
                pgsql_row = (int)row;
        }
 
-       if (field_name) {
-               field_offset = PQfnumber(pgsql_result, ZSTR_VAL(field_name));
-               if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) {
-                       php_error_docref(NULL, E_WARNING, "Bad column offset specified");
-                       RETURN_FALSE;
-               }
-       } else {
-               if (field_offset < 0) {
-                       zend_argument_value_error(argc, "must be greater than or equal to 0");
-               }
-               if (field_offset >= PQnfields(pgsql_result)) {
-                       php_error_docref(NULL, E_WARNING, "Bad column offset specified");
-                       RETURN_FALSE;
-               }
+       field_offset = field_arg_to_offset(pgsql_result, field_name, field_offset, argc);
+       if (field_offset < 0) {
+               RETURN_THROWS();
        }
 
        switch (entry_type) {
index 181d62c9cdd67f676528b57d90e75cfe5bda9703..4e2b21e4f2d8101c2bd4c8d9b2be3530ca9524db 100644 (file)
@@ -118,37 +118,37 @@ function pg_last_notice($connection, int $option = PGSQL_NOTICE_LAST): array|str
 function pg_field_table($result, int $field_number, bool $oid_only = false): string|int|false {}
 
 /** @param resource $result */
-function pg_field_name($result, int $field_number): string|false {}
+function pg_field_name($result, int $field_number): string {}
 
 /**
  * @param resource $result
  * @alias pg_field_name
  * @deprecated
  */
-function pg_fieldname($result, int $field_number): string|false {}
+function pg_fieldname($result, int $field_number): string {}
 
 /** @param resource $result */
-function pg_field_size($result, int $field_number): int|false {}
+function pg_field_size($result, int $field_number): int {}
 
 /**
  * @param resource $result
  * @alias pg_field_size
  * @deprecated
  */
-function pg_fieldsize($result, int $field_number): int|false {}
+function pg_fieldsize($result, int $field_number): int {}
 
 /** @param resource $result */
-function pg_field_type($result, int $field_number): string|false {}
+function pg_field_type($result, int $field_number): string {}
 
 /**
  * @param resource $result
  * @alias pg_field_type
  * @deprecated
  */
-function pg_fieldtype($result, int $field_number): string|false {}
+function pg_fieldtype($result, int $field_number): string {}
 
 /** @param resource $result */
-function pg_field_type_oid($result, int $field_number): string|int|false {}
+function pg_field_type_oid($result, int $field_number): string|int {}
 
 /** @param resource $result */
 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 =
 function pg_fetch_all($result, int $result_type = PGSQL_ASSOC): array|false {}
 
 /** @param resource $result */
-function pg_fetch_all_columns($result, int $column_number = 0): array|false {}
+function pg_fetch_all_columns($result, int $field_number = 0): array {}
 
 /** @param resource $result */
 function pg_result_seek($result, int $row_number): bool {}
index c2b23871548bec4c768cc2d3b7b21eb17c9f327e..f6cc2cf69c602145ec467a28c8d32ce0d89eeb11 100644 (file)
@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 87152e947ab7bfb3a9d7df30dd6fbccac504504e */
+ * Stub hash: 3f5e097d572721b42f2ad438c2af8c0d1f9c9086 */
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1)
        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
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, oid_only, _IS_BOOL, 0, "false")
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_name, 0, 2, MAY_BE_STRING|MAY_BE_FALSE)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_name, 0, 2, IS_STRING, 0)
        ZEND_ARG_INFO(0, result)
        ZEND_ARG_TYPE_INFO(0, field_number, IS_LONG, 0)
 ZEND_END_ARG_INFO()
 
 #define arginfo_pg_fieldname arginfo_pg_field_name
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_size, 0, 2, MAY_BE_LONG|MAY_BE_FALSE)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_field_size, 0, 2, IS_LONG, 0)
        ZEND_ARG_INFO(0, result)
        ZEND_ARG_TYPE_INFO(0, field_number, IS_LONG, 0)
 ZEND_END_ARG_INFO()
@@ -111,7 +111,7 @@ ZEND_END_ARG_INFO()
 
 #define arginfo_pg_fieldtype arginfo_pg_field_name
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_type_oid, 0, 2, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_field_type_oid, 0, 2, MAY_BE_STRING|MAY_BE_LONG)
        ZEND_ARG_INFO(0, result)
        ZEND_ARG_TYPE_INFO(0, field_number, IS_LONG, 0)
 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
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_type, IS_LONG, 0, "PGSQL_ASSOC")
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_all_columns, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all_columns, 0, 1, IS_ARRAY, 0)
        ZEND_ARG_INFO(0, result)
-       ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, column_number, IS_LONG, 0, "0")
+       ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, field_number, IS_LONG, 0, "0")
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_result_seek, 0, 2, _IS_BOOL, 0)
index 1cd439bc204ac1c0ff0c9c038f7693a3cbc5ceee..ce062cafd6bfbc965bfd19b123943a066d11567e 100644 (file)
@@ -31,6 +31,32 @@ for ($i=0; $i < $rows; $i++)
     pg_fetch_result($result, $i, 0);
 }
 
+try {
+    pg_fetch_result($result, 0, -1);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_fetch_result($result, 0, 3);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_fetch_result($result, 0, "unknown");
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_fetch_all_columns($result, -1);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_fetch_all_columns($result, 3);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+
 pg_result_error($result);
 if (function_exists('pg_result_error_field')) {
     pg_result_error_field($result, PGSQL_DIAG_SEVERITY);
@@ -61,6 +87,42 @@ pg_field_type($result, 0);
 pg_field_prtlen($result, 0);
 pg_field_is_null($result, 0);
 
+try {
+    pg_field_is_null($result, -1);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_field_is_null($result, 3);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_field_is_null($result, "unknown");
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_field_name($result, -1);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_field_name($result, 3);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_field_table($result, -1);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    pg_field_table($result, 3);
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+
 $result = pg_query($db, "INSERT INTO ".$table_name." VALUES (9999, 'ABC');");
 pg_last_oid($result);
 
@@ -70,4 +132,16 @@ pg_close($db);
 echo "OK";
 ?>
 --EXPECT--
+Argument #3 must be greater than or equal to 0
+Argument #3 must be less than the number of fields for this result set
+Argument #3 must be a field name from this result set
+pg_fetch_all_columns(): Argument #2 ($field_number) must be greater than or equal to 0
+pg_fetch_all_columns(): Argument #2 ($field_number) must be less than the number of fields for this result set
+Argument #2 must be greater than or equal to 0
+Argument #2 must be less than the number of fields for this result set
+Argument #2 must be a field name from this result set
+pg_field_name(): Argument #2 ($field_number) must be greater than or equal to 0
+pg_field_name(): Argument #2 ($field_number) must be less than the number of fields for this result set
+pg_field_table(): Argument #2 ($field_number) must be greater than or equal to 0
+pg_field_table(): Argument #2 ($field_number) must be less than the number of fields for this result set
 OK