Skip to content

Commit 2f84315

Browse files
committed
ext/pgsql: Refactor parameter parsing for a few functions
1 parent 67e5d6c commit 2f84315

File tree

1 file changed

+93
-71
lines changed

1 file changed

+93
-71
lines changed

ext/pgsql/pgsql.c

Lines changed: 93 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,39 +1978,12 @@ PHP_FUNCTION(pg_fetch_result)
19781978
/* }}} */
19791979

19801980
/* {{{ void php_pgsql_fetch_hash */
1981-
static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_type, int into_object)
1981+
static void php_pgsql_fetch_hash(zval *return_value, const zval *result, zend_long row, bool row_is_null, zend_long result_type)
19821982
{
1983-
zval *result;
19841983
PGresult *pgsql_result;
19851984
pgsql_result_handle *pg_result;
19861985
int i, num_fields, pgsql_row;
1987-
zend_long row;
1988-
bool row_is_null = true;
19891986
char *field_name;
1990-
HashTable *ctor_params = NULL;
1991-
zend_class_entry *ce = NULL;
1992-
1993-
if (into_object) {
1994-
ZEND_PARSE_PARAMETERS_START(1, 4)
1995-
Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce)
1996-
Z_PARAM_OPTIONAL
1997-
Z_PARAM_LONG_OR_NULL(row, row_is_null)
1998-
Z_PARAM_CLASS(ce)
1999-
Z_PARAM_ARRAY_HT(ctor_params)
2000-
ZEND_PARSE_PARAMETERS_END();
2001-
2002-
if (!ce) {
2003-
ce = zend_standard_class_def;
2004-
}
2005-
result_type = PGSQL_ASSOC;
2006-
} else {
2007-
ZEND_PARSE_PARAMETERS_START(1, 3)
2008-
Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce)
2009-
Z_PARAM_OPTIONAL
2010-
Z_PARAM_LONG_OR_NULL(row, row_is_null)
2011-
Z_PARAM_LONG(result_type)
2012-
ZEND_PARSE_PARAMETERS_END();
2013-
}
20141987

20151988
if (!row_is_null && row < 0) {
20161989
zend_argument_value_error(2, "must be greater than or equal to 0");
@@ -2054,7 +2027,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
20542027
add_assoc_null(return_value, field_name);
20552028
}
20562029
} else {
2057-
char *element = PQgetvalue(pgsql_result, pgsql_row, i);
2030+
const char *element = PQgetvalue(pgsql_result, pgsql_row, i);
20582031
if (element) {
20592032
const size_t element_len = strlen(element);
20602033

@@ -2069,66 +2042,116 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
20692042
}
20702043
}
20712044
}
2072-
2073-
if (into_object) {
2074-
zval dataset;
2075-
2076-
ZVAL_COPY_VALUE(&dataset, return_value);
2077-
zend_result obj_initialized = object_init_ex(return_value, ce);
2078-
if (UNEXPECTED(obj_initialized == FAILURE)) {
2079-
RETURN_THROWS();
2080-
}
2081-
if (!ce->default_properties_count && !ce->__set) {
2082-
Z_OBJ_P(return_value)->properties = Z_ARR(dataset);
2083-
} else {
2084-
zend_merge_properties(return_value, Z_ARRVAL(dataset));
2085-
zval_ptr_dtor(&dataset);
2086-
}
2087-
2088-
if (ce->constructor) {
2089-
zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value),
2090-
/* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params);
2091-
} else if (ctor_params && zend_hash_num_elements(ctor_params) > 0) {
2092-
zend_argument_value_error(3,
2093-
"must be empty when the specified class (%s) does not have a constructor",
2094-
ZSTR_VAL(ce->name)
2095-
);
2096-
}
2097-
}
20982045
}
20992046
/* }}} */
21002047

21012048
/* {{{ Get a row as an enumerated array */
21022049
PHP_FUNCTION(pg_fetch_row)
21032050
{
2104-
php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_NUM, 0);
2051+
zval *result;
2052+
zend_long row = 0;
2053+
bool row_is_null = true;
2054+
zend_long result_type = PGSQL_NUM;
2055+
2056+
ZEND_PARSE_PARAMETERS_START(1, 3)
2057+
Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce)
2058+
Z_PARAM_OPTIONAL
2059+
Z_PARAM_LONG_OR_NULL(row, row_is_null)
2060+
Z_PARAM_LONG(result_type)
2061+
ZEND_PARSE_PARAMETERS_END();
2062+
2063+
php_pgsql_fetch_hash(return_value, result, row, row_is_null, result_type);
21052064
}
21062065
/* }}} */
21072066

