Skip to content

Commit 9825014

Browse files
committed
ext/pgsql: Refactor parameter parsing for a few functions
1 parent 4461e29 commit 9825014

File tree

1 file changed

+93
-72
lines changed

1 file changed

+93
-72
lines changed

ext/pgsql/pgsql.c

Lines changed: 93 additions & 72 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,67 +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-
zval_ptr_dtor(&dataset);
2080-
RETURN_THROWS();
2081-
}
2082-
if (!ce->default_properties_count && !ce->__set) {
2083-
Z_OBJ_P(return_value)->properties = Z_ARR(dataset);
2084-
} else {
2085-
zend_merge_properties(return_value, Z_ARRVAL(dataset));
2086-
zval_ptr_dtor(&dataset);
2087-
}
2088-
2089-
if (ce->constructor) {
2090-
zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value),
2091-
/* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params);
2092-
} else if (ctor_params && zend_hash_num_elements(ctor_params) > 0) {
2093-
zend_argument_value_error(3,
2094-
"must be empty when the specified class (%s) does not have a constructor",
2095-
ZSTR_VAL(ce->name)
2096-
);
2097-
}
2098-
}
20992045
}
21002046
/* }}} */
21012047

21022048
/* {{{ Get a row as an enumerated array */
21032049
PHP_FUNCTION(pg_fetch_row)
21042050
{
2105-
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);
21062064
}
21072065
/* }}} */
21082066

21092067
/* {{{ Fetch a row as an assoc array */
21102068
PHP_FUNCTION(pg_fetch_assoc)
21112069
{
2112-
/* pg_fetch_assoc() is added from PHP 4.3.0. It should raise error, when
2113-
there is 3rd parameter */
2114-
if (ZEND_NUM_ARGS() > 2)
2115-
WRONG_PARAM_COUNT;
2116-
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);
21172081
}
21182082
/* }}} */
21192083

21202084
/* {{{ Fetch a row as an array */
21212085
PHP_FUNCTION(pg_fetch_array)
21222086
{
2123-
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);
21242100
}
21252101
/* }}} */
21262102

21272103
/* {{{ Fetch a row as an object */
21282104
PHP_FUNCTION(pg_fetch_object)
21292105
{
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+
21302132
/* pg_fetch_object() allowed result_type used to be. 3rd parameter
21312133
must be allowed for compatibility */
2132-
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 overridden 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+
}
21332155
}
21342156
/* }}} */
21352157

@@ -2863,19 +2885,18 @@ PHP_FUNCTION(pg_lo_import)
28632885
Oid returned_oid;
28642886
pgsql_link_handle *link;
28652887

2866-
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
2867-
"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+
}
28682893
link = Z_PGSQL_LINK_P(pgsql_link);
28692894
CHECK_PGSQL_LINK(link);
2870-
}
2871-
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
2872-
"P|z", &file_in, &oid) == SUCCESS) {
2895+
} else {
2896+
/* Load implicit connection */
28732897
link = FETCH_DEFAULT_LINK();
28742898
CHECK_DEFAULT_LINK(link);
28752899
}
2876-
else {
2877-
WRONG_PARAM_COUNT;
2878-
}
28792900

28802901
if (php_check_open_basedir(ZSTR_VAL(file_in))) {
28812902
RETURN_FALSE;

0 commit comments

Comments
 (0)