Skip to content

Commit ca263a6

Browse files
authored
Merge pull request #3992 from ruby/claude/cloudflare-error-pr-3989-a9b7cf
Read the Pagefind entry as UTF-8
2 parents b5cff3d + f17678c commit ca263a6

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

lib/search_index.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,13 @@ def index_key(lang)
8686
lang.tr("_", "-").downcase
8787
end
8888

89+
# The entry is UTF-8 no matter what locale the build runs under: Pagefind
90+
# lists the word characters it splits on in `include_characters`, and those
91+
# reach past ASCII. Build hosts that leave the locale at POSIX, Cloudflare
92+
# Pages among them, give `File.read` a US-ASCII string, and JSON.parse raises
93+
# on the first of those bytes as it converts the source to UTF-8.
8994
def read_entry
90-
JSON.parse(File.read(@entry_path))
95+
JSON.parse(File.read(@entry_path, encoding: Encoding::UTF_8))
9196
rescue Errno::ENOENT
9297
raise Error, "#{@entry_path} is missing, Pagefind wrote no index"
9398
rescue JSON::ParserError => e

test/test_search_index.rb

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,31 @@
1717
teardown_tempdir
1818
end
1919

20+
# `include_characters` is the list of characters Pagefind counts as part of a
21+
# word. It reaches past ASCII, which is what makes the entry a UTF-8 file.
2022
def write_entry(languages)
21-
File.write(@entry_path, JSON.generate({ "version" => "1.5.2", "languages" => languages }))
23+
entry = {
24+
"version" => "1.5.2",
25+
"languages" => languages,
26+
"include_characters" => ["_", "‿", "⁀", "_"],
27+
}
28+
File.write(@entry_path, JSON.generate(entry))
2229
end
2330

2431
def read_entry
25-
JSON.parse(File.read(@entry_path))
32+
JSON.parse(File.read(@entry_path, encoding: Encoding::UTF_8))
33+
end
34+
35+
# Stands in for a build host that leaves the locale at POSIX, which is what
36+
# Cloudflare Pages does.
37+
def with_default_external(encoding)
38+
original = Encoding.default_external
39+
verbose, $VERBOSE = $VERBOSE, nil
40+
Encoding.default_external = encoding
41+
yield
42+
ensure
43+
Encoding.default_external = original
44+
$VERBOSE = verbose
2645
end
2746

2847
def search_index(pagefind: SearchIndex::PAGEFIND)
@@ -148,6 +167,14 @@ def stub_pagefind(status)
148167
_(error.message).must_match(/missing index "en"/)
149168
end
150169

170+
it "reads the entry as UTF-8 whatever locale the build runs under" do
171+
write_entry({ "en" => { "hash" => "en_abc", "wasm" => "en", "page_count" => 560 } })
172+
173+
with_default_external(Encoding::US_ASCII) { search_index.apply_fallbacks }
174+
175+
_(read_entry["languages"]["bg"]["hash"]).must_equal "en_abc"
176+
end
177+
151178
it "raises when the bundle has no languages" do
152179
write_entry({})
153180

0 commit comments

Comments
 (0)