Repository navigation
Conversation
For the '*' repeater, the h/H case leaves size at -1. Unlike the a/A/Z
cases, which set size to the number of bytes they consumed, the hex case
never updates it, so "inputpos += size" moved the position one byte
backwards instead of to the end of the input. Any code following h* or
H* therefore re-read input that had already been consumed:
unpack("H*a/H*b", "\xab\xcd"); // b => "abcd" instead of ""
unpack("H*a/Cb", "\xab\xcd"); // b => 171 instead of a warning
Set size to the number of input bytes consumed by the nibbles that were
read. This is what was already used for explicit counts, so only the '*'
case changes.
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.
This change and the description below were written by an LLM (Claude Code).
With the
*repeater, the h/H case inunpack()leavessizeat -1. The a/A/Z cases setsizeto the number of bytes they consumed, but the hex case never does, soinputpos += sizemoves the position one byte backwards instead of to the end of the input. Any format code afterh*orH*then re-reads data that was already consumed:The fix sets
sizeto the number of input bytes the nibbles came from,(len + 1) / 2. For explicit counts that's the value it already had, so only the*case changes.The new phpt fails without the fix, and ext/standard/tests/strings passes with it.
Targeting PHP-8.4 as the lowest branch that still gets bug fixes. PHP-8.5 and up have the same bug, but the surrounding lines differ, so the merge-up needs the same line added by hand.