Skip to content

Detect native PHAR archives - #7

Merged
andrew merged 1 commit into
mainfrom
detect-native-phar
Aug 16, 2026
Merged

Detect native PHAR archives#7
andrew merged 1 commit into
mainfrom
detect-native-phar

Conversation

@andrew

@andrew andrew commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

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 ReasonNeedMore until the manifest and payload bounds can be checked.

Closes #3

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 / mimePHAR and 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 thread phar.go
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 thread phar.go
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 thread phar.go
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 thread phar.go
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)
}
@andrew
andrew merged commit cbdd549 into main Aug 16, 2026
5 checks passed
@andrew
andrew deleted the detect-native-phar branch August 16, 2026 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detect native PHAR archives

2 participants