fix: HTTP::Tiny redirect following and binary-safe mirror downloads#472
Merged
fix: HTTP::Tiny redirect following and binary-safe mirror downloads#472
Conversation
- Enable HttpClient.Redirect.NORMAL so 301/302/303/307/308 redirects are followed automatically (fixes jcpan failing to fetch from CPAN mirrors that redirect, e.g. cpan.org -> www.cpan.org) - Expand getStatusReason() to cover all common HTTP status codes instead of returning "Unknown Status" for redirects - Rewrite mirror() to use BodyHandlers.ofByteArray() instead of delegating to request() which uses ofString(). The string-based path corrupted binary downloads (.tar.gz files) by decoding bytes as UTF-8 then re-encoding with getBytes() - Add url field to response hash (final URL after redirects) - Add proper 599 error response in mirror() on IOException, matching Perl HTTP::Tiny behavior Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…flag contamination This fixes binary data corruption in Image::ExifTool write operations where UTF-8 flagged strings concatenated with byte buffers would cause the output buffer to lose its BYTE_STRING type, leading to double-encoding on re-read. Key changes: - JVM backend .= (concat-assign): Use setPreservingByteString() instead of set() to maintain BYTE_STRING type when target was byte string and result fits in Latin-1 - Bytecode interpreter .= : Same BYTE_STRING preservation logic - RuntimeScalar.setPreservingByteString(): New method for type-preserving assignment used by both backends - RuntimeSubstrLvalue.set(): Preserve BYTE_STRING when parent is byte string - Operator.java 4-arg substr: Return BYTE_STRING when original was BYTE_STRING - is_utf8/_utf8_on/_utf8_off: Only operate on STRING type (not INTEGER/DOUBLE) - Unpack format handlers: Set BYTE_STRING type for binary output - RuntimeHash key creation: Use BYTE_STRING for ASCII-only keys - StringOperators.stringConcat: Produce BYTE_STRING when both operands are non-UTF8 and result fits in Latin-1 - SprintfOperator: Produce BYTE_STRING for %c with byte values ExifTool test improvements: - PNG: 6/7 -> 7/7, IPTC: 7/8 -> 8/8, XMP: 53/54 -> 54/54 - Writer: 53/61 -> 60/61, GIF: 2/5 -> 5/5 - CanonRaw, FujiFilm, MIE, Nikon: all now pass fully Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…al'd code
When `split` was called without an explicit string argument (e.g., bare
`split` or `split /PAT/`), it relied on the runtime fallback to
getGlobalVariable("main::_"). This worked in JVM-compiled code but failed
in bytecode-interpreted code (eval'd strings because the bytecode compiler
compiled the empty argument list in scalar context, producing a spurious
value that was then treated as the string to split.
Fix: In parseSplit(), when no string argument is provided, explicitly add
-A as the default argument in the AST. This is consistent with how other
operators (defined, print, chomp) handle the -A default, and ensures both
JVM and bytecode backends correctly resolve -A at runtime.
This fixes ExifTool Writer test 6 (TimeCodes encoding), Geotag tests
2/4/9/10 (GPX parsing), and Geolocation test 5 (GPS track processing),
all of which used bare inside eval'd code strings.
ExifTool test results: 113/113 files pass, 600/600 tests pass (100%).
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
EOF
)
d6d86ea to
86baa2f
Compare
…ide effects In stringConcat(), b.toString() may trigger FETCH on a tied variable, which can modify the left operand (runtimeScalar) as a side effect. The previous code cached aStr = runtimeScalar.toString() before calling b.toString(), using a stale value. Now we read b first, matching Perl behavior where the left SV reflects modifications from tied-var FETCHes. Fixes regression in opbasic/concat.t test 253 (RT #132595). Note: op/lexsub.t test 99 shows a -1 change, but this is a false regression. The old is_utf8() incorrectly returned true for undef (checking type != BYTE_STRING), which masked a pre-existing bug where my sub in eval does not return a proper coderef. The new is_utf8() correctly returns false for undef, matching Perl behavior. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…wraps with CREATE_REF The bytecode compiler's backslash operator had a special case to avoid wrapping CODE values with CREATE_REF, but it only matched \&name where the operand was an IdentifierNode (regular package subs). For lexical subs (my sub), the AST has &($hidden_var) where the operand is an OperatorNode, which fell through to the generic path that applied CREATE_REF, producing REF(CODE) instead of CODE. The fix broadens the special case to match any \& expression, since the & operator already produces a CODE value via CODE_DEREF_NONSTRICT. This matches the JVM backend's createCodeReference behavior. Fixes lexsub.t tests 99-100 (my sub with UTF-8 prototype). Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
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.
Summary
HttpClient.Redirect.NORMALso HTTP 301/302/303/307/308 redirects are followed automatically. This fixesjcpanfailing to fetch from CPAN mirrors that redirect (e.g.cpan.org→www.cpan.org).getStatusReason()to cover all common HTTP status codes instead of returning "Unknown Status" for redirects and other codes.mirror()to useBodyHandlers.ofByteArray()instead of delegating torequest()which usesofString(). The string-based path corrupted binary downloads (.tar.gzfiles) by decoding bytes as UTF-8 then re-encoding withgetBytes().urlfield to response hash reflecting the final URL after redirects.mirror()onIOException, matching Perl HTTP::Tiny behavior.Test plan
make— all unit tests pass./jperl -e 'use HTTP::Tiny; ...'— 301 redirect from cpan.org now returns status=200./jcpan -t Image::ExifTool— downloads, checksums, configures, and runs full ExifTool test suiteGenerated with Devin