PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - http - http_api.c
Test: PHP Code Coverage
Date: 2008-09-05 Instrumented lines: 326
Code covered: 61.7 % Executed lines: 201
Legend: not executed executed

       1                 : /*
       2                 :     +--------------------------------------------------------------------+
       3                 :     | PECL :: http                                                       |
       4                 :     +--------------------------------------------------------------------+
       5                 :     | Redistribution and use in source and binary forms, with or without |
       6                 :     | modification, are permitted provided that the conditions mentioned |
       7                 :     | in the accompanying LICENSE file are met.                          |
       8                 :     +--------------------------------------------------------------------+
       9                 :     | Copyright (c) 2004-2007, Michael Wallner <mike@php.net>            |
      10                 :     +--------------------------------------------------------------------+
      11                 : */
      12                 : 
      13                 : /* $Id: http_api.c,v 1.170 2008/03/12 07:46:32 mike Exp $ */
      14                 : 
      15                 : #define HTTP_WANT_SAPI
      16                 : #include "php_http.h"
      17                 : 
      18                 : #include "php_output.h"
      19                 : #include "ext/standard/url.h"
      20                 : #include "ext/standard/php_lcg.h"
      21                 : 
      22                 : #include "php_http_api.h"
      23                 : #include "php_http_send_api.h"
      24                 : 
      25                 : #ifdef ZEND_ENGINE_2
      26                 : #       include "php_http_exception_object.h"
      27                 : #endif
      28                 : 
      29                 : PHP_MINIT_FUNCTION(http_support)
      30            9669 : {
      31            9669 :         HTTP_LONG_CONSTANT("HTTP_SUPPORT", HTTP_SUPPORT);
      32            9669 :         HTTP_LONG_CONSTANT("HTTP_SUPPORT_REQUESTS", HTTP_SUPPORT_REQUESTS);
      33            9669 :         HTTP_LONG_CONSTANT("HTTP_SUPPORT_MAGICMIME", HTTP_SUPPORT_MAGICMIME);
      34            9669 :         HTTP_LONG_CONSTANT("HTTP_SUPPORT_ENCODINGS", HTTP_SUPPORT_ENCODINGS);
      35            9669 :         HTTP_LONG_CONSTANT("HTTP_SUPPORT_SSLREQUESTS", HTTP_SUPPORT_SSLREQUESTS);
      36            9669 :         HTTP_LONG_CONSTANT("HTTP_SUPPORT_EVENTS", HTTP_SUPPORT_EVENTS);
      37                 :         
      38            9669 :         HTTP_LONG_CONSTANT("HTTP_PARAMS_ALLOW_COMMA", HTTP_PARAMS_ALLOW_COMMA);
      39            9669 :         HTTP_LONG_CONSTANT("HTTP_PARAMS_ALLOW_FAILURE", HTTP_PARAMS_ALLOW_FAILURE);
      40            9669 :         HTTP_LONG_CONSTANT("HTTP_PARAMS_RAISE_ERROR", HTTP_PARAMS_RAISE_ERROR);
      41            9669 :         HTTP_LONG_CONSTANT("HTTP_PARAMS_DEFAULT", HTTP_PARAMS_DEFAULT);
      42                 :         
      43            9669 :         return SUCCESS;
      44                 : }
      45                 : 
      46                 : PHP_HTTP_API long _http_support(long feature)
      47              12 : {
      48              12 :         long support = HTTP_SUPPORT;
      49                 :         
      50                 : #ifdef HTTP_HAVE_CURL
      51              12 :         support |= HTTP_SUPPORT_REQUESTS;
      52                 : #       ifdef HTTP_HAVE_SSL
      53              12 :         support |= HTTP_SUPPORT_SSLREQUESTS;
      54                 : #       endif
      55                 : #       ifdef HTTP_HAVE_EVENT
      56                 :         support |= HTTP_SUPPORT_EVENTS;
      57                 : #       endif
      58                 : #endif
      59                 : #ifdef HTTP_HAVE_MAGIC
      60              12 :         support |= HTTP_SUPPORT_MAGICMIME;
      61                 : #endif
      62                 : #ifdef HTTP_HAVE_ZLIB
      63              12 :         support |= HTTP_SUPPORT_ENCODINGS;
      64                 : #endif
      65                 : 
      66              12 :         if (feature) {
      67              12 :                 return (feature == (support & feature));
      68                 :         }
      69               0 :         return support;
      70                 : }
      71                 : 
      72                 : /* char *pretty_key(char *, size_t, zend_bool, zend_bool) */
      73                 : char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen)
      74             915 : {
      75                 :         size_t i;
      76                 :         int wasalpha;
      77                 :         
      78             915 :         if (key && key_len) {
      79             915 :                 if ((wasalpha = HTTP_IS_CTYPE(alpha, key[0]))) {
      80             915 :                         key[0] = (char) (uctitle ? HTTP_TO_CTYPE(upper, key[0]) : HTTP_TO_CTYPE(lower, key[0]));
      81                 :                 }
      82            8664 :                 for (i = 1; i < key_len; i++) {
      83            7749 :                         if (HTTP_IS_CTYPE(alpha, key[i])) {
      84            7172 :                                 key[i] = (char) (((!wasalpha) && uctitle) ? HTTP_TO_CTYPE(upper, key[i]) : HTTP_TO_CTYPE(lower, key[i]));
      85            7172 :                                 wasalpha = 1;
      86                 :                         } else {
      87             577 :                                 if (xhyphen && (key[i] == '_')) {
      88               5 :                                         key[i] = '-';
      89                 :                                 }
      90             577 :                                 wasalpha = 0;
      91                 :                         }
      92                 :                 }
      93                 :         }
      94             915 :         return key;
      95                 : }
      96                 : /* }}} */
      97                 : 
      98                 : /* {{{ http_boundary(char *, size_t) */
      99                 : size_t _http_boundary(char *buf, size_t buf_len TSRMLS_DC)
     100               0 : {
     101               0 :         return snprintf(buf, buf_len, "%lu%0.9f", (ulong) HTTP_G->request.time, (float) php_combined_lcg(TSRMLS_C));
     102                 : }
     103                 : /* }}} */
     104                 : 
     105                 : /* {{{ void http_error(long, long, char*) */
     106                 : void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...)
     107              18 : {
     108                 :         va_list args;
     109                 :         
     110              18 :         va_start(args, format);
     111                 : #ifdef ZEND_ENGINE_2
     112              34 :         if ((type == E_THROW) || (GLOBAL_ERROR_HANDLING == EH_THROW)) {
     113                 :                 char *message;
     114              16 :                 zend_class_entry *ce = http_exception_get_for_code(code);
     115                 :                 
     116              16 :                 http_try {
     117              16 :                         vspprintf(&message, 0, format, args);
     118              16 :                         zend_throw_exception(ce, message, code TSRMLS_CC);
     119              16 :                         efree(message);
     120              16 :                 } http_catch(GLOBAL_EXCEPTION_CLASS ? GLOBAL_EXCEPTION_CLASS : HTTP_EX_DEF_CE);
     121                 :         } else
     122                 : #endif
     123               2 :         php_verror(NULL, "", type, format, args TSRMLS_CC);
     124              18 :         va_end(args);
     125              18 : }
     126                 : /* }}} */
     127                 : 
     128                 : #ifdef ZEND_ENGINE_2
     129                 : static inline void copy_bt_args(zval *from, zval *to TSRMLS_DC)
     130              12 : {
     131              12 :         zval **args, **trace_0, *old_trace_0, *trace = NULL;
     132                 :         
     133              12 :         if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), from, "trace", lenof("trace"), 0 TSRMLS_CC))) {
     134              12 :                 if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
     135              12 :                         old_trace_0 = *trace_0;
     136              12 :                         if (Z_TYPE_PP(trace_0) == IS_ARRAY && SUCCESS == zend_hash_find(Z_ARRVAL_PP(trace_0), "args", sizeof("args"), (void *) &args)) {
     137              12 :                                 if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), to, "trace", lenof("trace"), 0 TSRMLS_CC))) {
     138              12 :                                         if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
     139              12 :                                                 ZVAL_ADDREF(*args);
     140              12 :                                                 add_assoc_zval(*trace_0, "args", *args);
     141                 :                                         }
     142                 :                                 }
     143                 :                         }
     144                 :                 }
     145                 :         }
     146              12 : }
     147                 : 
     148                 : /* {{{ zval *http_exception_wrap(zval *, zval *, zend_class_entry *) */
     149                 : zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC)
     150               7 : {
     151               7 :         int inner = 1;
     152                 :         char *message;
     153                 :         zval *sub_exception, *tmp_exception;
     154                 :         
     155               7 :         if (!new_exception) {
     156               2 :                 MAKE_STD_ZVAL(new_exception);
     157               2 :                 object_init_ex(new_exception, ce);
     158                 :                 
     159               2 :                 zend_update_property(ce, new_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC);
     160               2 :                 copy_bt_args(old_exception, new_exception TSRMLS_CC);
     161                 :                 
     162               2 :                 sub_exception = old_exception;
     163                 :                 
     164               8 :                 while ((sub_exception = zend_read_property(Z_OBJCE_P(sub_exception), sub_exception, "innerException", lenof("innerException"), 0 TSRMLS_CC)) && Z_TYPE_P(sub_exception) == IS_OBJECT) {
     165               4 :                         ++inner;
     166                 :                 }
     167                 :                 
     168               2 :                 spprintf(&message, 0, "Exception caused by %d inner exception(s)", inner);
     169               2 :                 zend_update_property_string(ZEND_EXCEPTION_GET_DEFAULT(), new_exception, "message", lenof("message"), message TSRMLS_CC);
     170               2 :                 efree(message);
     171                 :         } else {
     172               5 :                 sub_exception = new_exception;
     173               5 :                 tmp_exception = new_exception;
     174                 :                 
     175              10 :                 while ((tmp_exception = zend_read_property(Z_OBJCE_P(tmp_exception), tmp_exception, "innerException", lenof("innerException"), 0 TSRMLS_CC)) && Z_TYPE_P(tmp_exception) == IS_OBJECT) {
     176               0 :                         sub_exception = tmp_exception;
     177                 :                 }
     178                 :                 
     179               5 :                 zend_update_property(Z_OBJCE_P(sub_exception), sub_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC);
     180               5 :                 copy_bt_args(old_exception, new_exception TSRMLS_CC);
     181               5 :                 copy_bt_args(old_exception, sub_exception TSRMLS_CC);
     182                 :         }
     183                 :         
     184               7 :         zval_ptr_dtor(&old_exception);
     185               7 :         return new_exception;
     186                 : }
     187                 : /* }}} */
     188                 : 
     189                 : /* {{{ STATUS http_object_new(zend_object_value *, const char *, uint, http_object_new_t, zend_class_entry *, void *, void **) */
     190                 : STATUS _http_object_new(zend_object_value *ov, const char *cname_str, uint cname_len, http_object_new_t create, zend_class_entry *parent_ce, void *intern_ptr, void **obj_ptr TSRMLS_DC)
     191               3 : {
     192               3 :         zend_class_entry *ce = parent_ce;
     193                 :         
     194               3 :         if (cname_str && cname_len) {
     195               0 :                 if (!(ce = zend_fetch_class(HTTP_ZAPI_CONST_CAST(char *) cname_str, cname_len, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC))) {
     196               0 :                         return FAILURE;
     197                 :                 }
     198               0 :                 if (!instanceof_function(ce, parent_ce TSRMLS_CC)) {
     199               0 :                         http_error_ex(HE_WARNING, HTTP_E_RUNTIME, "Class %s does not extend %s", cname_str, parent_ce->name);
     200               0 :                         return FAILURE;
     201                 :                 }
     202                 :         }
     203                 :         
     204               3 :         *ov = create(ce, intern_ptr, obj_ptr TSRMLS_CC);
     205               3 :         return SUCCESS;
     206                 : }
     207                 : /* }}} */
     208                 : #endif /* ZEND_ENGINE_2 */
     209                 : 
     210                 : /* {{{ void http_log(char *, char *, char *) */
     211                 : void _http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC)
     212               0 : {
     213                 :         time_t now;
     214                 :         struct tm nowtm;
     215               0 :         char datetime[20] = {0};
     216                 :         
     217               0 :         now = HTTP_G->request.time;
     218               0 :         strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", php_localtime_r(&now, &nowtm));
     219                 : 
     220                 : #define HTTP_LOG_WRITE(file, type, msg) \
     221                 :         if (file && *file) { \
     222                 :                 php_stream *log = php_stream_open_wrapper_ex(file, "ab", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT); \
     223                 :                  \
     224                 :                 if (log) { \
     225                 :                         php_stream_printf(log TSRMLS_CC, "%s\t[%s]\t%s\t<%s>%s", datetime, type, msg, SG(request_info).request_uri, PHP_EOL); \
     226                 :                         php_stream_close(log); \
     227                 :                 } \
     228                 :          \
     229                 :         }
     230                 :         
     231               0 :         HTTP_LOG_WRITE(file, ident, message);
     232               0 :         HTTP_LOG_WRITE(HTTP_G->log.composite, ident, message);
     233               0 : }
     234                 : /* }}} */
     235                 : 
     236                 : static void http_ob_blackhole(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
     237               0 : {
     238               0 :         *handled_output = ecalloc(1,1);
     239               0 :         *handled_output_len = 0;
     240               0 : }
     241                 : 
     242                 : /* {{{ STATUS http_exit(int, char*, char*) */
     243                 : STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header TSRMLS_DC)
     244               0 : {
     245               0 :         if (    (send_header && (SUCCESS != http_send_status_header(status, header))) ||
     246                 :                         (status && (SUCCESS != http_send_status(status)))) {
     247               0 :                 http_error_ex(HE_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, STR_PTR(header));
     248               0 :                 STR_FREE(header);
     249               0 :                 STR_FREE(body);
     250               0 :                 return FAILURE;
     251                 :         }
     252                 :         
     253               0 :         if (!OG(ob_lock)) {
     254               0 :                 php_end_ob_buffers(0 TSRMLS_CC);
     255                 :         }
     256               0 :         if ((SUCCESS == sapi_send_headers(TSRMLS_C)) && body) {
     257               0 :                 PHPWRITE(body, strlen(body));
     258                 :         }
     259                 :         
     260               0 :         switch (status) {
     261               0 :                 case 301:       http_log(HTTP_G->log.redirect, "301-REDIRECT", header);                    break;
     262               0 :                 case 302:       http_log(HTTP_G->log.redirect, "302-REDIRECT", header);                    break;
     263               0 :                 case 303:       http_log(HTTP_G->log.redirect, "303-REDIRECT", header);                    break;
     264               0 :                 case 305:       http_log(HTTP_G->log.redirect, "305-REDIRECT", header);                    break;
     265               0 :                 case 307:       http_log(HTTP_G->log.redirect, "307-REDIRECT", header);                    break;
     266               0 :                 case 304:       http_log(HTTP_G->log.cache, "304-CACHE", header);                          break;
     267               0 :                 case 404:       http_log(HTTP_G->log.not_found, "404-NOTFOUND", NULL);                     break;
     268               0 :                 case 405:       http_log(HTTP_G->log.allowed_methods, "405-ALLOWED", header);      break;
     269               0 :                 default:        http_log(NULL, header, body);                                                                   break;
     270                 :         }
     271                 :         
     272               0 :         STR_FREE(header);
     273               0 :         STR_FREE(body);
     274                 :         
     275               0 :         if (HTTP_G->force_exit) {
     276               0 :                 zend_bailout();
     277                 :         } else {
     278               0 :                 php_ob_set_internal_handler(http_ob_blackhole, 4096, "blackhole", 0 TSRMLS_CC);
     279                 :         }
     280                 :         
     281               0 :         return SUCCESS;
     282                 : }
     283                 : /* }}} */
     284                 : 
     285                 : /* {{{ STATUS http_check_method(char *) */
     286                 : STATUS _http_check_method_ex(const char *method, const char *methods)
     287               0 : {
     288                 :         const char *found;
     289                 : 
     290               0 :         if (    (found = strstr(methods, method)) &&
     291                 :                         (found == method || !HTTP_IS_CTYPE(alpha, found[-1])) &&
     292                 :                         (strlen(found) >= strlen(method) && !HTTP_IS_CTYPE(alpha, found[strlen(method)]))) {
     293               0 :                 return SUCCESS;
     294                 :         }
     295               0 :         return FAILURE;
     296                 : }
     297                 : /* }}} */
     298                 : 
     299                 : /* {{{ zval *http_get_server_var_ex(char *, size_t) */
     300                 : PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_len, zend_bool check TSRMLS_DC)
     301              18 : {
     302                 :         zval **hsv, **var;
     303                 :         char *env;
     304                 :         
     305                 :         /* if available, this is a lot faster than accessing $_SERVER */
     306              18 :         if (sapi_module.getenv) {
     307               0 :                 if ((!(env = sapi_module.getenv((char *) key, key_len TSRMLS_CC))) || (check && !*env)) {
     308               0 :                         return NULL;
     309                 :                 }
     310               0 :                 if (HTTP_G->server_var) {
     311               0 :                         zval_ptr_dtor(&HTTP_G->server_var);
     312                 :                 }
     313               0 :                 MAKE_STD_ZVAL(HTTP_G->server_var);
     314               0 :                 ZVAL_STRING(HTTP_G->server_var, env, 1);
     315               0 :                 return HTTP_G->server_var;
     316                 :         }
     317                 :         
     318                 : #ifdef ZEND_ENGINE_2
     319              18 :         zend_is_auto_global("_SERVER", lenof("_SERVER") TSRMLS_CC);
     320                 : #endif
     321                 :         
     322              18 :         if ((SUCCESS != zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &hsv)) || (Z_TYPE_PP(hsv) != IS_ARRAY)) {
     323               0 :                 return NULL;
     324                 :         }
     325              18 :         if ((SUCCESS != zend_hash_find(Z_ARRVAL_PP(hsv), HTTP_ZAPI_CONST_CAST(char *) key, key_len + 1, (void *) &var))) {
     326               7 :                 return NULL;
     327                 :         }
     328              11 :         if (check && !((Z_TYPE_PP(var) == IS_STRING) && Z_STRVAL_PP(var) && Z_STRLEN_PP(var))) {
     329               0 :                 return NULL;
     330                 :         }
     331              11 :         return *var;
     332                 : }
     333                 : /* }}} */
     334                 : 
     335                 : /* {{{ STATUS http_get_request_body(char **, size_t *) */
     336                 : PHP_HTTP_API STATUS _http_get_request_body_ex(char **body, size_t *length, zend_bool dup TSRMLS_DC)
     337               3 : {
     338               3 :         *length = 0;
     339               3 :         *body = NULL;
     340                 :         
     341               3 :         if (SG(request_info).raw_post_data) {
     342               3 :                 *length = SG(request_info).raw_post_data_length;
     343               3 :                 *body = SG(request_info).raw_post_data;
     344                 :                 
     345               3 :                 if (dup) {
     346               3 :                         *body = estrndup(*body, *length);
     347                 :                 }
     348               3 :                 return SUCCESS;
     349               0 :         } else if (sapi_module.read_post && !HTTP_G->read_post_data) {
     350                 :                 char buf[4096];
     351                 :                 int len;
     352                 :                 
     353               0 :                 HTTP_G->read_post_data = 1;
     354                 :                 
     355               0 :                 while (0 < (len = sapi_module.read_post(buf, sizeof(buf) TSRMLS_CC))) {
     356               0 :                         *body = erealloc(*body, *length + len + 1);
     357               0 :                         memcpy(*body + *length, buf, len);
     358               0 :                         *length += len;
     359               0 :                         (*body)[*length] = '\0';
     360                 :                 }
     361                 :                 
     362                 :                 /* check for error */
     363               0 :                 if (len < 0) {
     364               0 :                         STR_FREE(*body);
     365               0 :                         *length = 0;
     366               0 :                         return FAILURE;
     367                 :                 }
     368                 :                 
     369               0 :                 SG(request_info).raw_post_data = *body;
     370               0 :                 SG(request_info).raw_post_data_length = *length;
     371                 :                 
     372               0 :                 if (dup) {
     373               0 :                         *body = estrndup(*body, *length);
     374                 :                 }
     375               0 :                 return SUCCESS;
     376                 :         }
     377                 :         
     378               0 :         return FAILURE;
     379                 : }
     380                 : /* }}} */
     381                 : 
     382                 : /* {{{ php_stream *http_get_request_body_stream(void) */
     383                 : PHP_HTTP_API php_stream *_http_get_request_body_stream(TSRMLS_D)
     384               1 : {
     385               1 :         php_stream *s = NULL;
     386                 :         
     387               1 :         if (SG(request_info).raw_post_data) {
     388               1 :                 s = php_stream_open_wrapper("php://input", "rb", 0, NULL);
     389               0 :         } else if (sapi_module.read_post && !HTTP_G->read_post_data) {
     390               0 :                 HTTP_G->read_post_data = 1;
     391                 :                 
     392               0 :                 if ((s = php_stream_temp_new())) {
     393                 :                         char buf[4096];
     394                 :                         int len;
     395                 :                         
     396               0 :                         while (0 < (len = sapi_module.read_post(buf, sizeof(buf) TSRMLS_CC))) {
     397               0 :                                 php_stream_write(s, buf, len);
     398                 :                         }
     399                 :                         
     400               0 :                         if (len < 0) {
     401               0 :                                 php_stream_close(s);
     402               0 :                                 s = NULL;
     403                 :                         } else {
     404               0 :                                 php_stream_rewind(s);
     405                 :                         }
     406                 :                 }
     407                 :         }
     408                 :         
     409               1 :         return s;
     410                 : }
     411                 : /* }}} */
     412                 : 
     413                 : /* {{{ void http_parse_params_default_callback(...) */
     414                 : PHP_HTTP_API void _http_parse_params_default_callback(void *arg, const char *key, int keylen, const char *val, int vallen TSRMLS_DC)
     415              11 : {
     416                 :         char *kdup;
     417                 :         zval tmp, *entry;
     418              11 :         HashTable *ht = (HashTable *) arg;
     419                 :         
     420              11 :         if (ht) {
     421              11 :                 INIT_ZARR(tmp, ht);
     422                 :                 
     423              11 :                 if (vallen) {
     424               5 :                         MAKE_STD_ZVAL(entry);
     425               5 :                         array_init(entry);
     426               5 :                         if (keylen) {
     427               5 :                                 kdup = estrndup(key, keylen);
     428               5 :                                 add_assoc_stringl_ex(entry, kdup, keylen + 1, (char *) val, vallen, 1);
     429               5 :                                 efree(kdup);
     430                 :                         } else {
     431               0 :                                 add_next_index_stringl(entry, (char *) val, vallen, 1);
     432                 :                         }
     433               5 :                         add_next_index_zval(&tmp, entry);
     434                 :                 } else {
     435               6 :                         add_next_index_stringl(&tmp, (char *) key, keylen, 1);
     436                 :                 }
     437                 :         }
     438              11 : }
     439                 : /* }}} */
     440                 : 
     441                 : /* {{{ STATUS http_parse_params(const char *, HashTable *) */
     442                 : PHP_HTTP_API STATUS _http_parse_params_ex(const char *param, int flags, http_parse_params_callback cb, void *cb_arg TSRMLS_DC)
     443              41 : {
     444                 : #define ST_QUOTE        1
     445                 : #define ST_VALUE        2
     446                 : #define ST_KEY          3
     447                 : #define ST_ASSIGN       4
     448                 : #define ST_ADD          5
     449                 :         
     450              41 :         int st = ST_KEY, keylen = 0, vallen = 0;
     451              41 :         char *s, *c, *key = NULL, *val = NULL;
     452                 :         
     453              41 :         for(c = s = estrdup(param);;) {
     454             910 :         continued:
     455                 : #if 0
     456                 :         {
     457                 :                 char *tk = NULL, *tv = NULL;
     458                 :                 
     459                 :                 if (key) {
     460                 :                         if (keylen) {
     461                 :                                 tk= estrndup(key, keylen);
     462                 :                         } else {
     463                 :                                 tk = ecalloc(1, 7);
     464                 :                                 memcpy(tk, key, 3);
     465                 :                                 tk[3]='.'; tk[4]='.'; tk[5]='.';
     466                 :                         }
     467                 :                 }
     468                 :                 if (val) {
     469                 :                         if (vallen) {
     470                 :                                 tv = estrndup(val, vallen);
     471                 :                         } else {
     472                 :                                 tv = ecalloc(1, 7);
     473                 :                                 memcpy(tv, val, 3);
     474                 :                                 tv[3]='.'; tv[4]='.'; tv[5]='.';
     475                 :                         }
     476                 :                 }
     477                 :                 fprintf(stderr, "[%6s] %c \"%s=%s\"\n",
     478                 :                                 (
     479                 :                                                 st == ST_QUOTE ? "QUOTE" :
     480                 :                                                 st == ST_VALUE ? "VALUE" :
     481                 :                                                 st == ST_KEY ? "KEY" :
     482                 :                                                 st == ST_ASSIGN ? "ASSIGN" :
     483                 :                                                 st == ST_ADD ? "ADD":
     484                 :                                                 "HUH?"
     485                 :                                 ), *c?*c:'0', tk, tv
     486                 :                 );
     487                 :                 STR_FREE(tk); STR_FREE(tv);
     488                 :         }
     489                 : #endif
     490             910 :                 switch (st) {
     491                 :                         case ST_QUOTE:
     492              61 :                         quote:
     493              61 :                                 if (*c == '"') {
     494              14 :                                         if (*(c-1) == '\\') {
     495               2 :                                                 memmove(c-1, c, strlen(c)+1);
     496               2 :                                                 goto quote;
     497                 :                                         } else {
     498              12 :                                                 goto add;
     499                 :                                         }
     500                 :                                 } else {
     501              47 :                                         if (!val) {
     502              14 :                                                 val = c;
     503                 :                                         }
     504              47 :                                         if (!*c) {
     505               3 :                                                 --val;
     506               3 :                                                 st = ST_ADD;
     507                 :                                         }
     508                 :                                 }
     509              47 :                                 break;
     510                 :                                 
     511                 :                         case ST_VALUE:
     512             474 :                                 switch (*c) {
     513                 :                                         case '"':
     514              16 :                                                 if (!val) {
     515              15 :                                                         st = ST_QUOTE;
     516                 :                                                 }
     517              16 :                                                 break;
     518                 :                                         
     519                 :                                         case ' ':
     520              31 :                                                 break;
     521                 :                                         
     522                 :                                         case ';':
     523                 :                                         case '\0':
     524              31 :                                                 goto add;
     525                 :                                                 break;
     526                 :                                         case ',':
     527               3 :                                                 if (flags & HTTP_PARAMS_ALLOW_COMMA) {
     528               0 :                                                         goto add;
     529                 :                                                 }
     530                 :                                         default:
     531             396 :                                                 if (!val) {
     532              24 :                                                         val = c;
     533                 :                                                 }
     534                 :                                                 break;
     535                 :                                 }
     536             443 :                                 break;
     537                 :                                 
     538                 :                         case ST_KEY:
     539             358 :                                 switch (*c) {
     540                 :                                         case ',':
     541               2 :                                                 if (flags & HTTP_PARAMS_ALLOW_COMMA) {
     542               2 :                                                         goto allow_comma;
     543                 :                                                 }
     544                 :                                         case '\r':
     545                 :                                         case '\n':
     546                 :                                         case '\t':
     547                 :                                         case '\013':
     548                 :                                         case '\014':
     549               0 :                                                 goto failure;
     550                 :                                                 break;
     551                 :                                         
     552                 :                                         case '=':
     553              41 :                                                 if (key) {
     554              41 :                                                         keylen = c - key;
     555              41 :                                                         st = ST_VALUE;
     556                 :                                                 } else {
     557               0 :                                                         goto failure;
     558                 :                                                 }
     559              41 :                                                 break;
     560                 :                                         
     561                 :                                         case ' ':
     562              28 :                                                 if (key) {
     563               8 :                                                         keylen = c - key;
     564               8 :                                                         st = ST_ASSIGN;
     565                 :                                                 }
     566              28 :                                                 break;
     567                 :                                         
     568                 :                                         case ';':
     569                 :                                         case '\0':
     570              33 :                                         allow_comma:
     571              33 :                                                 if (key) {
     572               9 :                                                         keylen = c-- - key;
     573               9 :                                                         st = ST_ADD;
     574                 :                                                 }
     575              33 :                                                 break;
     576                 :                                         
     577                 :                                         default:
     578             256 :                                                 if (!key) {
     579              58 :                                                         key = c;
     580                 :                                                 }
     581                 :                                                 break;
     582                 :                                 }
     583             358 :                                 break;
     584                 :                                 
     585                 :                         case ST_ASSIGN:
     586               8 :                                 if (*c == '=') {
     587               5 :                                         st = ST_VALUE;
     588               6 :                                 } else if (!*c || *c == ';' || ((flags & HTTP_PARAMS_ALLOW_COMMA) && *c == ',')) {
     589               3 :                                         st = ST_ADD;
     590               0 :                                 } else if (*c != ' ') {
     591               0 :                                         goto failure;
     592                 :                                 }
     593               8 :                                 break;
     594                 :                                 
     595                 :                         case ST_ADD:
     596              58 :                         add:
     597              58 :                                 if (val) {
     598              38 :                                         vallen = c - val;
     599              38 :                                         if (st != ST_QUOTE) {
     600              27 :                                                 while (val[vallen-1] == ' ') --vallen;
     601                 :                                         }
     602                 :                                 } else {
     603              20 :                                         val = "";
     604              20 :                                         vallen = 0;
     605                 :                                 }
     606                 :                                 
     607              58 :                                 cb(cb_arg, key, keylen, val, vallen TSRMLS_CC);
     608                 :                                 
     609              58 :                                 st = ST_KEY;
     610              58 :                                 key = val = NULL;
     611              58 :                                 keylen = vallen = 0;
     612                 :                                 break;
     613                 :                 }
     614             914 :                 if (*c) {
     615             869 :                         ++c;
     616              45 :                 } else if (st == ST_ADD) {
     617               4 :                         goto add;
     618                 :                 } else {
     619              41 :                         break;
     620                 :                 }
     621             869 :         }
     622                 :         
     623              41 :         efree(s);
     624              41 :         return SUCCESS;
     625                 :         
     626               0 : failure:
     627               0 :         if (flags & HTTP_PARAMS_RAISE_ERROR) {
     628               0 :                 http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Unexpected character (%c) at pos %tu of %zu", *c, c-s, strlen(s));
     629                 :         }
     630               0 :         if (flags & HTTP_PARAMS_ALLOW_FAILURE) {
     631               0 :                 if (st == ST_KEY) {
     632               0 :                         if (key) {
     633               0 :                                 keylen = c - key;
     634                 :                         } else {
     635               0 :                                 key = c;
     636                 :                         }
     637                 :                 } else {
     638               0 :                         --c;
     639                 :                 }
     640               0 :                 st = ST_ADD;
     641               0 :                 goto continued;
     642                 :         }
     643               0 :         efree(s);
     644               0 :         return FAILURE;
     645                 : }
     646                 : /* }}} */
     647                 : 
     648                 : /* {{{ array_join */
     649                 : int apply_array_append_func(void *pDest, int num_args, va_list args, zend_hash_key *hash_key)
     650               0 : {
     651                 :         int flags;
     652               0 :         char *key = NULL;
     653                 :         HashTable *dst;
     654               0 :         zval **data = NULL, **value = (zval **) pDest;
     655                 :         
     656               0 :         dst = va_arg(args, HashTable *);
     657               0 :         flags = va_arg(args, int);
     658                 :         
     659               0 :         if ((!(flags & ARRAY_JOIN_STRONLY)) || hash_key->nKeyLength) {
     660               0 :                 if ((flags & ARRAY_JOIN_PRETTIFY) && hash_key->nKeyLength) {
     661               0 :                         key = pretty_key(estrndup(hash_key->arKey, hash_key->nKeyLength - 1), hash_key->nKeyLength - 1, 1, 1);
     662               0 :                         zend_hash_find(dst, key, hash_key->nKeyLength, (void *) &data);
     663                 :                 } else {
     664               0 :                         zend_hash_quick_find(dst, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void *) &data);
     665                 :                 }
     666                 :                 
     667               0 :                 ZVAL_ADDREF(*value);
     668               0 :                 if (data) {
     669               0 :                         if (Z_TYPE_PP(data) != IS_ARRAY) {
     670               0 :                                 convert_to_array(*data);
     671                 :                         }
     672               0 :                         add_next_index_zval(*data, *value);
     673               0 :                 } else if (key) {
     674               0 :                         zend_hash_add(dst, key, hash_key->nKeyLength, value, sizeof(zval *), NULL);
     675                 :                 } else {
     676               0 :                         zend_hash_quick_add(dst, hash_key->arKey, hash_key->nKeyLength, hash_key->h, value, sizeof(zval *), NULL);
     677                 :                 }
     678                 :                 
     679               0 :                 if (key) {
     680               0 :                         efree(key);
     681                 :                 }
     682                 :         }
     683                 :         
     684               0 :         return ZEND_HASH_APPLY_KEEP;
     685                 : }
     686                 : 
     687                 : int apply_array_merge_func(void *pDest, int num_args, va_list args, zend_hash_key *hash_key)
     688             263 : {
     689                 :         int flags;
     690             263 :         char *key = NULL;
     691                 :         HashTable *dst;
     692             263 :         zval **value = (zval **) pDest;
     693                 :         
     694             263 :         dst = va_arg(args, HashTable *);
     695             263 :         flags = va_arg(args, int);
     696                 :         
     697             263 :         if ((!(flags & ARRAY_JOIN_STRONLY)) || hash_key->nKeyLength) {
     698             263 :                 ZVAL_ADDREF(*value);
     699             267 :                 if ((flags & ARRAY_JOIN_PRETTIFY) && hash_key->nKeyLength) {
     700               4 :                         key = pretty_key(estrndup(hash_key->arKey, hash_key->nKeyLength - 1), hash_key->nKeyLength - 1, 1, 1);
     701               4 :                         zend_hash_update(dst, key, hash_key->nKeyLength, (void *) value, sizeof(zval *), NULL);
     702               4 :                         efree(key);
     703                 :                 } else {
     704             259 :                         zend_hash_quick_update(dst, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void *) value, sizeof(zval *), NULL);
     705                 :                 }
     706                 :         }
     707                 :         
     708             263 :         return ZEND_HASH_APPLY_KEEP;
     709                 : }
     710                 : /* }}} */
     711                 : 
     712                 : /*
     713                 :  * Local variables:
     714                 :  * tab-width: 4
     715                 :  * c-basic-offset: 4
     716                 :  * End:
     717                 :  * vim600: noet sw=4 ts=4 fdm=marker
     718                 :  * vim<600: noet sw=4 ts=4
     719                 :  */
     720                 : 

Generated by: LTP GCOV extension version 1.5

Generated at Fri, 05 Sep 2008 19:43:35 +0000 (31 hours ago)

Copyright © 2005-2008 The PHP Group
All rights reserved.