Detect native PHAR archives - #7
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class detection for native PHAR archives by locating the PHP stub boundary and validating the subsequent manifest/entry structure, while preserving existing precedence for container-based PHARs (ZIP/TAR) and outer compression formats (gzip/bzip2).
Changes:
- Introduces
FormatPHAR/mimePHARand native PHAR validation logic (stub boundary + manifest + payload bounds). - Extends binary detection to return “need more” state for incomplete PHAR prefixes and plumbs that into
DetectPrefix(ReasonNeedMore). - Adds dedicated PHAR unit tests and seeds PHAR inputs into allocation and fuzz tests; updates README docs.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| signatures.go | Adds binaryFormatState with PHAR validation + “need more” support. |
| magic.go | Adds FormatPHAR/mimePHAR and propagates PHAR “need more” into DetectPrefix. |
| phar.go | Implements native PHAR stub/manifest/entry validation. |
| phar_test.go | Adds comprehensive native PHAR detection and rejection tests, plus prefix ReasonNeedMore coverage. |
| magic_test.go | Adds PHAR fixture to allocation test corpus. |
| fuzz_test.go | Adds PHAR seed input for fuzzing Detect. |
| README.md | Documents native PHAR support and updated performance characteristics. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+28
to
+34
| func nativePHAR(data []byte) pharStatus { | ||
| stubEnd := bytes.Index(data, []byte(pharHaltCompiler)) | ||
| if stubEnd < 0 { | ||
| return pharNotFound | ||
| } | ||
| stubEnd += len(pharHaltCompiler) | ||
|
|
Comment on lines
+56
to
+63
| entryCount := binary.LittleEndian.Uint32(manifest) | ||
| if entryCount == 0 { | ||
| return pharNotFound | ||
| } | ||
| apiVersion := binary.BigEndian.Uint16(manifest[4:6]) | ||
| if apiVersion&pharAPIVersionMask < pharMinimumAPIVersion { | ||
| return pharNotFound | ||
| } |
Comment on lines
+103
to
+121
| func pharManifestOffset(data []byte, offset int) (int, pharStatus) { | ||
| if offset >= len(data) { | ||
| return 0, pharIncomplete | ||
| } | ||
| if data[offset] != ' ' && data[offset] != '\n' { | ||
| return offset, pharValid | ||
| } | ||
| if len(data)-offset < pharClosingTagSize { | ||
| return 0, pharIncomplete | ||
| } | ||
| if data[offset+1] != '?' || data[offset+2] != '>' { | ||
| return offset, pharValid | ||
| } | ||
|
|
||
| offset += pharClosingTagSize | ||
| if offset >= len(data) { | ||
| return 0, pharIncomplete | ||
| } | ||
| switch data[offset] { |
Comment on lines
+88
to
+95
| compressedSize := binary.LittleEndian.Uint32(manifest[offset+8:]) | ||
| metadataLength := binary.LittleEndian.Uint32(manifest[offset+20:]) | ||
| offset += pharEntryFixedLen - pharManifestLengthSize | ||
| if !pharSkip(manifest, &offset, metadataLength) { | ||
| return pharNotFound | ||
| } | ||
| payloadLength += uint64(compressedSize) | ||
| } |
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.
Detect native PHAR archives by validating the PHP stub boundary, manifest structure, entry records, and stored payload sizes.
Preserve the physical outer format for ZIP-, TAR-, gzip-, and bzip2-based PHARs. Incomplete native PHAR prefixes now return
ReasonNeedMoreuntil the manifest and payload bounds can be checked.Closes #3