canon 0.3.110 → 0.3.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 831a2d23d844114132e9a234a4e1452f08aacc36ef0947d80c7100358bbbe209
4
- data.tar.gz: ff423e64f21b9e5e6c93694c124fc404b95e31ad5b4ed3162262c62023bd5c35
3
+ metadata.gz: afbb918c5dd097f911cfb587efa51b493ceed18976086f141f54373a8ab2c277
4
+ data.tar.gz: d6ef44bf2617820a71df1ec06b69e50a8436ee4879714f3fe3c9bf070fad8782
5
5
  SHA512:
6
- metadata.gz: 35762c78b2ba5bd8090cb799566ecabec4d863bd956c27c0a9119bf8025cda2bad8d49f9a93b4242ece7bfc5de7e8ef5a939bce5e3f955e46af925857379e704
7
- data.tar.gz: 4b932b9b03940bc536887cbf4a750ce265b2992afc775b446ea9a56b675d23f52724b7b7a6f710ae3258a4c5e73c69bfc01bd67b56087554ca0a3c47a5f35343
6
+ metadata.gz: 1f5a7911c15b91176afd697b75e01836f7aec79363df4f79bc504d79d5ae307ec0432151c6cde2ada42071ad95c97bcde03b6e265d23b6ff512e8cf663c5a95a
7
+ data.tar.gz: 4b35e4166db83dfc545a55c3f89093e09dc1f7d7e1d5b591f1306fac6b49bb7ce0346810fa4484fde9bcbd264dd34f0b5dec0d4d5a66869a2061d54e90afaac1
@@ -9,6 +9,14 @@ module Canon
9
9
  def self.format(json)
10
10
  parsed = parse(json)
11
11
  JSON.pretty_generate(sort_json_keys(parsed))
12
+ rescue JSON::GeneratorError => e
13
+ # overflow numbers parse to ±Infinity, which JSON cannot
14
+ # represent: the rejection is canon's, so raise own error
15
+ # (the i_number_real_*_overflow corpus family)
16
+ raise Canon::ValidationError.new(
17
+ "JSON cannot represent #{e.message[/\S+/]}: number out of range",
18
+ format: :json,
19
+ )
12
20
  end
13
21
 
14
22
  def self.parse(json)
@@ -25,9 +25,14 @@ module Canon
25
25
  when Hash
26
26
  # Single pass: sorted keys once, one rebuilt hash (the
27
27
  # transform_values + sort.to_h form rebuilt every container
28
- # twice).
28
+ # twice). YAML mapping keys are heterogeneous by nature
29
+ # (strings, symbols, integers, nil, complex collections) —
30
+ # the canonical order is the TOTAL order over [class, to_s];
31
+ # homogeneous String keys sort exactly as before.
29
32
  sorted = {}
30
- obj.keys.sort.each { |key| sorted[key] = sort_yaml_keys(obj[key]) }
33
+ obj.keys.sort_by { |key| [key.class.name, key.to_s] }.each do |key|
34
+ sorted[key] = sort_yaml_keys(obj[key])
35
+ end
31
36
  sorted
32
37
  when Array
33
38
  obj.map { |item| sort_yaml_keys(item) }
@@ -18,6 +18,15 @@ module Canon
18
18
  def self.validate!(input)
19
19
  return if input.nil?
20
20
  return if input.is_a?(Hash) || input.is_a?(Array) # Already parsed
21
+ # The malformed-bytes corpus (JSONTestSuite n_*) carries
22
+ # invalid UTF-8: strip/compare would raise
23
+ # Encoding::CompatibilityError instead of a validation error
24
+ unless input.valid_encoding?
25
+ raise Canon::ValidationError.new(
26
+ "invalid byte sequence in #{input.encoding}",
27
+ format: :json,
28
+ )
29
+ end
21
30
  return if input.strip.empty?
22
31
 
23
32
  Canon::JsonParsing.parse(input)
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.3.110"
4
+ VERSION = "0.3.112"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.110
4
+ version: 0.3.112
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-22 00:00:00.000000000 Z
11
+ date: 2026-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs