dns_json 0.1.0 → 0.2.0

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: d8cd792f367a5afca6685d1739ba086f7922090bfca844c6802e7a8e551bc09d
4
- data.tar.gz: 6b2b2bbce0fd2d6fc2046d3ac2c6e6f6802588b7b138d08564b92c292fd7b6d7
3
+ metadata.gz: b29b6137d69056ed0139b7941615de79f65389671d83ecbb75bd6187596e556f
4
+ data.tar.gz: 294615c14a872f89a884c156615c61987c1607732f1aa08b586d3cfd10c65478
5
5
  SHA512:
6
- metadata.gz: 8a161dca28081a7f9fe94c9706692efdc28910796325409352c576d2342ed3b51ae68ad45b6f5412b8024a4e20585d18b2c69275014ea7f5c05fa96594bebe78
7
- data.tar.gz: 901c4e8ea33b37b6cdd94fa6999fb994f2c95998a41c4d1a1bbc45914e7733637b5aac571b825472ca98b139db7739f0869d8120485f6193fb76f2c547881a32
6
+ metadata.gz: 1d0680b62186f09a057844bca21f5f84837a8415b7714d6d307d8e7f68d9c497525d87e5b642a89fe2ebf2c4072e7c013a13b54a99dfc14cdf334190606d5110
7
+ data.tar.gz: 2285cd145074cad2fe596198b599ea8640b11077ca36fe396dd3eb3ef7b89e2e7f166b37e700169d8ca70584c980a35a3e261132fe1fdea2eab9b60951151eca
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 - 2026-10-12
4
+
5
+ - Preserve validation mode and resource limits when accessing a pair's query or response message.
6
+ - Preserve the caller's timestamp timezone when reading wire data, including frozen timestamps.
7
+
3
8
  ## 0.1.0 - 2026-10-12
4
9
 
5
10
  Initial release.
data/README.md CHANGED
@@ -1,22 +1,59 @@
1
- # dns_json
1
+ <h1 align="center">dns_json</h1>
2
2
 
