graphql 1.11.8 → 1.11.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b72615f5488c1aa58c921128dd067d9f098b4617c954ac267e37efa72a9107c
4
- data.tar.gz: 4690738202ecd5d048802c80f1fc87095e0c1de4a02adcba26e88415f401908c
3
+ metadata.gz: '03288f39c878bbb9e7e0831ec3b7f5238e4063439df8f1a8a297b6d2e88798c4'
4
+ data.tar.gz: 157ad2e363c871c5fe5e13322fe5ea98aedfee77febd0c77ea092507fa11d696
5
5
  SHA512:
6
- metadata.gz: 744ca52fc03919a071013a27139112c2c18e487f333ee335ea374feaef06bb904079d4c54e0ddf088d2b5dfa345172efb3063faefa792c1c8ade38616752fa1a
7
- data.tar.gz: 90fffd6928d128f2516e4f49c9d729a26a57101683e19d0a90818c45f431bae221e4b8b1bf8d7bc374e20c8e98e3f0a0963877e818ae946f999d40942182cddd
6
+ metadata.gz: 6ab05e247b8a3a3a1d08daec2edeb20fdc29b2cf196e34a5f84fbf228da1bd5da7ce445b2972648b6ce4c74f15e6d1dfc8b2eb1fc0929dd0df2b67f2db4e73da
7
+ data.tar.gz: 4ce3349c4cd3623827d1596bfbdb9b8974a26cc5ffc5be162c1f3b6fc1fb8922d8902e166345d14afcba77f8b693607769eee2db52907b79190f6beb5ee2ece2
@@ -157,7 +157,7 @@ module GraphQL
157
157
 
158
158
  accepts_definitions \
159
159
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
160
- :validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
160
+ :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
161
161
  :orphan_types, :resolve_type, :type_error, :parse_error,
162
162
  :error_bubbling,
163
163
  :raise_definition_error,
@@ -196,7 +196,7 @@ module GraphQL
196
196
  attr_accessor \
197
197
  :query, :mutation, :subscription,
198
198
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
199
- :validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
199
+ :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
200
200
  :orphan_types, :directives,
201
201
  :query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
202
202
  :cursor_encoder,
@@ -366,7 +366,7 @@ module GraphQL
366
366
  validator_opts = { schema: self }
367
367
  rules && (validator_opts[:rules] = rules)
368
368
  validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
369
- res = validator.validate(query, timeout: validate_timeout)
369
+ res = validator.validate(query, timeout: validate_timeout, max_errors: validate_max_errors)
370
370
  res[:errors]
371
371
  end
372
372
 
@@ -951,6 +951,7 @@ module GraphQL
951
951
  schema_defn.mutation = mutation && mutation.graphql_definition
952
952
  schema_defn.subscription = subscription && subscription.graphql_definition
953
953
  schema_defn.validate_timeout = validate_timeout
954
+ schema_defn.validate_max_errors = validate_max_errors
954
955
  schema_defn.max_complexity = max_complexity
955
956
  schema_defn.error_bubbling = error_bubbling
956
957
  schema_defn.max_depth = max_depth
@@ -1286,6 +1287,19 @@ module GraphQL
1286
1287
  end
1287
1288
  end
1288
1289
 
1290
+ attr_writer :validate_max_errors
1291
+
1292
+ def validate_max_errors(new_validate_max_errors = nil)
1293
+ if new_validate_max_errors
1294
+ @validate_max_errors = new_validate_max_errors
1295
+ elsif defined?(@validate_max_errors)
1296
+ @validate_max_errors
1297
+ else
1298
+ find_inherited_value(:validate_max_errors)
1299
+ end
1300
+ end
1301
+
1302
+
1289
1303
  attr_writer :max_complexity
1290
1304
 
1291
1305
  def max_complexity(max_complexity = nil)
@@ -205,6 +205,9 @@ module GraphQL
205
205
  private
206
206
 
207
207
  def add_error(error, path: nil)
208
+ if @context.too_many_errors?
209
+ throw :too_many_validation_errors
210
+ end
208
211
  error.path ||= (path || @path.dup)
209
212
  context.errors << error
210
213
  end
@@ -193,26 +193,26 @@ module GraphQL
193
193
  if node1.name != node2.name
194
194
  errored_nodes = [node1.name, node2.name].sort.join(" or ")
195
195
  msg = "Field '#{response_key}' has a field conflict: #{errored_nodes}?"
196
- context.errors << GraphQL::StaticValidation::FieldsWillMergeError.new(
196
+ add_error(GraphQL::StaticValidation::FieldsWillMergeError.new(
197
197
  msg,
198
198
  nodes: [node1, node2],
199
199
  path: [],
200
200
  field_name: response_key,
201
201
  conflicts: errored_nodes
202
- )
202
+ ))
203
203
  end
204
204
 
205
205
  if !same_arguments?(node1, node2)
206
206
  args = [serialize_field_args(node1), serialize_field_args(node2)]
207
207
  conflicts = args.map { |arg| GraphQL::Language.serialize(arg) }.join(" or ")
208
208
  msg = "Field '#{response_key}' has an argument conflict: #{conflicts}?"
209
- context.errors << GraphQL::StaticValidation::FieldsWillMergeError.new(
209
+ add_error(GraphQL::StaticValidation::FieldsWillMergeError.new(
210
210
  msg,
211
211
  nodes: [node1, node2],
212
212
  path: [],
213
213
  field_name: response_key,
214
214
  conflicts: conflicts
215
- )
215
+ ))
216
216
  end
