Download | Plain Text | No Line Numbers


  1. --- a/main/main.c 2025-11-21 11:19:17.088614216 +0100
  2. +++ b/main/main.c 2025-11-21 11:19:47.226411520 +0100
  3. @@ -278,6 +278,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. @@ -293,6 +304,26 @@
  22. }
  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. + zend_error(E_ERROR, "Failed to set memory limit to %zd bytes (Current memory usage is %zd bytes)", value, zend_memory_usage(true));
  36. + return FAILURE;
  37. + }
  38. +
  39. + PG(max_memory_limit) = value;
  40. + zend_alter_ini_entry(ZSTR_KNOWN(ZEND_STR_MEMORY_LIMIT), new_value, PHP_INI_ALL, stage);
  41. +
  42. + return SUCCESS;
  43. +}
  44. +
  45. /* {{{ PHP_INI_MH */
  46. static PHP_INI_MH(OnSetLogFilter)
  47. {
  48. @@ -753,7 +784,10 @@
  49. 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)
  50. STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals)
  51. PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, OnChangeBrowscap)
  52. - PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)
  53. +
  54. + PHP_INI_ENTRY("max_memory_limit", "-1", PHP_INI_SYSTEM, OnChangeMaxMemoryLimit)
  55. + PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)
  56. +
  57. PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision)
  58. PHP_INI_ENTRY("sendmail_from", NULL, PHP_INI_ALL, NULL)
  59. PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL)
  60. --- a/main/php_globals.h 2025-11-21 11:19:16.948615157 +0100
  61. +++ b/main/php_globals.h 2025-11-21 11:19:47.227411514 +0100
  62. @@ -72,6 +72,7 @@
  63. zend_long serialize_precision;
  64.  
  65. zend_long memory_limit;
  66. + zend_long max_memory_limit;
  67. zend_long max_input_time;
  68.  
  69. char *error_log;
  70. --- a/php.ini-development 2025-11-21 11:19:16.948615157 +0100
  71. +++ b/php.ini-development 2025-11-21 11:19:47.227411514 +0100
  72. @@ -445,6 +445,7 @@
  73. ; Maximum amount of memory a script may consume
  74. ; https://php.net/memory-limit
  75. memory_limit = 128M
  76. +max_memory_limit = -1
  77.  
  78. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  79. ; Error handling and logging ;
  80. --- a/php.ini-production 2025-11-21 11:19:16.949615151 +0100
  81. +++ b/php.ini-production 2025-11-21 11:19:47.228411507 +0100
  82. @@ -447,6 +447,7 @@
  83. ; Maximum amount of memory a script may consume
  84. ; https://php.net/memory-limit
  85. memory_limit = 128M
  86. +max_memory_limit = -1
  87.  
  88. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  89. ; Error handling and logging ;
  90. --- a/Zend/zend_ini.c 2025-11-18 23:17:16.000000000 +0100
  91. +++ b/Zend/zend_ini.c 2025-11-21 11:19:47.228411507 +0100
  92. @@ -247,10 +247,16 @@
  93. zend_unregister_ini_entries_ex(module_number, module_type);
  94. return FAILURE;
  95. }
  96. +
  97. + zend_string *prev_value = p->value;
  98. +
  99. if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
  100. (!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)) {
  101.  
  102. - p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
  103. + /* Skip assigning the value if the handler has already done so. */
  104. + if (p->value == prev_value) {
  105. + p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
  106. + }
  107. } else {
  108. p->value = ini_entry->value ?
  109. zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL;
  110. @@ -388,14 +394,20 @@
  111. zend_hash_add_ptr(EG(modified_ini_directives), ini_entry->name, ini_entry);
  112. }
  113.  
  114. + zend_string *prev_value = ini_entry->value;
  115. duplicate = zend_string_copy(new_value);
  116.  
  117. if (!ini_entry->on_modify
  118. || ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) {
  119. - if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
  120. - zend_string_release(ini_entry->value);
  121. + if (modified && ini_entry->orig_value != prev_value) { /* we already changed the value, free the changed value */
  122. + zend_string_release(prev_value);
  123. + }
  124. + /* Skip assigning the value if the handler has already done so. */
  125. + if (ini_entry->value == prev_value) {
  126. + ini_entry->value = duplicate;
  127. + } else {
  128. + zend_string_release(duplicate);
  129. }
  130. - ini_entry->value = duplicate;
  131. } else {
  132. zend_string_release(duplicate);
  133. return FAILURE;
  134. --- a/Zend/zend_string.h 2025-11-18 23:17:16.000000000 +0100
  135. +++ b/Zend/zend_string.h 2025-11-21 11:20:30.430120949 +0100
  136. @@ -631,6 +631,7 @@
  137. _(ZEND_STR_COUNT, "count") \
  138. _(ZEND_STR_SENSITIVEPARAMETER, "SensitiveParameter") \
  139. _(ZEND_STR_CONST_EXPR_PLACEHOLDER, "[constant expression]") \
  140. + _(ZEND_STR_MEMORY_LIMIT, "memory_limit") \
  141.  
  142.  
  143. typedef enum _zend_known_string_id {
  144.