3
- Read and write DNS messages as [RFC 8427](https://www.rfc-editor.org/rfc/rfc8427) JSON, including malformed packets used for diagnostics. Ruby 3.3+; CRuby, JRuby and TruffleRuby. No dependency on the other JSON format gems.
3
+ <p align="center">DNS wire messages and RFC 8427 JSON, with malformed-packet diagnostics.</p>
4
+
5
+ <p align="center">
6
+ <a href="https://rubygems.org/gems/dns_json"><img src="https://img.shields.io/gem/v/dns_json" alt="Gem version"></a>
7
+ <a href="https://github.com/ydah/dns_json/actions/workflows/main.yml"><img src="https://github.com/ydah/dns_json/actions/workflows/main.yml/badge.svg?branch=main" alt="CI"></a>
8
+ <a href="https://www.ruby-lang.org/"><img src="https://img.shields.io/badge/Ruby-%3E%3D%203.3-CC342D?logo=ruby&amp;logoColor=white" alt="Ruby 3.3 or later"></a>
9
+ <a href="LICENSE.txt"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License"></a>
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="#installation">Installation</a> &middot;
14
+ <a href="#quick-start">Quick start</a> &middot;
15
+ <a href="#wire-reconstruction-and-names">Wire reconstruction and names</a> &middot;
16
+ <a href="#development">Development</a> &middot;
17
+ <a href="#license">License</a>
18
+ </p>
19
+
20
+ Read and write DNS messages as [RFC 8427](https://www.rfc-editor.org/rfc/rfc8427) JSON, including malformed packets used for diagnostics.
21
+
22
+ ## Features
23
+
24
+ - Decode DNS wire messages, inspect diagnostics, and preserve original packet bytes.
25
+ - Build structured messages with RFC RDATA fields, output profiles, and JSON text sequences.
26
+ - Bound parsing and validation without performing DNS resolution.
27
+
28
+ ## Installation
29
+
30
+ Add the gem to your Gemfile:
4
31
 
5
32
  ```ruby
6
- require "dns_json"
33
+ gem "dns_json"
34
+ ```
7
35
 
8
- message = DNSJSON.from_wire(packet_bytes, date: Time.now)
9
- message.malformed? # true when wire diagnostics were collected
10
- message.problems # DNSJSON::Problem objects with byte offset and reason
11
- message.to_json(profile: DNSJSON::Profile::LOGGING)
12
- DNSJSON.parse(message.to_json).to_wire == packet_bytes # true
36
+ Then run `bundle install`.
37
+
38
+ Requires Ruby 3.3 or later and `json` 2.19.4 or later, below version 4. CI tests CRuby, JRuby, and TruffleRuby. No other gem from this format family is required.
39
+
40
+ ## Quick start
41
+
42
+ ```ruby
43
+ require "dns_json"
13
44
 
14
45
  query = DNSJSON::Message.new({
15
46
  "ID" => 1042, "RD" => 1, "QNAME" => "service.test.",
16
47
  "QTYPE" => 28, "QCLASS" => 1
17
48
  })
18
- query.to_wire
19
- query.qname
49
+ packet_bytes = query.to_wire
50
+ message = DNSJSON.from_wire(packet_bytes, date: Time.now)
51
+
52
+ message.qname # => "service.test."
53
+ message.malformed? # => false
54
+ message.problems # => [] (malformed input reports byte offsets and reasons)
55
+ message.to_json(profile: DNSJSON::Profile::LOGGING)
56
+ DNSJSON.parse(message.to_json).to_wire == packet_bytes # => true
20
57
  ```
21
58
 
22
59
  `Message` and `RR` wrap a Hash; `[]` accesses any member and `to_h` returns a deep copy. Unknown extension members survive the default JSON roundtrip. All RFC members are optional. `parse(..., strict: false)` retains invalid values and provides `warnings` with JSON Pointers; serialization validates strictly. JSON input and output use ASCII, with escaped Unicode in string values. Duplicate object keys are rejected on both json 2.x and 3.x.
@@ -64,24 +101,28 @@ Sequence readers process input incrementally, skip malformed elements by default
64
101
 
65
102
  Limits are configurable on `parse`, `from_wire`, and model construction: `max_bytes: 65_535`, `max_records: 4096`, `max_pointers: 128`, `max_json_bytes: 4_194_304`, `max_depth: 32`. Limits raise `LimitError`; reaching the record or pointer bound while decoding wire data instead returns a malformed message and preserves the original bytes. A JSON sequence has a per-element size bound.
66
103
 
67
- ## Development and release
104
+ ## Development
68
105
 
69
106
  ```sh
70
107
  bundle install
71
108
  bundle exec rake test
72
109
  COVERAGE=1 bundle exec rake test
73
- bundle exec rubocop
74
110
  bundle exec rbs -I sig validate
75
111
  bundle exec ruby script/benchmark.rb
76
- python3 -m venv tmp/interop/venv
77
- tmp/interop/venv/bin/python -m pip install --require-hashes -r script/interop-requirements.txt
78
- bundle exec ruby script/interop.rb
79
112
  ```
80
113
 
81
114
  RFC text, extracted examples and notices are downloaded only into ignored `tmp/`. No RFC excerpts, fixtures or third-party implementation source are distributed in Git or the gem. `script/sources.json` pins SHA-256 checksums; fixture generation tests §5.1, §5.2 and its rrSet alternative. The malformed optional fragment examples in §5.1 are not standalone JSON documents; equivalent combinations are covered by independently authored tests. `data/*.yml` contains independently maintained property/RDATA metadata and IANA type identifier facts. Run `script/update_registry.rb` to check the pinned registry; audit a new source and update the checksum before `--write`.
82
115
 
83
- Tests include all RDATA forms, a Ruby `resolv` oracle, pinned dnspython comparison, random packets and names, truncation, pointer loops, resource bounds, and JSON validation. CI covers supported CRuby versions plus head, JRuby and TruffleRuby on Ubuntu/macOS, json 2/3, coverage, lint, RBS and interoperability. dnspython and miekg/dns were reviewed as independent implementations; only dnspython is used in the external oracle.
116
+ Tests include all RDATA forms, a Ruby standard-library `resolv` oracle, random packets and names, truncation, pointer loops, resource bounds, and JSON validation. CI covers supported CRuby versions plus head, JRuby and TruffleRuby on Ubuntu/macOS, json 2/3, coverage, syntax checks, RBS and standard-library interoperability.
84
117
 
85
118
  A `v*` tag runs `.github/workflows/release.yml` with the GitHub environment `release`, validates/builds the gem, publishes through RubyGems Trusted Publishing, then creates the GitHub release from CHANGELOG. Initial RubyGems publication and Trusted Publishing setup require the owner's action before tagging.
86
119
 
120
+ ## Contributing
121
+
122
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/ydah/dns_json/issues). See [Development](#development) for the checks to run before submitting a change. Report security vulnerabilities privately as described in [SECURITY.md](SECURITY.md).
123
+
124
+ ## License
125
+
87
126
  MIT; see [LICENSE.txt](LICENSE.txt).
127
+
128
+ Additional dependencies must offer the MIT license, including development and comparison tools. The Ruby runtime and its standard libraries are exceptions to this policy. Reference documents and registry facts are test/specification inputs, not dependency implementations. See [implementation provenance](docs/provenance.md) for the scope and limits of the source audit.
data/SECURITY.md CHANGED
@@ -7,3 +7,5 @@ Treat captured DNS packets as untrusted. The reader bounds packet length, record
7
7
  This library performs no network requests during use, DNS resolution, DNSSEC validation, or packet transmission. JSON fields can intentionally disagree. `messageOctetsHEX` takes precedence over all other wire representations. Do not authorize a packet using one representation and then transmit another.
8
8
 
9
9
  The privacy profile excludes raw HEX, additional records (including EDNS Client Subnet), message identifiers, comments and unknown metadata. It retains query names and answer addresses and therefore is not an anonymizer. Apply your own retention and access policy.
10
+
11
+ Dependency changes must satisfy the MIT-only additional-dependency policy. The Ruby runtime and standard libraries are excepted. Consult the actual license files as well as package metadata; do not infer implementation provenance from packaging exclusions.
@@ -12,6 +12,7 @@ module DNSJSON
12
12
  raise ValidationError, "expected an object" unless data.is_a?(Hash)
13
13
 
14
14
  @limits = DNSJSON.validate_limits(limits)
15
+ @strict = strict
15
16
  @data = DNSJSON.copy(data)
16
17
  @problems = problems.freeze
17
18
  @warnings = validate
@@ -112,8 +113,8 @@ module DNSJSON
112
113
  super(data, **)
113
114
  end
114
115
 
115
- def query = self["queryMessage"] && Message.new(self["queryMessage"])
116
- def response = self["responseMessage"] && Message.new(self["responseMessage"])
116
+ def query = self["queryMessage"] && Message.new(self["queryMessage"], strict: @strict, **@limits)
117
+ def response = self["responseMessage"] && Message.new(self["responseMessage"], strict: @strict, **@limits)
117
118
  def to_wire = raise(ConversionError, "select the query or response before writing wire data")
118
119
  end
119
120
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DnsJson
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -49,7 +49,7 @@ module DNSJSON
49
49
  if date
50
50
  raise ArgumentError, "date must be a nonnegative Time" unless date.is_a?(Time) && date.to_f >= 0
51
51
 
52
- @data["dateString"] = date.utc.iso8601(6)
52
+ @data["dateString"] = date.getutc.iso8601(6)
53
53
  @data["dateSeconds"] = date.to_f
54
54
  end
55
55
  Message.new(@data, problems: @problems, **@limits)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dns_json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada
@@ -77,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
77
  - !ruby/object:Gem::Version
78
78
  version: '0'
79
79
  requirements: []
80
- rubygems_version: 4.0.16
80
+ rubygems_version: 3.6.9
81
81
  specification_version: 4
82
82
  summary: Read and write DNS messages as RFC 8427 JSON
83
83
  test_files: []