]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.0' into PHP-7.1
authorNikita Popov <nikic@php.net>
Mon, 2 Jan 2017 22:39:35 +0000 (23:39 +0100)
committerNikita Popov <nikic@php.net>
Mon, 2 Jan 2017 22:39:35 +0000 (23:39 +0100)
1  2 
NEWS
ext/mysqlnd/mysqlnd_wireprotocol.c
ext/standard/browscap.c

diff --cc NEWS
index 020bcc04e059341d9cd8b12580317981cd43dd58,8711158387233e9b26760f887fc23b1e39a6d295..c1fbefa669ffb5e11adf408ce35097fe81116d00
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -63,9 -53,11 +63,12 @@@ PH
    . Fixed bug #70213 (Unserialize context shared on double class lookup).
      (Taoguang Chen)
    . Fixed bug #73154 (serialize object with __sleep function crash). (Nikita)
+   . Fixed bug #70490 (get_browser function is very slow). (Nikita)
+   . Fixed bug #73265 (Loading browscap.ini at startup causes high memory usage).
+     (Nikita)
 +  . Add subject to mail log. (tomsommer)
  
 -- Zlib:
 +- Zlib
    . Fixed bug #73373 (deflate_add does not verify that output was not truncated).
      (Matt Bonneau)
  
index b057a44e8276f51411d02ac716de3ba37b1ec2a3,84f363b403b26743a410e80ce5bc14d0ebd2570e..d6fa9017bddd4d079a7ef8a87d7f4f86949bc573
@@@ -1468,7 -1443,13 +1468,7 @@@ php_mysqlnd_read_row_ex(MYSQLND_PFC * p
        zend_bool first_iteration = TRUE;
  
        DBG_ENTER("php_mysqlnd_read_row_ex");
+       
 -      /*
 -       * We're allocating 1 extra byte, as php_mysqlnd_rowp_read_text_protocol_aux
 -       * needs to be able to add a terminating \0 for atoi/atof.
 -       */
 -      prealloc_more_bytes++;
 -      
        /*
          To ease the process the server splits everything in packets up to 2^24 - 1.
          Even in the case the payload is evenly divisible by this value, the last
index a52ed2501f6f6814fe432ac68e15ee0a934dde02,71491bcb45945507fdaee38d67f2414bad1c3dae..c913cc8c978888b4bb68c288778fbf5fd3183ba5
@@@ -50,30 -69,91 +69,91 @@@ ZEND_DECLARE_MODULE_GLOBALS(browscap
  
  /* OBJECTS_FIXME: This whole extension needs going through. The use of objects looks pretty broken here */
  
- static void browscap_entry_dtor_request(zval *zvalue) /* {{{ */
+ static void browscap_entry_dtor(zval *zvalue)
  {
-       if (Z_TYPE_P(zvalue) == IS_ARRAY) {
-               zend_hash_destroy(Z_ARRVAL_P(zvalue));
-               efree(Z_ARR_P(zvalue));
-       } else if (Z_TYPE_P(zvalue) == IS_STRING) {
-               zend_string_release(Z_STR_P(zvalue));
+       browscap_entry *entry = Z_PTR_P(zvalue);
+       zend_string_release(entry->pattern);
+       if (entry->parent) {
+               zend_string_release(entry->parent);
        }
+       efree(entry);
  }
- /* }}} */
  
- static void browscap_entry_dtor_persistent(zval *zvalue) /* {{{ */ {
      if (Z_TYPE_P(zvalue) == IS_ARRAY) {
-               zend_hash_destroy(Z_ARRVAL_P(zvalue));
-               free(Z_ARR_P(zvalue));
-       } else if (Z_TYPE_P(zvalue) == IS_STRING) {
-               zend_string_release(Z_STR_P(zvalue));
+ static void browscap_entry_dtor_persistent(zval *zvalue)
+ {
+       browscap_entry *entry = Z_PTR_P(zvalue);
+       zend_string_release(entry->pattern);
+       if (entry->parent) {
+               zend_string_release(entry->parent);
        }
+       pefree(entry, 1);
+ }
+ static inline zend_bool is_placeholder(char c) {
+       return c == '?' || c == '*';
+ }
+ /* Length of prefix not containing any wildcards */
+ static uint8_t browscap_compute_prefix_len(zend_string *pattern) {
+       size_t i;
+       for (i = 0; i < ZSTR_LEN(pattern); i++) {
+               if (is_placeholder(ZSTR_VAL(pattern)[i])) {
+                       break;
+               }
+       }
+       return MIN(i, UINT8_MAX);
+ }
+ static size_t browscap_compute_contains(
+               zend_string *pattern, size_t start_pos,
+               uint16_t *contains_start, uint8_t *contains_len) {
+       size_t i = start_pos;
+       /* Find first non-placeholder character after prefix */
+       for (; i < ZSTR_LEN(pattern); i++) {
+               if (!is_placeholder(ZSTR_VAL(pattern)[i])) {
+                       /* Skip the case of a single non-placeholder character.
+                        * Let's try to find something longer instead. */
+                       if (i + 1 < ZSTR_LEN(pattern) &&
+                                       !is_placeholder(ZSTR_VAL(pattern)[i + 1])) {
+                               break;
+                       }
+               }
+       }
+       *contains_start = i;
+       /* Find first placeholder character after that */
+       for (; i < ZSTR_LEN(pattern); i++) {
+               if (is_placeholder(ZSTR_VAL(pattern)[i])) {
+                       break;
+               }
+       }
+       *contains_len = MIN(i - *contains_start, UINT8_MAX);
+       return i;
+ }
+ /* Length of regex, including escapes, anchors, etc. */
+ static size_t browscap_compute_regex_len(zend_string *pattern) {
+       size_t i, len = ZSTR_LEN(pattern);
+       for (i = 0; i < ZSTR_LEN(pattern); i++) {
+               switch (ZSTR_VAL(pattern)[i]) {
+                       case '*':
+                       case '.':
+                       case '\\':
+                       case '(':
+                       case ')':
+                       case '~':
+                       case '+':
+                               len++;
+                               break;
+               }
+       }
+       
+       return len + sizeof("~^$~")-1;
  }
- /* }}} */
  
- static void convert_browscap_pattern(zval *pattern, int persistent) /* {{{ */
+ static zend_string *browscap_convert_pattern(zend_string *pattern, int persistent) /* {{{ */
  {
 -      int i, j=0;
 +      size_t i, j=0;
        char *t;
        zend_string *res;
        char *lc_pattern;
@@@ -220,7 -392,8 +392,8 @@@ static void php_browscap_parser_cb(zva
  
  static int browscap_read_file(char *filename, browser_data *browdata, int persistent) /* {{{ */
  {
 -      zend_file_handle fh = {{0}};
 +      zend_file_handle fh;
+       browscap_parser_ctx ctx = {0};
  
        if (filename == NULL || filename[0] == '\0') {
                return FAILURE;