Skip to content

Instantly share code, notes, and snippets.

@dcsobral
Created September 28, 2012 16:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dcsobral/3800777 to your computer and use it in GitHub Desktop.
Save dcsobral/3800777 to your computer and use it in GitHub Desktop.
Adds a fake header to ZIP files to produce valid ZIP files that ZipInputStream cannot decode
#!/bin/sh
exec scala "$0" "$@"
!#
import java.io._
if (args.length != 2)
sys.error("Please pass input and output files as parameters")
val inputFile = new File(args(0))
val outputFile = new File(args(1))
val inputStream = new FileInputStream(inputFile)
val bytes = Iterator.continually(inputStream.read()).takeWhile(_ != -1).toArray
inputStream.close()
def getShort(i: Int) = bytes(i) + 0x100 * bytes(i + 1)
def getInt(i: Int) = getShort(i) + 0x10000 * getShort(i + 2)
val endOfCD = bytes.lastIndexOfSlice(Array(0x50, 0x4b, 5, 6))
val numberOfEntries = getShort(endOfCD + 10)
val centralDirectoryOffset = endOfCD + 16
val centralDirectory = getInt(centralDirectoryOffset)
def nextEntry(i: Int) = i + 46 + getShort(i + 28) + getShort(i + 30) + getShort(i + 32)
val entries = List.iterate(centralDirectory, numberOfEntries)(nextEntry)
val falseHeader =
Array(80, 75, 3, 4, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 70, 65, 75, 69)
bytes(centralDirectoryOffset) += falseHeader.length
entries foreach { i => bytes(i + 42) += falseHeader.length }
val outputStream = new FileOutputStream(outputFile)
outputStream.write(falseHeader map (_.toByte))
outputStream.write(bytes map (_.toByte))
outputStream.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment