contrast-agent 6.1.2 → 6.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (220) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -3
  3. data/.simplecov +1 -0
  4. data/Rakefile +0 -27
  5. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +7 -5
  6. data/ext/cs__assess_kernel/cs__assess_kernel.c +14 -3
  7. data/ext/cs__assess_kernel/cs__assess_kernel.h +2 -0
  8. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +10 -3
  9. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +2 -1
  10. data/ext/cs__assess_regexp/cs__assess_regexp.c +9 -7
  11. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.c → cs__assess_string_interpolation/cs__assess_string_interpolation.c} +14 -3
  12. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.h → cs__assess_string_interpolation/cs__assess_string_interpolation.h} +1 -1
  13. data/ext/{cs__assess_string_interpolation26 → cs__assess_string_interpolation}/extconf.rb +0 -0
  14. data/ext/cs__common/cs__common.c +5 -4
  15. data/ext/cs__contrast_patch/cs__contrast_patch.c +3 -10
  16. data/lib/contrast/agent/assess/events/source_event.rb +16 -12
  17. data/lib/contrast/agent/assess/policy/policy_node.rb +6 -0
  18. data/lib/contrast/agent/assess/policy/propagation_method.rb +3 -41
  19. data/lib/contrast/agent/assess/policy/propagation_node.rb +8 -0
  20. data/lib/contrast/agent/assess/policy/propagator/base.rb +2 -0
  21. data/lib/contrast/agent/assess/policy/source_method.rb +2 -47
  22. data/lib/contrast/agent/assess/policy/source_node.rb +1 -0
  23. data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -1
  24. data/lib/contrast/agent/assess/policy/trigger_node.rb +8 -0
  25. data/lib/contrast/agent/assess/property/evented.rb +4 -18
  26. data/lib/contrast/agent/assess/tag.rb +19 -0
  27. data/lib/contrast/agent/at_exit_hook.rb +9 -8
  28. data/lib/contrast/agent/inventory/database_config.rb +6 -3
  29. data/lib/contrast/agent/inventory/dependency_analysis.rb +3 -2
  30. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +13 -9
  31. data/lib/contrast/agent/middleware.rb +4 -0
  32. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +27 -2
  33. data/lib/contrast/agent/patching/policy/policy.rb +5 -0
  34. data/lib/contrast/agent/patching/policy/policy_node.rb +6 -0
  35. data/lib/contrast/agent/patching/policy/trigger_node.rb +3 -0
  36. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +3 -4
  37. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -0
  38. data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
  39. data/lib/contrast/agent/protect/rule/base.rb +1 -0
  40. data/lib/contrast/agent/protect/rule/no_sqli.rb +2 -0
  41. data/lib/contrast/agent/protect/rule/xss.rb +4 -0
  42. data/lib/contrast/agent/reporting/reporter.rb +33 -17
  43. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +21 -15
  44. data/lib/contrast/agent/reporting/reporting_events/application_inventory.rb +3 -18
  45. data/lib/contrast/agent/reporting/reporting_events/application_update.rb +5 -24
  46. data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +8 -1
  47. data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +83 -16
  48. data/lib/contrast/agent/reporting/reporting_events/finding.rb +9 -3
  49. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +10 -1
  50. data/lib/contrast/agent/reporting/reporting_events/finding_event_object.rb +11 -1
  51. data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +11 -1
  52. data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +12 -1
  53. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -1
  54. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +11 -1
  55. data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +11 -1
  56. data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +11 -1
  57. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +11 -1
  58. data/lib/contrast/agent/reporting/reporting_events/library_discovery.rb +29 -32
  59. data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +18 -20
  60. data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +11 -24
  61. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +13 -6
  62. data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +10 -4
  63. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +10 -4
  64. data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +9 -0
  65. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +10 -1
  66. data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +11 -4
  67. data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -8
  68. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +2 -6
  69. data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -32
  70. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -4
  71. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -11
  72. data/lib/contrast/agent/reporting/reporting_utilities/response.rb +60 -2
  73. data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +32 -10
  74. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +1 -1
  75. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +58 -26
  76. data/lib/contrast/agent/reporting/settings/application_settings.rb +8 -23
  77. data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +27 -33
  78. data/lib/contrast/agent/reporting/settings/bot_blocker.rb +68 -0
  79. data/lib/contrast/agent/reporting/settings/code_exclusion.rb +27 -0
  80. data/lib/contrast/agent/reporting/settings/exclusion_base.rb +33 -0
  81. data/lib/contrast/agent/reporting/settings/exclusions.rb +39 -57
  82. data/lib/contrast/agent/reporting/settings/helpers.rb +56 -0
  83. data/lib/contrast/agent/reporting/settings/input_exclusion.rb +37 -0
  84. data/lib/contrast/agent/reporting/settings/ip_filter.rb +35 -0
  85. data/lib/contrast/agent/reporting/settings/keyword.rb +74 -0
  86. data/lib/contrast/agent/reporting/settings/log_enhancer.rb +65 -0
  87. data/lib/contrast/agent/reporting/settings/protect.rb +4 -2
  88. data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +62 -115
  89. data/lib/contrast/agent/reporting/settings/reaction.rb +11 -2
  90. data/lib/contrast/agent/reporting/settings/rule_definition.rb +63 -0
  91. data/lib/contrast/agent/reporting/settings/sampling.rb +10 -0
  92. data/lib/contrast/agent/reporting/settings/sanitizer.rb +38 -0
  93. data/lib/contrast/agent/reporting/settings/sensitive_data_masking.rb +9 -1
  94. data/lib/contrast/agent/reporting/settings/sensitive_data_masking_rule.rb +7 -0
  95. data/lib/contrast/agent/reporting/settings/server_features.rb +8 -0
  96. data/lib/contrast/agent/reporting/settings/syslog.rb +176 -0
  97. data/lib/contrast/agent/reporting/settings/url_exclusion.rb +42 -0
  98. data/lib/contrast/agent/reporting/settings/validator.rb +17 -0
  99. data/lib/contrast/agent/request.rb +5 -7
  100. data/lib/contrast/agent/request_context.rb +8 -13
  101. data/lib/contrast/agent/request_context_extend.rb +8 -9
  102. data/lib/contrast/agent/request_handler.rb +10 -35
  103. data/lib/contrast/agent/rule_set.rb +4 -0
  104. data/lib/contrast/agent/service_heartbeat.rb +1 -1
  105. data/lib/contrast/agent/static_analysis.rb +6 -15
  106. data/lib/contrast/agent/telemetry/base.rb +35 -35
  107. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +2 -0
  108. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +2 -0
  109. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +5 -2
  110. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +3 -0
  111. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +3 -0
  112. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions.rb +0 -1
  113. data/lib/contrast/agent/thread_watcher.rb +2 -6
  114. data/lib/contrast/agent/version.rb +1 -1
  115. data/lib/contrast/agent.rb +1 -3
  116. data/lib/contrast/api/communication/socket.rb +1 -0
  117. data/lib/contrast/api/decorators/message.rb +0 -6
  118. data/lib/contrast/api/decorators.rb +0 -3
  119. data/lib/contrast/api/dtm.pb.rb +1 -1
  120. data/lib/contrast/api/settings.pb.rb +1 -1
  121. data/lib/contrast/components/assess.rb +0 -6
  122. data/lib/contrast/components/config.rb +18 -2
  123. data/lib/contrast/config/base_configuration.rb +0 -13
  124. data/lib/contrast/config/root_configuration.rb +1 -0
  125. data/lib/contrast/config/ruby_configuration.rb +2 -9
  126. data/lib/contrast/configuration.rb +0 -2
  127. data/lib/contrast/extension/assess/eval_trigger.rb +0 -4
  128. data/lib/contrast/extension/assess/hash.rb +3 -2
  129. data/lib/contrast/extension/assess/kernel.rb +22 -0
  130. data/lib/contrast/extension/assess/marshal.rb +16 -0
  131. data/lib/contrast/extension/assess/string.rb +21 -20
  132. data/lib/contrast/framework/base_support.rb +13 -4
  133. data/lib/contrast/framework/grape/support.rb +6 -6
  134. data/lib/contrast/framework/manager.rb +7 -23
  135. data/lib/contrast/framework/manager_extend.rb +1 -1
  136. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +11 -15
  137. data/lib/contrast/framework/rails/support.rb +9 -2
  138. data/lib/contrast/framework/sinatra/support.rb +3 -2
  139. data/lib/contrast/logger/aliased_logging.rb +33 -26
  140. data/lib/contrast/utils/assess/source_method_utils.rb +0 -9
  141. data/lib/contrast/utils/lru_cache.rb +3 -0
  142. data/lib/contrast/utils/middleware_utils.rb +2 -0
  143. data/lib/contrast/utils/patching/policy/patch_utils.rb +5 -22
  144. data/lib/contrast/utils/response_utils.rb +14 -1
  145. data/lib/contrast/utils/telemetry.rb +9 -0
  146. data/lib/contrast/utils/telemetry_client.rb +7 -7
  147. data/lib/contrast/utils/telemetry_hash.rb +36 -12
  148. data/lib/contrast/utils/telemetry_identifier.rb +8 -0
  149. data/lib/contrast/utils/thread_tracker.rb +26 -9
  150. data/lib/contrast/utils/timer.rb +6 -1
  151. data/lib/contrast.rb +35 -3
  152. data/lib/protobuf/code_generator.rb +129 -0
  153. data/lib/protobuf/decoder.rb +28 -0
  154. data/lib/protobuf/deprecation.rb +117 -0
  155. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +79 -0
  156. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +360 -0
  157. data/lib/protobuf/descriptors.rb +3 -0
  158. data/lib/protobuf/encoder.rb +11 -0
  159. data/lib/protobuf/enum.rb +365 -0
  160. data/lib/protobuf/exceptions.rb +9 -0
  161. data/lib/protobuf/field/base_field.rb +380 -0
  162. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  163. data/lib/protobuf/field/bool_field.rb +64 -0
  164. data/lib/protobuf/field/bytes_field.rb +67 -0
  165. data/lib/protobuf/field/double_field.rb +25 -0
  166. data/lib/protobuf/field/enum_field.rb +56 -0
  167. data/lib/protobuf/field/field_array.rb +102 -0
  168. data/lib/protobuf/field/field_hash.rb +122 -0
  169. data/lib/protobuf/field/fixed32_field.rb +25 -0
  170. data/lib/protobuf/field/fixed64_field.rb +28 -0
  171. data/lib/protobuf/field/float_field.rb +43 -0
  172. data/lib/protobuf/field/int32_field.rb +21 -0
  173. data/lib/protobuf/field/int64_field.rb +34 -0
  174. data/lib/protobuf/field/integer_field.rb +23 -0
  175. data/lib/protobuf/field/message_field.rb +51 -0
  176. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  177. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  178. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  179. data/lib/protobuf/field/sint32_field.rb +21 -0
  180. data/lib/protobuf/field/sint64_field.rb +21 -0
  181. data/lib/protobuf/field/string_field.rb +51 -0
  182. data/lib/protobuf/field/uint32_field.rb +21 -0
  183. data/lib/protobuf/field/uint64_field.rb +21 -0
  184. data/lib/protobuf/field/varint_field.rb +77 -0
  185. data/lib/protobuf/field.rb +74 -0
  186. data/lib/protobuf/generators/base.rb +85 -0
  187. data/lib/protobuf/generators/enum_generator.rb +39 -0
  188. data/lib/protobuf/generators/extension_generator.rb +27 -0
  189. data/lib/protobuf/generators/field_generator.rb +193 -0
  190. data/lib/protobuf/generators/file_generator.rb +262 -0
  191. data/lib/protobuf/generators/group_generator.rb +122 -0
  192. data/lib/protobuf/generators/message_generator.rb +104 -0
  193. data/lib/protobuf/generators/option_generator.rb +17 -0
  194. data/lib/protobuf/generators/printable.rb +160 -0
  195. data/lib/protobuf/generators/service_generator.rb +50 -0
  196. data/lib/protobuf/lifecycle.rb +33 -0
  197. data/lib/protobuf/logging.rb +39 -0
  198. data/lib/protobuf/message/fields.rb +233 -0
  199. data/lib/protobuf/message/serialization.rb +85 -0
  200. data/lib/protobuf/message.rb +241 -0
  201. data/lib/protobuf/optionable.rb +72 -0
  202. data/lib/protobuf/tasks/compile.rake +80 -0
  203. data/lib/protobuf/tasks.rb +1 -0
  204. data/lib/protobuf/varint.rb +20 -0
  205. data/lib/protobuf/varint_pure.rb +31 -0
  206. data/lib/protobuf/version.rb +3 -0
  207. data/lib/protobuf/wire_type.rb +10 -0
  208. data/lib/protobuf.rb +91 -0
  209. data/proto/dynamic_discovery.proto +46 -0
  210. data/proto/google/protobuf/compiler/plugin.proto +183 -0
  211. data/proto/google/protobuf/descriptor.proto +911 -0
  212. data/proto/rpc.proto +71 -0
  213. data/resources/assess/policy.json +2 -11
  214. data/ruby-agent.gemspec +2 -2
  215. metadata +105 -30
  216. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +0 -30
  217. data/lib/contrast/api/decorators/application_update.rb +0 -52
  218. data/lib/contrast/api/decorators/library.rb +0 -56
  219. data/lib/contrast/api/decorators/library_usage_update.rb +0 -31
  220. data/lib/contrast/framework/platform_version.rb +0 -22
