json_p3 0.4.0 → 0.4.1

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: db1ec71125b99bc877ba9856434a65e3f8e1c11a48b9566443c3b1a8b6860169
4
- data.tar.gz: ad176fdda64b4f741e9f86ab48d4c8e3ccd767187fc0fc0fe28a4e6967a071d2
3
+ metadata.gz: c045dc201d7af17b4292488327d4bd01fbba11454df29c9ec78e344a1c6f3ea3
4
+ data.tar.gz: c10613058ceafbf844d39a0114be75255ae453aa0f78d0d422fac864d749f364
5
5
  SHA512:
6
- metadata.gz: 3b153a665f534891e1ed1976ca6c180cd1c2427786b9f7b74fcea1953d7337135db669b3541d5eaba7fd2829dbd6c94e6c36236a4a6c6221d1bd5c0ac45f5a04
7
- data.tar.gz: 52303daa1cd27c3f3ed7187949f6b9a2cf2c95483e61cd8cf7ced438f5511ad9067f39496b1fe53a85932a3de2be15ebfa2c791fdbc9002aceb0c85395c04839
6
+ metadata.gz: c04571664ae937194618544cb6aac078d91519fa6cd750e355f20d4c7a9ed9056880a9ba91fbc856475baec508ee2e779939ef6ccfeff9d9963a32f9ccf52ad2
7
+ data.tar.gz: 6232640619d2d65acebd920a1a3d19b77bc194b4b639b46cea9e44abb23d852f09e5eb85c004e5dc6e1aec3dd21ad2c36dabe7a59677cedeb8b776a256d375bf
checksums.yaml.gz.sig CHANGED
Binary file
data/.rubocop.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  require:
2
2
  - rubocop-minitest
3
3
  - rubocop-rake
4
+
5
+ plugins:
4
6
  - rubocop-performance
5
7
 
6
8
  AllCops:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.4.1] - 2025-03-18
2
+
3
+ - Fixed `JSONPathSyntaxError` claiming "unbalanced parentheses" when the query has balanced brackets.
4
+
1
5
  ## [0.4.0] - 2025-02-10
2
6
 
3
7
  - Added `JSONP3.find_enum`, `JSONP3::JSONPathEnvironment.find_enum` and `JSONP3::JSONPath.find_enum`. `find_enum` is like `find`, but returns an Enumerable (usually an Enumerator) of `JSONPathNode` instances instead of a `JSONPathNodeList`. `find_enum` can be more efficient for some combinations of query and data, especially for large data and recursive queries.
data/README.md CHANGED
@@ -36,7 +36,7 @@ We follow <a href="https://datatracker.ietf.org/doc/html/rfc9535">RFC 9535</a> s
36
36
  Add `'json_p3'` to your Gemfile:
37
37
 
38
38
  ```
39
- gem 'json_p3', '~> 0.2.1'
39
+ gem 'json_p3', '~> 0.4.0'
40
40
  ```
41
41
 
42
42
  Or
data/lib/json_p3/lexer.rb CHANGED
@@ -20,6 +20,12 @@ module JSONP3 # rubocop:disable Style/Documentation
20
20
  tokens.last)
21
21
  end
22
22
 
23
+ unless lexer.bracket_stack.empty?
24
+ ch, index = *lexer.bracket_stack.last
25
+ msg = "unbalanced brackets"
26
+ raise JSONPathSyntaxError.new(msg, Token.new(:token_error, ch, index, query, message: msg))
27
+ end
28
+
23
29
  tokens
24
30
  end
25
31
 
@@ -33,11 +39,12 @@ module JSONP3 # rubocop:disable Style/Documentation
33
39
  S_ESCAPES = Set["b", "f", "n", "r", "t", "u", "/", "\\"].freeze
34
40
 
35
41
  # @dynamic tokens
36
- attr_reader :tokens
42
+ attr_reader :tokens, :bracket_stack
37
43
 
38
44
  def initialize(query)
39
45
  @filter_depth = 0
40
- @paren_stack = []
46
+ @func_call_stack = []
47
+ @bracket_stack = []
41
48
  @tokens = []
42
49
  @start = 0
43
50
  @query = query.freeze
@@ -135,6 +142,7 @@ module JSONP3 # rubocop:disable Style/Documentation
135
142
  emit(:token_double_dot, "..")
136
143
  :lex_descendant_segment
137
144
  when "["
145
+ @bracket_stack << ["[", @start]
138
146
  emit(:token_lbracket, "[")
139
147
  :lex_inside_bracketed_segment
140
148
  else
@@ -157,6 +165,7 @@ module JSONP3 # rubocop:disable Style/Documentation
157
165
  emit(:token_wild, "*")