217
217
  end
218
218
 
@@ -7,12 +7,12 @@ module GraphQL
7
7
  dependency_map = context.dependencies
8
8
  dependency_map.cyclical_definitions.each do |defn|
9
9
  if defn.node.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
10
- context.errors << GraphQL::StaticValidation::FragmentsAreFiniteError.new(
10
+ add_error(GraphQL::StaticValidation::FragmentsAreFiniteError.new(
11
11
  "Fragment #{defn.name} contains an infinite loop",
12
12
  nodes: defn.node,
13
13
  path: defn.path,
14
14
  name: defn.name
15
- )
15
+ ))
16
16
  end
17
17
  end
18
18
  end
@@ -19,10 +19,11 @@ module GraphQL
19
19
 
20
20
  def_delegators :@query, :schema, :document, :fragments, :operations, :warden
21
21
 
22
- def initialize(query, visitor_class)
22
+ def initialize(query, visitor_class, max_errors)
23
23
  @query = query
24
24
  @literal_validator = LiteralValidator.new(context: query.context)
25
25
  @errors = []
26
+ @max_errors = max_errors || Float::INFINITY
26
27
  @on_dependency_resolve_handlers = []
27
28
  @visitor = visitor_class.new(document, self)
28
29
  end
@@ -38,6 +39,10 @@ module GraphQL
38
39
  def validate_literal(ast_value, type)
39
40
  @literal_validator.validate(ast_value, type)
40
41
  end
42
+
43
+ def too_many_errors?
44
+ @errors.length >= @max_errors
45
+ end
41
46
  end
42
47
  end
43
48
  end
@@ -22,8 +22,9 @@ module GraphQL
22
22
  # @param query [GraphQL::Query]
23
23
  # @param validate [Boolean]
24
24
  # @param timeout [Float] Number of seconds to wait before aborting validation. Any positive number may be used, including Floats to specify fractional seconds.
25
+ # @param max_errors [Integer] Maximum number of errors before aborting validation. Any positive number will limit the number of errors. Defaults to nil for no limit.
25
26
  # @return [Array<Hash>]
26
- def validate(query, validate: true, timeout: nil)
27
+ def validate(query, validate: true, timeout: nil, max_errors: nil)
27
28
  query.trace("validate", { validate: validate, query: query }) do
28
29
  can_skip_rewrite = query.context.interpreter? && query.schema.using_ast_analysis? && query.schema.is_a?(Class)
29
30
  errors = if validate == false && can_skip_rewrite
@@ -32,23 +33,26 @@ module GraphQL
32
33
  rules_to_use = validate ? @rules : []
33
34
  visitor_class = BaseVisitor.including_rules(rules_to_use, rewrite: !can_skip_rewrite)
34
35
 
35
- context = GraphQL::StaticValidation::ValidationContext.new(query, visitor_class)
36
+ context = GraphQL::StaticValidation::ValidationContext.new(query, visitor_class, max_errors)
36
37
 
37
38
  begin
38
39
  # CAUTION: Usage of the timeout module makes the assumption that validation rules are stateless Ruby code that requires no cleanup if process was interrupted. This means no blocking IO calls, native gems, locks, or `rescue` clauses that must be reached.
39
40
  # A timeout value of 0 or nil will execute the block without any timeout.
40
41
  Timeout::timeout(timeout) do
41
- # Attach legacy-style rules.
42
- # Only loop through rules if it has legacy-style rules
43
- unless (legacy_rules = rules_to_use - GraphQL::StaticValidation::ALL_RULES).empty?
44
- legacy_rules.each do |rule_class_or_module|
45
- if rule_class_or_module.method_defined?(:validate)
46
- rule_class_or_module.new.validate(context)
42
+
43
+ catch(:too_many_validation_errors) do
44
+ # Attach legacy-style rules.
45
+ # Only loop through rules if it has legacy-style rules
46
+ unless (legacy_rules = rules_to_use - GraphQL::StaticValidation::ALL_RULES).empty?
47
+ legacy_rules.each do |rule_class_or_module|
48
+ if rule_class_or_module.method_defined?(:validate)
49
+ rule_class_or_module.new.validate(context)
50
+ end
47
51
  end
48
52
  end
49
- end
50
53
 
51
- context.visitor.visit
54
+ context.visitor.visit
55
+ end
52
56
  end
53
57
  rescue Timeout::Error
54
58
  handle_timeout(query, context)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.11.8"
3
+ VERSION = "1.11.9"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.8
4
+ version: 1.11.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-12 00:00:00.000000000 Z
11
+ date: 2021-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -741,7 +741,7 @@ metadata:
741
741
  source_code_uri: https://github.com/rmosolgo/graphql-ruby
742
742
  bug_tracker_uri: https://github.com/rmosolgo/graphql-ruby/issues
743
743
  mailing_list_uri: https://tinyletter.com/graphql-ruby
744
- post_install_message:
744
+ post_install_message:
745
745
  rdoc_options: []
746
746
  require_paths:
747
747
  - lib
@@ -756,8 +756,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
756
756
  - !ruby/object:Gem::Version
757
757
  version: '0'
758
758
  requirements: []
759
- rubygems_version: 3.1.4
760
- signing_key:
759
+ rubygems_version: 3.2.22
760
+ signing_key:
761
761
  specification_version: 4
762
762
  summary: A GraphQL language and runtime for Ruby
763
763
  test_files: []