|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +# Uses the Python zip implementation to create deterministic XPI's |
| 4 | +# Author: Yan Zhu, yan@mit.edu |
| 5 | + |
| 6 | +# ZipFile: infolist, write, writestr, |
| 7 | + |
| 8 | +import os |
| 9 | +import zipfile2_6 as zipfile |
| 10 | +import sys |
| 11 | +import time |
| 12 | +import glob |
| 13 | + |
| 14 | +xpiName = sys.argv[1] |
| 15 | +exclusionsFile = sys.argv[2] |
| 16 | +exclusions = [] |
| 17 | +tmpfile = '../pkg/tmp.xpi' |
| 18 | +compress = zipfile.ZIP_STORED |
| 19 | +testfile = 'testfile.txt' |
| 20 | + |
| 21 | +with open(exclusionsFile) as f: |
| 22 | + for line in f: |
| 23 | + exclusions.extend(glob.glob(line.strip())) |
| 24 | + |
| 25 | +xpiFile = zipfile.ZipFile(xpiName, mode='w', compression=compress) |
| 26 | + |
| 27 | +def createTmpZipInfo(): |
| 28 | + """ |
| 29 | + Create a non-deterministic zip in order to use the file info |
| 30 | + generated to create a deterministic zip |
| 31 | + """ |
| 32 | + xpiFileTmp = zipfile.ZipFile(tmpfile, mode='w', compression=compress) |
| 33 | + xpiFileTmp.write(testfile, compress_type=compress) |
| 34 | + xpiFileTmp.close() |
| 35 | + xpiFileTmp.infolist().sort(key = lambda x: x.filename) |
| 36 | + return xpiFileTmp.infolist() |
| 37 | + |
| 38 | +def constructZipDet(): |
| 39 | + """ |
| 40 | + Create a deterministic zip by setting timestamps, |
| 41 | + operating system, and pkzip version info to hard-coded |
| 42 | + values. See the pkzip specification at |
| 43 | + https://www.pkware.com/documents/casestudies/APPNOTE.TXT |
| 44 | + """ |
| 45 | + tmpInfo = createTmpZipInfo() |
| 46 | + for info in tmpInfo: |
| 47 | + info.date_time = time.gmtime(1378343307) |
| 48 | + info.create_system = 3 # aka, UNIX |
| 49 | + info.create_version = 20 |
| 50 | + info.extract_version = 20 |
| 51 | + xpiFile.writestr(info, open(info.filename).read()) |
| 52 | + |
| 53 | +constructZipDet() |
| 54 | +xpiFile.close() |
| 55 | +os.remove(tmpfile) |
0 commit comments