Skip to content

Commit e51da3a

Browse files
committed
Introduce _php_ibase_get_vars_count()
1 parent 2feccbb commit e51da3a

File tree

2 files changed

+78
-7
lines changed

2 files changed

+78
-7
lines changed

ibase_query.c

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,18 +2223,88 @@ PHP_FUNCTION(ibase_param_info)
22232223
return;
22242224
}
22252225

2226-
ib_query = (ibase_query *)zend_fetch_resource_ex(result_arg, LE_QUERY, le_query);
22272226

2228-
if (ib_query->in_sqlda == NULL) {
2229-
RETURN_FALSE;
2227+
static int _php_ibase_get_vars_count(ibase_query *ib_query)
2228+
{
2229+
int rv = FAILURE;
2230+
// size_t buf_size = 128;
2231+
// ISC_UCHAR *buf = emalloc(buf_size);
2232+
2233+
ISC_UCHAR buf[64] = {0};
2234+
size_t buf_size = sizeof(buf);
2235+
2236+
size_t pos;
2237+
2238+
static ISC_UCHAR info_req[] = {
2239+
isc_info_sql_stmt_type,
2240+
isc_info_sql_select,
2241+
isc_info_sql_num_variables,
2242+
isc_info_sql_bind,
2243+
isc_info_sql_num_variables,
2244+
};
2245+
// _php_ibase_parse_info_retry:
2246+
// memset(buf, 0, buf_size);
2247+
pos = 0;
2248+
2249+
// Assume buf will be tagged with `isc_info_truncated` and later in parsing
2250+
// we will catch that. Until `isc_info_truncated` is reached assume pos +=
2251+
// 2, etc are safe.
2252+
if (isc_dsql_sql_info(IB_STATUS, &ib_query->stmt, sizeof(info_req), (ISC_SCHAR *)info_req, buf_size, (ISC_SCHAR *)buf)) {
2253+
_php_ibase_error();
2254+
goto _php_ibase_parse_info_fail;
2255+
}
2256+
2257+
int ctx = 0;
2258+
while((buf[pos] != isc_info_end) && (pos < buf_size))
2259+
{
2260+
const ISC_UCHAR tag = buf[pos++];
2261+
switch(tag) {
2262+
case isc_info_sql_stmt_type: {
2263+
const ISC_USHORT size = (ISC_USHORT)isc_portable_integer(&buf[pos], 2); pos += 2;
2264+
ib_query->statement_type = (ISC_UCHAR)isc_portable_integer(&buf[pos], size); pos += size;
2265+
} break;
2266+
case isc_info_sql_select: ctx = 1; break;
2267+
case isc_info_sql_bind: ctx = 2; break;
2268+
case isc_info_sql_num_variables: {
2269+
const ISC_USHORT size = (ISC_USHORT)isc_portable_integer(&buf[pos], 2); pos += 2;
2270+
const ISC_USHORT count = (ISC_USHORT)isc_portable_integer(&buf[pos], size); pos += size;
2271+
if(ctx == 1) {
2272+
ib_query->out_fields_count = count;
2273+
} else if(ctx == 2) {
2274+
ib_query->in_fields_count = count;
2275+
} else {
2276+
fbp_fatal("isc_info_sql_num_variables: unknown ctx %d", ctx);
2277+
}
2278+
ctx = 0;
2279+
} break;
2280+
case isc_info_truncated: {
2281+
fbp_notice("BUG: sql_info buffer truncated, current capacity: %ld", buf_size);
2282+
// Dynamic resize
2283+
// buf_size *= 2;
2284+
// buf = erealloc(buf, buf_size);
2285+
// goto _php_ibase_parse_info_retry;
2286+
} break;
2287+
case isc_info_error: {
2288+
fbp_fatal("sql_info buffer error, pos: %lu", pos);
2289+
goto _php_ibase_parse_info_fail;
2290+
} break;
2291+
default: {
2292+
fbp_fatal("BUG: unrecognized sql_info entry: %d, pos: %lu", tag, pos);
2293+
goto _php_ibase_parse_info_fail;
2294+
} break;
2295+
}
22302296
}
22312297

2232-
if (field_arg < 0 || field_arg >= ib_query->in_sqlda->sqld) {
2233-
RETURN_FALSE;
2298+
if(buf[pos] != isc_info_end) {
2299+
fbp_fatal("BUG: sql_info unexpected end of buffer at pos: %lu", pos);
2300+
goto _php_ibase_parse_info_fail;
22342301
}
22352302

2236-
_php_ibase_field_info(return_value,ib_query->in_sqlda->sqlvar + field_arg);
2303+
rv = SUCCESS;
2304+
2305+
_php_ibase_parse_info_fail:
2306+
// efree(buf);
2307+
return rv;
22372308
}
2238-
/* }}} */
22392309

22402310
#endif /* HAVE_IBASE */

php_ibase_includes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ extern "C" {
254254
#endif
255255

256256
void _php_ibase_insert_alias(HashTable *ht, const char *alias, size_t alias_len);
257+
static int _php_ibase_get_vars_count(ibase_query *ib_query);
257258

258259
#ifdef __cplusplus
259260
}

0 commit comments

Comments
 (0)