@@ -0,0 +1,504 @@
1
+ module Protobuf
2
+ module Field
3
+ module BaseFieldObjectDefinitions
4
+
5
+ class ToHashValueToMessageHashWithStringKey
6
+ def initialize(selph)
7
+ @selph = selph
8
+ @name = selph.name.to_s
9
+ end
10
+
11
+ def call(values, result)
12
+ result[@name] = @selph.value_from_values(values).to_hash_value
13
+ end
14
+ end
15
+
16
+ class BaseToMessageHashWithStringKey
17
+ def initialize(selph)
18
+ @selph = selph
19
+ @name = selph.name.to_s
20
+ end
21
+
22
+ def call(values, result)
23
+ result[@name] = @selph.value_from_values(values)
24
+ end
25
+ end
26
+
27
+ class ToHashValueToMessageHash
28
+ def initialize(selph)
29
+ @selph = selph
30
+ @name = selph.name.to_sym
31
+ end
32
+
33
+ def call(values, result)
34
+ result[@name] = @selph.value_from_values(values).to_hash_value
35
+ end
36
+ end
37
+
38
+ class BaseToMessageHash
39
+ def initialize(selph)
40
+ @selph = selph
41
+ @name = selph.name.to_sym
42
+ end
43
+
44
+ def call(values, result)
45
+ result[@name] = @selph.value_from_values(values)
46
+ end
47
+ end
48
+
49
+ class RepeatedPackedEncodeToStream
50
+ def initialize(selph)
51
+ @selph = selph
52
+ @tag_encoded = selph.tag_encoded
53
+ end
54
+
55
+ def call(value, stream)
56
+ packed_value = value.map { |val| @selph.encode(val) }.join
57
+ stream << @tag_encoded << "#{::Protobuf::Field::VarintField.encode(packed_value.size)}#{packed_value}"
58
+ end
59
+ end
60
+
61
+ class BytesEncodeToStream
62
+ def initialize(selph)
63
+ @selph = selph
64
+ @tag_encoded = selph.tag_encoded
65
+ end
66
+
67
+ def call(value, stream)
68
+ value = value.encode if value.is_a?(::Protobuf::Message)
69
+ byte_size = ::Protobuf::Field::VarintField.encode(value.bytesize)
70
+
71
+ stream << @tag_encoded << byte_size << value
72
+ end
73
+ end
74
+
75
+ class StringEncodeToStream
76
+ def initialize(selph)
77
+ @selph = selph
78
+ @tag_encoded = selph.tag_encoded
79
+ end
80
+
81
+ def call(value, stream)
82
+ new_value = "" + value
83
+ if new_value.encoding != ::Protobuf::Field::StringField::ENCODING
84
+ new_value.encode!(::Protobuf::Field::StringField::ENCODING, :invalid => :replace, :undef => :replace, :replace => "")
85
+ end
86
+
87
+ stream << @tag_encoded << ::Protobuf::Field::VarintField.encode(new_value.bytesize) << new_value
88
+ end
89
+ end
90
+
91
+ class BaseEncodeToStream
92
+ def initialize(selph)
93
+ @selph = selph
94
+ @tag_encoded = selph.tag_encoded
95
+ end
96
+
97
+ def call(value, stream)
98
+ stream << @tag_encoded << @selph.encode(value)
99
+ end
100
+ end
101
+
102
+ class RepeatedNotPackedEncodeToStream
103
+ def initialize(selph)
104
+ @selph = selph
105
+ @tag_encoded = selph.tag_encoded
106
+ end
107
+
108
+ def call(value, stream)
109
+ value.each do |val|
110
+ stream << @tag_encoded << @selph.encode(val)
111
+ end
112
+ end
113
+ end
114
+
115
+ class BaseSetMethod
116
+ def initialize(selph)
117
+ @selph = selph
118
+ @name = selph.name
119
+ end
120
+
121
+ def call(message_instance, bytes)
122
+ message_instance.set_field(@name, @selph.decode(bytes), true, @selph)
123
+ end
124
+ end
125
+
126
+ class MapSetMethod
127
+ def initialize(selph)
128
+ @selph = selph
129
+ @name = selph.name
130
+ end
131
+
132
+ def call(message_instance, bytes)
133
+ hash = message_instance[@name]
134
+ entry = @selph.decode(bytes)
135
+ # decoded value could be nil for an
136
+ # enum value that is not recognized
137
+ hash[entry.key] = entry.value unless entry.value.nil?
138
+ hash[entry.key]
139
+ end
140
+ end
141
+
142
+ class RepeatedNotPackedSetMethod
143
+ def initialize(selph)
144
+ @selph = selph
145
+ @name = selph.name
146
+ end
147
+
148
+ def call(message_instance, bytes)
149
+ message_instance[@name] << @selph.decode(bytes)
150
+ end
151
+ end
152
+
153
+ class RepeatedPackedSetMethod
154
+ def initialize(selph)
155
+ @selph = selph
156
+ @name = selph.name
157
+ @wire_type = selph.wire_type
158
+ end
159
+
160
+ def call(message_instance, bytes)
161
+ array = message_instance[@name]
162
+ stream = ::StringIO.new(bytes)
163
+
164
+ if @wire_type == ::Protobuf::WireType::VARINT
165
+ array << @selph.decode(Varint.decode(stream)) until stream.eof?
166
+ elsif @wire_type == ::Protobuf::WireType::FIXED64
167
+ array << @selph.decode(stream.read(8)) until stream.eof?
168
+ elsif @wire_type == ::Protobuf::WireType::FIXED32
169
+ array << @selph.decode(stream.read(4)) until stream.eof?
170
+ end
171
+ end
172
+ end
173
+
174
+ class RequiredMapSetField
175
+ def initialize(selph)
176
+ @selph = selph
177
+ @tag = selph.tag
178
+ @fully_qualified_name = selph.fully_qualified_name
179
+ end
180
+
181
+ def call(values, value, _ignore_nil_for_repeated, message_instance)
182
+ unless value.is_a?(Hash)
183
+ fail TypeError, <<-TYPE_ERROR
184
+ Expected map value
185
+ Got '#{value.class}' for map protobuf field #{@selph.name}
186
+ TYPE_ERROR
187
+ end
188
+
189
+ if value.empty?
190
+ values.delete(@fully_qualified_name)
191
+ message_instance._protobuf_message_unset_required_field_tags << @tag
192
+ else
193
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
194
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
195
+ values[@fully_qualified_name].replace(value)
196
+ end
197
+ end
198
+ end
199
+
200
+ class MapSetField
201
+ def initialize(selph)
202
+ @selph = selph
203
+ @tag = selph.tag
204
+ @fully_qualified_name = selph.fully_qualified_name
205
+ end
206
+
207
+ def call(values, value, _ignore_nil_for_repeated, _message_instance)
208
+ unless value.is_a?(Hash)
209
+ fail TypeError, <<-TYPE_ERROR
210
+ Expected map value
211
+ Got '#{value.class}' for map protobuf field #{@selph.name}
212
+ TYPE_ERROR
213
+ end
214
+
215
+ if value.empty?
216
+ values.delete(@fully_qualified_name)
217
+ else
218
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
219
+ values[@fully_qualified_name].replace(value)
220
+ end
221
+ end
222
+ end
223
+
224
+ class RequiredRepeatedSetField
225
+ def initialize(selph)
226
+ @selph = selph
227
+ @tag = selph.tag
228
+ @fully_qualified_name = selph.fully_qualified_name
229
+ end
230
+
231
+ def call(values, value, ignore_nil_for_repeated, message_instance)
232
+ if value.nil? && ignore_nil_for_repeated
233
+ ::Protobuf.deprecator.deprecation_warning("['#{@fully_qualified_name}']=nil", "use an empty array instead of nil")
234
+ return
235
+ end
236
+
237
+ unless value.is_a?(Array)
238
+ fail TypeError, <<-TYPE_ERROR
239
+ Expected repeated value of type '#{@selph.type_class}'
240
+ Got '#{value.class}' for repeated protobuf field #{@selph.name}
241
+ TYPE_ERROR
242
+ end
243
+
244
+ value = value.compact
245
+
246
+ if value.empty?
247
+ values.delete(@fully_qualified_name)
248
+ message_instance._protobuf_message_unset_required_field_tags << @tag
249
+ else
250
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
251
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
252
+ values[@fully_qualified_name].replace(value)
253
+ end
254
+ end
255
+ end
256
+
257
+ class RepeatedSetField
258
+ def initialize(selph)
259
+ @selph = selph
260
+ @tag = selph.tag
261
+ @fully_qualified_name = selph.fully_qualified_name
262
+ end
263
+
264
+ def call(values, value, ignore_nil_for_repeated, _message_instance)
265
+ if value.nil? && ignore_nil_for_repeated
266
+ ::Protobuf.deprecator.deprecation_warning("['#{@fully_qualified_name}']=nil", "use an empty array instead of nil")
267
+ return
268
+ end
269
+
270
+ unless value.is_a?(Array)
271
+ fail TypeError, <<-TYPE_ERROR
272
+ Expected repeated value of type '#{@selph.type_class}'
273
+ Got '#{value.class}' for repeated protobuf field #{@selph.name}
274
+ TYPE_ERROR
275
+ end
276
+
277
+ value = value.compact
278
+
279
+ if value.empty?
280
+ values.delete(@fully_qualified_name)
281
+ else
282
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
283
+ values[@fully_qualified_name].replace(value)
284
+ end
285
+ end
286
+ end
287
+
288
+ class RequiredStringSetField
289
+ def initialize(selph)
290
+ @selph = selph
291
+ @tag = selph.tag
292
+ @fully_qualified_name = selph.fully_qualified_name
293
+ end
294
+
295
+ def call(values, value, _ignore_nil_for_repeated, message_instance)
296
+ if value
297
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
298
+ values[@fully_qualified_name] = if value.is_a?(String)
299
+ value
300
+ else
301
+ @selph.coerce!(value)
302
+ end
303
+ else
304
+ values.delete(@fully_qualified_name)
305
+ message_instance._protobuf_message_unset_required_field_tags << @tag
306
+ end
307
+ end
308
+ end
309
+
310
+ class StringSetField
311
+ def initialize(selph)
312
+ @selph = selph
313
+ @tag = selph.tag
314
+ @fully_qualified_name = selph.fully_qualified_name
315
+ end
316
+
317
+ def call(values, value, _ignore_nil_for_repeated, _message_instance)
318
+ if value
319
+ values[@fully_qualified_name] = if value.is_a?(String)
320
+ value
321
+ else
322
+ @selph.coerce!(value)
323
+ end
324
+ else
325
+ values.delete(@fully_qualified_name)
326
+ end
327
+ end
328
+ end
329
+
330
+ class RequiredBaseSetField
331
+ def initialize(selph)
332
+ @selph = selph
333
+ @tag = selph.tag
334
+ @fully_qualified_name = selph.fully_qualified_name
335
+ end
336
+
337
+ def call(values, value, _ignore_nil_for_repeated, message_instance)
338
+ if value.nil?
339
+ values.delete(@fully_qualified_name)
340
+ message_instance._protobuf_message_unset_required_field_tags << @tag
341
+ else
342
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
343
+ values[@fully_qualified_name] = @selph.coerce!(value)
344
+ end
345
+ end
346
+ end
347
+
348
+ class BaseSetField
349
+ def initialize(selph)
350
+ @selph = selph
351
+ @tag = selph.tag
352
+ @fully_qualified_name = selph.fully_qualified_name
353
+ end
354
+
355
+ def call(values, value, _ignore_nil_for_repeated, _message_instance)
356
+ if value.nil?
357
+ values.delete(@fully_qualified_name)
358
+ else
359
+ values[@fully_qualified_name] = @selph.coerce!(value)
360
+ end
361
+ end
362
+ end
363
+
364
+ class BaseFieldAndPresentPredicate
365
+ def initialize(selph)
366
+ @fully_qualified_name = selph.fully_qualified_name
367
+ end
368
+
369
+ def call(values)
370
+ values[@fully_qualified_name].present?
371
+ end
372
+ end
373
+
374
+ class BoolFieldAndPresentPredicate
375
+ BOOL_VALUES = [true, false].freeze
376
+
377
+ def initialize(selph)
378
+ @fully_qualified_name = selph.fully_qualified_name
379
+ end
380
+
381
+ def call(values)
382
+ BOOL_VALUES.include?(values[@fully_qualified_name])
383
+ end
384
+ end
385
+
386
+ class BaseFieldPredicate
387
+ def initialize(selph)
388
+ @fully_qualified_name = selph.fully_qualified_name
389
+ end
390
+
391
+ def call(values)
392
+ values.key?(@fully_qualified_name)
393
+ end
394
+ end
395
+
396
+ class RepeatedFieldPredicate
397
+ def initialize(selph)
398
+ @fully_qualified_name = selph.fully_qualified_name
399
+ end
400
+
401
+ def call(values)
402
+ values.key?(@fully_qualified_name) &&
403
+ values[@fully_qualified_name].present?
404
+ end
405
+ end
406
+
407
+ class BoolFieldValueFromValues
408
+ def initialize(selph)
409
+ @selph = selph
410
+ @fully_qualified_name = selph.fully_qualified_name
411
+ end
412
+
413
+ def call(values)
414
+ values.fetch(@fully_qualified_name) { @selph.default_value }
415
+ end
416
+ end
417
+
418
+ class BoolFieldValueFromValuesForSerialization
419
+ def initialize(selph)
420
+ @selph = selph
421
+ @fully_qualified_name = selph.fully_qualified_name
422
+ end
423
+
424
+ def call(values)
425
+ values.fetch(@fully_qualified_name) { @selph.default_value }
426
+ end
427
+ end
428
+
429
+ class BaseFieldValueFromValues
430
+ def initialize(selph)
431
+ @selph = selph
432
+ @fully_qualified_name = selph.fully_qualified_name
433
+ end
434
+
435
+ def call(values)
436
+ values[@fully_qualified_name] || @selph.default_value
437
+ end
438
+ end
439
+
440
+ class BaseFieldValueFromValuesForSerialization
441
+ def initialize(selph)
442
+ @selph = selph
443
+ @fully_qualified_name = selph.fully_qualified_name
444
+ end
445
+
446
+ def call(values)
447
+ values[@fully_qualified_name] || @selph.default_value
448
+ end
449
+ end
450
+
451
+ class MapValueFromValues
452
+ def initialize(selph)
453
+ @selph = selph
454
+ @fully_qualified_name = selph.fully_qualified_name
455
+ end
456
+
457
+ def call(values)
458
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
459
+ end
460
+ end
461
+
462
+ class MapValueFromValuesForSerialization
463
+ def initialize(selph)
464
+ @selph = selph
465
+ @fully_qualified_name = selph.fully_qualified_name
466
+ @type_class = selph.type_class
467
+ end
468
+
469
+ def call(values)
470
+ value = values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
471
+
472
+ array = []
473
+ value.each do |k, v|
474
+ array << @type_class.new(:key => k, :value => v)
475
+ end
476
+
477
+ array
478
+ end
479
+ end
480
+
481
+ class RepeatedFieldValueFromValues
482
+ def initialize(selph)
483
+ @selph = selph
484
+ @fully_qualified_name = selph.fully_qualified_name
485
+ end
486
+
487
+ def call(values)
488
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
489
+ end
490
+ end
491
+
492
+ class RepeatedFieldValueFromValuesForSerialization
493
+ def initialize(selph)
494
+ @selph = selph
495
+ @fully_qualified_name = selph.fully_qualified_name
496
+ end
497
+
498
+ def call(values)
499
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
500
+ end
501
+ end
502
+ end
503
+ end
504
+ end
@@ -0,0 +1,64 @@
1
+ require 'protobuf/field/varint_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class BoolField < VarintField
6
+ ONE = 1
7
+ FALSE_ENCODE = [0].pack('C')
8
+ FALSE_STRING = "false".freeze
9
+ FALSE_VALUES = [false, FALSE_STRING].freeze
10
+ TRUE_ENCODE = [1].pack('C')
11
+ TRUE_STRING = "true".freeze
12
+ TRUE_VALUES = [true, TRUE_STRING].freeze
13
+ ACCEPTABLES = [true, false, TRUE_STRING, FALSE_STRING].freeze
14
+
15
+ ##
16
+ # Class Methods
17
+ #
18
+
19
+ def self.default
20
+ false
21
+ end
22
+
23
+ ##
24
+ # Public Instance Methods
25
+ # #
26
+
27
+ def acceptable?(val)
28
+ ACCEPTABLES.include?(val)
29
+ end
30
+
31
+ def coerce!(val)
32
+ if TRUE_VALUES.include?(val)
33
+ true
34
+ elsif FALSE_VALUES.include?(val)
35
+ false
36
+ else
37
+ fail TypeError, "Expected value of type '#{type_class}' for field #{name}, but got '#{val.class}'"
38
+ end
39
+ end
40
+
41
+ def decode(value)
42
+ value == ONE
43
+ end
44
+
45
+ def encode(value)
46
+ value ? TRUE_ENCODE : FALSE_ENCODE
47
+ end
48
+
49
+ private
50
+
51
+ ##
52
+ # Private Instance Methods
53
+ #
54
+
55
+ def define_accessor(simple_field_name, _fully_qualified_field_name)
56
+ super
57
+ message_class.class_eval do
58
+ alias_method "#{simple_field_name}?", simple_field_name
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,67 @@
1
+ require 'protobuf/wire_type'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class BytesField < BaseField
6
+
7
+ ##
8
+ # Constants
9
+ #
10
+
11
+ BYTES_ENCODING = Encoding::BINARY
12
+
13
+ ##
14
+ # Class Methods
15
+ #
16
+
17
+ def self.default
18
+ ''
19
+ end
20
+
21
+ ##
22
+ # Public Instance Methods
23
+ #
24
+
25
+ def acceptable?(val)
26
+ val.is_a?(String) || val.nil? || val.is_a?(Symbol) || val.is_a?(::Protobuf::Message)
27
+ end
28
+
29
+ def decode(bytes)
30
+ bytes.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
31
+ bytes
32
+ end
33
+
34
+ def encode(value)
35
+ value_to_encode = if value.is_a?(::Protobuf::Message)
36
+ value.encode
37
+ else
38
+ "" + value
39
+ end
40
+
41
+ value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
42
+ "#{::Protobuf::Field::VarintField.encode(value_to_encode.bytesize)}#{value_to_encode}"
43
+ end
44
+
45
+ def wire_type
46
+ ::Protobuf::WireType::LENGTH_DELIMITED
47
+ end
48
+
49
+ def coerce!(value)
50
+ case value
51
+ when String, Symbol
52
+ value.to_s
53
+ when NilClass
54
+ nil
55
+ when ::Protobuf::Message
56
+ value.dup
57
+ else
58
+ fail TypeError, "Unacceptable value #{value} for field #{name} of type #{type_class}"
59
+ end
60
+ end
61
+
62
+ def json_encode(value)
63
+ Base64.strict_encode64(value)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ require 'protobuf/field/float_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class DoubleField < FloatField
6
+
7
+ ##
8
+ # Public Instance Methods
9
+ #
10
+
11
+ def decode(bytes)
12
+ bytes.unpack('E').first
13
+ end
14
+
15
+ def encode(value)
16
+ [value].pack('E')
17
+ end
18
+
19
+ def wire_type
20
+ WireType::FIXED64
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,56 @@
1
+ require 'protobuf/field/integer_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class EnumField < IntegerField
6
+
7
+ ##
8
+ # Class Methods
9
+ #
10
+
11
+ def self.default
12
+ fail NoMethodError, "#{self}.#{__method__} must be called on an instance"
13
+ end
14
+
15
+ ##
16
+ # Public Instance Methods
17
+ #
18
+ def encode(value)
19
+ # original CSGoogle's library uses 64bits integer for negative value
20
+ ::Protobuf::Field::VarintField.encode(value.to_i & 0xffff_ffff_ffff_ffff)
21
+ end
22
+
23
+ def decode(value)
24
+ value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
25
+ value if acceptable?(value)
26
+ end
27
+
28
+ def acceptable?(val)
29
+ !type_class.fetch(val).nil?
30
+ end
31
+
32
+ def enum?
33
+ true
34
+ end
35
+
36
+ def coerce!(value)
37
+ type_class.fetch(value) || fail(TypeError, "Invalid Enum value: #{value.inspect} for #{name}")
38
+ end
39
+
40
+ private
41
+
42
+ ##
43
+ # Private Instance Methods
44
+ #
45
+
46
+ def typed_default_value
47
+ if default.is_a?(Symbol)
48
+ type_class.const_get(default)
49
+ else
50
+ type_class.fetch(default) || type_class.enums.first
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+ end