Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix crash when adding alias with some labels
When passing some labels to User.addAlias, such as "AL" this could
cause a crash when starting the app the next time. This is due to
casting the wrong type as initializeFromJson's code used a contains
instead of an equals which can result in finding the wrong function.

To correct this switched this to equals("get$property", true) instead
and also added a check for it.parameterCount == 0 as we only want to
cast based on getters.

Also added tests for IdentityModel with a number of labels to ensure
this code changes covers common label values.

Lastly also removed the if (method == null) check to simplify the code,
as the when statement can handle this case.
  • Loading branch information
jkasten2 committed May 9, 2025
commit 5c473d5ef4d3d01b0fc744c7a916e15a6188da65
Original file line number Diff line number Diff line change
Expand Up @@ -94,28 +94,25 @@ open class Model(
data[property] = listOfItems
}
} else {
// Cast JSON value based on class's property getter name return type
val method =
this.javaClass.methods.firstOrNull {
it.returnType !=
Void::class.java &&
it.name.contains(
property,
it.returnType != Void::class.java &&
it.parameterCount == 0 &&
it.name.equals(
"get$property",
true,
)
}

if (method == null) {
data[property] = jsonObject.get(property)
} else {
when (method.returnType) {
Double::class.java, java.lang.Double::class.java -> data[property] = jsonObject.getDouble(property)
Long::class.java, java.lang.Long::class.java -> data[property] = jsonObject.getLong(property)
Float::class.java, java.lang.Float::class.java -> data[property] = jsonObject.getDouble(property).toFloat()
Int::class.java, java.lang.Integer::class.java -> data[property] = jsonObject.getInt(property)
Boolean::class.java, java.lang.Boolean::class.java -> data[property] = jsonObject.getBoolean(property)
String::class.java, java.lang.String::class.java -> data[property] = jsonObject.getString(property)
else -> data[property] = jsonObject.get(property)
}
when (method?.returnType) {
Double::class.java, java.lang.Double::class.java -> data[property] = jsonObject.getDouble(property)
Long::class.java, java.lang.Long::class.java -> data[property] = jsonObject.getLong(property)
Float::class.java, java.lang.Float::class.java -> data[property] = jsonObject.getDouble(property).toFloat()
Int::class.java, java.lang.Integer::class.java -> data[property] = jsonObject.getInt(property)
Boolean::class.java, java.lang.Boolean::class.java -> data[property] = jsonObject.getBoolean(property)
String::class.java, java.lang.String::class.java -> data[property] = jsonObject.getString(property)
else -> data[property] = jsonObject.get(property)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,77 @@
package com.onesignal.user.internal.properties

import com.onesignal.common.putJSONObject
import com.onesignal.user.internal.identity.IdentityModel
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import org.json.JSONObject
import java.util.UUID

class PropertiesModelTests : FunSpec({

test("successfully initializes varying tag names") {
// Given
val varyingTags =
JSONObject()
.putJSONObject(PropertiesModel::tags.name) {
it.put("value", "data1")
.put("isEmpty", "data2")
.put("object", "data3")
.put("1", "data4")
.put("false", "data5")
.put("15.7", "data6")
}
val propertiesModel = PropertiesModel()

// When
propertiesModel.initializeFromJson(varyingTags)
val tagsModel = propertiesModel.tags

// Then
tagsModel["value"] shouldBe "data1"
tagsModel["isEmpty"] shouldBe "data2"
tagsModel["object"] shouldBe "data3"
tagsModel["1"] shouldBe "data4"
tagsModel["false"] shouldBe "data5"
tagsModel["15.7"] shouldBe "data6"
}
})
class PropertiesModelTests :
FunSpec({

test("successfully initializes varying tag names") {
// Given
val varyingTags =
JSONObject()
.putJSONObject(PropertiesModel::tags.name) {
it
.put("value", "data1")
.put("isEmpty", "data2")
.put("object", "data3")
.put("1", "data4")
.put("false", "data5")
.put("15.7", "data6")
}
val propertiesModel = PropertiesModel()

// When
propertiesModel.initializeFromJson(varyingTags)
val tagsModel = propertiesModel.tags

// Then
tagsModel["value"] shouldBe "data1"
tagsModel["isEmpty"] shouldBe "data2"
tagsModel["object"] shouldBe "data3"
tagsModel["1"] shouldBe "data4"
tagsModel["false"] shouldBe "data5"
tagsModel["15.7"] shouldBe "data6"
}

test("successfully initializes varying of identities") {
// Given
val onesignalId = UUID.randomUUID().toString()
val varyingIdentities =
JSONObject()
.put("onesignal_id", onesignalId)
.put("external_id", "myExtId")
.put("a", "test1")
.put("al", "test2")
.put("b", "test3")
.put("value", "test4")
.put("isEmpty", "test5")
.put("object", "test6")
.put("id", "test7")
.put("os", "test8")
.put("myid", "test9")
.put("facebookID", "test10")
val identityModel = IdentityModel()

// When
identityModel.initializeFromJson(varyingIdentities)

// Then
identityModel.onesignalId shouldBe onesignalId
identityModel.externalId shouldBe "myExtId"
identityModel.getValue("a") shouldBe "test1"
identityModel.getValue("al") shouldBe "test2"
identityModel.getValue("b") shouldBe "test3"
identityModel.getValue("value") shouldBe "test4"
identityModel.getValue("isEmpty") shouldBe "test5"
identityModel.getValue("object") shouldBe "test6"
identityModel.getValue("id") shouldBe "test7"
identityModel.getValue("os") shouldBe "test8"
identityModel.getValue("myid") shouldBe "test9"
identityModel.getValue("facebookID") shouldBe "test10"
}
})
Loading