From 404cc45ee27a2f2bcf5c466d7c66767181e24860 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 4 May 2014 22:10:00 +0200 Subject: [PATCH] Get php-fpm to work At least phpinfo() works. Need to do more testing (how do you run fpm with valgrind?) --- sapi/fpm/fpm/fastcgi.c | 95 +++++++++++++++------------------------ sapi/fpm/fpm/fastcgi.h | 2 +- sapi/fpm/fpm/fpm_main.c | 73 +++++++++++++----------------- sapi/fpm/fpm/fpm_php.c | 39 +++++++--------- sapi/fpm/fpm/fpm_php.h | 2 +- sapi/fpm/fpm/fpm_status.c | 22 +++++---- 6 files changed, 97 insertions(+), 136 deletions(-) diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c index d77b6f8ca7..8fbdd36a24 100644 --- a/sapi/fpm/fpm/fastcgi.c +++ b/sapi/fpm/fpm/fastcgi.c @@ -479,11 +479,7 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e memcpy(tmp, p, eff_name_len); tmp[eff_name_len] = 0; s = estrndup((char*)p + name_len, val_len); - if (s == NULL) { - ret = 0; - break; - } - zend_hash_update(req->env, tmp, eff_name_len+1, &s, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, tmp, eff_name_len, s); p += name_len + val_len; } if (tmp != buf && tmp != NULL) { @@ -492,9 +488,9 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e return ret; } -static void fcgi_free_var(char **s) +static void fcgi_free_var(zval *zv) { - efree(*s); + efree(Z_PTR_P(zv)); } static int fcgi_read_request(fcgi_request *req) @@ -509,7 +505,7 @@ static int fcgi_read_request(fcgi_request *req) req->out_hdr = NULL; req->out_pos = req->out_buf; ALLOC_HASHTABLE(req->env); - zend_hash_init(req->env, 0, NULL, (void (*)(void *)) fcgi_free_var, 0); + zend_hash_init(req->env, 0, NULL, fcgi_free_var, 0); if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) || hdr.version < FCGI_VERSION_1) { @@ -546,15 +542,15 @@ static int fcgi_read_request(fcgi_request *req) switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + ((fcgi_begin_request*)buf)->roleB0) { case FCGI_RESPONDER: val = estrdup("RESPONDER"); - zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), val); break; case FCGI_AUTHORIZER: val = estrdup("AUTHORIZER"); - zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), val); break; case FCGI_FILTER: val = estrdup("FILTER"); - zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), val); break; default: return 0; @@ -593,12 +589,8 @@ static int fcgi_read_request(fcgi_request *req) } } else if (hdr.type == FCGI_GET_VALUES) { unsigned char *p = buf + sizeof(fcgi_header); - HashPosition pos; - char * str_index; - uint str_length; - ulong num_index; - int key_type; - zval ** value; + zend_string *key; + zval *value; if (safe_read(req, buf, len+padding) != len+padding) { req->keep = 0; @@ -610,28 +602,26 @@ static int fcgi_read_request(fcgi_request *req) return 0; } - zend_hash_internal_pointer_reset_ex(req->env, &pos); - while ((key_type = zend_hash_get_current_key_ex(req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTENT) { + ZEND_HASH_FOREACH_STR_KEY(req->env, key) { int zlen; - zend_hash_move_forward_ex(req->env, &pos); - if (key_type != HASH_KEY_IS_STRING) { + if (!key) { continue; } - if (zend_hash_find(&fcgi_mgmt_vars, str_index, str_length, (void**) &value) != SUCCESS) { + value = zend_hash_find(&fcgi_mgmt_vars, key); + if (!value) { continue; } - --str_length; - zlen = Z_STRLEN_PP(value); - if ((p + 4 + 4 + str_length + zlen) >= (buf + sizeof(buf))) { + zlen = Z_STRLEN_P(value); + if ((p + 4 + 4 + key->len + zlen) >= (buf + sizeof(buf))) { break; } - if (str_length < 0x80) { - *p++ = str_length; + if (key->len < 0x80) { + *p++ = key->len; } else { - *p++ = ((str_length >> 24) & 0xff) | 0x80; - *p++ = (str_length >> 16) & 0xff; - *p++ = (str_length >> 8) & 0xff; - *p++ = str_length & 0xff; + *p++ = ((key->len >> 24) & 0xff) | 0x80; + *p++ = (key->len >> 16) & 0xff; + *p++ = (key->len >> 8) & 0xff; + *p++ = key->len & 0xff; } if (zlen < 0x80) { *p++ = zlen; @@ -641,11 +631,11 @@ static int fcgi_read_request(fcgi_request *req) *p++ = (zlen >> 8) & 0xff; *p++ = zlen & 0xff; } - memcpy(p, str_index, str_length); - p += str_length; - memcpy(p, Z_STRVAL_PP(value), zlen); + memcpy(p, key->val, key->len); + p += key->len; + memcpy(p, Z_STRVAL_P(value), zlen); p += zlen; - } + } ZEND_HASH_FOREACH_END(); len = p - buf - sizeof(fcgi_header); len += fcgi_make_header((fcgi_header*)buf, FCGI_GET_VALUES_RESULT, 0, len); if (safe_write(req, buf, sizeof(fcgi_header)+len) != (int)sizeof(fcgi_header)+len) { @@ -1050,28 +1040,22 @@ int fcgi_finish_request(fcgi_request *req, int force_close) char* fcgi_getenv(fcgi_request *req, const char* var, int var_len) { - char **val; - - if (!req) return NULL; - - if (zend_hash_find(req->env, (char*)var, var_len+1, (void**)&val) == SUCCESS) { - return *val; + if (!req) { + return NULL; } - return NULL; + + return zend_hash_str_find_ptr(req->env, var, var_len); } char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val) { if (var && req) { if (val == NULL) { - zend_hash_del(req->env, var, var_len+1); + zend_hash_str_del(req->env, var, var_len); } else { - char **ret; - val = estrdup(val); - if (zend_hash_update(req->env, var, var_len+1, &val, sizeof(char*), (void**)&ret) == SUCCESS) { - return *ret; - } + zend_hash_str_update_ptr(req->env, var, var_len, val); + return val; } } return NULL; @@ -1079,19 +1063,14 @@ char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val) void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len) { - zval * zvalue; - zvalue = pemalloc(sizeof(*zvalue), 1); - Z_TYPE_P(zvalue) = IS_STRING; - Z_STRVAL_P(zvalue) = pestrndup(value, value_len, 1); - Z_STRLEN_P(zvalue) = value_len; - zend_hash_add(&fcgi_mgmt_vars, name, name_len + 1, &zvalue, sizeof(zvalue), NULL); + zval zvalue; + ZVAL_STR(&zvalue, STR_INIT(value, value_len, 1)); + zend_hash_str_add(&fcgi_mgmt_vars, name, name_len, &zvalue); } -void fcgi_free_mgmt_var_cb(void * ptr) +void fcgi_free_mgmt_var_cb(zval *zv) { - zval ** var = (zval **)ptr; - pefree(Z_STRVAL_PP(var), 1); - pefree(*var, 1); + STR_FREE(Z_STR_P(zv)); } char *fcgi_get_last_client_ip() /* {{{ */ diff --git a/sapi/fpm/fpm/fastcgi.h b/sapi/fpm/fpm/fastcgi.h index 34f9eef9da..5a8aa0e70e 100644 --- a/sapi/fpm/fpm/fastcgi.h +++ b/sapi/fpm/fpm/fastcgi.h @@ -131,7 +131,7 @@ ssize_t fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, i int fcgi_flush(fcgi_request *req, int close); void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len); -void fcgi_free_mgmt_var_cb(void * ptr); +void fcgi_free_mgmt_var_cb(zval *ptr); char *fcgi_get_last_client_ip(); diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 9b2878dd63..6b9abc859f 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -216,8 +216,9 @@ static php_cgi_globals_struct php_cgi_globals; #define TRANSLATE_SLASHES(path) #endif -static int print_module_info(zend_module_entry *module, void *arg TSRMLS_DC) +static int print_module_info(zval *zv TSRMLS_DC) { + zend_module_entry *module = Z_PTR_P(zv); php_printf("%s\n", module->name); return 0; } @@ -227,19 +228,18 @@ static int module_name_cmp(const void *a, const void *b TSRMLS_DC) Bucket *f = (Bucket *) a; Bucket *s = (Bucket *) b; - return strcasecmp( ((zend_module_entry *)f->xData)->name, - ((zend_module_entry *)s->xData)->name); + return strcasecmp( ((zend_module_entry *) Z_PTR(f->val))->name, + ((zend_module_entry *) Z_PTR(s->val))->name); } static void print_modules(TSRMLS_D) { HashTable sorted_registry; - zend_module_entry tmp; zend_hash_init(&sorted_registry, 50, NULL, NULL, 1); - zend_hash_copy(&sorted_registry, &module_registry, NULL, &tmp, sizeof(zend_module_entry)); + zend_hash_copy(&sorted_registry, &module_registry, NULL); zend_hash_sort(&sorted_registry, zend_qsort, module_name_cmp, 0 TSRMLS_CC); - zend_hash_apply_with_argument(&sorted_registry, (apply_func_arg_t) print_module_info, NULL TSRMLS_CC); + zend_hash_apply(&sorted_registry, print_module_info TSRMLS_CC); zend_hash_destroy(&sorted_registry); } @@ -568,32 +568,23 @@ static char *sapi_cgi_read_cookies(TSRMLS_D) void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC) { fcgi_request *request; - HashPosition pos; - char *var, **val; - uint var_len; - ulong idx; + zend_string *var; + char *val; int filter_arg; - - if (PG(http_globals)[TRACK_VARS_ENV] && - array_ptr != PG(http_globals)[TRACK_VARS_ENV] && - Z_TYPE_P(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && - zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV])) > 0 + if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && + Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) && + zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0 ) { zval_dtor(array_ptr); - *array_ptr = *PG(http_globals)[TRACK_VARS_ENV]; - INIT_PZVAL(array_ptr); - zval_copy_ctor(array_ptr); + ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_ENV]); return; - } else if (PG(http_globals)[TRACK_VARS_SERVER] && - array_ptr != PG(http_globals)[TRACK_VARS_SERVER] && - Z_TYPE_P(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && - zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER])) > 0 + } else if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && + Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_SERVER]) && + zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])) > 0 ) { zval_dtor(array_ptr); - *array_ptr = *PG(http_globals)[TRACK_VARS_SERVER]; - INIT_PZVAL(array_ptr); - zval_copy_ctor(array_ptr); + ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_SERVER]); return; } @@ -601,19 +592,16 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC) php_php_import_environment_variables(array_ptr TSRMLS_CC); request = (fcgi_request*) SG(server_context); - filter_arg = (array_ptr == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER; + filter_arg = Z_ARR_P(array_ptr) == Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) + ? PARSE_ENV : PARSE_SERVER; - for (zend_hash_internal_pointer_reset_ex(request->env, &pos); - zend_hash_get_current_key_ex(request->env, &var, &var_len, &idx, 0, &pos) == HASH_KEY_IS_STRING && - zend_hash_get_current_data_ex(request->env, (void **) &val, &pos) == SUCCESS; - zend_hash_move_forward_ex(request->env, &pos) - ) { + ZEND_HASH_FOREACH_STR_KEY_PTR(request->env, var, val) { unsigned int new_val_len; - if (sapi_module.input_filter(filter_arg, var, val, strlen(*val), &new_val_len TSRMLS_CC)) { - php_register_variable_safe(var, *val, new_val_len, array_ptr TSRMLS_CC); + if (var && sapi_module.input_filter(filter_arg, var->val, &val, strlen(val), &new_val_len TSRMLS_CC)) { + php_register_variable_safe(var->val, val, new_val_len, array_ptr TSRMLS_CC); } - } + } ZEND_HASH_FOREACH_END(); } static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC) @@ -695,17 +683,16 @@ static void sapi_cgi_log_message(char *message) static void php_cgi_ini_activate_user_config(char *path, int path_len, const char *doc_root, int doc_root_len, int start TSRMLS_DC) { char *ptr; - user_config_cache_entry *new_entry, *entry; time_t request_time = sapi_get_request_time(TSRMLS_C); + user_config_cache_entry *entry = zend_hash_str_find_ptr(&CGIG(user_config_cache), path, path_len); /* Find cached config entry: If not found, create one */ - if (zend_hash_find(&CGIG(user_config_cache), path, path_len + 1, (void **) &entry) == FAILURE) { - new_entry = pemalloc(sizeof(user_config_cache_entry), 1); - new_entry->expires = 0; - new_entry->user_config = (HashTable *) pemalloc(sizeof(HashTable), 1); - zend_hash_init(new_entry->user_config, 0, NULL, (dtor_func_t) config_zval_dtor, 1); - zend_hash_update(&CGIG(user_config_cache), path, path_len + 1, new_entry, sizeof(user_config_cache_entry), (void **) &entry); - free(new_entry); + if (!entry) { + entry = pemalloc(sizeof(user_config_cache_entry), 1); + entry->expires = 0; + entry->user_config = (HashTable *) pemalloc(sizeof(HashTable), 1); + zend_hash_init(entry->user_config, 0, NULL, (dtor_func_t) config_zval_dtor, 1); + zend_hash_str_update_ptr(&CGIG(user_config_cache), path, path_len, entry); } /* Check whether cache entry has expired and rescan if it is */ @@ -1966,7 +1953,7 @@ fastcgi_request_done: fpm_request_end(TSRMLS_C); fpm_log_write(NULL TSRMLS_CC); - STR_FREE(SG(request_info).path_translated); + efree(SG(request_info).path_translated); SG(request_info).path_translated = NULL; php_request_shutdown((void *) 0); diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index cd4d3aef3a..7112cb923b 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -28,7 +28,7 @@ static int fpm_php_zend_ini_alter_master(char *name, int name_length, char *new_ zend_ini_entry *ini_entry; char *duplicate; - if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE) { + if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length))) { return FAILURE; } @@ -89,7 +89,7 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */ if (!strcmp(name, "extension") && *value) { zval zv; php_dl(value, MODULE_PERSISTENT, &zv, 1 TSRMLS_CC); - return Z_BVAL(zv) ? 1 : -1; + return Z_TYPE(zv) == IS_TRUE; } if (fpm_php_zend_ini_alter_master(name, name_len+1, value, value_len, mode, PHP_INI_STAGE_ACTIVATE TSRMLS_CC) == FAILURE) { @@ -258,39 +258,30 @@ int fpm_php_limit_extensions(char *path) /* {{{ */ } /* }}} */ -char* fpm_php_get_string_from_table(char *table, char *key TSRMLS_DC) /* {{{ */ +char* fpm_php_get_string_from_table(zend_string *table, char *key TSRMLS_DC) /* {{{ */ { - zval **data, **tmp; - char *string_key; - uint string_len; - ulong num_key; + zval *data, *tmp; + zend_string *str; if (!table || !key) { return NULL; } /* inspired from ext/standard/info.c */ - zend_is_auto_global(table, strlen(table) TSRMLS_CC); + zend_is_auto_global(table TSRMLS_CC); /* find the table and ensure it's an array */ - if (zend_hash_find(&EG(symbol_table), table, strlen(table) + 1, (void **) &data) == SUCCESS && Z_TYPE_PP(data) == IS_ARRAY) { - - /* reset the internal pointer */ - zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data)); - - /* parse the array to look for our key */ - while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) { - /* ensure the key is a string */ - if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL) == HASH_KEY_IS_STRING) { - /* compare to our key */ - if (!strncmp(string_key, key, string_len)) { - return Z_STRVAL_PP(tmp); - } - } - zend_hash_move_forward(Z_ARRVAL_PP(data)); - } + data = zend_hash_find(&EG(symbol_table).ht, table); + if (!data || Z_TYPE_P(data) != IS_ARRAY) { + return NULL; } + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(data), str, tmp) { + if (str && !strncmp(str->val, key, str->len)) { + return Z_STRVAL_P(tmp); + } + } ZEND_HASH_FOREACH_END(); + return NULL; } /* }}} */ diff --git a/sapi/fpm/fpm/fpm_php.h b/sapi/fpm/fpm/fpm_php.h index d6054737d6..20f5a9454b 100644 --- a/sapi/fpm/fpm/fpm_php.h +++ b/sapi/fpm/fpm/fpm_php.h @@ -44,7 +44,7 @@ void fpm_php_soft_quit(); int fpm_php_init_main(); int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode); int fpm_php_limit_extensions(char *path); -char* fpm_php_get_string_from_table(char *table, char *key TSRMLS_DC); +char* fpm_php_get_string_from_table(zend_string *table, char *key TSRMLS_DC); #endif diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index 2363b57f80..e447648462 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -55,6 +55,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ int full, encode; char *short_syntax, *short_post; char *full_pre, *full_syntax, *full_post, *full_separator; + zend_string *_GET_str; if (!SG(request_info).request_uri) { return 0; @@ -126,13 +127,14 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } /* full status ? */ - full = (fpm_php_get_string_from_table("_GET", "full" TSRMLS_CC) != NULL); + _GET_str = STR_INIT("_GET", sizeof("_GET")-1, 0); + full = (fpm_php_get_string_from_table(_GET_str, "full" TSRMLS_CC) != NULL); short_syntax = short_post = NULL; full_separator = full_pre = full_syntax = full_post = NULL; encode = 0; /* HTML */ - if (fpm_php_get_string_from_table("_GET", "html" TSRMLS_CC)) { + if (fpm_php_get_string_from_table(_GET_str, "html" TSRMLS_CC)) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/html"), 1, 1 TSRMLS_CC); time_format = "%d/%b/%Y:%H:%M:%S %z"; encode = 1; @@ -207,7 +209,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } /* XML */ - } else if (fpm_php_get_string_from_table("_GET", "xml" TSRMLS_CC)) { + } else if (fpm_php_get_string_from_table(_GET_str, "xml" TSRMLS_CC)) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/xml"), 1, 1 TSRMLS_CC); time_format = "%s"; encode = 1; @@ -259,7 +261,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } /* JSON */ - } else if (fpm_php_get_string_from_table("_GET", "json" TSRMLS_CC)) { + } else if (fpm_php_get_string_from_table(_GET_str, "json" TSRMLS_CC)) { sapi_add_header_ex(ZEND_STRL("Content-Type: application/json"), 1, 1 TSRMLS_CC); time_format = "%s"; @@ -376,6 +378,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ PUTS(buffer); efree(buffer); + STR_RELEASE(_GET_str); if (short_post) { PUTS(short_post); @@ -384,7 +387,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ /* no need to test the var 'full' */ if (full_syntax) { int i, first; - size_t len; + zend_string *tmp_query_string; char *query_string; struct timeval duration, now; #ifdef HAVE_FPM_LQ @@ -413,12 +416,13 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } query_string = NULL; - len = 0; + tmp_query_string = NULL; if (proc.query_string[0] != '\0') { if (!encode) { query_string = proc.query_string; } else { - query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), &len, 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1 TSRMLS_CC); + tmp_query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1 TSRMLS_CC); + query_string = tmp_query_string->val; } } @@ -458,8 +462,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ PUTS(buffer); efree(buffer); - if (len > 0 && query_string) { - efree(query_string); + if (tmp_query_string) { + STR_FREE(tmp_query_string); } } -- 2.40.0