parse-stack-next 5.1.0 → 5.1.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: 772e66e343ad34518fc37221d1a838a54cccea2df2df768528d82ba47bfb5666
4
- data.tar.gz: efcac9f096ddbbedf78c3305b15094567e3f6ab94092621c263ccd428191d1c4
3
+ metadata.gz: bf1451bb2477254dffcd1758a04b44db981520e8662e34f077f34c58926b1c7b
4
+ data.tar.gz: 07165f4c4106e3d6a27a5a0a3822efcb7e8e57f9953b5f1ba2c5a4ff2975e439
5
5
  SHA512:
6
- metadata.gz: 0bb36aad589b3dbe9a447f199b817bf4af9db906a2691de3f92a655204dcfa67decf454c910b80b35269862db40dbc590ce82fe21656b91e197f6e1c59494397
7
- data.tar.gz: 5829b94978f92be9ab13fce27b4803b9c28b780ce6071be47dd1187d2ee2aeed98eb44efc5ac2f553f8de8f508be454505c68f8a76d3921f2beda47b234eb406
6
+ metadata.gz: 2fe51d5af265832b6b08053da792911b4c79db36e3dab1c3e1ec2383984c13354ee740c56587eca4a91081bdfddb0f73fe1d1cf14b5a33be85468836df95c181
7
+ data.tar.gz: 1ad6fdd0ede5db83526730cc4ae103be228085cbf2ae3819431e6f11faae4cac6b66b037a81d20fc50e2b0c375eae70eb590647fc295543b6097079d8548d408
data/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  ## parse-stack-next Changelog
2
2
 
3
+ ### 5.1.1
4
+
5
+ #### Suppress spurious className-mismatch warnings for system-class underscore aliases
6
+
7
+ Parse Server stores its built-in classes under leading-underscore names
8
+ (`_User`, `_Role`, `_Session`, `_Installation`) while the SDK and model
9
+ declarations refer to them without the underscore (`User`, `Role`, and so
10
+ on). These are the same class, but five className-mismatch warn sites
11
+ compared the two forms as raw strings, so building a server-sent pointer for
12
+ a `belongs_to :user` association (for example `Parse::Installation#user`,
13
+ added in 5.1.0) logged a pair of harmless-but-noisy warnings such as
14
+ `expected className="User", ignoring incoming className="_User"` on every
15
+ read. Autoload order contributed: when an association is declared,
16
+ `Parse::User` may not yet be registered, so the captured class name falls
17
+ back to `"User"` rather than `"_User"`.
18
+
19
+ - **FIXED**: Building a pointer whose declared class and incoming class differ
20
+ only by Parse Server's leading-underscore system prefix (`User`/`_User`,
21
+ `Role`/`_Role`, `Session`/`_Session`, `Installation`/`_Installation`) no
22
+ longer emits a className-mismatch warning. `Parse::Object.build`,
23
+ `Array#parse_objects`, the `belongs_to` getter and setter, and the
24
+ `has_many` relation builder now treat the two forms as the same class.
25
+ (`lib/parse/model/object.rb`,
26
+ `lib/parse/model/associations/belongs_to.rb`,
27
+ `lib/parse/model/associations/has_many.rb`)
28
+ - **NEW**: `Parse::Model.same_parse_class?(a, b)` returns true when two Parse
29
+ class-name strings denote the same class — string-equal, related by exactly
30
+ one Parse Server system-prefix underscore, or both resolving to the same
31
+ registered `Parse::Object` subclass (covering custom `parse_class` table
32
+ mappings). This is the canonical equality the warn sites now gate on.
33
+ (`lib/parse/model/model.rb`)
34
+ - **CHANGED**: The className-mismatch type-confusion guard is preserved. A
35
+ pointer to a genuinely different class shoved into a typed slot (for example
36
+ a `_Session` or `_Role` pointer in a `User`-typed association, whether from
37
+ hostile server JSON or mass assignment) still produces the warning, because
38
+ distinct classes — `nil`, and malformed names that differ by more than a
39
+ single system-prefix underscore such as `__User` — continue to compare
40
+ unequal. The warning is advisory: every call site builds the object from the
41
+ declared class regardless of the incoming className, so the equality check
42
+ only governs whether the mismatch is logged.
43
+
3
44
  ### 5.1.0
4
45
 
5
46
  #### `Parse::File` — URL normalization, presigned-URL stash, leak hardening
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parse-stack-next (5.1.0)
4
+ parse-stack-next (5.1.1)
5
5
  activemodel (>= 6.1, < 9)
6
6
  activesupport (>= 6.1, < 9)
7
7
  connection_pool (>= 2.2, < 4)
@@ -189,7 +189,7 @@ module Parse
189
189
  # prevents type confusion where a pointer to a different class
190
190
  # (e.g. _Session or _Role) gets shoved into a typed slot.
191
191
  incoming_class = val[Parse::Model::KEY_CLASS_NAME]
192
- if incoming_class && incoming_class != klassName
192
+ if incoming_class && !Parse::Model.same_parse_class?(incoming_class, klassName)
193
193
  warn "[#{self.class}] belongs_to :#{association_key} expected className=#{klassName.inspect}, ignoring incoming className=#{incoming_class.inspect}"
194
194
  end
195
195
  val = Parse::Object.build val, klassName, fetched_keys: nested_keys
@@ -229,7 +229,7 @@ module Parse
229
229
  nested_keys = nested_keys_for(key)
230
230
  # Always trust declared klassName over incoming hash className.
231
231
  incoming_class = val[Parse::Model::KEY_CLASS_NAME]
