diff options
-rw-r--r-- | ext/sqlite/php_sqlite.h | 2 | ||||
-rw-r--r-- | ext/sqlite/sqlite.c | 65 | ||||
-rwxr-xr-x | ext/sqlite/tests/sqlite_017.phpt | 33 |
3 files changed, 98 insertions, 2 deletions
diff --git a/ext/sqlite/php_sqlite.h b/ext/sqlite/php_sqlite.h index 37538ba30f..3f937e4656 100644 --- a/ext/sqlite/php_sqlite.h +++ b/ext/sqlite/php_sqlite.h @@ -78,6 +78,8 @@ PHP_FUNCTION(sqlite_error_string); PHP_FUNCTION(sqlite_create_aggregate); PHP_FUNCTION(sqlite_create_function); +PHP_FUNCTION(sqlite_udf_decode_binary); +PHP_FUNCTION(sqlite_udf_encode_binary); ZEND_BEGIN_MODULE_GLOBALS(sqlite) long assoc_case; diff --git a/ext/sqlite/sqlite.c b/ext/sqlite/sqlite.c index 49cdceb73c..416fab2a94 100644 --- a/ext/sqlite/sqlite.c +++ b/ext/sqlite/sqlite.c @@ -142,6 +142,8 @@ function_entry sqlite_functions[] = { PHP_FE(sqlite_unbuffered_query, NULL) PHP_FE(sqlite_create_aggregate, NULL) PHP_FE(sqlite_create_function, NULL) + PHP_FE(sqlite_udf_encode_binary, NULL) + PHP_FE(sqlite_udf_decode_binary, NULL) {NULL, NULL, NULL} }; @@ -1371,8 +1373,8 @@ PHP_FUNCTION(sqlite_current) } /* }}} */ -/* {{{ proto array sqlite_column(resource result, mixed index_or_name [, bool decode_binary]) - Fetches a column from the current row from a result set */ +/* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary]) + Fetches a column from the current row of a result set */ PHP_FUNCTION(sqlite_column) { zval *zres; @@ -1808,6 +1810,65 @@ PHP_FUNCTION(sqlite_create_function) } /* }}} */ +/* {{{ proto string sqlite_udf_encode_binary(string data) + Apply binary encoding (if required) to a string to return from an UDF */ +PHP_FUNCTION(sqlite_udf_encode_binary) +{ + char *data = NULL; + long datalen; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) { + return; + } + + if (data == NULL) { + RETURN_NULL(); + } + if (datalen && (data[0] == '\x01' || memchr(data, '\0', datalen) != NULL)) { + /* binary string */ + int enclen; + char *ret; + + ret = emalloc( 1 + ((256 * datalen + 1262) / 253) ); + ret[0] = '\x01'; + enclen = sqlite_encode_binary((const unsigned char*)data, datalen, ret+1); + RETVAL_STRINGL(ret, enclen+1, 0); + } else { + RETVAL_STRINGL(data, datalen, 1); + } +} +/* }}} */ + +/* {{{ proto string sqlite_udf_decode_binary(string data) + Decode binary encoding on a string parameter passed to an UDF */ +PHP_FUNCTION(sqlite_udf_decode_binary) +{ + char *data = NULL; + long datalen; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) { + return; + } + + if (data == NULL) { + RETURN_NULL(); + } + if (datalen && data[0] == '\x01') { + /* encoded string */ + int enclen; + char *ret; + + ret = emalloc(datalen); + enclen = sqlite_decode_binary((const unsigned char*)data+1, ret); + ret[enclen] = '\0'; + RETVAL_STRINGL(ret, enclen, 0); + } else { + RETVAL_STRINGL(data, datalen, 1); + } +} +/* }}} */ + + /* * Local variables: * tab-width: 4 diff --git a/ext/sqlite/tests/sqlite_017.phpt b/ext/sqlite/tests/sqlite_017.phpt new file mode 100755 index 0000000000..9058622f99 --- /dev/null +++ b/ext/sqlite/tests/sqlite_017.phpt @@ -0,0 +1,33 @@ +--TEST-- +sqlite: UDF binary handling functions +--SKIPIF-- +<?php # vim:ft=php +if (!extension_loaded("sqlite")) print "skip"; ?> +--FILE-- +<?php + +$data = array( + "hello there", + "this has a \x00 char in the middle", + "\x01 this has an 0x01 at the start", + "this has \x01 in the middle" + ); + +foreach ($data as $item) { + $coded = sqlite_udf_encode_binary($item); + echo bin2hex($coded) . "\n"; + $decoded = sqlite_udf_decode_binary($coded); + if ($item != $decoded) { + echo "FAIL! $item decoded is $decoded\n"; + } +} + +echo "OK!\n"; + +?> +--EXPECT-- +68656c6c6f207468657265 +0101736768721f6760721f601fff1f626760711f686d1f7367641f6c6863636b64 +0102ff1e726667711e665f711e5f6c1e2e762e2f1e5f721e7266631e71725f7072 +7468697320686173200120696e20746865206d6964646c65 +OK! |