158
166
  :lex_segment
159
167
  when "["
168
+ @bracket_stack << ["[", @start]
160
169
  emit(:token_lbracket, "[")
161
170
  :lex_inside_bracketed_segment
162
171
  else
@@ -208,6 +217,13 @@ module JSONP3 # rubocop:disable Style/Documentation
208
217
 
209
218
  case c
210
219
  when "]"
220
+ if @bracket_stack.empty? || @bracket_stack.last.first != "["
221
+ backup
222
+ error "unbalanced brackets"
223
+ return nil
224
+ end
225
+
226
+ @bracket_stack.pop
211
227
  emit(:token_rbracket, "]")
212
228
  return :lex_segment
213
229
  when ""
@@ -251,17 +267,13 @@ module JSONP3 # rubocop:disable Style/Documentation
251
267
  return nil
252
268
  when "]"
253
269
  @filter_depth -= 1
254
- if @paren_stack.length == 1
255
- error "unbalanced parentheses"
256
- return nil
257
- end
258
270
  backup
259
271
  return :lex_inside_bracketed_segment
260
272
  when ","
261
273
  emit(:token_comma, ",")
262
274
  # If we have unbalanced parens, we are inside a function call and a
263
275
  # comma separates arguments. Otherwise a comma separates selectors.
264
- next if @paren_stack.length.positive?
276
+ next if @func_call_stack.length.positive?
265
277
 
266
278
  @filter_depth -= 1
267
279
  return :lex_inside_bracketed_segment
@@ -270,17 +282,25 @@ module JSONP3 # rubocop:disable Style/Documentation
270
282
  when '"'
271
283
  return :lex_double_quoted_string_inside_filter_expression
272
284
  when "("
285
+ @bracket_stack << ["(", @start]
273
286
  emit(:token_lparen, "(")
274
287
  # Are we in a function call? If so, a function argument contains parens.
275
- @paren_stack[-1] += 1 if @paren_stack.length.positive?
288
+ @func_call_stack[-1] += 1 if @func_call_stack.length.positive?
276
289
  when ")"
290
+ if @bracket_stack.empty? || @bracket_stack.last.first != "("
291
+ backup
292
+ error "unbalanced brackets"
293
+ return nil
294
+ end
295
+
296
+ @bracket_stack.pop
277
297
  emit(:token_rparen, ")")
278
298
  # Are we closing a function call or a parenthesized expression?
279
- if @paren_stack.length.positive?
280
- if @paren_stack[-1] == 1
281
- @paren_stack.pop
299
+ if @func_call_stack.length.positive?
300
+ if @func_call_stack[-1] == 1
301
+ @func_call_stack.pop
282
302
  else
283
- @paren_stack[-1] -= 1
303
+ @func_call_stack[-1] -= 1
284
304
  end
285
305
  end
286
306
  when "$"
@@ -359,8 +379,9 @@ module JSONP3 # rubocop:disable Style/Documentation
359
379
  end
360
380
  # Function name
361
381
  # Keep track of parentheses for this function call.
362
- @paren_stack << 1
382
+ @func_call_stack << 1
363
383
  emit :token_function
384
+ @bracket_stack << ["(", @start]
364
385
  self.next
365
386
  ignore # move past LPAREN
366
387
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSONP3
4
- VERSION = "0.4.0"
4
+ VERSION = "0.4.1"
5
5
  end
data/sig/json_p3.rbs CHANGED
@@ -432,6 +432,8 @@ module JSONP3
432
432
 
433
433
  @paren_stack: Array[Integer]
434
434
 
435
+ @bracket_stack: Array[Array[untyped]]
436
+
435
437
  @tokens: Array[Token]
436
438
 
437
439
  @start: Integer
@@ -451,6 +453,9 @@ module JSONP3
451
453
  # @dynamic tokens
452
454
  attr_reader tokens: Array[Token]
453
455
 
456
+ # @dynamic tokens
457
+ attr_reader bracket_stack: Array[Array[untyped]]
458
+
454
459
  def initialize: (String query) -> void
455
460
 
456
461
  def run: () -> void
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_p3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Prior
@@ -36,7 +36,7 @@ cert_chain:
36
36
  6dM18fnfBc3yA4KI7AO8UAmRkTscMYV6f/K4YZR6ZYCNWRpY7rkg+arhf05aoSQf
37
37
  vn9bO1bzwdnG
38
38
  -----END CERTIFICATE-----
39
- date: 2025-02-10 00:00:00.000000000 Z
39
+ date: 2025-03-18 00:00:00.000000000 Z
40
40
  dependencies: []
41
41
  description: JSONPath following RFC 9535
42
42
  email:
metadata.gz.sig CHANGED
Binary file