1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#!/usr/bin/env luajit
-- Strip JSON comments and trailing commas from a manifest, inject the
-- extension's public key, and rewrite it.
local dkjson = require("dkjson")
local manifest_path = assert(arg[1], "usage: inject_extension_key.lua <manifest> <extension_key>")
local extension_key = assert(arg[2], "usage: inject_extension_key.lua <manifest> <extension_key>")
local manifest_file = assert(io.open(manifest_path, "r"))
local manifest_content = manifest_file:read("*a")
manifest_file:close()
-- Hand-rolled scanner that removes // and /* */ comments and mid-JSON
-- trailing commas while respecting string literals (including escapes).
local sanitized_chunks = {}
local character_position = 1
local content_length = #manifest_content
local inside_string_literal = false
local function trim_trailing_comma()
while #sanitized_chunks > 0 do
local last_chunk = sanitized_chunks[#sanitized_chunks]
if last_chunk ~= " " and last_chunk ~= "\t" and last_chunk ~= "\n" and last_chunk ~= "\r" then
break
end
sanitized_chunks[#sanitized_chunks] = nil
end
if #sanitized_chunks > 0 and sanitized_chunks[#sanitized_chunks] == "," then
sanitized_chunks[#sanitized_chunks] = nil
end
end
while character_position <= content_length do
local current_character = manifest_content:sub(character_position, character_position)
if inside_string_literal then
sanitized_chunks[#sanitized_chunks + 1] = current_character
if current_character == "\\" and character_position < content_length then
-- Preserve escaped characters verbatim so escape sequences are not split.
sanitized_chunks[#sanitized_chunks + 1] = manifest_content:sub(character_position + 1, character_position + 1)
character_position = character_position + 2
else
if current_character == '"' then
inside_string_literal = false
end
character_position = character_position + 1
end
else
local character_pair = manifest_content:sub(character_position, character_position + 1)
if current_character == '"' then
inside_string_literal = true
sanitized_chunks[#sanitized_chunks + 1] = current_character
character_position = character_position + 1
elseif character_pair == "//" then
local line_end_position = manifest_content:find("\n", character_position) or (content_length + 1)
character_position = line_end_position
elseif character_pair == "/*" then
local comment_end_position = manifest_content:find("%*/", character_position + 2)
if not comment_end_position then
break
end
character_position = comment_end_position + 2
elseif current_character == "]" or current_character == "}" then
trim_trailing_comma()
sanitized_chunks[#sanitized_chunks + 1] = current_character
character_position = character_position + 1
else
sanitized_chunks[#sanitized_chunks + 1] = current_character
character_position = character_position + 1
end
end
end
local manifest_data = dkjson.decode(table.concat(sanitized_chunks))
manifest_data.key = extension_key
manifest_file = assert(io.open(manifest_path, "w"))
manifest_file:write(dkjson.encode(manifest_data, { indent = true }))
manifest_file:close()
|