Diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Hold the avatar stub checks to an absolute hash
The stub mode checks only compared hashes with each other, and the
stand-in digest took any algorithm name, so md5, a misspelt sha256 or
hex in capitals passed everywhere luaossl is missing, which is every
machine here. The comparisons also passed with no hash found on either
side.
| -rw-r--r-- | tests/extensions/harness.lua | 5 | |
| -rw-r--r-- | tests/extensions/test-email-avatar.lua | 30 |
2 files changed, 28 insertions, 7 deletions
diff --git a/tests/extensions/harness.lua b/tests/extensions/harness.lua index 78e491e..5084ab4 100644 --- a/tests/extensions/harness.lua +++ b/tests/extensions/harness.lua @@ -201,10 +201,13 @@ local function fake_digest_bytes(text) return table.concat(bytes) end --- The slice of the luaossl digest interface the avatar filters use. +-- The slice of the luaossl digest interface the avatar filters use. Both +-- services document SHA-256, so the stand-in refuses any other algorithm. function harness.stub_digest() preload("openssl.digest", { new = function(algorithm) + assert(algorithm == "sha256", + "the avatar filters hash with sha256, not " .. tostring(algorithm)) return { final = function(self, text) return fake_digest_bytes(algorithm .. "\0" .. text) diff --git a/tests/extensions/test-email-avatar.lua b/tests/extensions/test-email-avatar.lua index 40375c8..5929634 100644 --- a/tests/extensions/test-email-avatar.lua +++ b/tests/extensions/test-email-avatar.lua @@ -14,7 +14,7 @@ local script = arg[1] local mode = h.mode("stub", "missing", "real") local base_url = "https://gravatar.com/avatar/" -if script:find("libravatar", 1, true) then +if script:match("[^/]*$"):find("libravatar", 1, true) then base_url = "https://seccdn.libravatar.org/avatar/" end @@ -44,9 +44,14 @@ if mode == "missing" then h.finish() end +local prefix = base_url:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") + +local function hash_in(attribute, output) + return output:match(attribute .. "='" .. prefix .. "([0-9a-f]+)%?") +end + local function hash_of(output) - local prefix = base_url:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") - return output:match("src='" .. prefix .. "(%x+)%?") + return hash_in("src", output) end local out, ret = render("<author@example.com>", "A U Thor") @@ -61,17 +66,22 @@ h.contains("the fetch carries no Referer", out, "referrerpolicy='no-referrer'") h.contains("the name follows the icon", out, "> A U Thor") h.equals("close answers zero", ret, 0) h.check("the hash is hex", hash_of(out) ~= nil) +h.equals("the dense image is of the same address", hash_in("srcset", out), hash_of(out)) +if mode == "stub" then + h.equals("the hash is of the bare address in two hex digits a byte", hash_of(out), + "8318f94a3e09d48151cb849a783e6895") +end -- The service hashes the trimmed lowercase address, so every spelling of one -- address has to reach it as the same hash. local plain = hash_of(render("author@example.com", "x")) local wrapped = hash_of(render("<author@example.com>", "x")) local shouting = hash_of(render(" <AUTHOR@Example.COM> ", "x")) -h.check("angle brackets do not change the hash", plain == wrapped) +h.check("angle brackets do not change the hash", plain ~= nil and plain == wrapped) h.check("case and padding do not change the hash", plain == shouting) local other = hash_of(render("other@example.com", "x")) -h.check("a different address hashes differently", plain ~= other) +h.check("a different address hashes differently", other ~= nil and plain ~= other) out = render(nil, "A U Thor") h.equals("no address draws no icon", out, "A U Thor") @@ -85,6 +95,11 @@ h.equals("empty angle brackets draw no icon", out, "A U Thor") out = h.run({ "<author@example.com>", "commit" }, { "A U ", "Thor" }) h.contains("the name is buffered across writes", out, "> A U Thor") +-- cgit hands the name over already escaped. +out = render("<author@example.com>", "A & B") +h.contains("a name keeps the escaping cgit gave it", out, "> A & B") +h.excludes("and is not escaped again", out, "&amp;") + -- A commit can carry any bytes in its address, and a log page runs the -- filter once per row, so the trim has to stay linear in a run of spaces. local started = os.clock() @@ -95,9 +110,12 @@ started = os.clock() render(string.rep("<", 40000), "x") h.check("a long run of open brackets is unwrapped quickly", os.clock() - started < 0.5) -h.check("the outermost brackets are the ones taken off", +h.check("text around the brackets is dropped", hash_of(render("x <author@example.com> y", "x")) == plain) +local reversed = hash_of(render("a>b<c", "x")) +h.check("a close before the open unwraps nothing", reversed ~= nil and reversed ~= plain) + if mode == "real" then out = render("test@example.com", "x") h.equals("a known address hashes to its sha256", hash_of(out), |
