curlybars 1.16.1.pre.2 → 1.16.1.pre.3
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 +4 -4
- data/lib/curlybars/method_whitelist.rb +11 -4
- data/lib/curlybars/rendering_support.rb +1 -1
- data/lib/curlybars/serialization_guard.rb +35 -0
- data/lib/curlybars/version.rb +1 -1
- data/lib/curlybars.rb +9 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e8152eb9d4e5789fce89e656283b0ae7be78799bafcd9755c99d793674a01d9a
|
|
4
|
+
data.tar.gz: 57102435a47d352a31c16d994e36bd61436b777e0e98409355bc31161045a44d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 797b775e410fff90804ecfad939a0f31add15dc199a4b3221dba6ab4d9ee165134b07c40b90d6e16ea87f331ee80226d9ab0ae28823c8508a0dd7c8c5671a57f
|
|
7
|
+
data.tar.gz: 5b2f6719689b4c047d3fa8a0b31dccd92457d5147eb40a0092331eb7b2f349297bdebd0b15b04702d0808bf154b6bbe69f9c2a7a83ddc71df80aae2fa3dbce0b
|
|
@@ -47,8 +47,8 @@ module Curlybars
|
|
|
47
47
|
|
|
48
48
|
contextual_block&.call(context, schema_adder)
|
|
49
49
|
|
|
50
|
-
schema = all_methods_without_type.
|
|
51
|
-
|
|
50
|
+
schema = all_methods_without_type.to_h do |method|
|
|
51
|
+
[method, nil]
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
methods_with_type_resolved = all_methods_with_type.transform_values do |type|
|
|
@@ -104,12 +104,19 @@ module Curlybars
|
|
|
104
104
|
define_method(:as_json) do |*args|
|
|
105
105
|
return @__as_json if defined?(@__as_json)
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
guard = args.first.is_a?(Hash) ? args.first[:curlybars_guard] : nil
|
|
108
|
+
guard&.enter!
|
|
109
|
+
|
|
110
|
+
@__as_json = allowed_methods.each_with_object({}) do |method, hash|
|
|
108
111
|
unless self.method(method).arity > 0
|
|
109
112
|
value = send(method)
|
|
110
|
-
|
|
113
|
+
serialized = value.equal?(self) ? "[circular reference]" : value.as_json(*args)
|
|
114
|
+
guard&.measure(serialized)
|
|
115
|
+
hash[method] = serialized
|
|
111
116
|
end
|
|
112
117
|
end
|
|
118
|
+
ensure
|
|
119
|
+
guard&.leave!
|
|
113
120
|
end
|
|
114
121
|
end
|
|
115
122
|
|
|
@@ -205,7 +205,7 @@ module Curlybars
|
|
|
205
205
|
|
|
206
206
|
eval(eval_source) # rubocop:disable Security/Eval -- eval is the established compilation pattern for the whole engine
|
|
207
207
|
rescue Curlybars::Error::Render => e
|
|
208
|
-
raise if e.id == 'render.timeout' || e.id == 'render.output_too_long'
|
|
208
|
+
raise if e.id == 'render.timeout' || e.id == 'render.output_too_long' || e.id == 'render.nesting_too_deep'
|
|
209
209
|
|
|
210
210
|
""
|
|
211
211
|
rescue StandardError
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Curlybars
|
|
2
|
+
class SerializationGuard
|
|
3
|
+
def initialize(budget:, depth_limit:)
|
|
4
|
+
@budget = budget
|
|
5
|
+
@depth_limit = depth_limit
|
|
6
|
+
@accumulated = 0
|
|
7
|
+
@depth = 0
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def enter!
|
|
11
|
+
@depth += 1
|
|
12
|
+
return unless @depth > @depth_limit
|
|
13
|
+
|
|
14
|
+
message = "Serialization nesting too deep (> #{@depth_limit})"
|
|
15
|
+
raise Curlybars::Error::Render.new('nesting_too_deep', message, nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def leave!
|
|
19
|
+
@depth -= 1
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def measure(value)
|
|
23
|
+
# Only String leaves are counted: deep-measuring every Hash/Array would
|
|
24
|
+
# mean serializing twice. This under-counts raw hash/array fields; the
|
|
25
|
+
# authoritative ceiling is still SafeBuffer#concat at the output node.
|
|
26
|
+
return unless value.is_a?(String)
|
|
27
|
+
|
|
28
|
+
@accumulated += value.bytesize
|
|
29
|
+
return unless @accumulated > @budget
|
|
30
|
+
|
|
31
|
+
message = "Output too long (> #{@budget} bytes)"
|
|
32
|
+
raise Curlybars::Error::Render.new('output_too_long', message, nil)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/curlybars/version.rb
CHANGED
data/lib/curlybars.rb
CHANGED
|
@@ -104,6 +104,14 @@ module Curlybars
|
|
|
104
104
|
finder.find(target_path, role: role)
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
+
def serialize(value)
|
|
108
|
+
guard = Curlybars::SerializationGuard.new(
|
|
109
|
+
budget: configuration.output_limit,
|
|
110
|
+
depth_limit: configuration.nesting_limit
|
|
111
|
+
)
|
|
112
|
+
value.to_json(curlybars_guard: guard)
|
|
113
|
+
end
|
|
114
|
+
|
|
107
115
|
def global_helpers_dependency_tree
|
|
108
116
|
@global_helpers_dependency_tree ||= begin
|
|
109
117
|
classes = Curlybars.configuration.global_helpers_provider_classes
|
|
@@ -147,6 +155,7 @@ module Curlybars
|
|
|
147
155
|
end
|
|
148
156
|
|
|
149
157
|
require 'curlybars/safe_buffer'
|
|
158
|
+
require 'curlybars/serialization_guard'
|
|
150
159
|
require 'curlybars/configuration'
|
|
151
160
|
require 'curlybars/rendering_support'
|
|
152
161
|
require 'curlybars/parser'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: curlybars
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.16.1.pre.
|
|
4
|
+
version: 1.16.1.pre.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Libo Cannici
|
|
@@ -123,6 +123,7 @@ files:
|
|
|
123
123
|
- lib/curlybars/railtie.rb
|
|
124
124
|
- lib/curlybars/rendering_support.rb
|
|
125
125
|
- lib/curlybars/safe_buffer.rb
|
|
126
|
+
- lib/curlybars/serialization_guard.rb
|
|
126
127
|
- lib/curlybars/template_handler.rb
|
|
127
128
|
- lib/curlybars/validation_context.rb
|
|
128
129
|
- lib/curlybars/version.rb
|