232
- if incoming_class && incoming_class != klassName
232
+ if incoming_class && !Parse::Model.same_parse_class?(incoming_class, klassName)
233
233
  warn "[#{self.class}] belongs_to :#{key} expected className=#{klassName.inspect}, ignoring incoming className=#{incoming_class.inspect}"
234
234
  end
235
235
  val = Parse::Object.build val, klassName, fetched_keys: nested_keys
@@ -533,7 +533,7 @@ module Parse
533
533
  # Prevents type-confusion attacks that would mark this relation
534
534
  # proxy as a different parse_class than the model declared.
535
535
  if val.is_a?(Hash) && val[Parse::Model::KEY_CLASS_NAME] &&
536
- val[Parse::Model::KEY_CLASS_NAME] != klassName &&
536
+ !Parse::Model.same_parse_class?(val[Parse::Model::KEY_CLASS_NAME], klassName) &&
537
537
  %w[Relation].include?(val["__type"])
538
538
  warn "[#{self.class}] has_many :#{key} expected className=#{klassName.inspect}, ignoring incoming className=#{val[Parse::Model::KEY_CLASS_NAME].inspect}"
539
539
  end
@@ -204,6 +204,47 @@ module Parse
204
204
  result
205
205
  end
206
206
  end
207
+
208
+ # Whether two Parse class-name strings denote the same class. This is the
209
+ # canonical equality used to suppress spurious className-mismatch warnings.
210
+ # Two names are the same class when they are string-equal, when one is the
211
+ # leading-underscore system form of the other (+User+ <-> +_User+, +Role+
212
+ # <-> +_Role+, +Installation+ <-> +_Installation+, +Session+ <->
213
+ # +_Session+), or when both resolve to the same registered +Parse::Object+
214
+ # subclass (covers custom +parse_class+ table mappings).
215
+ #
216
+ # The underscore rule is what makes the comparison correct independent of
217
+ # autoload order — at declaration time {find_class} may not yet have
218
+ # +Parse::User+ registered (so a +belongs_to :user+ captures +"User"+
219
+ # rather than +"_User"+), but the server always emits the +_User+ storage
220
+ # form, and both denote the same class. The rule matches exactly one
221
+ # system prefix underscore, so a malformed +"__User"+ is not conflated
222
+ # with +"_User"+.
223
+ #
224
+ # These warnings are an ADVISORY type-confusion signal, not the
225
+ # enforcement mechanism: every call site that consults this method builds
226
+ # the resulting object from the declared/trusted class regardless of the
227
+ # incoming className (see +Parse::Object.build+, which always uses the
228
+ # +table+ argument the caller passes). A false-positive here can therefore
229
+ # only suppress a log line — it can never route a pointer of the wrong
230
+ # class into a typed slot. Distinct classes still compare unequal (+User+
231
+ # vs +_Session+, +User+ vs +_Role+, and +nil+), so a genuinely mismatched
232
+ # pointer still surfaces in logs.
233
+ #
234
+ # @param a [String, Symbol, nil] a Parse class name.
235
+ # @param b [String, Symbol, nil] a Parse class name.
236
+ # @return [Boolean] true when both names denote the same Parse class.
237
+ def self.same_parse_class?(a, b)
238
+ return true if a == b
239
+ return false if a.nil? || b.nil?
240
+ a = a.to_s
241
+ b = b.to_s
242
+ return true if a == b
243
+ return true if (a == "_#{b}" && !b.start_with?("_")) ||
244
+ (b == "_#{a}" && !a.start_with?("_"))
245
+ ka = find_class(a)
246
+ !ka.nil? && ka == find_class(b)
247
+ end
207
248
  end
208
249
  end
209
250
 
@@ -1749,7 +1749,7 @@ module Parse
1749
1749
  className = parse_class
1750
1750
  end
1751
1751
  className ||= incoming_class
1752
- if className && incoming_class && incoming_class != className
1752
+ if className && incoming_class && !Parse::Model.same_parse_class?(incoming_class, className)
1753
1753
  warn "[Parse::Object.build] expected className=#{className.inspect}, ignoring incoming className=#{incoming_class.inspect}"
1754
1754
  end
1755
1755
  if json.is_a?(Hash) && json["error"].present? && json["code"].present?
@@ -2094,7 +2094,7 @@ class Array
2094
2094
  # Caller knows the type; warn on mismatch but always
2095
2095
  # use the declared className.
2096
2096
  incoming = m[f] || m[:className]
2097
- if incoming && incoming != className
2097
+ if incoming && !Parse::Model.same_parse_class?(incoming, className)
2098
2098
  warn "[Parse::Array#parse_objects] expected className=#{className.inspect}, ignoring incoming className=#{incoming.inspect}"
2099
2099
  end
2100
2100
  className
@@ -6,6 +6,6 @@ module Parse
6
6
  # The Parse Server SDK for Ruby
7
7
  module Stack
8
8
  # The current version.
9
- VERSION = "5.1.0"
9
+ VERSION = "5.1.1"
10
10
  end
11
11
  end
@@ -253,7 +253,8 @@ module Parse
253
253
  expected = parse_class
254
254
  return false if expected.nil?
255
255
  [@object, @original, @update].any? do |h|
256
- h.is_a?(Hash) && h["className"] && h["className"] != expected
256
+ h.is_a?(Hash) && h["className"] &&
257
+ !Parse::Model.same_parse_class?(h["className"], expected)
257
258
  end
258
259
  end
259
260
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parse-stack-next
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Persaud