[3.0] Parse memory settings that carry no unit designator - #9324
Merged
Sesquipedalian merged 1 commit intoAug 14, 2026
Merged
Conversation
memoryReturnBytes() removed the last character of the value before
parsing the number, on the assumption that it is always a designator.
PHP's shorthand notation is optional, so a plain byte count loses its
last digit: '128' reads as 12, and '2097152' reads as 209715.
Graphics\Image does exactly that, passing a computed byte count with no
designator, so resizing an image asks for a tenth of the memory it just
worked out that it needs.
The other value with no designator is '-1', which means there is no
limit. It read as 0, because intval('-') is 0, so setMemoryLimit() found
the current limit to be smaller than anything and set one. On a server
with no memory limit, asking for 128M capped it at 128M.
Only strips the last character when it is one of the designators PHP
accepts, and reports "no limit" as PHP_INT_MAX so that the callers
comparing it against an amount they need do not each have to special
case it.
The dead is_integer() check went with it; the parameter is typed string.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Jul 29, 2026
This was referenced Aug 2, 2026
Sesquipedalian
approved these changes
Aug 14, 2026
Member
|
We should check whether this is also an issue in SMF 2.1 and fix it if so. EDIT: Yes, it is. I'll submit a PR for that shortly. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This change was produced by an LLM. The code, the commit message and this
description were all written by Claude (Anthropic), driven by @albertlast. It has
not yet had human code review.
Everything stated below was verified by actually running it, rather than only
reasoned about. Even so, please review it as untrusted work: the diagnosis may be
right while the fix is not what SMF would prefer stylistically or architecturally.
Description
Sapi::memoryReturnBytes()removes the last character of the value before parsingthe number, on the assumption that it is always a unit designator:
PHP's shorthand notation is optional, so a setting may be a plain byte count. When it
is, the last digit is eaten:
'128'reads as12, and'2097152'reads as209715.Sources/Graphics/Image.phpdoes exactly that. It works out how much memory an imageneeds and passes the raw byte count with no designator:
so image resizing asks for a tenth of what it just calculated.
The other value carrying no designator is
-1, which is how PHP spells "no limit".substr('-1', 0, 1)is'-', andintval('-')is0, so an unlimited server reportszero bytes available.
setMemoryLimit()then finds the current limit smaller thananything at all and imposes one.
This strips the last character only when it is a designator PHP actually accepts, and
reports "no limit" as
PHP_INT_MAXso that the four call sites comparing it against anamount they need do not each have to special case it. The dead
is_integer()check atthe top went with it; the parameter is typed
string, so it never fired.How this was verified
PHP 8.4.23. Same script before and after the change.
Parsing:
'256M''1G''512K''128''2097152''-1'' 64M 'Then through the caller, with
memory_limitset to-1:Nothing that already worked changes: every value with a designator parses to the same
number as before.
php -land PHP-CS-Fixer clean.Relationship to other PRs
Sources/Sapi.phpis not touched by any other open PR.Found while writing unit tests for the stateless parts of the codebase (#9326). That
branch carries the regression tests for this fix, and reverting this file alone fails
exactly those tests. This PR is deliberately independent of it, so it can be merged on
its own.
Issues References (Fixes|Related|Closes)