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 - standard - url.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 349
Code covered: 86.5 % Executed lines: 302
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Jim Winstead <jimw@php.net>                                  |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : /* $Id: url.c 290199 2009-11-04 13:44:10Z iliaa $ */
      19                 : 
      20                 : #include <stdlib.h>
      21                 : #include <string.h>
      22                 : #include <ctype.h>
      23                 : #include <sys/types.h>
      24                 : 
      25                 : #include "php.h"
      26                 : 
      27                 : #include "url.h"
      28                 : #include "file.h"
      29                 : #ifdef _OSD_POSIX
      30                 : #ifndef APACHE
      31                 : #error On this EBCDIC platform, PHP is only supported as an Apache module.
      32                 : #else /*APACHE*/
      33                 : #ifndef CHARSET_EBCDIC
      34                 : #define CHARSET_EBCDIC /* this machine uses EBCDIC, not ASCII! */
      35                 : #endif
      36                 : #include "ebcdic.h"
      37                 : #endif /*APACHE*/
      38                 : #endif /*_OSD_POSIX*/
      39                 : 
      40                 : /* {{{ free_url
      41                 :  */
      42                 : PHPAPI void php_url_free(php_url *theurl)
      43            2526 : {
      44            2526 :         if (theurl->scheme)
      45            2272 :                 efree(theurl->scheme);
      46            2526 :         if (theurl->user)
      47             122 :                 efree(theurl->user);
      48            2526 :         if (theurl->pass)
      49              73 :                 efree(theurl->pass);
      50            2526 :         if (theurl->host)
      51            2154 :                 efree(theurl->host);
      52            2526 :         if (theurl->path)
      53            2389 :                 efree(theurl->path);
      54            2526 :         if (theurl->query)
      55             234 :                 efree(theurl->query);
      56            2526 :         if (theurl->fragment)
      57             123 :                 efree(theurl->fragment);
      58            2526 :         efree(theurl);
      59            2526 : }
      60                 : /* }}} */
      61                 : 
      62                 : /* {{{ php_replace_controlchars
      63                 :  */
      64                 : PHPAPI char *php_replace_controlchars_ex(char *str, int len)
      65            3224 : {
      66            3224 :         unsigned char *s = (unsigned char *)str;
      67            3224 :         unsigned char *e = (unsigned char *)str + len;
      68                 :         
      69            3224 :         if (!str) {
      70               0 :                 return (NULL);
      71                 :         }
      72                 :         
      73           33570 :         while (s < e) {
      74                 :             
      75           27122 :                 if (iscntrl(*s)) {
      76               0 :                         *s='_';
      77                 :                 }       
      78           27122 :                 s++;
      79                 :         }
      80                 :         
      81            3224 :         return (str);
      82                 : } 
      83                 : /* }}} */
      84                 : 
      85                 : PHPAPI char *php_replace_controlchars(char *str)
      86               0 : {
      87               0 :         return php_replace_controlchars_ex(str, strlen(str));
      88                 : } 
      89                 : 
      90                 : PHPAPI php_url *php_url_parse(char const *str)
      91             316 : {
      92             316 :         return php_url_parse_ex(str, strlen(str));
      93                 : }
      94                 : 
      95                 : /* {{{ php_url_parse
      96                 :  */
      97                 : PHPAPI php_url *php_url_parse_ex(char const *str, int length)
      98            1378 : {
      99                 :         char port_buf[6];
     100            1378 :         php_url *ret = ecalloc(1, sizeof(php_url));
     101                 :         char const *s, *e, *p, *pp, *ue;
     102                 :                 
     103            1378 :         s = str;
     104            1378 :         ue = s + length;
     105                 : 
     106                 :         /* parse scheme */
     107            2344 :         if ((e = memchr(s, ':', length)) && (e - s)) {
     108                 :                 /* validate scheme */
     109            1164 :                 p = s;
     110            7195 :                 while (p < e) {
     111                 :                         /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */
     112            4867 :                         if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') {
     113               0 :                                 if (e + 1 < ue) {
     114               0 :                                         goto parse_port;
     115                 :                                 } else {
     116               0 :                                         goto just_path;
     117                 :                                 }
     118                 :                         }
     119            4867 :                         p++;
     120                 :                 }
     121                 :         
     122            1164 :                 if (*(e + 1) == '\0') { /* only scheme is available */
     123              11 :                         ret->scheme = estrndup(s, (e - s));
     124              11 :                         php_replace_controlchars_ex(ret->scheme, (e - s));
     125              11 :                         goto end;
     126                 :                 }
     127                 : 
     128                 :                 /* 
     129                 :                  * certain schemas like mailto: and zlib: may not have any / after them
     130                 :                  * this check ensures we support those.
     131                 :                  */
     132            1153 :                 if (*(e+1) != '/') {
     133                 :                         /* check if the data we get is a port this allows us to 
     134                 :                          * correctly parse things like a.com:80
     135                 :                          */
     136              91 :                         p = e + 1;
     137             332 :                         while (isdigit(*p)) {
     138             150 :                                 p++;
     139                 :                         }
     140                 :                         
     141              91 :                         if ((*p == '\0' || *p == '/') && (p - e) < 7) {
     142              40 :                                 goto parse_port;
     143                 :                         }
     144                 :                         
     145              51 :                         ret->scheme = estrndup(s, (e-s));
     146              51 :                         php_replace_controlchars_ex(ret->scheme, (e - s));
     147                 :                         
     148              51 :                         length -= ++e - s;
     149              51 :                         s = e;
     150              51 :                         goto just_path;
     151                 :                 } else {
     152            1062 :                         ret->scheme = estrndup(s, (e-s));
     153            1062 :                         php_replace_controlchars_ex(ret->scheme, (e - s));
     154                 :                 
     155            1062 :                         if (*(e+2) == '/') {
     156            1031 :                                 s = e + 3;
     157            1031 :                                 if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
     158              76 :                                         if (*(e + 3) == '/') {
     159                 :                                                 /* support windows drive letters as in:
     160                 :                                                    file:///c:/somedir/file.txt
     161                 :                                                 */
     162              65 :                                                 if (*(e + 5) == ':') {
     163              27 :                                                         s = e + 4;
     164                 :                                                 }
     165              65 :                                                 goto nohost;
     166                 :                                         }
     167                 :                                 }
     168                 :                         } else {
     169              31 :                                 if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
     170              10 :                                         s = e + 1;
     171              10 :                                         goto nohost;
     172                 :                                 } else {
     173              21 :                                         length -= ++e - s;
     174              21 :                                         s = e;
     175              21 :                                         goto just_path;
     176                 :                                 }       
     177                 :                         }
     178                 :                 }       
     179             214 :         } else if (e) { /* no scheme, look for port */
     180              40 :                 parse_port:
     181              40 :                 p = e + 1;
     182              40 :                 pp = p;
     183                 :                 
     184             160 :                 while (pp-p < 6 && isdigit(*pp)) {
     185              80 :                         pp++;
     186                 :                 }
     187                 :                 
     188              40 :                 if (pp-p < 6 && (*pp == '/' || *pp == '\0')) {
     189              40 :                         memcpy(port_buf, p, (pp-p));
     190              40 :                         port_buf[pp-p] = '\0';
     191              40 :                         ret->port = atoi(port_buf);
     192                 :                 } else {
     193                 :                         goto just_path;
     194                 :                 }
     195                 :         } else {
     196             286 :                 just_path:
     197             286 :                 ue = s + length;
     198             286 :                 goto nohost;
     199                 :         }
     200                 :         
     201            1006 :         e = ue;
     202                 :         
     203            1006 :         if (!(p = memchr(s, '/', (ue - s)))) {
     204                 :                 char *query, *fragment;
     205                 : 
     206             462 :                 query = memchr(s, '?', (ue - s));
     207             462 :                 fragment = memchr(s, '#', (ue - s));
     208                 : 
     209             462 :                 if (query && fragment) {
     210               0 :                         if (query > fragment) {
     211               0 :                                 p = e = fragment;
     212                 :                         } else {
     213               0 :                                 p = e = query;
     214                 :                         }
     215             462 :                 } else if (query) {
     216              55 :                         p = e = query;
     217             407 :                 } else if (fragment) {
     218              10 :                         p = e = fragment;
     219                 :                 }
     220                 :         } else {
     221             544 :                 e = p;
     222                 :         }       
     223                 :                 
     224                 :         /* check for login and password */
     225            1006 :         if ((p = zend_memrchr(s, '@', (e-s)))) {
     226             168 :                 if ((pp = memchr(s, ':', (p-s)))) {
     227              92 :                         if ((pp-s) > 0) {
     228              82 :                                 ret->user = estrndup(s, (pp-s));
     229              82 :                                 php_replace_controlchars_ex(ret->user, (pp - s));
     230                 :                         }       
     231                 :                 
     232              92 :                         pp++;
     233              92 :                         if (p-pp > 0) {
     234              82 :                                 ret->pass = estrndup(pp, (p-pp));
     235              82 :                                 php_replace_controlchars_ex(ret->pass, (p-pp));
     236                 :                         }       
     237                 :                 } else {
     238              76 :                         ret->user = estrndup(s, (p-s));
     239              76 :                         php_replace_controlchars_ex(ret->user, (p-s));
     240                 :                 }
     241                 :                 
     242             168 :                 s = p + 1;
     243                 :         }
     244                 : 
     245                 :         /* check for port */
     246            1015 :         if (*s == '[' && *(e-1) == ']') {
     247                 :                 /* Short circuit portscan, 
     248                 :                    we're dealing with an 
     249                 :                    IPv6 embedded address */
     250               9 :                 p = s;
     251                 :         } else {
     252                 :                 /* memrchr is a GNU specific extension
     253                 :                    Emulate for wide compatability */
     254             997 :                 for(p = e; *p != ':' && p >= s; p--);
     255                 :         }
     256                 : 
     257            1456 :         if (p >= s && *p == ':') {
     258             468 :                 if (!ret->port) {
     259             428 :                         p++;
     260             428 :                         if (e-p > 5) { /* port cannot be longer then 5 characters */
     261              18 :                                 STR_FREE(ret->scheme);
     262              18 :                                 STR_FREE(ret->user);
     263              18 :                                 STR_FREE(ret->pass);
     264              18 :                                 efree(ret);
     265              18 :                                 return NULL;
     266             410 :                         } else if (e - p > 0) {
     267             328 :                                 memcpy(port_buf, p, (e-p));
     268             328 :                                 port_buf[e-p] = '\0';
     269             328 :                                 ret->port = atoi(port_buf);
     270                 :                         }
     271             410 :                         p--;
     272                 :                 }       
     273                 :         } else {
     274             538 :                 p = e;
     275                 :         }
     276                 :         
     277                 :         /* check if we have a valid host, if we don't reject the string as url */
     278             988 :         if ((p-s) < 1) {
     279             354 :                 STR_FREE(ret->scheme);
     280             354 :                 STR_FREE(ret->user);
     281             354 :                 STR_FREE(ret->pass);
     282             354 :                 efree(ret);
     283             354 :                 return NULL;
     284                 :         }
     285                 : 
     286             634 :         ret->host = estrndup(s, (p-s));
     287             634 :         php_replace_controlchars_ex(ret->host, (p - s));
     288                 :         
     289             634 :         if (e == ue) {
     290              88 :                 return ret;
     291                 :         }
     292                 :         
     293             546 :         s = e;
     294                 :         
     295             907 :         nohost:
     296                 :         
     297             907 :         if ((p = memchr(s, '?', (ue - s)))) {
     298             321 :                 pp = strchr(s, '#');
     299                 : 
     300             321 :                 if (pp && pp < p) {
     301               0 :                         p = pp;
     302               0 :                         goto label_parse;
     303                 :                 }
     304                 :         
     305             321 :                 if (p - s) {
     306             293 :                         ret->path = estrndup(s, (p-s));
     307             293 :                         php_replace_controlchars_ex(ret->path, (p - s));
     308                 :                 }       
     309                 :         
     310             321 :                 if (pp) {
     311             113 :                         if (pp - ++p) { 
     312             103 :                                 ret->query = estrndup(p, (pp-p));
     313             103 :                                 php_replace_controlchars_ex(ret->query, (pp - p));
     314                 :                         }
     315             113 :                         p = pp;
     316             113 :                         goto label_parse;
     317             208 :                 } else if (++p - ue) {
     318             131 :                         ret->query = estrndup(p, (ue-p));
     319             131 :                         php_replace_controlchars_ex(ret->query, (ue - p));
     320                 :                 }
     321             586 :         } else if ((p = memchr(s, '#', (ue - s)))) {
     322              20 :                 if (p - s) {
     323              10 :                         ret->path = estrndup(s, (p-s));
     324              10 :                         php_replace_controlchars_ex(ret->path, (p - s));
     325                 :                 }       
     326                 :                 
     327             133 :                 label_parse:
     328             133 :                 p++;
     329                 :                 
     330             133 :                 if (ue - p) {
     331             123 :                         ret->fragment = estrndup(p, (ue-p));
     332             123 :                         php_replace_controlchars_ex(ret->fragment, (ue - p));
     333                 :                 }       
     334                 :         } else {
     335             566 :                 ret->path = estrndup(s, (ue-s));
     336             566 :                 php_replace_controlchars_ex(ret->path, (ue - s));
     337                 :         }
     338             918 : end:
     339             918 :         return ret;
     340                 : }
     341                 : /* }}} */
     342                 : 
     343                 : /* {{{ proto mixed parse_url(string url, [int url_component])
     344                 :    Parse a URL and return its components */
     345                 : PHP_FUNCTION(parse_url)
     346            1043 : {
     347                 :         char *str;
     348                 :         int str_len;
     349                 :         php_url *resource;
     350            1043 :         long key = -1;
     351                 : 
     352            1043 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &key) == FAILURE) {
     353              18 :                 return;
     354                 :         }
     355                 : 
     356            1025 :         resource = php_url_parse_ex(str, str_len);
     357            1025 :         if (resource == NULL) {
     358             117 :                 php_error_docref1(NULL TSRMLS_CC, str, E_WARNING, "Unable to parse URL");
     359             117 :                 RETURN_FALSE;
     360                 :         }
     361                 : 
     362             908 :         if (key > -1) {
     363             716 :                 switch (key) {
     364                 :                         case PHP_URL_SCHEME:
     365              96 :                                 if (resource->scheme != NULL) RETVAL_STRING(resource->scheme, 1);
     366              96 :                                 break;
     367                 :                         case PHP_URL_HOST:
     368              90 :                                 if (resource->host != NULL) RETVAL_STRING(resource->host, 1);
     369              90 :                                 break;
     370                 :                         case PHP_URL_PORT:
     371              88 :                                 if (resource->port != 0) RETVAL_LONG(resource->port);
     372              88 :                                 break;
     373                 :                         case PHP_URL_USER:
     374              88 :                                 if (resource->user != NULL) RETVAL_STRING(resource->user, 1);
     375              88 :                                 break;
     376                 :                         case PHP_URL_PASS:
     377              88 :                                 if (resource->pass != NULL) RETVAL_STRING(resource->pass, 1);
     378              88 :                                 break;
     379                 :                         case PHP_URL_PATH:
     380              88 :                                 if (resource->path != NULL) RETVAL_STRING(resource->path, 1);
     381              88 :                                 break;
     382                 :                         case PHP_URL_QUERY:
     383              88 :                                 if (resource->query != NULL) RETVAL_STRING(resource->query, 1);
     384              88 :                                 break;
     385                 :                         case PHP_URL_FRAGMENT:
     386              88 :                                 if (resource->fragment != NULL) RETVAL_STRING(resource->fragment, 1);
     387              88 :                                 break;
     388                 :                         default:
     389               2 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid URL component identifier %ld", key);
     390               2 :                                 RETVAL_FALSE;
     391                 :                 }
     392             716 :                 goto done;
     393                 :         }
     394                 : 
     395                 :         /* allocate an array for return */
     396             192 :         array_init(return_value);
     397                 : 
     398                 :     /* add the various elements to the array */
     399             192 :         if (resource->scheme != NULL)
     400             143 :                 add_assoc_string(return_value, "scheme", resource->scheme, 1);
     401             192 :         if (resource->host != NULL)
     402             127 :                 add_assoc_string(return_value, "host", resource->host, 1);
     403             192 :         if (resource->port != 0)
     404              64 :                 add_assoc_long(return_value, "port", resource->port);
     405             192 :         if (resource->user != NULL)
     406              22 :                 add_assoc_string(return_value, "user", resource->user, 1);
     407             192 :         if (resource->pass != NULL)
     408              13 :                 add_assoc_string(return_value, "pass", resource->pass, 1);
     409             192 :         if (resource->path != NULL)
     410             165 :                 add_assoc_string(return_value, "path", resource->path, 1);
     411             192 :         if (resource->query != NULL)
     412              45 :                 add_assoc_string(return_value, "query", resource->query, 1);
     413             192 :         if (resource->fragment != NULL)
     414              23 :                 add_assoc_string(return_value, "fragment", resource->fragment, 1);
     415             908 : done:   
     416             908 :         php_url_free(resource);
     417                 : }
     418                 : /* }}} */
     419                 : 
     420                 : /* {{{ php_htoi
     421                 :  */
     422                 : static int php_htoi(char *s)
     423             126 : {
     424                 :         int value;
     425                 :         int c;
     426                 : 
     427             126 :         c = ((unsigned char *)s)[0];
     428             126 :         if (isupper(c))
     429               3 :                 c = tolower(c);
     430             126 :         value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
     431                 : 
     432             126 :         c = ((unsigned char *)s)[1];
     433             126 :         if (isupper(c))
     434              47 :                 c = tolower(c);
     435             126 :         value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
     436                 : 
     437             126 :         return (value);
     438                 : }
     439                 : /* }}} */
     440                 : 
     441                 : /* rfc1738:
     442                 : 
     443                 :    ...The characters ";",
     444                 :    "/", "?", ":", "@", "=" and "&" are the characters which may be
     445                 :    reserved for special meaning within a scheme...
     446                 : 
     447                 :    ...Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
     448                 :    reserved characters used for their reserved purposes may be used
     449                 :    unencoded within a URL...
     450                 : 
     451                 :    For added safety, we only leave -_. unencoded.
     452                 :  */
     453                 : 
     454                 : static unsigned char hexchars[] = "0123456789ABCDEF";
     455                 : 
     456                 : /* {{{ php_url_encode
     457                 :  */
     458                 : PHPAPI char *php_url_encode(char const *s, int len, int *new_length)
     459            1889 : {
     460                 :         register unsigned char c;
     461                 :         unsigned char *to, *start;
     462                 :         unsigned char const *from, *end;
     463                 :         
     464            1889 :         from = (unsigned char *)s;
     465            1889 :         end = (unsigned char *)s + len;
     466            1889 :         start = to = (unsigned char *) safe_emalloc(3, len, 1);
     467                 : 
     468           21410 :         while (from < end) {
     469           17632 :                 c = *from++;
     470                 : 
     471           17632 :                 if (c == ' ') {
     472              24 :                         *to++ = '+';
     473                 : #ifndef CHARSET_EBCDIC
     474           20424 :                 } else if ((c < '0' && c != '-' && c != '.') ||
     475                 :                                    (c < 'A' && c > '9') ||
     476                 :                                    (c > 'Z' && c < 'a' && c != '_') ||
     477                 :                                    (c > 'z')) {
     478            2816 :                         to[0] = '%';
     479            2816 :                         to[1] = hexchars[c >> 4];
     480            2816 :                         to[2] = hexchars[c & 15];
     481            2816 :                         to += 3;
     482                 : #else /*CHARSET_EBCDIC*/
     483                 :                 } else if (!isalnum(c) && strchr("_-.", c) == NULL) {
     484                 :                         /* Allow only alphanumeric chars and '_', '-', '.'; escape the rest */
     485                 :                         to[0] = '%';
     486                 :                         to[1] = hexchars[os_toascii[c] >> 4];
     487                 :                         to[2] = hexchars[os_toascii[c] & 15];
     488                 :                         to += 3;
     489                 : #endif /*CHARSET_EBCDIC*/
     490                 :                 } else {
     491           14792 :                         *to++ = c;
     492                 :                 }
     493                 :         }
     494            1889 :         *to = 0;
     495            1889 :         if (new_length) {
     496            1363 :                 *new_length = to - start;
     497                 :         }
     498            1889 :         return (char *) start;
     499                 : }
     500                 : /* }}} */
     501                 : 
     502                 : /* {{{ proto string urlencode(string str)
     503                 :    URL-encodes string */
     504                 : PHP_FUNCTION(urlencode)
     505            1333 : {
     506                 :         char *in_str, *out_str;
     507                 :         int in_str_len, out_str_len;
     508                 : 
     509            1333 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
     510                 :                                                           &in_str_len) == FAILURE) {
     511               8 :                 return;
     512                 :         }
     513                 : 
     514            1325 :         out_str = php_url_encode(in_str, in_str_len, &out_str_len);
     515            1325 :         RETURN_STRINGL(out_str, out_str_len, 0);
     516                 : }
     517                 : /* }}} */
     518                 : 
     519                 : /* {{{ proto string urldecode(string str)
     520                 :    Decodes URL-encoded string */
     521                 : PHP_FUNCTION(urldecode)
     522              31 : {
     523                 :         char *in_str, *out_str;
     524                 :         int in_str_len, out_str_len;
     525                 : 
     526              31 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
     527                 :                                                           &in_str_len) == FAILURE) {
     528               8 :                 return;
     529                 :         }
     530                 : 
     531              23 :         out_str = estrndup(in_str, in_str_len);
     532              23 :         out_str_len = php_url_decode(out_str, in_str_len);
     533                 : 
     534              23 :     RETURN_STRINGL(out_str, out_str_len, 0);
     535                 : }
     536                 : /* }}} */
     537                 : 
     538                 : /* {{{ php_url_decode
     539                 :  */
     540                 : PHPAPI int php_url_decode(char *str, int len)
     541             767 : {
     542             767 :         char *dest = str;
     543             767 :         char *data = str;
     544                 : 
     545           13765 :         while (len--) {
     546           12231 :                 if (*data == '+') {
     547              34 :                         *dest = ' ';
     548                 :                 }
     549           12293 :                 else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) 
     550                 :                                  && isxdigit((int) *(data + 2))) {
     551                 : #ifndef CHARSET_EBCDIC
     552              96 :                         *dest = (char) php_htoi(data + 1);
     553                 : #else
     554                 :                         *dest = os_toebcdic[(char) php_htoi(data + 1)];
     555                 : #endif
     556              96 :                         data += 2;
     557              96 :                         len -= 2;
     558                 :                 } else {
     559           12101 :                         *dest = *data;
     560                 :                 }
     561           12231 :                 data++;
     562           12231 :                 dest++;
     563                 :         }
     564             767 :         *dest = '\0';
     565             767 :         return dest - str;
     566                 : }
     567                 : /* }}} */
     568                 : 
     569                 : /* {{{ php_raw_url_encode
     570                 :  */
     571                 : PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length)
     572              21 : {
     573                 :         register int x, y;
     574                 :         unsigned char *str;
     575                 : 
     576              21 :         str = (unsigned char *) safe_emalloc(3, len, 1);
     577             209 :         for (x = 0, y = 0; len--; x++, y++) {
     578             188 :                 str[y] = (unsigned char) s[x];
     579                 : #ifndef CHARSET_EBCDIC
     580             188 :                 if ((str[y] < '0' && str[y] != '-' && str[y] != '.') ||
     581                 :                         (str[y] < 'A' && str[y] > '9') ||
     582                 :                         (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
     583                 :                         (str[y] > 'z' && str[y] != '~')) {
     584              36 :                         str[y++] = '%';
     585              36 :                         str[y++] = hexchars[(unsigned char) s[x] >> 4];
     586              36 :                         str[y] = hexchars[(unsigned char) s[x] & 15];
     587                 : #else /*CHARSET_EBCDIC*/
     588                 :                 if (!isalnum(str[y]) && strchr("_-.", str[y]) != NULL) {
     589                 :                         str[y++] = '%';
     590                 :                         str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4];
     591                 :                         str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 15];
     592                 : #endif /*CHARSET_EBCDIC*/
     593                 :                 }
     594                 :         }
     595              21 :         str[y] = '\0';
     596              21 :         if (new_length) {
     597              21 :                 *new_length = y;
     598                 :         }
     599              21 :         return ((char *) str);
     600                 : }
     601                 : /* }}} */
     602                 : 
     603                 : /* {{{ proto string rawurlencode(string str)
     604                 :    URL-encodes string */
     605                 : PHP_FUNCTION(rawurlencode)
     606              29 : {
     607                 :         char *in_str, *out_str;
     608                 :         int in_str_len, out_str_len;
     609                 : 
     610              29 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
     611                 :                                                           &in_str_len) == FAILURE) {
     612               8 :                 return;
     613                 :         }
     614                 : 
     615              21 :         out_str = php_raw_url_encode(in_str, in_str_len, &out_str_len);
     616              21 :         RETURN_STRINGL(out_str, out_str_len, 0);
     617                 : }
     618                 : /* }}} */
     619                 : 
     620                 : /* {{{ proto string rawurldecode(string str)
     621                 :    Decodes URL-encodes string */
     622                 : PHP_FUNCTION(rawurldecode)
     623              28 : {
     624                 :         char *in_str, *out_str;
     625                 :         int in_str_len, out_str_len;
     626                 : 
     627              28 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
     628                 :                                                           &in_str_len) == FAILURE) {
     629               8 :                 return;
     630                 :         }
     631                 : 
     632              20 :         out_str = estrndup(in_str, in_str_len);
     633              20 :         out_str_len = php_raw_url_decode(out_str, in_str_len);
     634                 : 
     635              20 :     RETURN_STRINGL(out_str, out_str_len, 0);
     636                 : }
     637                 : /* }}} */
     638                 : 
     639                 : /* {{{ php_raw_url_decode
     640                 :  */
     641                 : PHPAPI int php_raw_url_decode(char *str, int len)
     642              20 : {
     643              20 :         char *dest = str;
     644              20 :         char *data = str;
     645                 : 
     646             187 :         while (len--) {
     647             177 :                 if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) 
     648                 :                         && isxdigit((int) *(data + 2))) {
     649                 : #ifndef CHARSET_EBCDIC
     650              30 :                         *dest = (char) php_htoi(data + 1);
     651                 : #else
     652                 :                         *dest = os_toebcdic[(char) php_htoi(data + 1)];
     653                 : #endif
     654              30 :                         data += 2;
     655              30 :                         len -= 2;
     656                 :                 } else {
     657             117 :                         *dest = *data;
     658                 :                 }
     659             147 :                 data++;
     660             147 :                 dest++;
     661                 :         }
     662              20 :         *dest = '\0';
     663              20 :         return dest - str;
     664                 : }
     665                 : /* }}} */
     666                 : 
     667                 : /* {{{ proto array get_headers(string url[, int format])
     668                 :    fetches all the headers sent by the server in response to a HTTP request */
     669                 : PHP_FUNCTION(get_headers)
     670               5 : {
     671                 :         char *url;
     672                 :         int url_len;
     673                 :         php_stream_context *context;
     674                 :         php_stream *stream;
     675               5 :         zval **prev_val, **hdr = NULL, **h;
     676                 :         HashPosition pos;
     677                 :         HashTable *hashT;
     678               5 :         long format = 0;
     679                 :                 
     680               5 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &url, &url_len, &format) == FAILURE) {
     681               5 :                 return;
     682                 :         }
     683               0 :         context = FG(default_context) ? FG(default_context) : (FG(default_context) = php_stream_context_alloc());
     684                 : 
     685               0 :         if (!(stream = php_stream_open_wrapper_ex(url, "r", REPORT_ERRORS | STREAM_USE_URL | STREAM_ONLY_GET_HEADERS, NULL, context))) {
     686               0 :                 RETURN_FALSE;
     687                 :         }
     688                 : 
     689               0 :         if (!stream->wrapperdata || Z_TYPE_P(stream->wrapperdata) != IS_ARRAY) {
     690               0 :                 php_stream_close(stream);
     691               0 :                 RETURN_FALSE;
     692                 :         }
     693                 : 
     694               0 :         array_init(return_value);
     695                 : 
     696                 :         /* check for curl-wrappers that provide headers via a special "headers" element */
     697               0 :         if (zend_hash_find(HASH_OF(stream->wrapperdata), "headers", sizeof("headers"), (void **)&h) != FAILURE && Z_TYPE_PP(h) == IS_ARRAY) {
     698                 :                 /* curl-wrappers don't load data until the 1st read */ 
     699               0 :                 if (!Z_ARRVAL_PP(h)->nNumOfElements) {
     700               0 :                         php_stream_getc(stream);
     701                 :                 }
     702               0 :                 zend_hash_find(HASH_OF(stream->wrapperdata), "headers", sizeof("headers"), (void **)&h);
     703               0 :                 hashT = Z_ARRVAL_PP(h); 
     704                 :         } else {
     705               0 :                 hashT = HASH_OF(stream->wrapperdata);
     706                 :         }
     707                 : 
     708               0 :         zend_hash_internal_pointer_reset_ex(hashT, &pos);
     709               0 :         while (zend_hash_get_current_data_ex(hashT, (void**)&hdr, &pos) != FAILURE) {
     710               0 :                 if (!hdr || Z_TYPE_PP(hdr) != IS_STRING) {
     711               0 :                         zend_hash_move_forward_ex(hashT, &pos);
     712               0 :                         continue;
     713                 :                 }
     714               0 :                 if (!format) {
     715               0 : no_name_header:
     716               0 :                         add_next_index_stringl(return_value, Z_STRVAL_PP(hdr), Z_STRLEN_PP(hdr), 1);
     717                 :                 } else {
     718                 :                         char c;
     719                 :                         char *s, *p;
     720                 : 
     721               0 :                         if ((p = strchr(Z_STRVAL_PP(hdr), ':'))) {
     722               0 :                                 c = *p;
     723               0 :                                 *p = '\0';
     724               0 :                                 s = p + 1;
     725               0 :                                 while (isspace((int)*(unsigned char *)s)) {
     726               0 :                                         s++;
     727                 :                                 }
     728                 : 
     729               0 :                                 if (zend_hash_find(HASH_OF(return_value), Z_STRVAL_PP(hdr), (p - Z_STRVAL_PP(hdr) + 1), (void **) &prev_val) == FAILURE) {
     730               0 :                                         add_assoc_stringl_ex(return_value, Z_STRVAL_PP(hdr), (p - Z_STRVAL_PP(hdr) + 1), s, (Z_STRLEN_PP(hdr) - (s - Z_STRVAL_PP(hdr))), 1);
     731                 :                                 } else { /* some headers may occur more then once, therefor we need to remake the string into an array */
     732               0 :                                         convert_to_array(*prev_val);
     733               0 :                                         add_next_index_stringl(*prev_val, s, (Z_STRLEN_PP(hdr) - (s - Z_STRVAL_PP(hdr))), 1);
     734                 :                                 }
     735                 : 
     736               0 :                                 *p = c;
     737                 :                         } else {
     738               0 :                                 goto no_name_header;
     739                 :                         }
     740                 :                 }
     741               0 :                 zend_hash_move_forward_ex(hashT, &pos);
     742                 :         }
     743                 : 
     744               0 :         php_stream_close(stream);
     745                 : }
     746                 : /* }}} */
     747                 : 
     748                 : /*
     749                 :  * Local variables:
     750                 :  * tab-width: 4
     751                 :  * c-basic-offset: 4
     752                 :  * End:
     753                 :  * vim600: sw=4 ts=4 fdm=marker
     754                 :  * vim<600: sw=4 ts=4
     755                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:10 +0000 (3 days ago)

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