Download | Plain Text | No Line Numbers


  1. --- a/main/main.c 2026-10-21 15:53:49.978304568 +0200
  2. +++ b/main/main.c 2026-10-21 16:04:08.205360393 +0200
  3. @@ -320,6 +320,17 @@
  4. } else {
  5. value = Z_L(1)<<30; /* effectively, no limit */
  6. }
  7. +
  8. + /* If memory_limit exceeds max_memory_limit, set to max_memory_limit instead. */
  9. + if (value > PG(max_memory_limit)) {
  10. + zend_ini_entry *max_mem_limit_ini = zend_hash_str_find_ptr(EG(ini_directives), ZEND_STRL("max_memory_limit"));
  11. + entry->value = zend_string_init(ZSTR_VAL(max_mem_limit_ini->value), ZSTR_LEN(max_mem_limit_ini->value), true);
  12. + GC_MAKE_PERSISTENT_LOCAL(entry->value);
  13. + PG(memory_limit) = PG(max_memory_limit);
  14. +
  15. + return SUCCESS;
  16. + }
  17. +
  18. if (zend_set_memory_limit(value) == FAILURE) {
  19. /* When the memory limit is reset to the original level during deactivation, we may be
  20. * using more memory than the original limit while shutdown is still in progress.
  21. @@ -359,6 +370,32 @@
  22. return SUCCESS;
  23. }
  24.  
  25. +static PHP_INI_MH(OnChangeMaxMemoryLimit)
  26. +{
  27. + size_t value;
  28. + if (new_value) {
  29. + value = zend_ini_parse_uquantity_warn(new_value, entry->name);
  30. + } else {
  31. + value = Z_L(1) << 30; /* effectively, no limit */
  32. + }
  33. +
  34. + if (zend_set_memory_limit(value) == FAILURE) {
  35. + if (stage != ZEND_INI_STAGE_DEACTIVATE) {
  36. + zend_error(E_ERROR, "Failed to set memory limit to %zd bytes (Current memory usage is %zd bytes)", value, zend_memory_usage(true));
  37. + return FAILURE;
  38. + }
  39. + }
  40. +
  41. + PG(max_memory_limit) = value;
  42. + if (stage == ZEND_INI_STAGE_DEACTIVATE) {
  43. + PG(memory_limit) = value;
  44. + } else {
  45. + zend_alter_ini_entry(ZSTR_KNOWN(ZEND_STR_MEMORY_LIMIT), new_value, PHP_INI_ALL, stage);
  46. + }
  47. +
  48. + return SUCCESS;
  49. +}
  50. +
  51. /* {{{ PHP_INI_MH */
  52. static PHP_INI_MH(OnSetLogFilter)
  53. {
  54. @@ -824,8 +861,11 @@
  55. STD_PHP_INI_BOOLEAN("mail.mixed_lf_and_crlf", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_mixed_lf_and_crlf, php_core_globals, core_globals)
  56. STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals)
  57. PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, OnChangeBrowscap)
  58. - PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)
  59. +
  60. + PHP_INI_ENTRY("max_memory_limit", "-1", PHP_INI_SYSTEM, OnChangeMaxMemoryLimit)
  61. + PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)
  62. PHP_INI_ENTRY("memory_hard_limit_percent", NULL, PHP_INI_ALL, OnChangeMemoryHardLimitPercent)
  63. +
  64. PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision)
  65. PHP_INI_ENTRY("sendmail_from", NULL, PHP_INI_ALL, NULL)
  66. PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL)
  67. --- a/main/php_globals.h 2026-10-21 15:53:49.871360582 +0200
  68. +++ b/main/php_globals.h 2026-10-21 15:59:15.321666054 +0200
  69. @@ -72,6 +72,7 @@
  70. zend_long serialize_precision;
  71.  
  72. zend_long memory_limit;
  73. + zend_long max_memory_limit;
  74. zend_long max_input_time;
  75.  
  76. char *error_log;
  77. --- a/php.ini-development 2026-10-21 15:53:49.871802786 +0200
  78. +++ b/php.ini-development 2026-10-21 15:59:15.322014556 +0200
  79. @@ -435,6 +435,7 @@
  80. ; Maximum amount of memory a script may consume
  81. ; https://php.net/memory-limit
  82. memory_limit = 128M
  83. +max_memory_limit = -1
  84.  
  85. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  86. ; Error handling and logging ;
  87. --- a/php.ini-production 2026-10-21 15:53:49.872363380 +0200
  88. +++ b/php.ini-production 2026-10-21 15:59:15.322449804 +0200
  89. @@ -437,6 +437,7 @@
  90. ; Maximum amount of memory a script may consume
  91. ; https://php.net/memory-limit
  92. memory_limit = 128M
  93. +max_memory_limit = -1
  94.  
  95. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  96. ; Error handling and logging ;
  97. --- a/Zend/zend_ini.c 2026-10-19 16:38:59.000000000 +0200
  98. +++ b/Zend/zend_ini.c 2026-10-21 15:59:15.322842728 +0200
  99. @@ -247,10 +247,16 @@
  100. zend_unregister_ini_entries_ex(module_number, module_type);
  101. return FAILURE;
  102. }
  103. +
  104. + zend_string *prev_value = p->value;
  105. +
  106. if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
  107. (!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP) == SUCCESS)) {
  108.  
  109. - p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
  110. + /* Skip assigning the value if the handler has already done so. */
  111. + if (p->value == prev_value) {
  112. + p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
  113. + }
  114. } else {
  115. p->value = ini_entry->value ?
  116. zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL;
  117. @@ -388,14 +394,20 @@
  118. zend_hash_add_ptr(EG(modified_ini_directives), ini_entry->name, ini_entry);
  119. }
  120.  
  121. + zend_string *prev_value = ini_entry->value;
  122. duplicate = zend_string_copy(new_value);
  123.  
  124. if (!ini_entry->on_modify
  125. || ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) {
  126. - if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
  127. - zend_string_release(ini_entry->value);
  128. + if (modified && ini_entry->orig_value != prev_value) { /* we already changed the value, free the changed value */
  129. + zend_string_release(prev_value);
  130. + }
  131. + /* Skip assigning the value if the handler has already done so. */
  132. + if (ini_entry->value == prev_value) {
  133. + ini_entry->value = duplicate;
  134. + } else {
  135. + zend_string_release(duplicate);
  136. }
  137. - ini_entry->value = duplicate;
  138. } else {
  139. zend_string_release(duplicate);
  140. return FAILURE;
  141. --- a/Zend/zend_string.h 2026-10-19 16:38:59.000000000 +0200
  142. +++ b/Zend/zend_string.h 2026-10-21 15:59:15.323170860 +0200
  143. @@ -718,6 +718,7 @@
  144. _(ZEND_STR_SINCE, "since") \
  145. _(ZEND_STR_GET, "get") \
  146. _(ZEND_STR_SET, "set") \
  147. + _(ZEND_STR_MEMORY_LIMIT, "memory_limit") \
  148.  
  149.  
  150. typedef enum _zend_known_string_id {
  151.