jtd 0.1.4 → 0.1.5

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +184 -1
  4. data/lib/jtd/version.rb +1 -1
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 146b3d6415c65ecceea66782e16e722f212c3999f6061cff3c16e167b12f2cec
4
- data.tar.gz: 7acf1d589643b11afd706b1353ccd3bb0a8fc69e652f6d08f16389c53592a580
3
+ metadata.gz: a8db19fa99563fc87cf94665d369a2ab000da1ea9b629c468476f40388587c66
4
+ data.tar.gz: 59f1124d84474309f31e17caf56a8f6cec5226a2bb842896a3777c471d67642a
5
5
  SHA512:
6
- metadata.gz: a6272fba6cde2376c0073d4ff0535fa5fc5e214b3581f046ea89092bf1eaf6da9d388bffedaf6a9c714c88f119265a2c2b478b65b749cc79a295c54b2b272456
7
- data.tar.gz: 78dc808e525698104a1a274f15a2d023e22d563e5a92864b154d1176d90606a0466e8ab70bf9bf0931608d77ba6b3574e834436f540128b47a84d8120b04e2a1
6
+ metadata.gz: 14198dced04d5adb6ea790e436291214e9541e4a8641cc86029073401ea8047f0b4487b18821f5e13e347051d9c479d6ae0ca73c40bf62d58c9250cdc928d6df
7
+ data.tar.gz: 6cb2e3273377f2fa4031db499c2679917fce041eab536913487661d3ab681f053dd84a9f561a11783890852a4c8a7e2b58b0761d7bb9d3aab7c5b21c5a01f290
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jtd (0.1.4)
4
+ jtd (0.1.5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1 +1,184 @@
1
- # jtd: JSON Validation for Ruby
1
+ # jtd: JSON Validation for Python
2
+
3
+ [![Gem](https://img.shields.io/gem/v/jtd)](https://rubygems.org/gems/jtd)
4
+
5
+ `jtd` is a Ruby implementation of [JSON Type Definition][jtd], a schema language
6
+ for JSON. `jtd` primarily gives you two things:
7
+
8
+ 1. Validating input data against JSON Typedef schemas.
9
+ 2. A Ruby representation of JSON Typedef schemas.
10
+
11
+ With this package, you can add JSON Typedef-powered validation to your
12
+ application, or you can build your own tooling on top of JSON Type Definition.
13
+
14
+ ## Installation
15
+
16
+ You can install this package with `gem`:
17
+
18
+ ```bash
19
+ gem install jtd
20
+ ```
21
+
22
+ ## Documentation
23
+
24
+ Detailed API documentation is available online at:
25
+
26
+ https://rubydoc.info/gems/jtd/JTD
27
+
28
+ For more high-level documentation about JSON Typedef in general, or JSON Typedef
29
+ in combination with Python in particular, see:
30
+
31
+ * [The JSON Typedef Website][jtd]
32
+ * ["Validating JSON in Ruby with JSON Typedef"][jtd-ruby-validation]
33
+
34
+ ## Basic Usage
35
+
36
+ > For a more detailed tutorial and guidance on how to integrate `jtd` in your
37
+ > application, see ["Validating JSON in Ruby with JSON
38
+ > Typedef"][jtd-ruby-validation] in the JSON Typedef docs.
39
+
40
+ Here's an example of how you can use this package to validate JSON data against
41
+ a JSON Typedef schema:
42
+
43
+ ```ruby
44
+ require 'jtd'
45
+
46
+ schema = JTD::Schema.from_hash({
47
+ 'properties' => {
48
+ 'name' => { 'type' => 'string' },
49
+ 'age' => { 'type' => 'uint32' },
50
+ 'phones' => {
51
+ 'elements' => {
52
+ 'type' => 'string'
53
+ }
54
+ }
55
+ }
56
+ })
57
+
58
+ # JTD::validate returns an array of validation errors. If there were no problems
59
+ # with the input, it returns an empty array.
60
+
61
+ # Outputs: []
62
+ p JTD::validate(schema, {
63
+ 'name' => 'John Doe',
64
+ 'age' => 43,
65
+ 'phones' => ['+44 1234567', '+44 2345678'],
66
+ })
67
+
68
+ # This next input has three problems with it:
69
+ #
70
+ # 1. It's missing "name", which is a required property.
71
+ # 2. "age" is a string, but it should be an integer.
72
+ # 3. "phones[1]" is a number, but it should be a string.
73
+ #
74
+ # Each of those errors corresponds to one of the errors returned by validate.
75
+
76
+ # Outputs:
77
+ #
78
+ # [
79
+ # #<struct JTD::ValidationError
80
+ # instance_path=[],
81
+ # schema_path=["properties", "name"]
82
+ # >,
83
+ # #<struct JTD::ValidationError
84
+ # instance_path=["age"],
85
+ # schema_path=["properties", "age", "type"]
86
+ # >,
87
+ # #<struct JTD::ValidationError
88
+ # instance_path=["phones", "1"],
89
+ # schema_path=["properties", "phones", "elements", "type"]
90
+ # >
91
+ # ]
92
+ p JTD::validate(schema, {
93
+ 'age' => '43',
94
+ 'phones' => ['+44 1234567', 442345678],
95
+ })
96
+ ```
97
+
98
+ ## Advanced Usage: Limiting Errors Returned
99
+
100
+ By default, `JTD::validate` returns every error it finds. If you just care about
101
+ whether there are any errors at all, or if you can't show more than some number
102
+ of errors, then you can get better performance out of `JTD::validate` using the
103
+ `max_errors` option.
104
+
105
+ For example, taking the same example from before, but limiting it to 1 error, we
106
+ get:
107
+
108
+ ```python
109
+ # Outputs:
110
+ #
111
+ # [#<struct JTD::ValidationError instance_path=[], schema_path=["properties", "name"]>]
112
+ options = JTD::ValidationOptions.new(max_errors: 1)
113
+ p JTD::validate(schema, {
114
+ 'age' => '43',
115
+ 'phones' => ['+44 1234567', 442345678],
116
+ }, options)
117
+ ```
118
+
119
+ ## Advanced Usage: Handling Untrusted Schemas
120
+
121
+ If you want to run `jtd` against a schema that you don't trust, then you should:
122
+
123
+ 1. Ensure the schema is well-formed, using the `#verify` method on
124
+ `JTD::Schema`. That will check things like making sure all `ref`s have
125
+ corresponding definitions.
126
+
127
+ 2. Call `JTD::validate` with the `max_depth` option. JSON Typedef lets you write
128
+ recursive schemas -- if you're evaluating against untrusted schemas, you
129
+ might go into an infinite loop when evaluating against a malicious input,
130
+ such as this one:
131
+
132
+ ```json
133
+ {
134
+ "ref": "loop",
135
+ "definitions": {
136
+ "loop": {
137
+ "ref": "loop"
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ The `max_depth` option tells `JTD::validate` how many `ref`s to follow
144
+ recursively before giving up and raising `JTD::MaxDepthExceededError`.
145
+
146
+ Here's an example of how you can use `jtd` to evaluate data against an untrusted
147
+ schema:
148
+
149
+ ```ruby
150
+ require 'jtd'
151
+
152
+ # validate_untrusted returns true if `data` satisfies `schema`, and false if it
153
+ # does not. Throws an error if `schema` is invalid, or if validation goes in an
154
+ # infinite loop.
155
+ def validate_untrusted(schema, data)
156
+ schema.verify()
157
+
158
+ # You should tune max_depth to be high enough that most legitimate schemas
159
+ # evaluate without errors, but low enough that an attacker cannot cause a
160
+ # denial of service attack.
161
+ options = JTD::ValidationOptions.new(max_depth: 32)
162
+ JTD::validate(schema, data, options).empty?
163
+ end
164
+
165
+ # Returns true
166
+ validate_untrusted(JTD::Schema.from_hash({ 'type' => 'string' }), 'foo')
167
+
168
+ # Returns false
169
+ validate_untrusted(JTD::Schema.from_hash({ 'type' => 'string' }), nil)
170
+
171
+ # Raises ArgumentError (invalid type: nonsense)
172
+ validate_untrusted(JTD::Schema.from_hash({ 'type' => 'nonsense' }), 'foo')
173
+
174
+ # Raises JTD::MaxDepthExceededError (max depth exceeded during JTD::validate)
175
+ validate_untrusted(JTD::Schema.from_hash({
176
+ 'definitions' => {
177
+ 'loop' => { 'ref' => 'loop' },
178
+ },
179
+ 'ref' => 'loop',
180
+ }), nil)
181
+ ```
182
+
183
+ [jtd]: https://jsontypedef.com
184
+ [jtd-ruby-validation]: https://jsontypedef.com/docs/ruby/validation
data/lib/jtd/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module JTD
2
2
  # The version of the +jtd+ gem you are using.
3
- VERSION = '0.1.4'
3
+ VERSION = '0.1.5'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jtd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ulysse Carion