Skip to content

Commit fe636e3

Browse files
authored
Safely handle bad URIs when tracking deep links (#767)
* safely handle bad uris when tracking deep links * run spotless
1 parent 249004a commit fe636e3

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

analytics/src/main/java/com/segment/analytics/AnalyticsActivityLifecycleCallbacks.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,17 @@ private void trackDeepLink(Activity activity) {
173173

174174
Properties properties = new Properties();
175175
Uri uri = intent.getData();
176-
for (String parameter : uri.getQueryParameterNames()) {
177-
String value = uri.getQueryParameter(parameter);
178-
if (value != null && !value.trim().isEmpty()) {
179-
properties.put(parameter, value);
176+
try {
177+
for (String parameter : uri.getQueryParameterNames()) {
178+
String value = uri.getQueryParameter(parameter);
179+
if (value != null && !value.trim().isEmpty()) {
180+
properties.put(parameter, value);
181+
}
180182
}
183+
} catch (Exception e) {
184+
analytics
185+
.logger("LifecycleCallbacks")
186+
.error(e, "failed to get uri params for %s", uri.toString());
181187
}
182188

183189
properties.put("url", uri.toString());

analytics/src/test/java/com/segment/analytics/AnalyticsTest.kt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,77 @@ open class AnalyticsTest {
12101210
)
12111211
}
12121212

1213+
@Test
1214+
fun trackDeepLinks_bad_uri() {
1215+
Analytics.INSTANCES.clear()
1216+
1217+
val callback =
1218+
AtomicReference<ActivityLifecycleCallbacks>()
1219+
1220+
doNothing()
1221+
.whenever(application)
1222+
.registerActivityLifecycleCallbacks(
1223+
argThat<ActivityLifecycleCallbacks>(
1224+
object : NoDescriptionMatcher<ActivityLifecycleCallbacks>() {
1225+
override fun matchesSafely(item: ActivityLifecycleCallbacks): Boolean {
1226+
callback.set(item)
1227+
return true
1228+
}
1229+
})
1230+
)
1231+
1232+
analytics = Analytics(
1233+
application,
1234+
networkExecutor,
1235+
stats,
1236+
traitsCache,
1237+
analyticsContext,
1238+
defaultOptions,
1239+
Logger.with(Analytics.LogLevel.NONE),
1240+
"qaz", listOf(factory),
1241+
client,
1242+
Cartographer.INSTANCE,
1243+
projectSettingsCache,
1244+
"foo",
1245+
DEFAULT_FLUSH_QUEUE_SIZE,
1246+
DEFAULT_FLUSH_INTERVAL.toLong(),
1247+
analyticsExecutor,
1248+
true,
1249+
CountDownLatch(0),
1250+
false,
1251+
false,
1252+
optOut,
1253+
Crypto.none(), emptyList(), emptyMap(),
1254+
jsMiddleware,
1255+
ValueMap(),
1256+
lifecycle,
1257+
false,
1258+
true,
1259+
DEFAULT_API_HOST
1260+
)
1261+
1262+
val expectedURL = "wc:foo-bar-jk@1bridge=https%3A%2F%2Fbridge.walletconnect.org&key=1234"
1263+
1264+
val activity = Mockito.mock(Activity::class.java)
1265+
val intent = Mockito.mock(Intent::class.java)
1266+
val uri = Uri.parse(expectedURL)
1267+
1268+
whenever(intent.data).thenReturn(uri)
1269+
whenever(activity.intent).thenReturn(intent)
1270+
1271+
verify(integration, Mockito.never())
1272+
.track(
1273+
argThat<TrackPayload>(
1274+
object : NoDescriptionMatcher<TrackPayload>() {
1275+
override fun matchesSafely(payload: TrackPayload): Boolean {
1276+
return payload.event() == "Deep Link Opened" &&
1277+
payload.properties()
1278+
.getString("url") == expectedURL
1279+
}
1280+
})
1281+
)
1282+
}
1283+
12131284
@Test
12141285
fun trackDeepLinks_null() {
12151286
Analytics.INSTANCES.clear()

0 commit comments

Comments
 (0)