pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/lang/php56



Module Name:    pkgsrc
Committed By:   taca
Date:           Tue Oct 27 15:30:49 UTC 2026

Modified Files:
        pkgsrc/lang/php56: Makefile distinfo
        pkgsrc/lang/php56/patches: patch-Zend_zend__multiply.h
Added Files:
        pkgsrc/lang/php56/patches: patch-Zend_zend.c patch-Zend_zend__alloc.c
            patch-Zend_zend__alloc.h patch-Zend_zend__execute__API.c
            patch-Zend_zend__globals.h patch-Zend_zend__llist.c
            patch-Zend_zend__vm__execute.h patch-Zend_zend__vm__execute.skl
            patch-ext_session_session.c patch-ext_standard_basic__functions.h
            patch-ext_standard_php__incomplete__class.h
            patch-ext_standard_var.c patch-ext_standard_var__unserializer.c
            patch-ext_standard_var__unserializer.re patch-main_SAPI.c
            patch-main_main.c patch-main_php__variables.c patch-main_rfc1867.c

Log Message:
lang/php56: fix CVE-2026-109618 and CVE-2026-109619

Apply patch for CVE-2026-109618 and CVE-2026-109619.
Thanks to sborrill@ providing patch information.

Bump PKGREVISION.


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 pkgsrc/lang/php56/Makefile
cvs rdiff -u -r1.67 -r1.68 pkgsrc/lang/php56/distinfo
cvs rdiff -u -r0 -r1.1 pkgsrc/lang/php56/patches/patch-Zend_zend.c \
    pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.c \
    pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.h \
    pkgsrc/lang/php56/patches/patch-Zend_zend__execute__API.c \
    pkgsrc/lang/php56/patches/patch-Zend_zend__globals.h \
    pkgsrc/lang/php56/patches/patch-Zend_zend__llist.c \
    pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.h \
    pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.skl \
    pkgsrc/lang/php56/patches/patch-ext_session_session.c \
    pkgsrc/lang/php56/patches/patch-ext_standard_basic__functions.h \
    pkgsrc/lang/php56/patches/patch-ext_standard_php__incomplete__class.h \
    pkgsrc/lang/php56/patches/patch-ext_standard_var.c \
    pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.c \
    pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.re \
    pkgsrc/lang/php56/patches/patch-main_SAPI.c \
    pkgsrc/lang/php56/patches/patch-main_main.c \
    pkgsrc/lang/php56/patches/patch-main_php__variables.c \
    pkgsrc/lang/php56/patches/patch-main_rfc1867.c
cvs rdiff -u -r1.1 -r1.2 \
    pkgsrc/lang/php56/patches/patch-Zend_zend__multiply.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/lang/php56/Makefile
diff -u pkgsrc/lang/php56/Makefile:1.49 pkgsrc/lang/php56/Makefile:1.50
--- pkgsrc/lang/php56/Makefile:1.49     Sat Aug 29 02:43:37 2026
+++ pkgsrc/lang/php56/Makefile  Tue Oct 27 15:30:48 2026
@@ -1,10 +1,10 @@
-# $NetBSD: Makefile,v 1.49 2026/08/29 02:43:37 mef Exp $
+# $NetBSD: Makefile,v 1.50 2026/10/27 15:30:48 taca Exp $
 
 #
 # We can't omit PKGNAME here to handle PKG_OPTIONS.
 #
 PKGNAME=               ${PHP_PKG_PREFIX}-${PHP_VERSION}
-PKGREVISION=           6
+PKGREVISION=           7
 CATEGORIES=            lang
 
 COMMENT=               PHP Hypertext Preprocessor version 5.6

Index: pkgsrc/lang/php56/distinfo
diff -u pkgsrc/lang/php56/distinfo:1.67 pkgsrc/lang/php56/distinfo:1.68
--- pkgsrc/lang/php56/distinfo:1.67     Sat Aug 29 02:43:37 2026
+++ pkgsrc/lang/php56/distinfo  Tue Oct 27 15:30:48 2026
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.67 2026/08/29 02:43:37 mef Exp $
+$NetBSD: distinfo,v 1.68 2026/10/27 15:30:48 taca Exp $
 
 BLAKE2s (PHP-5.6.31-OpenSSL-1.1.0-compatibility-20170801.patch) = 9eaf6505d80e90147fd0b993fb501620030eea24ccd69e42c49d8faf50d47775
 SHA512 (PHP-5.6.31-OpenSSL-1.1.0-compatibility-20170801.patch) = bbe39ad27a5a82c705692c921b214c5630227ed9852f0432340f74533b5e618d9bea01bff75a4b7a1f1b72876b6d092d2db4533758d9a927f274cff7361f3eb4
@@ -8,7 +8,15 @@ SHA512 (php-5.6.40.tar.xz) = 997b5a952a6
 Size (php-5.6.40.tar.xz) = 12472236 bytes
 SHA1 (patch-Makefile.global) = cf4dec0e4adf4ceceffb498919c1b463db9c6e66
 SHA1 (patch-TSRM_threads.m4) = 83c51ef32371598689f2610726a2902e503b1d55
-SHA1 (patch-Zend_zend__multiply.h) = b51442f44e5b5853162a1ac7e451359d292b8210
+SHA1 (patch-Zend_zend.c) = faed48a92db61da305ab30cadc98df01c1436fb2
+SHA1 (patch-Zend_zend__alloc.c) = a011b5bab60d1775a4fdaeff50df31fc2f9ba77c
+SHA1 (patch-Zend_zend__alloc.h) = a9ef44b5880ff72ecccbb3269b126e72105f10bf
+SHA1 (patch-Zend_zend__execute__API.c) = 068bf1d940915073062d2dfb1ae407d1a4872d8d
+SHA1 (patch-Zend_zend__globals.h) = 3b3a499420f42c2211a653c140c11078ac9c374d
+SHA1 (patch-Zend_zend__llist.c) = 988d9882d48a94b69e97570a4a9a4e79f04ff81c
+SHA1 (patch-Zend_zend__multiply.h) = a2d1286e16971a406a4cfa13575f004d1f3af794
+SHA1 (patch-Zend_zend__vm__execute.h) = 2364bdcde9e9dff85820b35e54bb1fe2e8226907
+SHA1 (patch-Zend_zend__vm__execute.skl) = 0615c7f0ed6e5f98f0782df41922d498794c4dc9
 SHA1 (patch-acinclude.m4) = 46ee41b151927673b0d17fbd13a3159b2f7aab0a
 SHA1 (patch-aclocal.m4) = f24f25d8da5d846902ba94ec59fe4838bd24dda1
 SHA1 (patch-configure.in) = 67ed9f97785ba4bf3f6405d4af07fc32b972ba4e
@@ -37,12 +45,22 @@ SHA1 (patch-ext_pdo_config.m4) = 2cd85e7
 SHA1 (patch-ext_phar_Makefile.frag) = b39927055edd6fd3a02fb1d954e8fc69089ef01c
 SHA1 (patch-ext_phar_phar_phar.php) = 159f7934c3ca35e036739aa446f84fe2b7f72026
 SHA1 (patch-ext_recode_recode.c) = a97a1815d6a41410f68c289debbb9396128a2159
+SHA1 (patch-ext_session_session.c) = 4a2bffc26711f8258632433ddda1d612459d9855
 SHA1 (patch-ext_sqlite3_config0.m4) = 2435e1518a88c7d05eb93cf3c8e716fe4ea0748b
 SHA1 (patch-ext_standard_basic__functions.c) = ca1de427a3d793c3a3e99581fbd2d1fcf99aeb30
+SHA1 (patch-ext_standard_basic__functions.h) = 04506f91783498421e0d1b32b8bcc9477e41a077
 SHA1 (patch-ext_standard_php__dns.h) = 8e544eb637044e9428a0becb7402336f64a3a23d
+SHA1 (patch-ext_standard_php__incomplete__class.h) = 5123320a7e1d7ddac12b5e752b130277bf970fea
+SHA1 (patch-ext_standard_var.c) = 4618e6acf10de73226f5741d6246ae113a3489fb
+SHA1 (patch-ext_standard_var__unserializer.c) = 4d532463190fdaee4b39996be17ffd0b5c216b70
+SHA1 (patch-ext_standard_var__unserializer.re) = defcc69425eac0ac8ca7d47a699716a0e98bb254
 SHA1 (patch-ext_tidy_tidy.c) = 8f075f17ac913f21e65f4b704574c0ae5ffdfc84
 SHA1 (patch-ext_xml_compat.c) = fbea14c738728d33cdaf38405688ed6361f8894d
 SHA1 (patch-ext_xsl_php__xsl.h) = a9877bff7bacc77926a4541a0ac171c00ad1a627
+SHA1 (patch-main_SAPI.c) = db0702693307616062379e767bb84994ad20dd03
+SHA1 (patch-main_main.c) = c90a96a8d66bf2191df097bde97693ae870d1d8d
+SHA1 (patch-main_php__variables.c) = 0b351a7e30716f3ca861c8a21ad9f1fb7083cfc6
+SHA1 (patch-main_rfc1867.c) = 72f92bd0ffd34247ea9e2f6eef806e0e7dbc218d
 SHA1 (patch-makedist) = 091d5c0ba3e890ade475faa33446c8f97bcb7bc3
 SHA1 (patch-php.ini-development) = e1a187070a9dfc28762d7476d9acc796a93c7fac
 SHA1 (patch-php.ini-production) = f978e200175a161893669391f784f8072488ff24

Index: pkgsrc/lang/php56/patches/patch-Zend_zend__multiply.h
diff -u pkgsrc/lang/php56/patches/patch-Zend_zend__multiply.h:1.1 pkgsrc/lang/php56/patches/patch-Zend_zend__multiply.h:1.2
--- pkgsrc/lang/php56/patches/patch-Zend_zend__multiply.h:1.1   Sat Aug 29 02:43:37 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__multiply.h       Tue Oct 27 15:30:49 2026
@@ -1,18 +1,17 @@
-$NetBSD: patch-Zend_zend__multiply.h,v 1.1 2026/08/29 02:43:37 mef Exp $
+$NetBSD: patch-Zend_zend__multiply.h,v 1.2 2026/10/27 15:30:49 taca Exp $
 
 https://mail-index.netbsd.org/pkgsrc-users/2026/08/28/msg043351.html
 Quick hack by importing from php85 
 
---- Zend/zend_multiply.h.orig  2019-01-09 18:54:13.000000000 +0900
-+++ Zend/zend_multiply.h       2026-08-29 09:48:42.223797552 +0900
-@@ -56,14 +56,17 @@
- } while (0)
+--- Zend/zend_multiply.h.orig  2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_multiply.h
+@@ -57,13 +57,16 @@
  
  #elif defined(__aarch64__) && defined(__GNUC__)
-+
+ 
 +typedef int64_t zend_long;
 +
- 
++
  #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {     \
 -      long __tmpvar;                                                                                                  \
 +      zend_long __tmpvar;                                                                                                     \

Added files:

Index: pkgsrc/lang/php56/patches/patch-Zend_zend.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend.c Tue Oct 27 15:30:48 2026
@@ -0,0 +1,24 @@
+$NetBSD: patch-Zend_zend.c,v 1.1 2026/10/27 15:30:48 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend.c.orig   2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend.c
+@@ -577,6 +577,7 @@ static void executor_globals_ctor(zend_e
+ #endif
+       EG(saved_fpu_cw_ptr) = NULL;
+       EG(active) = 0;
++      EG(delayed_oom) = ZEND_OOM_STATE_NONE;
+ }
+ /* }}} */
+ 
+@@ -1339,6 +1340,9 @@ ZEND_API int zend_execute_scripts(int ty
+               if (EG(active_op_array)) {
+                       EG(return_value_ptr_ptr) = retval ? retval : NULL;
+                       zend_execute(EG(active_op_array) TSRMLS_CC);
++                      if (ZEND_OOM_PENDING()) {
++                              zend_handle_delayed_oom(TSRMLS_C);
++                      }
+                       zend_exception_restore(TSRMLS_C);
+                       if (EG(exception)) {
+                               if (EG(user_exception_handler)) {
Index: pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.c  Tue Oct 27 15:30:48 2026
@@ -0,0 +1,455 @@
+$NetBSD: patch-Zend_zend__alloc.c,v 1.1 2026/10/27 15:30:48 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend_alloc.c.orig     2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_alloc.c
+@@ -426,12 +426,17 @@ struct _zend_mm_heap {
+       size_t              real_size;
+       size_t              real_peak;
+       size_t              limit;
++      size_t              hard_limit;             /* see zend_mm_update_hard_limit() */
+       size_t              size;
+       size_t              peak;
+       size_t              reserve_size;
+       void               *reserve;
+       int                 overflow;
+       int                 internal;
++      /* Delayed OOM error, raised by zend_handle_delayed_oom() */
++      uint                oom_lineno;
++      char                oom_filename[1024];
++      char                oom_message[1024];
+ #if ZEND_MM_CACHE
+       unsigned int        cached;
+       zend_mm_free_block *cache[ZEND_MM_NUM_BUCKETS];
+@@ -1117,6 +1122,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_e
+       heap->overflow = 0;
+       heap->real_peak = 0;
+       heap->limit = ZEND_MM_LONG_CONST(1)<<(ZEND_MM_NUM_BUCKETS-2);
++      heap->hard_limit = heap->limit;
+       heap->size = 0;
+       heap->peak = 0;
+       heap->internal = internal;
+@@ -1598,6 +1604,27 @@ static int zend_mm_check_heap(zend_mm_he
+ }
+ #endif
+ 
++/* The hard limit leaves room above memory_limit for the request to reach the
++ * next safe point: 200% of memory_limit, or memory_limit + 1G above 1G. */
++static void zend_mm_update_hard_limit(zend_mm_heap *heap)
++{
++      size_t headroom = MIN(heap->limit, (size_t) 1024 * 1024 * 1024);
++      size_t hard_limit = (heap->limit > (size_t) -1 - headroom) ? (size_t) -1 : heap->limit + headroom;
++
++      if (heap->real_size > heap->limit) {
++              /* memory_limit is changed while exceeded (e.g. reset by the fatal
++               * error handler): neither move the hard limit up again, nor below
++               * the current usage */
++              if (heap->hard_limit > hard_limit && heap->hard_limit >= heap->real_size) {
++                      hard_limit = heap->hard_limit;
++              }
++              if (hard_limit < heap->real_size) {
++                      hard_limit = (heap->real_size > (size_t) -1 - headroom) ? (size_t) -1 : heap->real_size + headroom;
++              }
++      }
++      heap->hard_limit = hard_limit;
++}
++
+ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
+ {
+       zend_mm_storage *storage;
+@@ -1737,73 +1764,122 @@ ZEND_API void zend_mm_shutdown(zend_mm_h
+                       heap->reserve = _zend_mm_alloc_int(heap, heap->reserve_size  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
+               }
+               heap->overflow = 0;
++              zend_mm_update_hard_limit(heap);
+       }
+ }
+ 
+-static void zend_mm_safe_error(zend_mm_heap *heap,
+-      const char *format,
+-      size_t limit,
+-#if ZEND_DEBUG
+-      const char *filename,
+-      uint lineno,
+-#endif
+-      size_t size)
++static void zend_mm_error_location(const char **error_filename, uint *error_lineno)
+ {
+-      if (heap->reserve) {
+-              _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
+-              heap->reserve = NULL;
++      TSRMLS_FETCH();
++
++      if (zend_is_compiling(TSRMLS_C)) {
++              *error_filename = zend_get_compiled_filename(TSRMLS_C);
++              *error_lineno = zend_get_compiled_lineno(TSRMLS_C);
++      } else if (EG(in_execution)) {
++              *error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
++              *error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
++      } else {
++              *error_filename = NULL;
++              *error_lineno = 0;
+       }
+-      if (heap->overflow == 0) {
+-              const char *error_filename;
+-              uint error_lineno;
+-              TSRMLS_FETCH();
+-              if (zend_is_compiling(TSRMLS_C)) {
+-                      error_filename = zend_get_compiled_filename(TSRMLS_C);
+-                      error_lineno = zend_get_compiled_lineno(TSRMLS_C);
+-              } else if (EG(in_execution)) {
+-                      error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
+-                      error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
+-              } else {
+-                      error_filename = NULL;
+-                      error_lineno = 0;
+-              }
+-              if (!error_filename) {
+-                      error_filename = "Unknown";
+-              }
+-              heap->overflow = 1;
+-              zend_try {
+-                      zend_error_noreturn(E_ERROR,
+-                              format,
+-                              limit,
+-#if ZEND_DEBUG
+-                              filename,
+-                              lineno,
++      if (!*error_filename) {
++              *error_filename = "Unknown";
++      }
++}
++
++/* Real allocation failure (mmap/malloc): there is no safe way to continue */
++#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
++static void zend_mm_out_of_memory(zend_mm_heap *heap, size_t size) __attribute__ ((noreturn));
+ #endif
+-                              size);
+-              } zend_catch {
+-                      if (heap->overflow == 2) {
+-                              fprintf(stderr, "\nFatal error: ");
+-                              fprintf(stderr,
+-                                      format,
+-                                      limit,
+-#if ZEND_DEBUG
+-                                      filename,
+-                                      lineno,
++static void zend_mm_out_of_memory(zend_mm_heap *heap, size_t size)
++{
++      const char *error_filename;
++      uint error_lineno;
++
++      zend_mm_error_location(&error_filename, &error_lineno);
++      fprintf(stderr, "Out of memory (allocated %ld) (tried to allocate %lu bytes) in %s on line %d\n",
++              (long) heap->real_size, (unsigned long) size, error_filename, error_lineno);
++/* See http://support.microsoft.com/kb/190351 */
++#ifdef PHP_WIN32
++      fflush(stderr);
+ #endif
+-                                      size);
+-                              fprintf(stderr, " in %s on line %d\n", error_filename, error_lineno);
+-                      }
++      exit(1);
++}
++
++#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
++static void zend_mm_hard_limit_error(zend_mm_heap *heap, size_t size) __attribute__ ((noreturn));
++#endif
++static void zend_mm_hard_limit_error(zend_mm_heap *heap, size_t size)
++{
++      const char *error_filename;
++      uint error_lineno;
++
++      zend_mm_error_location(&error_filename, &error_lineno);
++      fprintf(stderr, "Hard memory limit of %lu bytes exhausted (tried to allocate %lu bytes) in %s on line %d\n",
++              (unsigned long) heap->hard_limit, (unsigned long) size, error_filename, error_lineno);
+ /* See http://support.microsoft.com/kb/190351 */
+ #ifdef PHP_WIN32
+-                      fflush(stderr);
++      fflush(stderr);
++#endif
++      _exit(137);
++}
++
++/* Record a memory limit error, to be raised at the next safe point by
++ * zend_handle_delayed_oom(). Bailing out from here would leave whatever the
++ * caller was in the middle of initializing reachable by the shutdown
++ * sequence (CVE-2026-109618). */
++static void zend_mm_delayed_error(zend_mm_heap *heap, const char *format, ...)
++{
++      const char *error_filename;
++      uint error_lineno;
++      va_list args;
++      TSRMLS_FETCH();
++
++      if (EG(delayed_oom) != ZEND_OOM_STATE_NONE) {
++              return;
++      }
++
++      zend_mm_error_location(&error_filename, &error_lineno);
++
++      va_start(args, format);
++      vsnprintf(heap->oom_message, sizeof(heap->oom_message), format, args);
++      va_end(args);
++      snprintf(heap->oom_filename, sizeof(heap->oom_filename), "%s", error_filename);
++      heap->oom_lineno = error_lineno;
++
++      EG(delayed_oom) = ZEND_OOM_STATE_PENDING;
++}
++
++/* Called when an allocation of add_size bytes makes the heap grow beyond the
++ * soft limit (memory_limit). Does not return when the hard limit would be
++ * exceeded. */
++static void zend_mm_limit_exceeded(zend_mm_heap *heap, size_t add_size
++#if ZEND_DEBUG
++      , const char *filename, uint lineno
++#endif
++      , size_t size)
++{
++      if (add_size > heap->hard_limit || heap->real_size > heap->hard_limit - add_size) {
++              zend_mm_hard_limit_error(heap, size);
++      }
++      if (heap->overflow == 0) {
++#if ZEND_DEBUG
++              zend_mm_delayed_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %lu bytes)", (long) heap->limit, filename, lineno, (unsigned long) size);
++#else
++              zend_mm_delayed_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %lu bytes)", (long) heap->limit, (unsigned long) size);
+ #endif
+-              } zend_end_try();
+-      } else {
+-              heap->overflow = 2;
+       }
+-      zend_bailout();
+ }
+ 
++#if ZEND_DEBUG
++# define ZEND_MM_LIMIT_EXCEEDED(heap, add_size, size) \
++      zend_mm_limit_exceeded(heap, add_size, __zend_filename, __zend_lineno, size)
++#else
++# define ZEND_MM_LIMIT_EXCEEDED(heap, add_size, size) \
++      zend_mm_limit_exceeded(heap, add_size, size)
++#endif
++
++
+ static zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *heap, size_t true_size)
+ {
+       zend_mm_free_block *best_fit;
+@@ -1965,18 +2041,14 @@ static void *_zend_mm_alloc_int(zend_mm_
+                       segment_size = heap->block_size;
+               }
+ 
+-              if (segment_size < true_size ||
+-                  heap->real_size + segment_size > heap->limit) {
+-                      /* Memory limit overflow */
+-#if ZEND_MM_CACHE
+-                      zend_mm_free_cache(heap);
+-#endif
++              if (segment_size < true_size) {
++                      /* Integer overflow */
+                       HANDLE_UNBLOCK_INTERRUPTIONS();
+-#if ZEND_DEBUG
+-                      zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %lu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
+-#else
+-                      zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %lu bytes)", heap->limit, size);
+-#endif
++                      zend_mm_out_of_memory(heap, size);
++              }
++              if (heap->real_size + segment_size > heap->limit) {
++                      /* Memory limit overflow: report it later, see zend_mm_delayed_error() */
++                      ZEND_MM_LIMIT_EXCEEDED(heap, segment_size, size);
+               }
+ 
+               segment = (zend_mm_segment *) ZEND_MM_STORAGE_ALLOC(segment_size);
+@@ -1988,11 +2060,7 @@ static void *_zend_mm_alloc_int(zend_mm_
+ #endif
+ out_of_memory:
+                       HANDLE_UNBLOCK_INTERRUPTIONS();
+-#if ZEND_DEBUG
+-                      zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
+-#else
+-                      zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, size);
+-#endif
++                      zend_mm_out_of_memory(heap, size);
+                       return NULL;
+               }
+ 
+@@ -2276,21 +2344,15 @@ realloc_segment:
+               }
+ 
+               segment_copy = (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE);
+-              if (segment_size < true_size ||
+-                  heap->real_size + segment_size - segment_copy->size > heap->limit) {
+-                      if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
+-                              zend_mm_add_to_free_list(heap, (zend_mm_free_block *) next_block);
+-                      }
+-#if ZEND_MM_CACHE
+-                      zend_mm_free_cache(heap);
+-#endif
++              if (segment_size < true_size) {
++                      /* Integer overflow */
+                       HANDLE_UNBLOCK_INTERRUPTIONS();
+-#if ZEND_DEBUG
+-                      zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %ld bytes)", heap->limit, __zend_filename, __zend_lineno, size);
+-#else
+-                      zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %ld bytes)", heap->limit, size);
+-#endif
+-                      return NULL;
++                      zend_mm_out_of_memory(heap, size);
++              }
++              if (segment_size > segment_copy->size &&
++                  heap->real_size + (segment_size - segment_copy->size) > heap->limit) {
++                      /* Memory limit overflow: report it later, see zend_mm_delayed_error() */
++                      ZEND_MM_LIMIT_EXCEEDED(heap, segment_size - segment_copy->size, size);
+               }
+ 
+               segment = ZEND_MM_STORAGE_REALLOC(segment_copy, segment_size);
+@@ -2300,11 +2362,7 @@ realloc_segment:
+ #endif
+ out_of_memory:
+                       HANDLE_UNBLOCK_INTERRUPTIONS();
+-#if ZEND_DEBUG
+-                      zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %ld bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
+-#else
+-                      zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %ld bytes)", heap->real_size, size);
+-#endif
++                      zend_mm_out_of_memory(heap, size);
+                       return NULL;
+               }
+               heap->real_size += segment_size - segment->size;
+@@ -2458,6 +2516,20 @@ ZEND_API size_t _zend_mem_block_size(voi
+       return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
+ }
+ 
++/* Not reporting this as a fatal error: bailing out from an allocation leaves
++ * the caller's state inconsistent (CVE-2026-109618) */
++#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
++static void zend_mm_safe_address_overflow(size_t nmemb, size_t size, size_t offset) __attribute__ ((noreturn));
++#endif
++static void zend_mm_safe_address_overflow(size_t nmemb, size_t size, size_t offset)
++{
++      char buf[256];
++
++      snprintf(buf, sizeof(buf), "Possible integer overflow in memory allocation (%lu * %lu + %lu)",
++              (unsigned long) nmemb, (unsigned long) size, (unsigned long) offset);
++      zend_mm_panic(buf);
++}
++
+ #if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
+ 
+ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+@@ -2472,7 +2544,7 @@ static inline size_t safe_address(size_t
+              "rm"(offset));
+ 
+       if (UNEXPECTED(overflow)) {
+-              zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++              zend_mm_safe_address_overflow(nmemb, size, offset);
+               return 0;
+       }
+       return res;
+@@ -2501,7 +2573,7 @@ static inline size_t safe_address(size_t
+ 
+ #undef LP_SUFF
+         if (UNEXPECTED(overflow)) {
+-                zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++                zend_mm_safe_address_overflow(nmemb, size, offset);
+                 return 0;
+         }
+         return res;
+@@ -2522,7 +2594,7 @@ static inline size_t safe_address(size_t
+                "1"(0));
+ 
+         if (UNEXPECTED(overflow)) {
+-                zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++                zend_mm_safe_address_overflow(nmemb, size, offset);
+                 return 0;
+         }
+         return res;
+@@ -2542,7 +2614,7 @@ static inline size_t safe_address(size_t
+                "r"(offset));
+ 
+         if (UNEXPECTED(overflow)) {
+-                zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++                zend_mm_safe_address_overflow(nmemb, size, offset);
+                 return 0;
+         }
+         return res;
+@@ -2555,7 +2627,7 @@ static inline size_t safe_address(size_t
+       zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
+ 
+       if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
+-              zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++              zend_mm_safe_address_overflow(nmemb, size, offset);
+               return 0;
+       }
+       return (size_t) res;
+@@ -2570,7 +2642,7 @@ static inline size_t safe_address(size_t
+       double _delta = (double)res - _d;
+ 
+       if (UNEXPECTED((_d + _delta ) != _d)) {
+-              zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++              zend_mm_safe_address_overflow(nmemb, size, offset);
+               return 0;
+       }
+       return res;
+@@ -2582,7 +2654,10 @@ ZEND_API void *_safe_emalloc_string(size
+ {
+       size_t str_size = safe_address(nmemb, size, offset);
+       if (UNEXPECTED(str_size > INT_MAX)) {
+-              zend_error_noreturn(E_ERROR, "String allocation overflow, max size is %d", INT_MAX);
++              char buf[64];
++
++              snprintf(buf, sizeof(buf), "String allocation overflow, max size is %d", INT_MAX);
++              zend_mm_panic(buf);
+       }
+       return emalloc_rel(str_size);
+ }
+@@ -2691,11 +2766,48 @@ ZEND_API char *zend_strndup(const char *
+ }
+ 
+ 
++static void zend_mm_error_cb(int type, const char *error_filename, uint error_lineno, const char *format, ...)
++{
++      va_list args;
++
++      va_start(args, format);
++      zend_error_cb(type, error_filename, error_lineno, format, args);
++      va_end(args);
++}
++
++ZEND_API void zend_handle_delayed_oom(TSRMLS_D)
++{
++      zend_mm_heap *heap = AG(mm_heap);
++
++      if (EG(delayed_oom) != ZEND_OOM_STATE_PENDING) {
++              return;
++      }
++      EG(delayed_oom) = ZEND_OOM_STATE_HANDLING;
++
++      /* Let error reporting allocate beyond the soft limit */
++      heap->overflow = 1;
++
++      /* An exception may be in flight. Reporting it may run user code
++       * (__toString()), which must not happen now. */
++      EG(exception) = NULL;
++
++      zend_try {
++              zend_mm_error_cb(E_ERROR, heap->oom_filename, heap->oom_lineno, "%s", heap->oom_message);
++      } zend_catch {
++      } zend_end_try();
++
++      heap->overflow = 0;
++      EG(delayed_oom) = ZEND_OOM_STATE_HANDLED;
++
++      zend_bailout();
++}
++
+ ZEND_API int zend_set_memory_limit(size_t memory_limit)
+ {
+       TSRMLS_FETCH();
+ 
+       AG(mm_heap)->limit = (memory_limit >= AG(mm_heap)->block_size) ? memory_limit : AG(mm_heap)->block_size;
++      zend_mm_update_hard_limit(AG(mm_heap));
+ 
+       return SUCCESS;
+ }
Index: pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.h
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.h:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__alloc.h  Tue Oct 27 15:30:48 2026
@@ -0,0 +1,40 @@
+$NetBSD: patch-Zend_zend__alloc.h,v 1.1 2026/10/27 15:30:48 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend_alloc.h.orig     2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_alloc.h
+@@ -50,6 +50,25 @@ typedef struct _zend_leak_info {
+       uint orig_lineno;
+ } zend_leak_info;
+ 
++/* Delayed out of memory handling (CVE-2026-109618).
++ *
++ * Exceeding memory_limit no longer bails out (longjmp) from inside the
++ * allocator, where the caller may have left request memory in an
++ * inconsistent state. Instead the allocation succeeds, the error is recorded
++ * and raised as a fatal error at the next safe point (between two opcodes, or
++ * once request startup has finished parsing the request). Memory usage beyond
++ * a hard limit (twice memory_limit, or memory_limit + 1G for limits above 1G)
++ * terminates the process immediately with _exit(). */
++typedef enum _zend_oom_state {
++      ZEND_OOM_STATE_NONE = 0,
++      ZEND_OOM_STATE_PENDING,
++      ZEND_OOM_STATE_HANDLING,
++      ZEND_OOM_STATE_HANDLED
++} zend_oom_state;
++
++#define ZEND_HAS_OOM() (UNEXPECTED(EG(delayed_oom) != ZEND_OOM_STATE_NONE))
++#define ZEND_OOM_PENDING() (UNEXPECTED(EG(delayed_oom) == ZEND_OOM_STATE_PENDING))
++
+ BEGIN_EXTERN_C()
+ 
+ ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_MALLOC;
+@@ -142,6 +161,7 @@ inline static void * __zend_realloc(void
+ #define safe_estrndup(ptr, len) ((ptr)?(estrndup((ptr), (len))):STR_EMPTY_ALLOC())
+ 
+ ZEND_API int zend_set_memory_limit(size_t memory_limit);
++ZEND_API void zend_handle_delayed_oom(TSRMLS_D);
+ 
+ ZEND_API void start_memory_manager(TSRMLS_D);
+ ZEND_API void shutdown_memory_manager(int silent, int full_shutdown TSRMLS_DC);
Index: pkgsrc/lang/php56/patches/patch-Zend_zend__execute__API.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend__execute__API.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__execute__API.c   Tue Oct 27 15:30:48 2026
@@ -0,0 +1,41 @@
+$NetBSD: patch-Zend_zend__execute__API.c,v 1.1 2026/10/27 15:30:48 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend_execute_API.c.orig       2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_execute_API.c
+@@ -330,6 +330,23 @@ void shutdown_executor(TSRMLS_D) /* {{{ 
+ 
+       zend_shutdown_fpu(TSRMLS_C);
+ 
++      /* A bailout may have skipped the resets above. zend_error() may use these
++       * before the next init_executor(), e.g. for INI warnings or upload
++       * progress during request startup (CVE-2026-109619). */
++      EG(user_error_handler) = NULL;
++      EG(user_exception_handler) = NULL;
++      EG(error_handling) = EH_NORMAL;
++      EG(exception_class) = NULL;
++      EG(exception) = NULL;
++      EG(prev_exception) = NULL;
++      EG(current_execute_data) = NULL;
++      EG(active_symbol_table) = NULL;
++      EG(active_op_array) = NULL;
++      EG(opline_ptr) = NULL;
++      EG(in_execution) = 0;
++      EG(in_autoload) = NULL;
++      EG(autoload_func) = NULL;
++
+       EG(active) = 0;
+ }
+ /* }}} */
+@@ -639,6 +656,10 @@ int zend_call_function(zend_fcall_info *
+               return FAILURE; /* executor is already inactive */
+       }
+ 
++      if (ZEND_OOM_PENDING()) {
++              zend_handle_delayed_oom(TSRMLS_C);
++      }
++
+       if (EG(exception)) {
+               return FAILURE; /* we would result in an instable executor otherwise */
+       }
Index: pkgsrc/lang/php56/patches/patch-Zend_zend__globals.h
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend__globals.h:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__globals.h        Tue Oct 27 15:30:48 2026
@@ -0,0 +1,17 @@
+$NetBSD: patch-Zend_zend__globals.h,v 1.1 2026/10/27 15:30:48 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend_globals.h.orig   2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_globals.h
+@@ -265,6 +265,10 @@ struct _zend_executor_globals {
+ #endif
+ 
+       void *reserved[ZEND_MAX_RESERVED_RESOURCES];
++
++      /* zend_oom_state, see zend_alloc.h. Kept last so that the offsets of the
++       * fields above do not change. */
++      zend_uchar delayed_oom;
+ };
+ 
+ struct _zend_ini_scanner_globals {
Index: pkgsrc/lang/php56/patches/patch-Zend_zend__llist.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend__llist.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__llist.c  Tue Oct 27 15:30:49 2026
@@ -0,0 +1,15 @@
+$NetBSD: patch-Zend_zend__llist.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend_llist.c.orig     2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_llist.c
+@@ -115,6 +115,8 @@ ZEND_API void zend_llist_destroy(zend_ll
+               current = next;
+       }
+ 
++      l->head  = NULL;
++      l->tail  = NULL;
+       l->count = 0;
+ }
+ 
Index: pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.h
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.h:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.h    Tue Oct 27 15:30:49 2026
@@ -0,0 +1,17 @@
+$NetBSD: patch-Zend_zend__vm__execute.h,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend_vm_execute.h.orig        2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_vm_execute.h
+@@ -359,6 +359,10 @@ zend_vm_enter:
+                       zend_timeout(0);
+               }
+ #endif
++              /* Safe point: no opcode is being executed */
++              if (ZEND_OOM_PENDING()) {
++                      zend_handle_delayed_oom(TSRMLS_C);
++              }
+ 
+               if ((ret = OPLINE->handler(execute_data TSRMLS_CC)) > 0) {
+                       switch (ret) {
Index: pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.skl
diff -u /dev/null pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.skl:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-Zend_zend__vm__execute.skl  Tue Oct 27 15:30:49 2026
@@ -0,0 +1,17 @@
+$NetBSD: patch-Zend_zend__vm__execute.skl,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- Zend/zend_vm_execute.skl.orig      2019-01-09 09:54:13.000000000 +0000
++++ Zend/zend_vm_execute.skl
+@@ -27,6 +27,10 @@ zend_vm_enter:
+                       zend_timeout(0);
+               }
+ #endif
++              /* Safe point: no opcode is being executed */
++              if (ZEND_OOM_PENDING()) {
++                      zend_handle_delayed_oom(TSRMLS_C);
++              }
+ 
+               {%ZEND_VM_DISPATCH%} {
+                       {%INTERNAL_EXECUTOR%}
Index: pkgsrc/lang/php56/patches/patch-ext_session_session.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-ext_session_session.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-ext_session_session.c       Tue Oct 27 15:30:49 2026
@@ -0,0 +1,59 @@
+$NetBSD: patch-ext_session_session.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- ext/session/session.c.orig 2019-01-09 09:54:13.000000000 +0000
++++ ext/session/session.c
+@@ -2642,6 +2642,9 @@ static void php_session_rfc1867_update(p
+               progress->next_update = Z_LVAL_P(progress->post_bytes_processed) + progress->update_step;
+       }
+ 
++      /* Runs before RINIT: no code may run on behalf of the session data, see
++       * BG(incomplete_classes_only) (CVE-2026-109619) */
++      BG(incomplete_classes_only)++;
+       php_session_initialize(TSRMLS_C);
+       PS(session_status) = php_session_active;
+       IF_SESSION_VARS() {
+@@ -2649,16 +2652,19 @@ static void php_session_rfc1867_update(p
+               ZEND_SET_SYMBOL_WITH_LENGTH(Z_ARRVAL_P(PS(http_session_vars)), progress->key.c, progress->key.len+1, progress->data, 2, 0);
+       }
+       php_session_flush(TSRMLS_C);
++      BG(incomplete_classes_only)--;
+ } /* }}} */
+ 
+ static void php_session_rfc1867_cleanup(php_session_rfc1867_progress *progress TSRMLS_DC) /* {{{ */
+ {
++      BG(incomplete_classes_only)++;
+       php_session_initialize(TSRMLS_C);
+       PS(session_status) = php_session_active;
+       IF_SESSION_VARS() {
+               zend_hash_del(Z_ARRVAL_P(PS(http_session_vars)), progress->key.c, progress->key.len+1);
+       }
+       php_session_flush(TSRMLS_C);
++      BG(incomplete_classes_only)--;
+ } /* }}} */
+ 
+ static int php_session_rfc1867_callback(unsigned int event, void *event_data, void **extra TSRMLS_DC) /* {{{ */
+@@ -2678,6 +2684,11 @@ static int php_session_rfc1867_callback(
+       switch(event) {
+               case MULTIPART_EVENT_START: {
+                       multipart_event_start *data = (multipart_event_start *) event_data;
++
++                      /* This runs before RINIT: a previous request interrupted by a fatal
++                       * error may have left these pointing to freed memory */
++                      php_rinit_session_globals(TSRMLS_C);
++
+                       progress = ecalloc(1, sizeof(php_session_rfc1867_progress));
+                       progress->content_length = data->content_length;
+                       progress->sname_len  = strlen(PS(session_name));
+@@ -2825,6 +2836,10 @@ static int php_session_rfc1867_callback(
+                                       php_session_rfc1867_update(progress, 1 TSRMLS_CC);
+                               }
+                               php_rshutdown_session_globals(TSRMLS_C);
++
++                              /* $_SESSION was populated with unresolved classes, see
++                               * php_session_rfc1867_update() */
++                              zend_delete_global_variable("_SESSION", sizeof("_SESSION")-1 TSRMLS_CC);
+                       }
+ 
+                       if (progress->data) {
Index: pkgsrc/lang/php56/patches/patch-ext_standard_basic__functions.h
diff -u /dev/null pkgsrc/lang/php56/patches/patch-ext_standard_basic__functions.h:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-ext_standard_basic__functions.h     Tue Oct 27 15:30:49 2026
@@ -0,0 +1,28 @@
+$NetBSD: patch-ext_standard_basic__functions.h,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- ext/standard/basic_functions.h.orig        2019-01-09 09:54:13.000000000 +0000
++++ ext/standard/basic_functions.h
+@@ -230,6 +230,13 @@ typedef struct _php_basic_globals {
+ #endif
+ 
+       int umask;
++
++      /* var.c: while non-zero, php_var_unserialize() represents every object
++       * as __PHP_Incomplete_Class without resolving its class, and
++       * php_var_serialize() writes such objects back unchanged. Used by the
++       * session upload progress handler, which runs before RINIT. Kept last so
++       * that the offsets of the fields above do not change. */
++      unsigned incomplete_classes_only;
+ } php_basic_globals;
+ 
+ #ifdef ZTS
+@@ -261,6 +268,7 @@ PHPAPI extern zend_bool register_user_sh
+ PHPAPI extern zend_bool remove_user_shutdown_function(char *function_name, size_t function_len TSRMLS_DC);
+ PHPAPI extern zend_bool append_user_shutdown_function(php_shutdown_function_entry shutdown_function_entry TSRMLS_DC);
+ 
++PHPAPI void php_basic_early_rinit(TSRMLS_D);
+ PHPAPI void php_call_shutdown_functions(TSRMLS_D);
+ PHPAPI void php_free_shutdown_functions(TSRMLS_D);
+ 
Index: pkgsrc/lang/php56/patches/patch-ext_standard_php__incomplete__class.h
diff -u /dev/null pkgsrc/lang/php56/patches/patch-ext_standard_php__incomplete__class.h:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-ext_standard_php__incomplete__class.h       Tue Oct 27 15:30:49 2026
@@ -0,0 +1,16 @@
+$NetBSD: patch-ext_standard_php__incomplete__class.h,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- ext/standard/php_incomplete_class.h.orig   2019-01-09 09:54:13.000000000 +0000
++++ ext/standard/php_incomplete_class.h
+@@ -52,6 +52,9 @@
+ 
+ #define INCOMPLETE_CLASS "__PHP_Incomplete_Class"
+ #define MAGIC_MEMBER "__PHP_Incomplete_Class_Name"
++/* Set by php_var_unserialize() while BG(incomplete_classes_only): the raw
++ * payload of a C: value, written back unchanged by php_var_serialize() */
++#define MAGIC_MEMBER_SERIALIZED "__PHP_Incomplete_Class_Serialized"
+ 
+ #ifdef __cplusplus
+ extern "C" {
Index: pkgsrc/lang/php56/patches/patch-ext_standard_var.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-ext_standard_var.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-ext_standard_var.c  Tue Oct 27 15:30:49 2026
@@ -0,0 +1,37 @@
+$NetBSD: patch-ext_standard_var.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- ext/standard/var.c.orig    2019-01-09 09:54:13.000000000 +0000
++++ ext/standard/var.c
+@@ -768,6 +768,30 @@ static void php_var_serialize_intern(sma
+                                       ce = Z_OBJCE_P(struc);
+                               }
+ 
++                              if (ce && ce == PHP_IC_ENTRY && UNEXPECTED(BG(incomplete_classes_only))) {
++                                      /* C: value kept by php_var_unserialize(), see BG(incomplete_classes_only) */
++                                      zval **payload;
++                                      char *class_name;
++                                      zend_uint name_len;
++
++                                      if (zend_hash_find(Z_OBJPROP_P(struc), MAGIC_MEMBER_SERIALIZED, sizeof(MAGIC_MEMBER_SERIALIZED), (void **) &payload) == SUCCESS
++                                                      && Z_TYPE_PP(payload) == IS_STRING
++                                                      && (class_name = php_lookup_class_name(struc, &name_len)) != NULL) {
++                                              smart_str_appendl(buf, "C:", 2);
++                                              smart_str_append_long(buf, (int)name_len);
++                                              smart_str_appendl(buf, ":\"", 2);
++                                              smart_str_appendl(buf, class_name, name_len);
++                                              smart_str_appendl(buf, "\":", 2);
++
++                                              smart_str_append_long(buf, (int)Z_STRLEN_PP(payload));
++                                              smart_str_appendl(buf, ":{", 2);
++                                              smart_str_appendl(buf, Z_STRVAL_PP(payload), Z_STRLEN_PP(payload));
++                                              smart_str_appendc(buf, '}');
++                                              efree(class_name);
++                                              return;
++                                      }
++                              }
++
+                               if (ce && ce->serialize != NULL) {
+                                       /* has custom handler */
+                                       unsigned char *serialized_data = NULL;
Index: pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.c    Tue Oct 27 15:30:49 2026
@@ -0,0 +1,1429 @@
+$NetBSD: patch-ext_standard_var__unserializer.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- ext/standard/var_unserializer.c.orig       2019-01-09 10:25:59.000000000 +0000
++++ ext/standard/var_unserializer.c
+@@ -1,4 +1,5 @@
+-/* Generated by re2c 0.15.3 */
++/* Generated by re2c 1.1.1 */
++#line 1 "ext/standard/var_unserializer.re"
+ /*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+@@ -279,6 +280,7 @@ static char *unserialize_str(const unsig
+ #define YYMARKER marker
+ 
+ 
++#line 288 "ext/standard/var_unserializer.re"
+ 
+ 
+ 
+@@ -366,6 +368,16 @@ static inline int process_nested_data(UN
+                       return 0;
+               }
+ 
++              /* The members that incomplete_classes_only mode writes itself cannot be
++               * told apart from that bookkeeping: reject them */
++              if (objprops && UNEXPECTED(BG(incomplete_classes_only)) && Z_TYPE_P(key) == IS_STRING
++                              && ((Z_STRLEN_P(key) == sizeof(MAGIC_MEMBER) - 1 && !memcmp(Z_STRVAL_P(key), MAGIC_MEMBER, sizeof(MAGIC_MEMBER) - 1))
++                                      || (Z_STRLEN_P(key) == sizeof(MAGIC_MEMBER_SERIALIZED) - 1 && !memcmp(Z_STRVAL_P(key), MAGIC_MEMBER_SERIALIZED, sizeof(MAGIC_MEMBER_SERIALIZED) - 1)))) {
++                      var_push_dtor_no_addref(var_hash, &key);
++                      var_push_dtor_no_addref(var_hash, &data);
++                      return 0;
++              }
++
+               if (!objprops) {
+                       switch (Z_TYPE_P(key)) {
+                       case IS_LONG:
+@@ -412,7 +424,7 @@ static inline int finish_nested_data(UNS
+       return 1;
+ }
+ 
+-static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
++static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce, int keep_payload)
+ {
+       long datalen;
+ 
+@@ -425,7 +437,16 @@ static inline int object_custom(UNSERIAL
+               return 0;
+       }
+ 
+-      if (ce->unserialize == NULL) {
++      if (keep_payload) {
++              /* The class was not resolved (see BG(incomplete_classes_only)): keep
++               * the payload verbatim, so that the object serializes back unchanged */
++              zval *payload;
++
++              object_init_ex(*rval, ce);
++              MAKE_STD_ZVAL(payload);
++              ZVAL_STRINGL(payload, (char *) *p, datalen, 1);
++              zend_hash_update(Z_OBJPROP_PP(rval), MAGIC_MEMBER_SERIALIZED, sizeof(MAGIC_MEMBER_SERIALIZED), &payload, sizeof(payload), NULL);
++      } else if (ce->unserialize == NULL) {
+               zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
+               object_init_ex(*rval, ce);
+       } else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
+@@ -526,6 +547,7 @@ PHPAPI int php_var_unserialize(UNSERIALI
+ 
+ 
+ 
++#line 551 "ext/standard/var_unserializer.c"
+ {
+       YYCTYPE yych;
+       static const unsigned char yybm[] = {
+@@ -566,524 +588,407 @@ PHPAPI int php_var_unserialize(UNSERIALI
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'C':
+-      case 'O':       goto yy13;
++      case 'O':       goto yy4;
+       case 'N':       goto yy5;
+-      case 'R':       goto yy2;
+-      case 'S':       goto yy10;
+-      case 'a':       goto yy11;
+-      case 'b':       goto yy6;
+-      case 'd':       goto yy8;
+-      case 'i':       goto yy7;
++      case 'R':       goto yy6;
++      case 'S':       goto yy7;
++      case 'a':       goto yy8;
++      case 'b':       goto yy9;
++      case 'd':       goto yy10;
++      case 'i':       goto yy11;
+       case 'o':       goto yy12;
+-      case 'r':       goto yy4;
+-      case 's':       goto yy9;
+-      case '}':       goto yy14;
+-      default:        goto yy16;
++      case 'r':       goto yy13;
++      case 's':       goto yy14;
++      case '}':       goto yy15;
++      default:        goto yy2;
+       }
+ yy2:
+-      yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy95;
++      ++YYCURSOR;
+ yy3:
++#line 935 "ext/standard/var_unserializer.re"
+       { return 0; }
++#line 611 "ext/standard/var_unserializer.c"
+ yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy89;
++      if (yych == ':') goto yy17;
+       goto yy3;
+ yy5:
+       yych = *++YYCURSOR;
+-      if (yych == ';') goto yy87;
++      if (yych == ';') goto yy19;
+       goto yy3;
+ yy6:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy83;
++      if (yych == ':') goto yy21;
+       goto yy3;
+ yy7:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy77;
++      if (yych == ':') goto yy22;
+       goto yy3;
+ yy8:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy53;
++      if (yych == ':') goto yy23;
+       goto yy3;
+ yy9:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy46;
++      if (yych == ':') goto yy24;
+       goto yy3;
+ yy10:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy39;
++      if (yych == ':') goto yy25;
+       goto yy3;
+ yy11:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy32;
++      if (yych == ':') goto yy26;
+       goto yy3;
+ yy12:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy25;
++      if (yych == ':') goto yy27;
+       goto yy3;
+ yy13:
+       yych = *(YYMARKER = ++YYCURSOR);
+-      if (yych == ':') goto yy17;
++      if (yych == ':') goto yy28;
+       goto yy3;
+ yy14:
++      yych = *(YYMARKER = ++YYCURSOR);
++      if (yych == ':') goto yy29;
++      goto yy3;
++yy15:
+       ++YYCURSOR;
++#line 929 "ext/standard/var_unserializer.re"
+       {
+       /* this is the case where we have less data than planned */
+       php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
+       return 0; /* not sure if it should be 0 or 1 here? */
+ }
+-yy16:
+-      yych = *++YYCURSOR;
+-      goto yy3;
++#line 664 "ext/standard/var_unserializer.c"
+ yy17:
+       yych = *++YYCURSOR;
+       if (yybm[0+yych] & 128) {
+-              goto yy20;
++              goto yy31;
+       }
+-      if (yych == '+') goto yy19;
++      if (yych == '+') goto yy30;
+ yy18:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+ yy19:
++      ++YYCURSOR;
++#line 599 "ext/standard/var_unserializer.re"
++      {
++      *p = YYCURSOR;
++      INIT_PZVAL(*rval);
++      ZVAL_NULL(*rval);
++      return 1;
++}
++#line 683 "ext/standard/var_unserializer.c"
++yy21:
+       yych = *++YYCURSOR;
+-      if (yybm[0+yych] & 128) {
+-              goto yy20;
++      if (yych <= ',') {
++              if (yych == '+') goto yy33;
++              goto yy18;
++      } else {
++              if (yych <= '-') goto yy33;
++              if (yych <= '/') goto yy18;
++              if (yych <= '9') goto yy34;
++              goto yy18;
+       }
++yy22:
++      yych = *++YYCURSOR;
++      if (yych == '+') goto yy36;
++      if (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy37;
+       goto yy18;
+-yy20:
+-      ++YYCURSOR;
+-      if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+-      yych = *YYCURSOR;
+-      if (yybm[0+yych] & 128) {
+-              goto yy20;
+-      }
++yy23:
++      yych = *++YYCURSOR;
++      if (yych == '+') goto yy39;
+       if (yych <= '/') goto yy18;
+-      if (yych >= ';') goto yy18;
++      if (yych <= '9') goto yy40;
++      goto yy18;
++yy24:
+       yych = *++YYCURSOR;
+-      if (yych != '"') goto yy18;
+-      ++YYCURSOR;
+-      {
+-      size_t len, len2, len3, maxlen;
+-      long elements;
+-      char *class_name;
+-      zend_class_entry *ce;
+-      zend_class_entry **pce;
+-      int incomplete_class = 0;
+-
+-      int custom_object = 0;
+-
+-      zval *user_func;
+-      zval *retval_ptr;
+-      zval **args[1];
+-      zval *arg_func_name;
+-
+-    if (!var_hash) return 0;
+-      if (*start == 'C') {
+-              custom_object = 1;
+-      }
+-
+-      INIT_PZVAL(*rval);
+-      len2 = len = parse_uiv(start + 2);
+-      maxlen = max - YYCURSOR;
+-      if (maxlen < len || len == 0) {
+-              *p = start + 2;
+-              return 0;
+-      }
+-
+-      class_name = (char*)YYCURSOR;
+-
+-      YYCURSOR += len;
+-
+-      if (*(YYCURSOR) != '"') {
+-              *p = YYCURSOR;
+-              return 0;
+-      }
+-      if (*(YYCURSOR+1) != ':') {
+-              *p = YYCURSOR+1;
+-              return 0;
+-      }
+-
+-      len3 = strspn(class_name, 
"0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\");
+-      if (len3 != len)
+-      {
+-              *p = YYCURSOR + len3 - len;
+-              return 0;
+-      }
+-
+-      class_name = estrndup(class_name, len);
+-
+-      do {
+-              /* Try to find class directly */
+-              BG(serialize_lock)++;
+-              if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
+-                      BG(serialize_lock)--;
+-                      if (EG(exception)) {
+-                              efree(class_name);
+-                              return 0;
+-                      }
+-                      ce = *pce;
+-                      break;
+-              }
+-              BG(serialize_lock)--;
+-
+-              if (EG(exception)) {
+-                      efree(class_name);
+-                      return 0;
+-              }
+-
+-              /* Check for unserialize callback */
+-              if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
+-                      incomplete_class = 1;
+-                      ce = PHP_IC_ENTRY;
+-                      break;
+-              }
+-
+-              /* Call unserialize callback */
+-              MAKE_STD_ZVAL(user_func);
+-              ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
+-              args[0] = &arg_func_name;
+-              MAKE_STD_ZVAL(arg_func_name);
+-              ZVAL_STRING(arg_func_name, class_name, 1);
+-              BG(serialize_lock)++;
+-              if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
+-                      BG(serialize_lock)--;
+-                      if (EG(exception)) {
+-                              efree(class_name);
+-                              zval_ptr_dtor(&user_func);
+-                              zval_ptr_dtor(&arg_func_name);
+-                              return 0;
+-                      }
+-                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
+-                      incomplete_class = 1;
+-                      ce = PHP_IC_ENTRY;
+-                      zval_ptr_dtor(&user_func);
+-                      zval_ptr_dtor(&arg_func_name);
+-                      break;
+-              }
+-              BG(serialize_lock)--;
+-              if (retval_ptr) {
+-                      zval_ptr_dtor(&retval_ptr);
+-              }
+-              if (EG(exception)) {
+-                      efree(class_name);
+-                      zval_ptr_dtor(&user_func);
+-                      zval_ptr_dtor(&arg_func_name);
+-                      return 0;
+-              }
+-
+-              /* The callback function may have defined the class */
+-              BG(serialize_lock)++;
+-              if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
+-                      ce = *pce;
++      if (yych <= '/') goto yy18;
++      if (yych <= '1') goto yy42;
++      goto yy18;
++yy25:
++      yych = *++YYCURSOR;
++      if (yych <= '/') {
++              if (yych <= ',') {
++                      if (yych == '+') goto yy43;
++                      goto yy18;
+               } else {
+-                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
+-                      incomplete_class = 1;
+-                      ce = PHP_IC_ENTRY;
++                      if (yych <= '-') goto yy44;
++                      if (yych <= '.') goto yy45;
++                      goto yy18;
+               }
+-              BG(serialize_lock)--;
+-
+-              zval_ptr_dtor(&user_func);
+-              zval_ptr_dtor(&arg_func_name);
+-              break;
+-      } while (1);
+-
+-      *p = YYCURSOR;
+-
+-      if (custom_object) {
+-              int ret;
+-
+-              ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
+-
+-              if (ret && incomplete_class) {
+-                      php_store_class_name(*rval, class_name, len2);
++      } else {
++              if (yych <= 'I') {
++                      if (yych <= '9') goto yy46;
++                      if (yych <= 'H') goto yy18;
++                      goto yy48;
++              } else {
++                      if (yych == 'N') goto yy49;
++                      goto yy18;
+               }
+-              efree(class_name);
+-              return ret;
+       }
+-
+-      elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
+-
+-      if (elements < 0) {
+-         efree(class_name);
+-         return 0;
++yy26:
++      yych = *++YYCURSOR;
++      if (yych <= ',') {
++              if (yych == '+') goto yy50;
++              goto yy18;
++      } else {
++              if (yych <= '-') goto yy50;
++              if (yych <= '/') goto yy18;
++              if (yych <= '9') goto yy51;
++              goto yy18;
+       }
+-
+-      if (incomplete_class) {
+-              php_store_class_name(*rval, class_name, len2);
++yy27:
++      yych = *++YYCURSOR;
++      if (yych <= ',') {
++              if (yych == '+') goto yy53;
++              goto yy18;
++      } else {
++              if (yych <= '-') goto yy53;
++              if (yych <= '/') goto yy18;
++              if (yych <= '9') goto yy54;
++              goto yy18;
+       }
+-      efree(class_name);
+-
+-      return object_common2(UNSERIALIZE_PASSTHRU, elements);
+-}
+-yy25:
++yy28:
+       yych = *++YYCURSOR;
+       if (yych <= ',') {
+-              if (yych != '+') goto yy18;
++              if (yych == '+') goto yy56;
++              goto yy18;
+       } else {
+-              if (yych <= '-') goto yy26;
++              if (yych <= '-') goto yy56;
+               if (yych <= '/') goto yy18;
+-              if (yych <= '9') goto yy27;
++              if (yych <= '9') goto yy57;
+               goto yy18;
+       }
+-yy26:
++yy29:
+       yych = *++YYCURSOR;
++      if (yych == '+') goto yy59;
+       if (yych <= '/') goto yy18;
+-      if (yych >= ':') goto yy18;
+-yy27:
++      if (yych <= '9') goto yy60;
++      goto yy18;
++yy30:
++      yych = *++YYCURSOR;
++      if (yybm[0+yych] & 128) {
++              goto yy31;
++      }
++      goto yy18;
++yy31:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
++      if (yybm[0+yych] & 128) {
++              goto yy31;
++      }
+       if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy27;
+-      if (yych >= ';') goto yy18;
++      if (yych <= ':') goto yy62;
++      goto yy18;
++yy33:
+       yych = *++YYCURSOR;
+-      if (yych != '"') goto yy18;
++      if (yych <= '/') goto yy18;
++      if (yych >= ':') goto yy18;
++yy34:
+       ++YYCURSOR;
+-      {
+-      long elements;
+-    if (!var_hash) return 0;
+-
+-      INIT_PZVAL(*rval);
+-
+-      elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
+-      if (elements < 0) {
+-              return 0;
+-      }
+-      return object_common2(UNSERIALIZE_PASSTHRU, elements);
+-}
+-yy32:
+-      yych = *++YYCURSOR;
+-      if (yych == '+') goto yy33;
++      if (YYLIMIT <= YYCURSOR) YYFILL(1);
++      yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych <= '9') goto yy34;
++      if (yych == ';') goto yy63;
+       goto yy18;
+-yy33:
++yy36:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
+-yy34:
++yy37:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy34;
+-      if (yych >= ';') goto yy18;
++      if (yych <= '9') goto yy37;
++      if (yych <= ':') goto yy65;
++      goto yy18;
++yy39:
+       yych = *++YYCURSOR;
+-      if (yych != '{') goto yy18;
++      if (yych <= '/') goto yy18;
++      if (yych >= ':') goto yy18;
++yy40:
+       ++YYCURSOR;
+-      {
+-      long elements = parse_iv(start + 2);
+-      /* use iv() not uiv() in order to check data range */
+-      *p = YYCURSOR;
+-    if (!var_hash) return 0;
+-
+-      if (elements < 0) {
+-              return 0;
++      if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
++      yych = *YYCURSOR;
++      if (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy40;
++      if (yych <= ':') goto yy66;
++      goto yy18;
++yy42:
++      yych = *++YYCURSOR;
++      if (yych == ';') goto yy67;
++      goto yy18;
++yy43:
++      yych = *++YYCURSOR;
++      if (yych == '.') goto yy45;
++      if (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy46;
++      goto yy18;
++yy44:
++      yych = *++YYCURSOR;
++      if (yych <= '/') {
++              if (yych != '.') goto yy18;
++      } else {
++              if (yych <= '9') goto yy46;
++              if (yych == 'I') goto yy48;
++              goto yy18;
+       }
+-
+-      INIT_PZVAL(*rval);
+-
+-      array_init_size(*rval, elements);
+-
+-      if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
+-              return 0;
++yy45:
++      yych = *++YYCURSOR;
++      if (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy69;
++      goto yy18;
++yy46:
++      ++YYCURSOR;
++      if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
++      yych = *YYCURSOR;
++      if (yych <= ':') {
++              if (yych <= '.') {
++                      if (yych <= '-') goto yy18;
++                      goto yy69;
++              } else {
++                      if (yych <= '/') goto yy18;
++                      if (yych <= '9') goto yy46;
++                      goto yy18;
++              }
++      } else {
++              if (yych <= 'E') {
++                      if (yych <= ';') goto yy71;
++                      if (yych <= 'D') goto yy18;
++                      goto yy73;
++              } else {
++                      if (yych == 'e') goto yy73;
++                      goto yy18;
++              }
+       }
+-
+-      return finish_nested_data(UNSERIALIZE_PASSTHRU);
+-}
+-yy39:
++yy48:
++      yych = *++YYCURSOR;
++      if (yych == 'N') goto yy74;
++      goto yy18;
++yy49:
++      yych = *++YYCURSOR;
++      if (yych == 'A') goto yy75;
++      goto yy18;
++yy50:
+       yych = *++YYCURSOR;
+-      if (yych == '+') goto yy40;
+       if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy41;
++      if (yych >= ':') goto yy18;
++yy51:
++      ++YYCURSOR;
++      if (YYLIMIT <= YYCURSOR) YYFILL(1);
++      yych = *YYCURSOR;
++      if (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy51;
++      if (yych == ';') goto yy76;
+       goto yy18;
+-yy40:
++yy53:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
+-yy41:
++yy54:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy41;
+-      if (yych >= ';') goto yy18;
++      if (yych <= '9') goto yy54;
++      if (yych <= ':') goto yy78;
++      goto yy18;
++yy56:
+       yych = *++YYCURSOR;
+-      if (yych != '"') goto yy18;
++      if (yych <= '/') goto yy18;
++      if (yych >= ':') goto yy18;
++yy57:
+       ++YYCURSOR;
+-      {
+-      size_t len, maxlen;
+-      char *str;
+-
+-      len = parse_uiv(start + 2);
+-      maxlen = max - YYCURSOR;
+-      if (maxlen < len) {
+-              *p = start + 2;
+-              return 0;
+-      }
+-
+-      if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
+-              return 0;
+-      }
+-
+-      if (*(YYCURSOR) != '"') {
+-              efree(str);
+-              *p = YYCURSOR;
+-              return 0;
+-      }
+-
+-      if (*(YYCURSOR + 1) != ';') {
+-              efree(str);
+-              *p = YYCURSOR + 1;
+-              return 0;
+-      }
+-
+-      YYCURSOR += 2;
+-      *p = YYCURSOR;
+-
+-      INIT_PZVAL(*rval);
+-      ZVAL_STRINGL(*rval, str, len, 0);
+-      return 1;
+-}
+-yy46:
+-      yych = *++YYCURSOR;
+-      if (yych == '+') goto yy47;
++      if (YYLIMIT <= YYCURSOR) YYFILL(1);
++      yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy48;
++      if (yych <= '9') goto yy57;
++      if (yych == ';') goto yy79;
+       goto yy18;
+-yy47:
++yy59:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
+-yy48:
++yy60:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy48;
+-      if (yych >= ';') goto yy18;
++      if (yych <= '9') goto yy60;
++      if (yych <= ':') goto yy81;
++      goto yy18;
++yy62:
+       yych = *++YYCURSOR;
+-      if (yych != '"') goto yy18;
++      if (yych == '"') goto yy82;
++      goto yy18;
++yy63:
+       ++YYCURSOR;
++#line 555 "ext/standard/var_unserializer.re"
+       {
+-      size_t len, maxlen;
+-      char *str;
+-
+-      len = parse_uiv(start + 2);
+-      maxlen = max - YYCURSOR;
+-      if (maxlen < len) {
+-              *p = start + 2;
+-              return 0;
+-      }
+-
+-      str = (char*)YYCURSOR;
++      long id;
+ 
+-      YYCURSOR += len;
++      *p = YYCURSOR;
++      if (!var_hash) return 0;
+ 
+-      if (*(YYCURSOR) != '"') {
+-              *p = YYCURSOR;
++      id = parse_iv(start + 2) - 1;
++      if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+               return 0;
+       }
+ 
+-      if (*(YYCURSOR + 1) != ';') {
+-              *p = YYCURSOR + 1;
+-              return 0;
++      if (*rval != NULL) {
++              var_push_dtor_no_addref(var_hash, rval);
+       }
++      *rval = *rval_ref;
++      Z_ADDREF_PP(rval);
++      Z_SET_ISREF_PP(rval);
+ 
+-      YYCURSOR += 2;
+-      *p = YYCURSOR;
+-
+-      INIT_PZVAL(*rval);
+-      ZVAL_STRINGL(*rval, str, len, 1);
+       return 1;
+ }
+-yy53:
+-      yych = *++YYCURSOR;
+-      if (yych <= '/') {
+-              if (yych <= ',') {
+-                      if (yych == '+') goto yy57;
+-                      goto yy18;
+-              } else {
+-                      if (yych <= '-') goto yy55;
+-                      if (yych <= '.') goto yy60;
+-                      goto yy18;
+-              }
+-      } else {
+-              if (yych <= 'I') {
+-                      if (yych <= '9') goto yy58;
+-                      if (yych <= 'H') goto yy18;
+-                      goto yy56;
+-              } else {
+-                      if (yych != 'N') goto yy18;
+-              }
+-      }
++#line 954 "ext/standard/var_unserializer.c"
++yy65:
+       yych = *++YYCURSOR;
+-      if (yych == 'A') goto yy76;
++      if (yych == '"') goto yy84;
+       goto yy18;
+-yy55:
+-      yych = *++YYCURSOR;
+-      if (yych <= '/') {
+-              if (yych == '.') goto yy60;
+-              goto yy18;
+-      } else {
+-              if (yych <= '9') goto yy58;
+-              if (yych != 'I') goto yy18;
+-      }
+-yy56:
++yy66:
+       yych = *++YYCURSOR;
+-      if (yych == 'N') goto yy72;
++      if (yych == '{') goto yy86;
+       goto yy18;
+-yy57:
+-      yych = *++YYCURSOR;
+-      if (yych == '.') goto yy60;
+-      if (yych <= '/') goto yy18;
+-      if (yych >= ':') goto yy18;
+-yy58:
++yy67:
+       ++YYCURSOR;
+-      if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+-      yych = *YYCURSOR;
+-      if (yych <= ':') {
+-              if (yych <= '.') {
+-                      if (yych <= '-') goto yy18;
+-                      goto yy70;
+-              } else {
+-                      if (yych <= '/') goto yy18;
+-                      if (yych <= '9') goto yy58;
+-                      goto yy18;
+-              }
+-      } else {
+-              if (yych <= 'E') {
+-                      if (yych <= ';') goto yy63;
+-                      if (yych <= 'D') goto yy18;
+-                      goto yy65;
+-              } else {
+-                      if (yych == 'e') goto yy65;
+-                      goto yy18;
+-              }
+-      }
+-yy60:
+-      yych = *++YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych >= ':') goto yy18;
+-yy61:
++#line 606 "ext/standard/var_unserializer.re"
++      {
++      *p = YYCURSOR;
++      INIT_PZVAL(*rval);
++      ZVAL_BOOL(*rval, parse_iv(start + 2));
++      return 1;
++}
++#line 972 "ext/standard/var_unserializer.c"
++yy69:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+       yych = *YYCURSOR;
+       if (yych <= ';') {
+               if (yych <= '/') goto yy18;
+-              if (yych <= '9') goto yy61;
++              if (yych <= '9') goto yy69;
+               if (yych <= ':') goto yy18;
+       } else {
+               if (yych <= 'E') {
+                       if (yych <= 'D') goto yy18;
+-                      goto yy65;
++                      goto yy73;
+               } else {
+-                      if (yych == 'e') goto yy65;
++                      if (yych == 'e') goto yy73;
+                       goto yy18;
+               }
+       }
+-yy63:
++yy71:
+       ++YYCURSOR;
++#line 655 "ext/standard/var_unserializer.re"
+       {
+ #if SIZEOF_LONG == 4
+ use_double:
+@@ -1093,238 +998,416 @@ use_double:
+       ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
+       return 1;
+ }
+-yy65:
++#line 1002 "ext/standard/var_unserializer.c"
++yy73:
+       yych = *++YYCURSOR;
+       if (yych <= ',') {
+-              if (yych != '+') goto yy18;
++              if (yych == '+') goto yy88;
++              goto yy18;
+       } else {
+-              if (yych <= '-') goto yy66;
++              if (yych <= '-') goto yy88;
+               if (yych <= '/') goto yy18;
+-              if (yych <= '9') goto yy67;
++              if (yych <= '9') goto yy89;
+               goto yy18;
+       }
+-yy66:
++yy74:
+       yych = *++YYCURSOR;
+-      if (yych <= ',') {
+-              if (yych == '+') goto yy69;
+-              goto yy18;
+-      } else {
+-              if (yych <= '-') goto yy69;
+-              if (yych <= '/') goto yy18;
+-              if (yych >= ':') goto yy18;
+-      }
+-yy67:
+-      ++YYCURSOR;
+-      if (YYLIMIT <= YYCURSOR) YYFILL(1);
+-      yych = *YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy67;
+-      if (yych == ';') goto yy63;
++      if (yych == 'F') goto yy91;
+       goto yy18;
+-yy69:
++yy75:
+       yych = *++YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy67;
++      if (yych == 'N') goto yy91;
+       goto yy18;
+-yy70:
++yy76:
+       ++YYCURSOR;
+-      if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+-      yych = *YYCURSOR;
+-      if (yych <= ';') {
+-              if (yych <= '/') goto yy18;
+-              if (yych <= '9') goto yy70;
+-              if (yych <= ':') goto yy18;
+-              goto yy63;
+-      } else {
+-              if (yych <= 'E') {
+-                      if (yych <= 'D') goto yy18;
+-                      goto yy65;
++#line 613 "ext/standard/var_unserializer.re"
++      {
++#if SIZEOF_LONG == 4
++      int digits = YYCURSOR - start - 3;
++
++      if (start[2] == '-' || start[2] == '+') {
++              digits--;
++      }
++
++      /* Use double for large long values that were serialized on a 64-bit system */
++      if (digits >= MAX_LENGTH_OF_LONG - 1) {
++              if (digits == MAX_LENGTH_OF_LONG - 1) {
++                      int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
++
++                      if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
++                              goto use_double;
++                      }
+               } else {
+-                      if (yych == 'e') goto yy65;
+-                      goto yy18;
++                      goto use_double;
+               }
+       }
+-yy72:
+-      yych = *++YYCURSOR;
+-      if (yych != 'F') goto yy18;
+-yy73:
+-      yych = *++YYCURSOR;
+-      if (yych != ';') goto yy18;
+-      ++YYCURSOR;
+-      {
++#endif
+       *p = YYCURSOR;
+       INIT_PZVAL(*rval);
+-
+-      if (!strncmp(start + 2, "NAN", 3)) {
+-              ZVAL_DOUBLE(*rval, php_get_nan());
+-      } else if (!strncmp(start + 2, "INF", 3)) {
+-              ZVAL_DOUBLE(*rval, php_get_inf());
+-      } else if (!strncmp(start + 2, "-INF", 4)) {
+-              ZVAL_DOUBLE(*rval, -php_get_inf());
+-      }
+-
++      ZVAL_LONG(*rval, parse_iv(start + 2));
+       return 1;
+ }
+-yy76:
+-      yych = *++YYCURSOR;
+-      if (yych == 'N') goto yy73;
+-      goto yy18;
+-yy77:
+-      yych = *++YYCURSOR;
+-      if (yych <= ',') {
+-              if (yych != '+') goto yy18;
+-      } else {
+-              if (yych <= '-') goto yy78;
+-              if (yych <= '/') goto yy18;
+-              if (yych <= '9') goto yy79;
+-              goto yy18;
+-      }
++#line 1051 "ext/standard/var_unserializer.c"
+ yy78:
+       yych = *++YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych >= ':') goto yy18;
++      if (yych == '"') goto yy92;
++      goto yy18;
+ yy79:
+       ++YYCURSOR;
+-      if (YYLIMIT <= YYCURSOR) YYFILL(1);
+-      yych = *YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy79;
+-      if (yych != ';') goto yy18;
++#line 576 "ext/standard/var_unserializer.re"
++      {
++      long id;
++
++      *p = YYCURSOR;
++      if (!var_hash) return 0;
++
++      id = parse_iv(start + 2) - 1;
++      if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
++              return 0;
++      }
++
++      if (*rval == *rval_ref) return 0;
++
++      if (*rval != NULL) {
++              var_push_dtor_no_addref(var_hash, rval);
++      }
++      *rval = *rval_ref;
++      Z_ADDREF_PP(rval);
++      Z_UNSET_ISREF_PP(rval);
++
++      return 1;
++}
++#line 1081 "ext/standard/var_unserializer.c"
++yy81:
++      yych = *++YYCURSOR;
++      if (yych == '"') goto yy94;
++      goto yy18;
++yy82:
+       ++YYCURSOR;
++#line 767 "ext/standard/var_unserializer.re"
+       {
+-#if SIZEOF_LONG == 4
+-      int digits = YYCURSOR - start - 3;
++      size_t len, len2, len3, maxlen;
++      long elements;
++      char *class_name;
++      zend_class_entry *ce;
++      zend_class_entry **pce;
++      int incomplete_class = 0;
+ 
+-      if (start[2] == '-' || start[2] == '+') {
+-              digits--;
++      int custom_object = 0;
++
++      zval *user_func;
++      zval *retval_ptr;
++      zval **args[1];
++      zval *arg_func_name;
++
++    if (!var_hash) return 0;
++      if (*start == 'C') {
++              custom_object = 1;
+       }
+ 
+-      /* Use double for large long values that were serialized on a 64-bit system */
+-      if (digits >= MAX_LENGTH_OF_LONG - 1) {
+-              if (digits == MAX_LENGTH_OF_LONG - 1) {
+-                      int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
++      INIT_PZVAL(*rval);
++      len2 = len = parse_uiv(start + 2);
++      maxlen = max - YYCURSOR;
++      if (maxlen < len || len == 0) {
++              *p = start + 2;
++              return 0;
++      }
+ 
+-                      if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
+-                              goto use_double;
++      class_name = (char*)YYCURSOR;
++
++      YYCURSOR += len;
++
++      if (*(YYCURSOR) != '"') {
++              *p = YYCURSOR;
++              return 0;
++      }
++      if (*(YYCURSOR+1) != ':') {
++              *p = YYCURSOR+1;
++              return 0;
++      }
++
++      len3 = strspn(class_name, 
"0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\");
++      if (len3 != len)
++      {
++              *p = YYCURSOR + len3 - len;
++              return 0;
++      }
++
++      class_name = estrndup(class_name, len);
++
++      do {
++              if (BG(incomplete_classes_only)) {
++                      /* Do not look the class up at all, so that no code (autoloader,
++                       * unserialize_callback_func, __wakeup(), unserialize()) can run */
++                      incomplete_class = 1;
++                      ce = PHP_IC_ENTRY;
++                      break;
++              }
++
++              /* Try to find class directly */
++              BG(serialize_lock)++;
++              if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
++                      BG(serialize_lock)--;
++                      if (EG(exception)) {
++                              efree(class_name);
++                              return 0;
+                       }
++                      ce = *pce;
++                      break;
++              }
++              BG(serialize_lock)--;
++
++              if (EG(exception)) {
++                      efree(class_name);
++                      return 0;
++              }
++
++              /* Check for unserialize callback */
++              if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
++                      incomplete_class = 1;
++                      ce = PHP_IC_ENTRY;
++                      break;
++              }
++
++              /* Call unserialize callback */
++              MAKE_STD_ZVAL(user_func);
++              ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
++              args[0] = &arg_func_name;
++              MAKE_STD_ZVAL(arg_func_name);
++              ZVAL_STRING(arg_func_name, class_name, 1);
++              BG(serialize_lock)++;
++              if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
++                      BG(serialize_lock)--;
++                      if (EG(exception)) {
++                              efree(class_name);
++                              zval_ptr_dtor(&user_func);
++                              zval_ptr_dtor(&arg_func_name);
++                              return 0;
++                      }
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
++                      incomplete_class = 1;
++                      ce = PHP_IC_ENTRY;
++                      zval_ptr_dtor(&user_func);
++                      zval_ptr_dtor(&arg_func_name);
++                      break;
++              }
++              BG(serialize_lock)--;
++              if (retval_ptr) {
++                      zval_ptr_dtor(&retval_ptr);
++              }
++              if (EG(exception)) {
++                      efree(class_name);
++                      zval_ptr_dtor(&user_func);
++                      zval_ptr_dtor(&arg_func_name);
++                      return 0;
++              }
++
++              /* The callback function may have defined the class */
++              BG(serialize_lock)++;
++              if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
++                      ce = *pce;
+               } else {
+-                      goto use_double;
++                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
++                      incomplete_class = 1;
++                      ce = PHP_IC_ENTRY;
+               }
+-      }
+-#endif
++              BG(serialize_lock)--;
++
++              zval_ptr_dtor(&user_func);
++              zval_ptr_dtor(&arg_func_name);
++              break;
++      } while (1);
++
+       *p = YYCURSOR;
+-      INIT_PZVAL(*rval);
+-      ZVAL_LONG(*rval, parse_iv(start + 2));
+-      return 1;
++
++      if (custom_object) {
++              int ret;
++
++              ret = object_custom(UNSERIALIZE_PASSTHRU, ce, incomplete_class && BG(incomplete_classes_only));
++
++              if (ret && incomplete_class) {
++                      php_store_class_name(*rval, class_name, len2);
++              }
++              efree(class_name);
++              return ret;
++      }
++
++      elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
++
++      if (elements < 0) {
++         efree(class_name);
++         return 0;
++      }
++
++      if (incomplete_class) {
++              php_store_class_name(*rval, class_name, len2);
++      }
++      efree(class_name);
++
++      return object_common2(UNSERIALIZE_PASSTHRU, elements);
+ }
+-yy83:
+-      yych = *++YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych >= '2') goto yy18;
+-      yych = *++YYCURSOR;
+-      if (yych != ';') goto yy18;
++#line 1250 "ext/standard/var_unserializer.c"
++yy84:
+       ++YYCURSOR;
++#line 698 "ext/standard/var_unserializer.re"
+       {
++      size_t len, maxlen;
++      char *str;
++
++      len = parse_uiv(start + 2);
++      maxlen = max - YYCURSOR;
++      if (maxlen < len) {
++              *p = start + 2;
++              return 0;
++      }
++
++      if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
++              return 0;
++      }
++
++      if (*(YYCURSOR) != '"') {
++              efree(str);
++              *p = YYCURSOR;
++              return 0;
++      }
++
++      if (*(YYCURSOR + 1) != ';') {
++              efree(str);
++              *p = YYCURSOR + 1;
++              return 0;
++      }
++
++      YYCURSOR += 2;
+       *p = YYCURSOR;
++
+       INIT_PZVAL(*rval);
+-      ZVAL_BOOL(*rval, parse_iv(start + 2));
++      ZVAL_STRINGL(*rval, str, len, 0);
+       return 1;
+ }
+-yy87:
++#line 1288 "ext/standard/var_unserializer.c"
++yy86:
+       ++YYCURSOR;
++#line 733 "ext/standard/var_unserializer.re"
+       {
++      long elements = parse_iv(start + 2);
++      /* use iv() not uiv() in order to check data range */
+       *p = YYCURSOR;
++    if (!var_hash) return 0;
++
++      if (elements < 0) {
++              return 0;
++      }
++
+       INIT_PZVAL(*rval);
+-      ZVAL_NULL(*rval);
+-      return 1;
++
++      array_init_size(*rval, elements);
++
++      if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
++              return 0;
++      }
++
++      return finish_nested_data(UNSERIALIZE_PASSTHRU);
+ }
+-yy89:
++#line 1312 "ext/standard/var_unserializer.c"
++yy88:
+       yych = *++YYCURSOR;
+       if (yych <= ',') {
+-              if (yych != '+') goto yy18;
++              if (yych == '+') goto yy96;
++              goto yy18;
+       } else {
+-              if (yych <= '-') goto yy90;
++              if (yych <= '-') goto yy96;
+               if (yych <= '/') goto yy18;
+-              if (yych <= '9') goto yy91;
+-              goto yy18;
++              if (yych >= ':') goto yy18;
+       }
+-yy90:
+-      yych = *++YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych >= ':') goto yy18;
+-yy91:
++yy89:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy91;
+-      if (yych != ';') goto yy18;
++      if (yych <= '9') goto yy89;
++      if (yych == ';') goto yy71;
++      goto yy18;
++yy91:
++      yych = *++YYCURSOR;
++      if (yych == ';') goto yy97;
++      goto yy18;
++yy92:
+       ++YYCURSOR;
++#line 754 "ext/standard/var_unserializer.re"
+       {
+-      long id;
++      long elements;
++    if (!var_hash) return 0;
+ 
+-      *p = YYCURSOR;
+-      if (!var_hash) return 0;
++      INIT_PZVAL(*rval);
+ 
+-      id = parse_iv(start + 2) - 1;
+-      if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
++      elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
++      if (elements < 0) {
+               return 0;
+       }
++      return object_common2(UNSERIALIZE_PASSTHRU, elements);
++}
++#line 1350 "ext/standard/var_unserializer.c"
++yy94:
++      ++YYCURSOR;
++#line 665 "ext/standard/var_unserializer.re"
++      {
++      size_t len, maxlen;
++      char *str;
+ 
+-      if (*rval == *rval_ref) return 0;
++      len = parse_uiv(start + 2);
++      maxlen = max - YYCURSOR;
++      if (maxlen < len) {
++              *p = start + 2;
++              return 0;
++      }
+ 
+-      if (*rval != NULL) {
+-              var_push_dtor_no_addref(var_hash, rval);
++      str = (char*)YYCURSOR;
++
++      YYCURSOR += len;
++
++      if (*(YYCURSOR) != '"') {
++              *p = YYCURSOR;
++              return 0;
+       }
+-      *rval = *rval_ref;
+-      Z_ADDREF_PP(rval);
+-      Z_UNSET_ISREF_PP(rval);
+ 
++      if (*(YYCURSOR + 1) != ';') {
++              *p = YYCURSOR + 1;
++              return 0;
++      }
++
++      YYCURSOR += 2;
++      *p = YYCURSOR;
++
++      INIT_PZVAL(*rval);
++      ZVAL_STRINGL(*rval, str, len, 1);
+       return 1;
+ }
+-yy95:
+-      yych = *++YYCURSOR;
+-      if (yych <= ',') {
+-              if (yych != '+') goto yy18;
+-      } else {
+-              if (yych <= '-') goto yy96;
+-              if (yych <= '/') goto yy18;
+-              if (yych <= '9') goto yy97;
+-              goto yy18;
+-      }
++#line 1386 "ext/standard/var_unserializer.c"
+ yy96:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+-      if (yych >= ':') goto yy18;
++      if (yych <= '9') goto yy89;
++      goto yy18;
+ yy97:
+       ++YYCURSOR;
+-      if (YYLIMIT <= YYCURSOR) YYFILL(1);
+-      yych = *YYCURSOR;
+-      if (yych <= '/') goto yy18;
+-      if (yych <= '9') goto yy97;
+-      if (yych != ';') goto yy18;
+-      ++YYCURSOR;
++#line 640 "ext/standard/var_unserializer.re"
+       {
+-      long id;
+-
+-      *p = YYCURSOR;
+-      if (!var_hash) return 0;
+-
+-      id = parse_iv(start + 2) - 1;
+-      if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+-              return 0;
+-      }
++      *p = YYCURSOR;
++      INIT_PZVAL(*rval);
+ 
+-      if (*rval != NULL) {
+-              var_push_dtor_no_addref(var_hash, rval);
++      if (!strncmp(start + 2, "NAN", 3)) {
++              ZVAL_DOUBLE(*rval, php_get_nan());
++      } else if (!strncmp(start + 2, "INF", 3)) {
++              ZVAL_DOUBLE(*rval, php_get_inf());
++      } else if (!strncmp(start + 2, "-INF", 4)) {
++              ZVAL_DOUBLE(*rval, -php_get_inf());
+       }
+-      *rval = *rval_ref;
+-      Z_ADDREF_PP(rval);
+-      Z_SET_ISREF_PP(rval);
+ 
+       return 1;
+ }
++#line 1409 "ext/standard/var_unserializer.c"
+ }
++#line 937 "ext/standard/var_unserializer.re"
+ 
+ 
+       return 0;
Index: pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.re
diff -u /dev/null pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.re:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-ext_standard_var__unserializer.re   Tue Oct 27 15:30:49 2026
@@ -0,0 +1,74 @@
+$NetBSD: patch-ext_standard_var__unserializer.re,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- ext/standard/var_unserializer.re.orig      2019-01-09 09:54:13.000000000 +0000
++++ ext/standard/var_unserializer.re
+@@ -372,6 +372,16 @@ static inline int process_nested_data(UN
+                       return 0;
+               }
+ 
++              /* The members that incomplete_classes_only mode writes itself cannot be
++               * told apart from that bookkeeping: reject them */
++              if (objprops && UNEXPECTED(BG(incomplete_classes_only)) && Z_TYPE_P(key) == IS_STRING
++                              && ((Z_STRLEN_P(key) == sizeof(MAGIC_MEMBER) - 1 && !memcmp(Z_STRVAL_P(key), MAGIC_MEMBER, sizeof(MAGIC_MEMBER) - 1))
++                                      || (Z_STRLEN_P(key) == sizeof(MAGIC_MEMBER_SERIALIZED) - 1 && !memcmp(Z_STRVAL_P(key), MAGIC_MEMBER_SERIALIZED, sizeof(MAGIC_MEMBER_SERIALIZED) - 1)))) {
++                      var_push_dtor_no_addref(var_hash, &key);
++                      var_push_dtor_no_addref(var_hash, &data);
++                      return 0;
++              }
++
+               if (!objprops) {
+                       switch (Z_TYPE_P(key)) {
+                       case IS_LONG:
+@@ -418,7 +428,7 @@ static inline int finish_nested_data(UNS
+       return 1;
+ }
+ 
+-static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
++static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce, int keep_payload)
+ {
+       long datalen;
+ 
+@@ -431,7 +441,16 @@ static inline int object_custom(UNSERIAL
+               return 0;
+       }
+ 
+-      if (ce->unserialize == NULL) {
++      if (keep_payload) {
++              /* The class was not resolved (see BG(incomplete_classes_only)): keep
++               * the payload verbatim, so that the object serializes back unchanged */
++              zval *payload;
++
++              object_init_ex(*rval, ce);
++              MAKE_STD_ZVAL(payload);
++              ZVAL_STRINGL(payload, (char *) *p, datalen, 1);
++              zend_hash_update(Z_OBJPROP_PP(rval), MAGIC_MEMBER_SERIALIZED, sizeof(MAGIC_MEMBER_SERIALIZED), &payload, sizeof(payload), NULL);
++      } else if (ce->unserialize == NULL) {
+               zend_error(E_WARNING, "Class %s has no unserializer", ce->name);
+               object_init_ex(*rval, ce);
+       } else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
+@@ -796,6 +815,14 @@ object ":" uiv ":" ["]    {
+       class_name = estrndup(class_name, len);
+ 
+       do {
++              if (BG(incomplete_classes_only)) {
++                      /* Do not look the class up at all, so that no code (autoloader,
++                       * unserialize_callback_func, __wakeup(), unserialize()) can run */
++                      incomplete_class = 1;
++                      ce = PHP_IC_ENTRY;
++                      break;
++              }
++
+               /* Try to find class directly */
+               BG(serialize_lock)++;
+               if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
+@@ -875,7 +902,7 @@ object ":" uiv ":" ["]     {
+       if (custom_object) {
+               int ret;
+ 
+-              ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
++              ret = object_custom(UNSERIALIZE_PASSTHRU, ce, incomplete_class && BG(incomplete_classes_only));
+ 
+               if (ret && incomplete_class) {
+                       php_store_class_name(*rval, class_name, len2);
Index: pkgsrc/lang/php56/patches/patch-main_SAPI.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-main_SAPI.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-main_SAPI.c Tue Oct 27 15:30:49 2026
@@ -0,0 +1,19 @@
+$NetBSD: patch-main_SAPI.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- main/SAPI.c.orig   2019-01-09 09:54:13.000000000 +0000
++++ main/SAPI.c
+@@ -185,6 +185,12 @@ SAPI_API void sapi_handle_post(void *arg
+               SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg TSRMLS_CC);
+               efree(SG(request_info).content_type_dup);
+               SG(request_info).content_type_dup = NULL;
++
++              /* Request parsing reached the memory limit: fail the request now that
++               * the parsed data is consistent again */
++              if (ZEND_OOM_PENDING()) {
++                      zend_handle_delayed_oom(TSRMLS_C);
++              }
+       }
+ }
+ 
Index: pkgsrc/lang/php56/patches/patch-main_main.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-main_main.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-main_main.c Tue Oct 27 15:30:49 2026
@@ -0,0 +1,84 @@
+$NetBSD: patch-main_main.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- main/main.c.orig   2019-01-09 09:54:13.000000000 +0000
++++ main/main.c
+@@ -628,6 +628,7 @@ PHP_INI_BEGIN()
+       PHP_INI_ENTRY("disable_functions",                      "",                     PHP_INI_SYSTEM,         NULL)
+       PHP_INI_ENTRY("disable_classes",                        "",                     PHP_INI_SYSTEM,         NULL)
+       PHP_INI_ENTRY("max_file_uploads",                       "20",                   PHP_INI_SYSTEM|PHP_INI_PERDIR,          NULL)
++      PHP_INI_ENTRY("max_multipart_body_parts",       "-1",                   PHP_INI_SYSTEM|PHP_INI_PERDIR,          NULL)
+ 
+       STD_PHP_INI_BOOLEAN("allow_url_fopen",          "1",            PHP_INI_SYSTEM,         OnUpdateBool,           allow_url_fopen,                php_core_globals,               core_globals)
+       STD_PHP_INI_BOOLEAN("allow_url_include",        "0",            PHP_INI_SYSTEM,         OnUpdateBool,           allow_url_include,              php_core_globals,               core_globals)
+@@ -782,6 +783,13 @@ PHPAPI void php_verror(const char *docre
+       char *message;
+       int is_function = 0;
+ 
++      /* Do not pile up diagnostics while a memory limit error is pending, see
++       * zend_handle_delayed_oom(). Fatal errors are still raised, as callers
++       * may not expect them to return. */
++      if (ZEND_HAS_OOM() && !(type & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE))) {
++              return;
++      }
++
+       /* get error text into buffer and escape for html if necessary */
+       buffer_len = vspprintf(&buffer, 0, format, args);
+ 
+@@ -1632,6 +1640,8 @@ int php_request_startup(TSRMLS_D)
+       signal(SIGCHLD, sigchld_handler);
+ #endif
+ 
++      EG(delayed_oom) = ZEND_OOM_STATE_NONE;
++
+       zend_try {
+               PG(in_error_log) = 0;
+               PG(during_request_startup) = 1;
+@@ -1645,6 +1655,7 @@ int php_request_startup(TSRMLS_D)
+               PG(in_user_include) = 0;
+ 
+               zend_activate(TSRMLS_C);
++              php_basic_early_rinit(TSRMLS_C);
+               sapi_activate(TSRMLS_C);
+ 
+ #ifdef ZEND_SIGNALS
+@@ -1822,6 +1833,11 @@ void php_request_shutdown(void *dummy)
+ 
+       report_memleaks = PG(report_memleaks);
+ 
++      /* A memory limit error that was already reported does not prevent the
++       * shutdown functions and destructors from running, see
++       * zend_handle_delayed_oom() */
++      EG(delayed_oom) = ZEND_OOM_STATE_NONE;
++
+       /* EG(opline_ptr) points into nirvana and therefore cannot be safely accessed
+        * inside zend_executor callback functions.
+        */
+@@ -1880,6 +1896,8 @@ void php_request_shutdown(void *dummy)
+               for (i=0; i<NUM_TRACK_VARS; i++) {
+                       if (PG(http_globals)[i]) {
+                               zval_ptr_dtor(&PG(http_globals)[i]);
++                              /* May be accessed before php_request_startup() */
++                              PG(http_globals)[i] = NULL;
+                       }
+               }
+       } zend_end_try();
+@@ -1920,6 +1938,7 @@ void php_request_shutdown(void *dummy)
+       zend_try {
+               shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0 TSRMLS_CC);
+       } zend_end_try();
++      EG(delayed_oom) = ZEND_OOM_STATE_NONE;
+       zend_interned_strings_restore(TSRMLS_C);
+ 
+       /* 12. Reset max_execution_time */
+@@ -1937,6 +1956,9 @@ void php_request_shutdown(void *dummy)
+ #ifdef HAVE_DTRACE
+       DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
+ #endif /* HAVE_DTRACE */
++
++      /* May be accessed before php_request_startup() */
++      PG(modules_activated) = 0;
+ }
+ /* }}} */
+ 
Index: pkgsrc/lang/php56/patches/patch-main_php__variables.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-main_php__variables.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-main_php__variables.c       Tue Oct 27 15:30:49 2026
@@ -0,0 +1,33 @@
+$NetBSD: patch-main_php__variables.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- main/php_variables.c.orig  2019-01-09 09:54:13.000000000 +0000
++++ main/php_variables.c
+@@ -150,6 +150,13 @@ PHPAPI void php_register_variable_ex(cha
+                               return;
+                       }
+ 
++                      /* Each level retains an array, so stop once over the memory limit */
++                      if (ZEND_HAS_OOM()) {
++                              zval_dtor(val);
++                              free_alloca(var_orig, use_heap);
++                              return;
++                      }
++
+                       ip++;
+                       index_s = ip;
+                       if (isspace(*ip)) {
+@@ -308,6 +315,12 @@ static inline int add_post_vars(zval *ar
+                                       max_vars);
+                       return FAILURE;
+               }
++              if (ZEND_HAS_OOM()) {
++                      return FAILURE;
++              }
++      }
++      if (ZEND_HAS_OOM()) {
++              return FAILURE;
+       }
+ 
+       if (!eof && vars->str.c != vars->ptr) {
Index: pkgsrc/lang/php56/patches/patch-main_rfc1867.c
diff -u /dev/null pkgsrc/lang/php56/patches/patch-main_rfc1867.c:1.1
--- /dev/null   Tue Oct 27 15:30:49 2026
+++ pkgsrc/lang/php56/patches/patch-main_rfc1867.c      Tue Oct 27 15:30:49 2026
@@ -0,0 +1,162 @@
+$NetBSD: patch-main_rfc1867.c,v 1.1 2026/10/27 15:30:49 taca Exp $
+
+https://raw.githubusercontent.com/Anton-Barinov/php2shell-patches/refs/heads/main/patches/php-5.6-enhanced-universal.patch
+
+--- main/rfc1867.c.orig        2019-01-09 09:54:13.000000000 +0000
++++ main/rfc1867.c
+@@ -249,6 +249,12 @@ static int fill_buffer(multipart_buffer 
+ 
+       self->buf_begin = self->buffer;
+ 
++      /* The declared Content-Length was checked against post_max_size, but the
++       * body may be longer (or chunked) */
++      if (SG(post_max_size) > 0 && SG(read_post_bytes) > SG(post_max_size)) {
++              return 0;
++      }
++
+       /* calculate the free space in the buffer */
+       bytes_to_read = self->bufsize - self->bytes_in_buffer;
+ 
+@@ -400,6 +406,14 @@ static int find_boundary(multipart_buffe
+       return 0;
+ }
+ 
++static char *php_mime_get_hdr_value(zend_llist header, char *key);
++
++static zend_bool php_mime_should_save_hdr(const char *name)
++{
++      return !strcasecmp(name, "Content-Disposition")
++              || !strcasecmp(name, "Content-Type");
++}
++
+ /* parse headers */
+ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC)
+ {
+@@ -441,15 +455,31 @@ static int multipart_buffer_headers(mult
+                       }
+ 
+                       *value = '\0';
+-                      do { value++; } while(isspace(*value));
+ 
+-                      key = estrdup(line);
+-                      smart_str_appends(&buf_value, value);
++                      /* An unbounded number of headers would be kept in memory: keep
++                       * only the ones we use, and ignore duplicates */
++                      if (!php_mime_should_save_hdr(line)
++                                      || php_mime_get_hdr_value(*header, line)) {
++                              key = NULL;
++                      } else {
++                              do { value++; } while(isspace(*value));
++
++                              key = estrdup(line);
++                              smart_str_appends(&buf_value, value);
++                      }
+               } else if (buf_value.c) { /* If no ':' on the line, add to previous line */
+                       smart_str_appends(&buf_value, line);
+               } else {
+                       continue;
+               }
++
++              if (ZEND_HAS_OOM()) {
++                      if (key) {
++                              efree(key);
++                      }
++                      smart_str_free(&buf_value);
++                      return 0;
++              }
+       }
+       if(buf_value.c && key) {
+               /* add the last one to the list */
+@@ -664,6 +694,9 @@ static char *multipart_buffer_read_body(
+               out = erealloc(out, total_bytes + read_bytes + 1);
+               memcpy(out + total_bytes, buf, read_bytes);
+               total_bytes += read_bytes;
++              if (ZEND_HAS_OOM()) {
++                      break;
++              }
+       }
+ 
+       if (out) {
+@@ -696,6 +729,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_
+       void *event_extra_data = NULL;
+       unsigned int llen = 0;
+       int upload_cnt = INI_INT("max_file_uploads");
++      long body_parts_cnt = INI_INT("max_multipart_body_parts");
++      long body_parts_limit;
+       const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
+       php_rfc1867_getword_t getword;
+       php_rfc1867_getword_conf_t getword_conf;
+@@ -717,6 +752,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_
+               return;
+       }
+ 
++      if (body_parts_cnt < 0) {
++              body_parts_cnt = PG(max_input_vars) + upload_cnt;
++      }
++      body_parts_limit = body_parts_cnt;
++
+       /* Get the boundary */
+       boundary = strstr(content_type_dup, "boundary");
+       if (!boundary) {
+@@ -782,6 +822,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_
+               if (php_rfc1867_callback(MULTIPART_EVENT_START, &event_start, &event_extra_data TSRMLS_CC) == FAILURE) {
+                       goto fileupload_done;
+               }
++              if (ZEND_HAS_OOM()) {
++                      goto fileupload_done;
++              }
+       }
+ 
+       while (!multipart_buffer_eof(mbuff TSRMLS_CC))
+@@ -793,6 +836,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_
+ 
+               zend_llist_clean(&header);
+ 
++              if (ZEND_HAS_OOM()) {
++                      /* A previous body part has reached the memory limit: stop here */
++                      goto fileupload_done;
++              }
++
+               if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) {
+                       goto fileupload_done;
+               }
+@@ -801,6 +849,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_
+                       char *pair = NULL;
+                       int end = 0;
+ 
++                      if (--body_parts_cnt < 0) {
++                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Multipart body parts limit exceeded %ld. To increase the limit change max_multipart_body_parts in php.ini.", 
body_parts_limit);
++                              goto fileupload_done;
++                      }
++
+                       while (isspace(*cd)) {
+                               ++cd;
+                       }
+@@ -856,6 +909,17 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_
+                               char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC);
+                               unsigned int new_val_len; /* Dummy variable */
+ 
++                              if (ZEND_HAS_OOM()) {
++                                      if (value) {
++                                              efree(value);
++                                      }
++                                      efree(param);
++                                      if (filename) {
++                                              efree(filename);
++                                      }
++                                      goto fileupload_done;
++                              }
++
+                               if (!value) {
+                                       value = estrdup("");
+                                       value_len = 0;
+@@ -1287,6 +1351,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_
+       }
+ 
+ fileupload_done:
++      if (SG(post_max_size) > 0 && SG(read_post_bytes) > SG(post_max_size)) {
++              sapi_module.sapi_error(E_WARNING, "Actual POST length does not match Content-Length, and exceeds %ld bytes", SG(post_max_size));
++      }
+       if (php_rfc1867_callback != NULL) {
+               multipart_event_end event_end;
+ 



Home | Main Index | Thread Index | Old Index