21082067
/* {{{ Fetch a row as an assoc array */
21092068
PHP_FUNCTION(pg_fetch_assoc)
21102069
{
2111-
/* pg_fetch_assoc() is added from PHP 4.3.0. It should raise error, when
2112-
there is 3rd parameter */
2113-
if (ZEND_NUM_ARGS() > 2)
2114-
WRONG_PARAM_COUNT;
2115-
php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 0);
2070+
zval *result;
2071+
zend_long row = 0;
2072+
bool row_is_null = true;
2073+
2074+
ZEND_PARSE_PARAMETERS_START(1, 2)
2075+
Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce)
2076+
Z_PARAM_OPTIONAL
2077+
Z_PARAM_LONG_OR_NULL(row, row_is_null)
2078+
ZEND_PARSE_PARAMETERS_END();
2079+
2080+
php_pgsql_fetch_hash(return_value, result, row, row_is_null, PGSQL_ASSOC);
21162081
}
21172082
/* }}} */
21182083

21192084
/* {{{ Fetch a row as an array */
21202085
PHP_FUNCTION(pg_fetch_array)
21212086
{
2122-
php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_BOTH, 0);
2087+
zval *result;
2088+
zend_long row = 0;
2089+
bool row_is_null = true;
2090+
zend_long result_type = PGSQL_BOTH;
2091+
2092+
ZEND_PARSE_PARAMETERS_START(1, 3)
2093+
Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce)
2094+
Z_PARAM_OPTIONAL
2095+
Z_PARAM_LONG_OR_NULL(row, row_is_null)
2096+
Z_PARAM_LONG(result_type)
2097+
ZEND_PARSE_PARAMETERS_END();
2098+
2099+
php_pgsql_fetch_hash(return_value, result, row, row_is_null, result_type);
21232100
}
21242101
/* }}} */
21252102

21262103
/* {{{ Fetch a row as an object */
21272104
PHP_FUNCTION(pg_fetch_object)
21282105
{
2106+
zval *result;
2107+
zend_long row = 0;
2108+
bool row_is_null = true;
2109+
zend_class_entry *ce = NULL;
2110+
HashTable *ctor_params = NULL;
2111+
2112+
ZEND_PARSE_PARAMETERS_START(1, 4)
2113+
Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce)
2114+
Z_PARAM_OPTIONAL
2115+
Z_PARAM_LONG_OR_NULL(row, row_is_null)
2116+
Z_PARAM_CLASS(ce)
2117+
Z_PARAM_ARRAY_HT(ctor_params)
2118+
ZEND_PARSE_PARAMETERS_END();
2119+
2120+
if (!ce) {
2121+
ce = zend_standard_class_def;
2122+
}
2123+
2124+
if (!ce->constructor && ctor_params && zend_hash_num_elements(ctor_params) > 0) {
2125+
zend_argument_value_error(3,
2126+
"must be empty when the specified class (%s) does not have a constructor",
2127+
ZSTR_VAL(ce->name)
2128+
);
2129+
RETURN_THROWS();
2130+
}
2131+
21292132
/* pg_fetch_object() allowed result_type used to be. 3rd parameter
21302133
must be allowed for compatibility */
2131-
php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 1);
2134+
zval dataset;
2135+
php_pgsql_fetch_hash(&dataset, result, row, row_is_null, PGSQL_ASSOC);
2136+
2137+
// TODO: Check CE is an instantiable class earlier?
2138+
zend_result obj_initialized = object_init_ex(return_value, ce);
2139+
if (UNEXPECTED(obj_initialized == FAILURE)) {
2140+
zval_ptr_dtor(&dataset);
2141+
RETURN_THROWS();
2142+
}
2143+
if (!ce->default_properties_count && !ce->__set) {
2144+
Z_OBJ_P(return_value)->properties = Z_ARR(dataset);
2145+
} else {
2146+
zend_merge_properties(return_value, Z_ARRVAL(dataset));
2147+
zval_ptr_dtor(&dataset);
2148+
}
2149+
2150+
// TODO: Need to grab constructor via object handler as this allows instantiating internal objects with overriden get_constructor
2151+
if (ce->constructor) {
2152+
zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value),
2153+
/* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params);
2154+
}
21322155
}
21332156
/* }}} */
21342157

@@ -2862,19 +2885,18 @@ PHP_FUNCTION(pg_lo_import)
28622885
Oid returned_oid;
28632886
pgsql_link_handle *link;
28642887

2865-
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
2866-
"OP|z", &pgsql_link, pgsql_link_ce, &file_in, &oid) == SUCCESS) {
2888+
/* Deprecated signature with implicit connection */
2889+
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "P|z", &file_in, &oid) == FAILURE) {
2890+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP|z", &pgsql_link, pgsql_link_ce, &file_in, &oid) == FAILURE) {
2891+
RETURN_THROWS();
2892+
}
28672893
link = Z_PGSQL_LINK_P(pgsql_link);
28682894
CHECK_PGSQL_LINK(link);
2869-
}
2870-
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
2871-
"P|z", &file_in, &oid) == SUCCESS) {
2895+
} else {
2896+
/* Load implicit connection */
28722897
link = FETCH_DEFAULT_LINK();
28732898
CHECK_DEFAULT_LINK(link);
28742899
}
2875-
else {
2876-
WRONG_PARAM_COUNT;
2877-
}
28782900

28792901
if (php_check_open_basedir(ZSTR_VAL(file_in))) {
28802902
RETURN_FALSE;

0 commit comments

Comments
 (0)