LEFT | RIGHT |
1 # This Source Code Form is subject to the terms of the Mozilla Public | 1 # This Source Code Form is subject to the terms of the Mozilla Public |
2 # License, v. 2.0. If a copy of the MPL was not distributed with this | 2 # License, v. 2.0. If a copy of the MPL was not distributed with this |
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. | 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | 4 |
5 import sys | 5 import errno |
| 6 import io |
| 7 import json |
6 import os | 8 import os |
7 import re | 9 import re |
8 import json | 10 from StringIO import StringIO |
9 import struct | 11 import struct |
10 import io | 12 import sys |
11 from StringIO import StringIO | 13 import collections |
12 | 14 |
13 from packager import (readMetadata, getDefaultFileName, getBuildVersion, | 15 from packager import (readMetadata, getDefaultFileName, getBuildVersion, |
14 getTemplate, Files) | 16 getTemplate, Files) |
15 | 17 |
16 defaultLocale = 'en_US' | 18 defaultLocale = 'en_US' |
17 | 19 |
18 | 20 |
19 def getIgnoredFiles(params): | 21 def getIgnoredFiles(params): |
20 return {'store.description'} | 22 return {'store.description'} |
21 | 23 |
22 | 24 |
23 def getPackageFiles(params): | 25 def getPackageFiles(params): |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 137 |
136 return manifest.encode('utf-8') | 138 return manifest.encode('utf-8') |
137 | 139 |
138 | 140 |
139 def createInfoModule(params): | 141 def createInfoModule(params): |
140 template = getTemplate('chromeInfo.js.tmpl') | 142 template = getTemplate('chromeInfo.js.tmpl') |
141 return template.render(params).encode('utf-8') | 143 return template.render(params).encode('utf-8') |
142 | 144 |
143 | 145 |
144 def convertJS(params, files): | 146 def convertJS(params, files): |
145 from jshydra.abp_rewrite import doRewrite | 147 from jshydra.abp_rewrite import rewrite_js |
| 148 |
| 149 output_files = collections.OrderedDict() |
| 150 args = collections.defaultdict(list) |
146 | 151 |
147 for item in params['metadata'].items('convert_js'): | 152 for item in params['metadata'].items('convert_js'): |
148 file, sources = item | 153 filename, arg = re.search(r'^(.*?)(?:\[(.*)\])?$', item[0]).groups() |
149 baseDir = os.path.dirname(item.source) | 154 if arg is None: |
150 | 155 output_files[filename] = (item[1].split(), item.source) |
151 # Make sure the file is inside an included directory | 156 else: |
152 if '/' in file and not files.isIncluded(file): | 157 args[filename].append('{}={}'.format(arg, item[1])) |
153 continue | 158 |
154 | 159 for filename, (input_files, origin) in output_files.iteritems(): |
155 sourceFiles = sources.split() | 160 if '/' in filename and not files.isIncluded(filename): |
156 args = [] | 161 continue |
157 try: | 162 |
158 argsStart = sourceFiles.index('--arg') | 163 base_dir = os.path.dirname(origin) |
159 args = sourceFiles[argsStart + 1:] | 164 jshydra_args = ['--arg', ' '.join(args[filename])] |
160 sourceFiles = sourceFiles[0:argsStart] | 165 |
161 except ValueError: | 166 for input_filename in input_files: |
162 pass | 167 jshydra_args.append(os.path.join(base_dir, input_filename)) |
163 | 168 files.pop(input_filename, None) |
164 # Source files of the conversion shouldn't be part of the build | 169 |
165 for sourceFile in sourceFiles: | 170 files[filename] = rewrite_js(jshydra_args) |
166 if sourceFile in files: | |
167 del files[sourceFile] | |
168 | |
169 sourceFiles = map(lambda f: os.path.abspath(os.path.join(baseDir, f)), s
ourceFiles) | |
170 files[file] = doRewrite(sourceFiles, args) | |
171 | 171 |
172 | 172 |
173 def toJson(data): | 173 def toJson(data): |
174 return json.dumps( | 174 return json.dumps( |
175 data, ensure_ascii=False, sort_keys=True, | 175 data, ensure_ascii=False, sort_keys=True, |
176 indent=2, separators=(',', ': ') | 176 indent=2, separators=(',', ': ') |
177 ).encode('utf-8') + '\n' | 177 ).encode('utf-8') + '\n' |
178 | 178 |
179 | 179 |
180 def importGeckoLocales(params, files): | 180 def importGeckoLocales(params, files): |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 # Remove access keys | 245 # Remove access keys |
246 value = sourceData[stringID] | 246 value = sourceData[stringID] |
247 match = re.search(r'^(.*?)\s*\(&.\)$', value) | 247 match = re.search(r'^(.*?)\s*\(&.\)$', value) |
248 if match: | 248 if match: |
249 value = match.group(1) | 249 value = match.group(1) |
250 else: | 250 else: |
251 index = value.find('&') | 251 index = value.find('&') |
252 if index >= 0: | 252 if index >= 0: |
253 value = value[0:index] + value[index + 1:] | 253 value = value[0:index] + value[index + 1:] |
254 data[key] = {'message': value} | 254 data[key] = {'message': value} |
255 except Exception, e: | 255 except Exception as e: |
256 print 'Warning: error importing locale data from %s: %s' % (sour
ceFile, e) | 256 print 'Warning: error importing locale data from %s: %s' % (sour
ceFile, e) |
257 | 257 |
258 files[targetFile] = toJson(data) | 258 files[targetFile] = toJson(data) |
259 | 259 |
260 | 260 |
261 def truncate(text, length_limit): | 261 def truncate(text, length_limit): |
262 if len(text) <= length_limit: | 262 if len(text) <= length_limit: |
263 return text | 263 return text |
264 return text[:length_limit - 1].rstrip() + u'\u2026' | 264 return text[:length_limit - 1].rstrip() + u'\u2026' |
265 | 265 |
(...skipping 22 matching lines...) Expand all Loading... |
288 data = json.loads(files[filename]) | 288 data = json.loads(files[filename]) |
289 for name, info in defaults.iteritems(): | 289 for name, info in defaults.iteritems(): |
290 data.setdefault(name, info) | 290 data.setdefault(name, info) |
291 for name, limit in limits.iteritems(): | 291 for name, limit in limits.iteritems(): |
292 if name in data: | 292 if name in data: |
293 data[name]['message'] = truncate(data[name]['message'], limit) | 293 data[name]['message'] = truncate(data[name]['message'], limit) |
294 files[filename] = toJson(data) | 294 files[filename] = toJson(data) |
295 | 295 |
296 | 296 |
297 def signBinary(zipdata, keyFile): | 297 def signBinary(zipdata, keyFile): |
298 import M2Crypto | 298 from Crypto.Hash import SHA |
299 if not os.path.exists(keyFile): | 299 from Crypto.PublicKey import RSA |
300 M2Crypto.RSA.gen_key(1024, 65537, callback=lambda x: None).save_key(keyF
ile, cipher=None) | 300 from Crypto.Signature import PKCS1_v1_5 |
301 key = M2Crypto.EVP.load_key(keyFile) | 301 |
302 key.sign_init() | 302 try: |
303 key.sign_update(zipdata) | 303 with open(keyFile, 'rb') as file: |
304 return key.final() | 304 key = RSA.importKey(file.read()) |
| 305 except IOError as e: |
| 306 if e.errno != errno.ENOENT: |
| 307 raise |
| 308 key = RSA.generate(2048) |
| 309 with open(keyFile, 'wb') as file: |
| 310 file.write(key.exportKey('PEM')) |
| 311 |
| 312 return PKCS1_v1_5.new(key).sign(SHA.new(zipdata)) |
305 | 313 |
306 | 314 |
307 def getPublicKey(keyFile): | 315 def getPublicKey(keyFile): |
308 import M2Crypto | 316 from Crypto.PublicKey import RSA |
309 return M2Crypto.EVP.load_key(keyFile).as_der() | 317 with open(keyFile, 'rb') as file: |
| 318 return RSA.importKey(file.read()).publickey().exportKey('DER') |
310 | 319 |
311 | 320 |
312 def writePackage(outputFile, pubkey, signature, zipdata): | 321 def writePackage(outputFile, pubkey, signature, zipdata): |
313 if isinstance(outputFile, basestring): | 322 if isinstance(outputFile, basestring): |
314 file = open(outputFile, 'wb') | 323 file = open(outputFile, 'wb') |
315 else: | 324 else: |
316 file = outputFile | 325 file = outputFile |
317 if pubkey != None and signature != None: | 326 if pubkey != None and signature != None: |
318 file.write(struct.pack('<4sIII', 'Cr24', 2, len(pubkey), len(signature))
) | 327 file.write(struct.pack('<4sIII', 'Cr24', 2, len(pubkey), len(signature))
) |
319 file.write(pubkey) | 328 file.write(pubkey) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 files['qunit/index.html'] = createScriptPage(params, 'testIndex.html.tmp
l', | 384 files['qunit/index.html'] = createScriptPage(params, 'testIndex.html.tmp
l', |
376 ('general', 'testScripts')) | 385 ('general', 'testScripts')) |
377 | 386 |
378 zipdata = files.zipToString() | 387 zipdata = files.zipToString() |
379 signature = None | 388 signature = None |
380 pubkey = None | 389 pubkey = None |
381 if keyFile != None: | 390 if keyFile != None: |
382 signature = signBinary(zipdata, keyFile) | 391 signature = signBinary(zipdata, keyFile) |
383 pubkey = getPublicKey(keyFile) | 392 pubkey = getPublicKey(keyFile) |
384 writePackage(outFile, pubkey, signature, zipdata) | 393 writePackage(outFile, pubkey, signature, zipdata) |
LEFT | RIGHT |