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

LCOV - code coverage report
Current view: top level - ext/opcache - zend_accelerator_blacklist.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 12 168 7.1 %
Date: 2014-08-04 Functions: 2 9 22.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend OPcache                                                         |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 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             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    |          Stanislav Malyshev <stas@zend.com>                          |
      18             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      19             :    +----------------------------------------------------------------------+
      20             : */
      21             : 
      22             : #include "main/php.h"
      23             : #include "main/fopen_wrappers.h"
      24             : #include "ZendAccelerator.h"
      25             : #include "zend_accelerator_blacklist.h"
      26             : 
      27             : #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
      28             : # include "ext/ereg/php_regex.h"
      29             : #else
      30             : # include "main/php_regex.h"
      31             : #endif
      32             : 
      33             : #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
      34             : # include "ext/standard/php_string.h"
      35             : #endif
      36             : 
      37             : #ifdef ZEND_WIN32
      38             : # define REGEX_MODE (REG_EXTENDED|REG_NOSUB|REG_ICASE)
      39             : #else
      40             : # define REGEX_MODE (REG_EXTENDED|REG_NOSUB)
      41             : #endif
      42             : 
      43             : #ifdef HAVE_GLOB
      44             : #ifdef PHP_WIN32
      45             : #include "win32/glob.h"
      46             : #else
      47             : #include <glob.h>
      48             : #endif
      49             : #endif
      50             : 
      51             : #define ZEND_BLACKLIST_BLOCK_SIZE       32
      52             : 
      53             : struct _zend_regexp_list {
      54             :         regex_t           comp_regex;
      55             :         zend_regexp_list *next;
      56             : };
      57             : 
      58             : zend_blacklist accel_blacklist;
      59             : 
      60           0 : void zend_accel_blacklist_init(zend_blacklist *blacklist)
      61             : {
      62           0 :         blacklist->pos = 0;
      63           0 :         blacklist->size = ZEND_BLACKLIST_BLOCK_SIZE;
      64             : 
      65           0 :         if (blacklist->entries != NULL) {
      66           0 :                 zend_accel_blacklist_shutdown(blacklist);
      67             :         }
      68             : 
      69           0 :         blacklist->entries = (zend_blacklist_entry *) calloc(sizeof(zend_blacklist_entry), blacklist->size);
      70           0 :         if (!blacklist->entries) {
      71           0 :                 zend_accel_error(ACCEL_LOG_FATAL, "Blacklist initialization: no memory\n");
      72           0 :                 return;
      73             :         }
      74           0 :         blacklist->regexp_list = NULL;
      75             : }
      76             : 
      77           0 : static void blacklist_report_regexp_error(regex_t *comp_regex, int reg_err)
      78             : {
      79             :         char *errbuf;
      80           0 :         int errsize = regerror(reg_err, comp_regex, NULL, 0);
      81           0 :         errbuf = malloc(errsize);
      82           0 :         if (!errbuf) {
      83           0 :                 zend_accel_error(ACCEL_LOG_ERROR, "Blacklist compilation: no memory\n");
      84           0 :                 return;
      85             :         }
      86           0 :         regerror(reg_err, comp_regex, errbuf, errsize);
      87           0 :         zend_accel_error(ACCEL_LOG_ERROR, "Blacklist compilation: %s\n", errbuf);
      88           0 :         free(errbuf);
      89             : }
      90             : 
      91           0 : static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
      92             : {
      93             :         int i, reg_err;
      94             :         zend_regexp_list **regexp_list_it, *it;
      95           0 :         char regexp[12*1024], *p, *end, *c, *backtrack = NULL;
      96             : 
      97           0 :         if (blacklist->pos == 0) {
      98             :                 /* we have no blacklist to talk about */
      99           0 :                 return;
     100             :         }
     101             : 
     102           0 :         regexp_list_it = &(blacklist->regexp_list);
     103             : 
     104           0 :         regexp[0] = '^';
     105           0 :         regexp[1] = '(';
     106           0 :         p = regexp + 2;
     107           0 :         end = regexp + sizeof(regexp) - sizeof("[^\\\\]*)\0");
     108             : 
     109           0 :         for (i = 0; i < blacklist->pos; ) {
     110           0 :                 c = blacklist->entries[i].path;
     111           0 :                 if (p + blacklist->entries[i].path_length < end) {
     112           0 :                         while (*c && p < end) {
     113           0 :                                 switch (*c) {
     114             :                                         case '?':
     115           0 :                                                 c++;
     116             : #ifdef ZEND_WIN32
     117             :                                                 p[0] = '[';                     /* * => [^\\] on Win32 */
     118             :                                                 p[1] = '^';
     119             :                                                 p[2] = '\\';
     120             :                                                 p[3] = '\\';
     121             :                                                 p[4] = ']';
     122             :                                                 p += 5;
     123             : #else
     124           0 :                                                 p[0] = '[';                     /* * => [^/] on *nix */
     125           0 :                                                 p[1] = '^';
     126           0 :                                                 p[2] = '/';
     127           0 :                                                 p[3] = ']';
     128           0 :                                                 p += 4;
     129             : #endif
     130           0 :                                                 break;
     131             :                                         case '*':
     132           0 :                                                 c++;
     133           0 :                                                 if (*c == '*') {
     134           0 :                                                         c++;
     135           0 :                                                         p[0] = '.';                     /* ** => .* */
     136           0 :                                                         p[1] = '*';
     137           0 :                                                         p += 2;
     138             :                                                 } else {
     139             : #ifdef ZEND_WIN32
     140             :                                                         p[0] = '[';                     /* * => [^\\]* on Win32 */
     141             :                                                         p[1] = '^';
     142             :                                                         p[2] = '\\';
     143             :                                                         p[3] = '\\';
     144             :                                                         p[4] = ']';
     145             :                                                         p[5] = '*';
     146             :                                                         p += 6;
     147             : #else
     148           0 :                                                         p[0] = '[';                     /* * => [^/]* on *nix */
     149           0 :                                                         p[1] = '^';
     150           0 :                                                         p[2] = '/';
     151           0 :                                                         p[3] = ']';
     152           0 :                                                         p[4] = '*';
     153           0 :                                                         p += 5;
     154             : #endif
     155             :                                                 }
     156           0 :                                                 break;
     157             :                                         case '^':
     158             :                                         case '.':
     159             :                                         case '[':
     160             :                                         case ']':
     161             :                                         case '$':
     162             :                                         case '(':
     163             :                                         case ')':
     164             :                                         case '|':
     165             :                                         case '+':
     166             :                                         case '{':
     167             :                                         case '}':
     168             :                                         case '\\':
     169           0 :                                                 *p++ = '\\';
     170             :                                                 /* break missing intentionally */
     171             :                                         default:
     172           0 :                                                 *p++ = *c++;
     173             :                                 }
     174             :                         }
     175             :                 }
     176             : 
     177           0 :                 if (*c || i == blacklist->pos - 1) {
     178           0 :                         if (*c) {
     179           0 :                                 if (!backtrack) {
     180           0 :                                         zend_accel_error(ACCEL_LOG_ERROR, "Too long blacklist entry\n");
     181             :                                 }
     182           0 :                                 p = backtrack;
     183             :                         } else {
     184           0 :                                 i++;
     185             :                         }
     186           0 :                         *p++ = ')';
     187           0 :                         *p++ = '\0';
     188             : 
     189           0 :                         it = (zend_regexp_list*)malloc(sizeof(zend_regexp_list));
     190           0 :                         if (!it) {
     191           0 :                                 zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
     192           0 :                                 return;
     193             :                         }
     194           0 :                         it->next = NULL;
     195             : 
     196           0 :                         if ((reg_err = regcomp(&it->comp_regex, regexp, REGEX_MODE)) != 0) {
     197           0 :                                 blacklist_report_regexp_error(&it->comp_regex, reg_err);
     198             :                         }
     199             :                         /* prepare for the next iteration */
     200           0 :                         p = regexp + 2;
     201           0 :                         *regexp_list_it = it;
     202           0 :                         regexp_list_it = &it->next;
     203             :                 } else {
     204           0 :                         backtrack = p;
     205           0 :                         *p++ = '|';
     206           0 :                         i++;
     207             :                 }
     208             :         }
     209             : }
     210             : 
     211       21146 : void zend_accel_blacklist_shutdown(zend_blacklist *blacklist)
     212             : {
     213       21146 :         zend_blacklist_entry *p = blacklist->entries, *end = blacklist->entries + blacklist->pos;
     214             : 
     215       42292 :         while (p<end) {
     216           0 :                 free(p->path);
     217           0 :                 p++;
     218             :         }
     219       21146 :         free(blacklist->entries);
     220       21146 :         blacklist->entries = NULL;
     221       21146 :         if (blacklist->regexp_list) {
     222           0 :                 zend_regexp_list *temp, *it = blacklist->regexp_list;
     223           0 :                 while (it) {
     224           0 :                         regfree(&it->comp_regex);
     225           0 :                         temp = it;
     226           0 :                         it = it->next;
     227           0 :                         free(temp);
     228             :                 }
     229             :         }
     230       21146 : }
     231             : 
     232           0 : static inline void zend_accel_blacklist_allocate(zend_blacklist *blacklist)
     233             : {
     234           0 :         if (blacklist->pos == blacklist->size) {
     235           0 :                 blacklist->size += ZEND_BLACKLIST_BLOCK_SIZE;
     236           0 :                 blacklist->entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry)*blacklist->size);
     237             :         }
     238           0 : }
     239             : 
     240             : #ifdef HAVE_GLOB
     241           0 : static void zend_accel_blacklist_loadone(zend_blacklist *blacklist, char *filename)
     242             : #else
     243             : void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
     244             : #endif
     245             : {
     246           0 :         char buf[MAXPATHLEN + 1], real_path[MAXPATHLEN + 1], *blacklist_path = NULL;
     247             :         FILE *fp;
     248             :         int path_length, blacklist_path_length;
     249             :         TSRMLS_FETCH();
     250             : 
     251           0 :         if ((fp = fopen(filename, "r")) == NULL) {
     252           0 :                 zend_accel_error(ACCEL_LOG_WARNING, "Cannot load blacklist file: %s\n", filename);
     253           0 :                 return;
     254             :         }
     255             : 
     256           0 :         zend_accel_error(ACCEL_LOG_DEBUG,"Loading blacklist file:  '%s'", filename);
     257             : 
     258           0 :         if (VCWD_REALPATH(filename, buf)) {
     259             : #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
     260             :                 blacklist_path_length = php_dirname(buf, strlen(buf));
     261             : #else
     262           0 :                 blacklist_path_length = zend_dirname(buf, strlen(buf));
     263             : #endif
     264           0 :                 blacklist_path = zend_strndup(buf, blacklist_path_length);
     265             :         }
     266             : 
     267           0 :         memset(buf, 0, sizeof(buf));
     268           0 :         memset(real_path, 0, sizeof(real_path));
     269             : 
     270           0 :         while (fgets(buf, MAXPATHLEN, fp) != NULL) {
     271             :                 char *path_dup, *pbuf;
     272           0 :                 path_length = strlen(buf);
     273           0 :                 if (path_length > 0 && buf[path_length - 1] == '\n') {
     274           0 :                         buf[--path_length] = 0;
     275           0 :                         if (path_length > 0 && buf[path_length - 1] == '\r') {
     276           0 :                                 buf[--path_length] = 0;
     277             :                         }
     278             :                 }
     279             : 
     280             :                 /* Strip ctrl-m prefix */
     281           0 :                 pbuf = &buf[0];
     282           0 :                 while (*pbuf == '\r') {
     283           0 :                         *pbuf++ = 0;
     284           0 :                         path_length--;
     285             :                 }
     286             : 
     287             :                 /* strip \" */
     288           0 :                 if (pbuf[0] == '\"' && pbuf[path_length - 1]== '\"') {
     289           0 :                         *pbuf++ = 0;
     290           0 :                         path_length -= 2;
     291             :                 }
     292             : 
     293           0 :                 if (path_length == 0) {
     294           0 :                         continue;
     295             :                 }
     296             : 
     297             :                 /* skip comments */
     298           0 :                 if (pbuf[0]==';') {
     299           0 :                         continue;
     300             :                 }
     301             : 
     302           0 :                 path_dup = zend_strndup(pbuf, path_length);
     303           0 :                 if (blacklist_path) {
     304           0 :                         expand_filepath_ex(path_dup, real_path, blacklist_path, blacklist_path_length TSRMLS_CC);
     305             :                 } else {
     306           0 :                         expand_filepath(path_dup, real_path TSRMLS_CC);
     307             :                 }
     308           0 :                 path_length = strlen(real_path);
     309             : 
     310           0 :                 free(path_dup);
     311             : 
     312           0 :                 zend_accel_blacklist_allocate(blacklist);
     313           0 :                 blacklist->entries[blacklist->pos].path_length = path_length;
     314           0 :                 blacklist->entries[blacklist->pos].path = (char *)malloc(path_length + 1);
     315           0 :                 if (!blacklist->entries[blacklist->pos].path) {
     316           0 :                         zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
     317           0 :                         fclose(fp);
     318           0 :                         return;
     319             :                 }
     320           0 :                 blacklist->entries[blacklist->pos].id = blacklist->pos;
     321           0 :                 memcpy(blacklist->entries[blacklist->pos].path, real_path, path_length + 1);
     322           0 :                 blacklist->pos++;
     323             :         }
     324           0 :         fclose(fp);
     325           0 :         if (blacklist_path) {
     326           0 :                 free(blacklist_path);
     327             :         }
     328           0 :         zend_accel_blacklist_update_regexp(blacklist);
     329             : }
     330             : 
     331             : #ifdef HAVE_GLOB
     332           0 : void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
     333             : {
     334             :         glob_t globbuf;
     335             :         int    ret;
     336             :         unsigned int i;
     337             : 
     338           0 :         memset(&globbuf, 0, sizeof(glob_t));
     339             : 
     340           0 :         ret = glob(filename, 0, NULL, &globbuf);
     341             : #ifdef GLOB_NOMATCH
     342           0 :         if (ret == GLOB_NOMATCH || !globbuf.gl_pathc) {
     343             : #else
     344             :         if (!globbuf.gl_pathc) {
     345             : #endif
     346           0 :                 zend_accel_error(ACCEL_LOG_WARNING, "No blacklist file found matching: %s\n", filename);
     347             :         } else {
     348           0 :                 for(i=0 ; i<globbuf.gl_pathc; i++) {
     349           0 :                         zend_accel_blacklist_loadone(blacklist, globbuf.gl_pathv[i]);
     350             :                 }
     351           0 :                 globfree(&globbuf);
     352             :         }
     353           0 : }
     354             : #endif
     355             : 
     356         423 : zend_bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *verify_path)
     357             : {
     358         423 :         int ret = 0;
     359         423 :         zend_regexp_list *regexp_list_it = blacklist->regexp_list;
     360             : 
     361         423 :         if (regexp_list_it == NULL) {
     362         423 :                 return 0;
     363             :         }
     364           0 :         while (regexp_list_it != NULL) {
     365           0 :                 if (regexec(&(regexp_list_it->comp_regex), verify_path, 0, NULL, 0) == 0) {
     366           0 :                         ret = 1;
     367           0 :                         break;
     368             :                 }
     369           0 :                 regexp_list_it = regexp_list_it->next;
     370             :         }
     371           0 :         return ret;
     372             : }
     373             : 
     374           0 : void zend_accel_blacklist_apply(zend_blacklist *blacklist, apply_func_arg_t func, void *argument TSRMLS_DC)
     375             : {
     376             :         int i;
     377             : 
     378           0 :         for (i = 0; i < blacklist->pos; i++) {
     379           0 :                 func(&blacklist->entries[i], argument TSRMLS_CC);
     380             :         }
     381           0 : }

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:08 +0000 (29 days ago)

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