summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Richter <georg@php.net>2004-08-25 13:57:35 +0000
committerGeorg Richter <georg@php.net>2004-08-25 13:57:35 +0000
commitc8572b0bba9264d9357bc556c07000d913cf0259 (patch)
treec3d3f9ee84e99495b6fcd3e9dd1739563e7244f0
parentb96ebb376f3e35c341521df0c3d517459cfe84de (diff)
downloadphp-git-c8572b0bba9264d9357bc556c07000d913cf0259.tar.gz
changed local_infile_handler:
mysql client lib now uses php_local_infile functions by default, which allows to use php_fopen_wrapper: e.g. LOAD DATA LOCAL INFILE 'http://foo.com/bar.csv' ... mysql_set_local_infile_handler now only supports a callback function for read.
-rw-r--r--ext/mysqli/mysqli.c132
-rw-r--r--ext/mysqli/mysqli_api.c51
-rw-r--r--ext/mysqli/mysqli_nonapi.c5
-rw-r--r--ext/mysqli/php_mysqli.h7
4 files changed, 84 insertions, 111 deletions
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 0575a411dd..a6cb3de2fe 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -107,16 +107,11 @@ void php_clear_stmt_bind(MY_STMT *stmt)
/* {{{ php_clear_mysql */
void php_clear_mysql(MY_MYSQL *mysql) {
- int i;
-
- for (i=0; i < 3; i++) {
- if (&mysql->callback_func[i]) {
- zval_dtor(&mysql->callback_func[i]);
- }
- }
-
- if (mysql->local_infile) {
- zval_ptr_dtor(&mysql->local_infile);
+ if (mysql->li_read) {
+ printf("freeing...\n");
+ efree(Z_STRVAL_P(mysql->li_read));
+ FREE_ZVAL(mysql->li_read);
+ mysql->li_read = NULL;
}
}
/* }}} */
@@ -774,15 +769,23 @@ if (a) {\
memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
memcpy(source, dest, LOCAL_INFILE_ERROR_LEN-1);
+/* {{{ void php_set_local_infile_handler_default
+*/
+void php_set_local_infile_handler_default(MY_MYSQL *mysql) {
+ /* register internal callback functions */
+ mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read,
+ &php_local_infile_end, &php_local_infile_error, (void *)mysql);
+ mysql->li_read = NULL;
+}
+/* }}} */
+
/* {{{ php_local_infile_init
*/
int php_local_infile_init(void **ptr, const char *filename, void *userdata)
{
mysqli_local_infile *data;
MY_MYSQL *mysql;
- zval ***callback_args;
- int argc = 2;
- int i, rc = 0;
+ php_stream_context *context = NULL;
TSRMLS_FETCH();
@@ -791,45 +794,28 @@ int php_local_infile_init(void **ptr, const char *filename, void *userdata)
return 1;
}
- if (!(mysql = data->userdata = userdata)) {
+ if (!(mysql = (MY_MYSQL *)userdata)) {
LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
return 1;
}
- ALLOC_CALLBACK_ARGS(callback_args, 0, argc);
-
- ZVAL_STRING(*callback_args[0], (char *)filename, 1);
- ZVAL_STRING(*callback_args[1], "", 1);
-
- if (call_user_function_ex(EG(function_table),
- NULL,
- &mysql->callback_func[0],
- &mysql->local_infile,
- argc,
- callback_args,
- 0,
- NULL TSRMLS_CC) == SUCCESS) {
+ /* check open_basedir */
+ if (PG(open_basedir)) {
+ if (php_check_open_basedir_ex(filename, 0 TSRMLS_CC) == -1) {
+ LOCAL_INFILE_ERROR_MSG(data->error_msg, "open_basedir restriction in effect. Unable to open file");
+ return 1;
+ }
+ }
- /* check if user callback function returned a valid filehandle */
- convert_to_string_ex(callback_args[1]);
+ mysql->li_stream = php_stream_open_wrapper_ex((char *)filename, "r", 0, NULL, context);
- if (Z_TYPE_P(mysql->local_infile) != IS_RESOURCE) {
- if (!strlen(Z_STRVAL_P(*callback_args[1]))) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
- } else {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[1]));
- }
- rc = 1;
- } else {
- }
- } else {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
- rc = 1;
+ if (mysql->li_stream == NULL) {
+ return 1;
}
- FREE_CALLBACK_ARGS(callback_args, 0, argc);
+ data->userdata = mysql;
- return rc;
+ return 0;
}
/* }}} */
@@ -838,7 +824,8 @@ int php_local_infile_read(void *ptr, char *buf, uint buf_len)
mysqli_local_infile *data;
MY_MYSQL *mysql;
zval ***callback_args;
- zval *retval;
+ zval *retval;
+ zval *fp;
int argc = 4;
int i;
long rc;
@@ -846,21 +833,35 @@ int php_local_infile_read(void *ptr, char *buf, uint buf_len)
TSRMLS_FETCH();
data= (mysqli_local_infile *)ptr;
-
mysql = data->userdata;
+ /* default processing */
+ if (!mysql->li_read) {
+ int count;
+
+ count = (int)php_stream_read(mysql->li_stream, buf, buf_len);
+
+ if (count < 0) {
+ LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(2));
+ }
+
+ return count;
+ }
+
ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
/* set parameters: filepointer, buffer, buffer_len, errormsg */
- callback_args[0] = &mysql->local_infile;
+ MAKE_STD_ZVAL(fp);
+ php_stream_to_zval(mysql->li_stream, fp);
+ callback_args[0] = &fp;
ZVAL_STRING(*callback_args[1], "", 1);
ZVAL_LONG(*callback_args[2], buf_len);
ZVAL_STRING(*callback_args[3], "", 1);
if (call_user_function_ex(EG(function_table),
NULL,
- &mysql->callback_func[1],
+ mysql->li_read,
&retval,
argc,
callback_args,
@@ -888,6 +889,7 @@ int php_local_infile_read(void *ptr, char *buf, uint buf_len)
}
FREE_CALLBACK_ARGS(callback_args, 1, argc);
+ efree(fp);
return rc;
}
@@ -896,6 +898,7 @@ int php_local_infile_read(void *ptr, char *buf, uint buf_len)
int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
{
mysqli_local_infile *data = (mysqli_local_infile *) ptr;
+
if (data) {
strcpy(error_msg, data->error_msg);
return 2000;
@@ -911,42 +914,19 @@ void php_local_infile_end(void *ptr)
{
mysqli_local_infile *data;
MY_MYSQL *mysql;
- zval ***callback_args;
- zval *retval;
- int argc = 1;
- int i;
TSRMLS_FETCH();
data= (mysqli_local_infile *)ptr;
- mysql = data->userdata;
-
- ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
-
- /* set parameters: filepointer, buffer, buffer_len, errormsg */
-
- callback_args[0] = &mysql->local_infile;
-
- call_user_function_ex(EG(function_table),
- NULL,
- &mysql->callback_func[2],
- &retval,
- argc,
- callback_args,
- 0,
- NULL TSRMLS_CC);
-
- if (retval) {
- zval_ptr_dtor(&retval);
- }
-
- if (mysql->local_infile) {
- zval_ptr_dtor(&mysql->local_infile);
+ if (!(mysql = data->userdata)) {
+ efree(data);
+ return;
}
- FREE_CALLBACK_ARGS(callback_args, 1, argc);
-// efree(data);
+ php_stream_close(mysql->li_stream);
+ //efree(data);
+ return;
}
/* }}} */
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index d6fa8fe6c2..b432da3cd0 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -258,7 +258,7 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
for (i=start; i < var_cnt + start ; i++) {
ofs = i - start;
stmt->result.is_null[ofs] = 0;
-
+ //bind[ofs].truncated = NULL;
col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
switch (col_type) {
@@ -406,7 +406,7 @@ PHP_FUNCTION(mysqli_close)
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link");
mysql_close(mysql->mysql);
-
+ php_clear_mysql(mysql);
MYSQLI_CLEAR_RESOURCE(&mysql_link);
RETURN_TRUE;
}
@@ -1036,7 +1036,6 @@ PHP_FUNCTION(mysqli_set_local_infile_default)
{
MY_MYSQL *mysql;
zval *mysql_link;
- int i;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -1044,52 +1043,41 @@ PHP_FUNCTION(mysqli_set_local_infile_default)
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link");
- for (i=0; i < 3; i++) {
- if (&mysql->callback_func[i]) {
- zval_dtor(&mysql->callback_func[i]);
- }
+ if (mysql->li_read) {
+ efree(Z_STRVAL_P(mysql->li_read));
+ zval_dtor(mysql->li_read);
+ mysql->li_read = NULL;
}
-
- mysql_set_local_infile_default(mysql->mysql);
}
/* }}} */
-/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback init_func,
- callback read_func, callback end_func)
+/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func)
Set callback functions for LOAD DATA LOCAL INFILE */
PHP_FUNCTION(mysqli_set_local_infile_handler)
{
MY_MYSQL *mysql;
zval *mysql_link;
char *callback_name;
- zval *callback_func[4];
- int i;
+ zval *callback_func;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ozzzz", &mysql_link, mysqli_link_class_entry,
- &callback_func[0], &callback_func[1], &callback_func[2], &callback_func[3]) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &mysql_link, mysqli_link_class_entry,
+ &callback_func) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link");
- /* check callback functions */
- for (i=0; i < 3; i++) {
- if (!zend_is_callable(callback_func[i], 0, &callback_name)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
- efree(callback_name);
- RETURN_FALSE;
- }
+ /* check callback function */
+ if (!zend_is_callable(callback_func, 0, &callback_name)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
efree(callback_name);
+ RETURN_FALSE;
}
+ efree(callback_name);
- /* save callback functions */
- for (i=0; i < 3; i++) {
- ZVAL_STRING(&mysql->callback_func[i], callback_func[i]->value.str.val, 1);
- }
-
- /* register internal callback functions */
- mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read,
- &php_local_infile_end, &php_local_infile_error, (void *)mysql);
+ /* save callback function */
+ ALLOC_ZVAL(mysql->li_read);
+ ZVAL_STRING(mysql->li_read, callback_func->value.str.val, 1);
}
/* }}} */
@@ -1324,6 +1312,9 @@ PHP_FUNCTION(mysqli_real_connect)
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *)mysql_error(mysql->mysql) TSRMLS_CC);
mysql->mysql->reconnect = MyG(reconnect);
+
+ /* set our own local_infile handler */
+ php_set_local_infile_handler_default(mysql);
if (object) {
((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->valid = 1;
diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c
index 053e1421e8..2d8f48d2a3 100644
--- a/ext/mysqli/mysqli_nonapi.c
+++ b/ext/mysqli/mysqli_nonapi.c
@@ -40,7 +40,6 @@ PHP_FUNCTION(mysqli_connect)
unsigned int hostname_len, username_len, passwd_len, dbname_len, socket_len;
long port=0;
-
if (getThis() && !ZEND_NUM_ARGS()) {
RETURN_NULL();
}
@@ -90,6 +89,9 @@ PHP_FUNCTION(mysqli_connect)
mysql->mysql->reconnect = MyG(reconnect);
+ /* set our own local_infile handler */
+ php_set_local_infile_handler_default(mysql);
+
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)mysql;
@@ -247,7 +249,6 @@ PHP_FUNCTION(mysqli_query)
RETURN_FALSE;
}
-
if (!mysql_field_count(mysql->mysql)) {
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h
index c5a090fa2e..7a29d8b6d3 100644
--- a/ext/mysqli/php_mysqli.h
+++ b/ext/mysqli/php_mysqli.h
@@ -53,9 +53,8 @@ typedef struct {
typedef struct {
MYSQL *mysql;
- /* callback functions for load data local infile support */
- zval callback_func[3];
- zval *local_infile;
+ zval *li_read;
+ php_stream *li_stream;
} MY_MYSQL;
typedef struct {
@@ -112,6 +111,7 @@ extern mysqli_property_entry mysqli_stmt_property_entries[];
extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object);
extern void php_clear_stmt_bind(MY_STMT *stmt);
+void php_clear_mysql(MY_MYSQL *);
extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
extern void php_mysqli_report_error(char *sqlstate, int errorno, char *error TSRMLS_DC);
extern void php_mysqli_report_index(char *query, unsigned int status TSRMLS_DC);
@@ -119,6 +119,7 @@ extern int php_local_infile_init(void **, const char *, void *);
extern int php_local_infile_read(void *, char *, uint);
extern void php_local_infile_end(void *);
extern int php_local_infile_error(void *, char *, uint);
+extern void php_set_local_infile_handler_default(MY_MYSQL *);
zend_class_entry *mysqli_link_class_entry;
zend_class_entry *mysqli_stmt_class_entry;