Skip to content

Commit

Permalink
Merge branch 'integration/v6' into PLAT-6042_Exception_thrown_on_crea…
Browse files Browse the repository at this point in the history
…tion_of_Configuration_object_with_no_API_key
  • Loading branch information
YYChen01988 committed Jul 19, 2023
2 parents 04dba9f + 8d4dbea commit dbe9492
Show file tree
Hide file tree
Showing 33 changed files with 194 additions and 81 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
* Added `Session.apiKey` so that it can be changed in an `OnSessionCallback`
[#1855](https://github.com/bugsnag/bugsnag-android/pull/1855)

* Configuration.persistUser is now true by default, matching the configuration of other platforms.
[#1863](https://github.com/bugsnag/bugsnag-android/pull/1863)

### Bug fixes

* Prevent rare app crash while migrating old `SharedPreferences` data from older versions of `bugsnag-android`
Expand All @@ -25,6 +28,9 @@
* ANR or NDK detection warnings can be suppressed (using `enabledErrorTypes`) when plugin is excluded.
[#1832](https://github.com/bugsnag/bugsnag-android/pull/1832)

* Support using regexes to define redacted keys and discard classes.
[#1856](https://github.com/bugsnag/bugsnag-android/pull/1856)

## 5.29.0 (2023-03-23)

### Enhancements
Expand Down
3 changes: 2 additions & 1 deletion bugsnag-android-core/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<CurrentIssues>
<ID>ComplexMethod:ConfigInternal.kt$ConfigInternal$fun getConfigDifferences(): Map&lt;String, Any></ID>
<ID>ImplicitDefaultLocale:DeliveryHeaders.kt$String.format("%02x", byte)</ID>
<ID>LongMethod:ManifestConfigLoaderTest.kt$ManifestConfigLoaderTest$@Test fun testManifestOverridesDefaults()</ID>
<ID>LongParameterList:App.kt$App$( /** * The architecture of the running application binary */ var binaryArch: String?, /** * The package name of the application */ var id: String?, /** * The release stage set in [Configuration.releaseStage] */ var releaseStage: String?, /** * The version of the application set in [Configuration.version] */ var version: String?, /** The revision ID from the manifest (React Native apps only) */ var codeBundleId: String?, /** * The unique identifier for the build of the application set in [Configuration.buildUuid] */ var buildUuid: String?, /** * The application type set in [Configuration#version] */ var type: String?, /** * The version code of the application set in [Configuration.versionCode] */ var versionCode: Number? )</ID>
<ID>LongParameterList:AppDataCollector.kt$AppDataCollector$( appContext: Context, private val packageManager: PackageManager?, private val config: ImmutableConfig, private val sessionTracker: SessionTracker, private val activityManager: ActivityManager?, private val launchCrashTracker: LaunchCrashTracker, private val memoryTrimState: MemoryTrimState )</ID>
<ID>LongParameterList:AppWithState.kt$AppWithState$( binaryArch: String?, id: String?, releaseStage: String?, version: String?, codeBundleId: String?, buildUuid: String?, type: String?, versionCode: Number?, /** * The number of milliseconds the application was running before the event occurred */ var duration: Number?, /** * The number of milliseconds the application was running in the foreground before the * event occurred */ var durationInForeground: Number?, /** * Whether the application was in the foreground when the event occurred */ var inForeground: Boolean?, /** * Whether the application was launching when the event occurred */ var isLaunching: Boolean? )</ID>
Expand All @@ -15,7 +16,7 @@
<ID>LongParameterList:DeviceIdStore.kt$DeviceIdStore$( context: Context, deviceIdfile: File = File(context.filesDir, "device-id"), deviceIdGenerator: () -> UUID = { UUID.randomUUID() }, internalDeviceIdfile: File = File(context.filesDir, "internal-device-id"), internalDeviceIdGenerator: () -> UUID = { UUID.randomUUID() }, private val sharedPrefMigrator: SharedPrefMigrator, logger: Logger )</ID>
<ID>LongParameterList:DeviceWithState.kt$DeviceWithState$( buildInfo: DeviceBuildInfo, jailbroken: Boolean?, id: String?, locale: String?, totalMemory: Long?, runtimeVersions: MutableMap&lt;String, Any>, /** * The number of free bytes of storage available on the device */ var freeDisk: Long?, /** * The number of free bytes of memory available on the device */ var freeMemory: Long?, /** * The orientation of the device when the event occurred: either portrait or landscape */ var orientation: String?, /** * The timestamp on the device when the event occurred */ var time: Date? )</ID>
<ID>LongParameterList:EventFilenameInfo.kt$EventFilenameInfo.Companion$( obj: Any, uuid: String = UUID.randomUUID().toString(), apiKey: String?, timestamp: Long = System.currentTimeMillis(), config: ImmutableConfig, isLaunching: Boolean? = null )</ID>
<ID>LongParameterList:EventInternal.kt$EventInternal$( apiKey: String, logger: Logger, breadcrumbs: MutableList&lt;Breadcrumb> = mutableListOf(), discardClasses: Set&lt;String> = setOf(), errors: MutableList&lt;Error> = mutableListOf(), metadata: Metadata = Metadata(), featureFlags: FeatureFlags = FeatureFlags(), originalError: Throwable? = null, projectPackages: Collection&lt;String> = setOf(), severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION), threads: MutableList&lt;Thread&gt; = mutableListOf(), user: User = User(), redactionKeys: Set&lt;String>? = null )</ID>
<ID>LongParameterList:EventInternal.kt$EventInternal$( apiKey: String, logger: Logger, breadcrumbs: MutableList&lt;Breadcrumb> = mutableListOf(), discardClasses: Set&lt;Pattern> = setOf(), errors: MutableList&lt;Error> = mutableListOf(), metadata: Metadata = Metadata(), featureFlags: FeatureFlags = FeatureFlags(), originalError: Throwable? = null, projectPackages: Collection&lt;String> = setOf(), severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION), threads: MutableList&lt;Thread> = mutableListOf(), user: User = User(), redactionKeys: Set&lt;Pattern>? = null )</ID>
<ID>LongParameterList:EventStorageModule.kt$EventStorageModule$( contextModule: ContextModule, configModule: ConfigModule, dataCollectionModule: DataCollectionModule, bgTaskService: BackgroundTaskService, trackerModule: TrackerModule, systemServiceModule: SystemServiceModule, notifier: Notifier, callbackState: CallbackState )</ID>
<ID>LongParameterList:NativeStackframe.kt$NativeStackframe$( /** * The name of the method that was being executed */ var method: String?, /** * The location of the source file */ var file: String?, /** * The line number within the source file this stackframe refers to */ var lineNumber: Number?, /** * The address of the instruction where the event occurred. */ var frameAddress: Long?, /** * The address of the function where the event occurred. */ var symbolAddress: Long?, /** * The address of the library where the event occurred. */ var loadAddress: Long?, /** * Whether this frame identifies the program counter */ var isPC: Boolean?, /** * The type of the error */ var type: ErrorType? = null, /** * Identifies the exact build this frame originates from. */ var codeIdentifier: String? = null, )</ID>
<ID>LongParameterList:StateEvent.kt$StateEvent.Install$( @JvmField val apiKey: String, @JvmField val autoDetectNdkCrashes: Boolean, @JvmField val appVersion: String?, @JvmField val buildUuid: String?, @JvmField val releaseStage: String?, @JvmField val lastRunInfoPath: String, @JvmField val consecutiveLaunchCrashes: Int, @JvmField val sendThreads: ThreadSendPolicy )</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import java.util.regex.Pattern

class ManifestConfigLoaderTest {

Expand All @@ -29,7 +30,7 @@ class ManifestConfigLoaderTest {
assertTrue(autoDetectErrors)
assertTrue(autoTrackSessions)
assertEquals(ThreadSendPolicy.ALWAYS, sendThreads)
assertFalse(persistUser)
assertTrue(persistUser)

// endpoints
assertEquals(endpoints.notify, "https://notify.bugsnag.com")
Expand All @@ -40,9 +41,9 @@ class ManifestConfigLoaderTest {
assertEquals(0, versionCode)
assertNull(releaseStage)
assertNull(enabledReleaseStages)
assertEquals(emptySet<String>(), discardClasses)
assertEquals(emptySet<Pattern>(), discardClasses)
assertEquals(emptySet<String>(), projectPackages)
assertEquals(setOf("password"), redactedKeys)
assertEquals(".*password.*", redactedKeys.single().pattern())

// misc
assertEquals(maxBreadcrumbs, 100)
Expand Down Expand Up @@ -79,9 +80,9 @@ class ManifestConfigLoaderTest {
putInt("com.bugsnag.android.VERSION_CODE", 55)
putString("com.bugsnag.android.RELEASE_STAGE", "beta")
putString("com.bugsnag.android.ENABLED_RELEASE_STAGES", "beta,production,staging")
putString("com.bugsnag.android.DISCARD_CLASSES", "com.bugsnag.FooKt,org.example.String")
putString("com.bugsnag.android.DISCARD_CLASSES", ".*com.bugsnag.FooKt.*,.*org.example.String.*")
putString("com.bugsnag.android.PROJECT_PACKAGES", "com.bugsnag,com.example")
putString("com.bugsnag.android.REDACTED_KEYS", "password,auth,foo")
putString("com.bugsnag.android.REDACTED_KEYS", ".*password.*,.*auth.*,.*foo.*")

// misc
putInt("com.bugsnag.android.MAX_BREADCRUMBS", 75)
Expand Down Expand Up @@ -115,9 +116,12 @@ class ManifestConfigLoaderTest {
assertEquals(55, versionCode)
assertEquals("beta", releaseStage)
assertEquals(setOf("beta", "production", "staging"), enabledReleaseStages)
assertEquals(setOf("com.bugsnag.FooKt", "org.example.String"), discardClasses)
assertEquals(setOf("com.bugsnag", "com.example"), projectPackages)
assertEquals(setOf("password", "auth", "foo"), redactedKeys)

assertEquals(".*com.bugsnag.FooKt.*", discardClasses.first().pattern())
assertEquals(".*org.example.String.*", discardClasses.last().pattern())
assertEquals(".*password.*", redactedKeys.first().pattern())
assertEquals(".*foo.*", redactedKeys.last().pattern())

// misc
assertEquals(maxBreadcrumbs, 75)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.RejectedExecutionException;
import java.util.regex.Pattern;

/**
* A Bugsnag Client instance allows you to use Bugsnag in your Android app.
Expand Down Expand Up @@ -792,7 +793,7 @@ void notifyInternal(@NonNull Event event,
@Nullable OnErrorCallback onError) {
// set the redacted keys on the event as this
// will not have been set for RN/Unity events
Collection<String> redactedKeys = metadataState.getMetadata().getRedactedKeys();
Collection<Pattern> redactedKeys = metadataState.getMetadata().getRedactedKeys();
event.setRedactedKeys(redactedKeys);

// get session for event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.bugsnag.android
import android.content.Context
import java.io.File
import java.util.EnumSet
import java.util.regex.Pattern

internal class ConfigInternal(
var apiKey: String
Expand All @@ -23,7 +24,7 @@ internal class ConfigInternal(
var versionCode: Int? = 0
var releaseStage: String? = null
var sendThreads: ThreadSendPolicy = ThreadSendPolicy.ALWAYS
var persistUser: Boolean = false
var persistUser: Boolean = true

var launchDurationMillis: Long = DEFAULT_LAUNCH_CRASH_THRESHOLD_MS

Expand All @@ -45,13 +46,13 @@ internal class ConfigInternal(
var maxStringValueLength: Int = DEFAULT_MAX_STRING_VALUE_LENGTH
var context: String? = null

var redactedKeys: Set<String>
var redactedKeys: Set<Pattern>
get() = metadataState.metadata.redactedKeys
set(value) {
metadataState.metadata.redactedKeys = value
}

var discardClasses: Set<String> = emptySet()
var discardClasses: Set<Pattern> = emptySet()
var enabledReleaseStages: Set<String>? = null
var enabledBreadcrumbTypes: Set<BreadcrumbType>? = null
var telemetry: Set<Telemetry> = EnumSet.of(Telemetry.INTERNAL_ERRORS, Telemetry.USAGE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.File;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

/**
* User-specified configuration storage object, contains information
Expand Down Expand Up @@ -641,7 +642,7 @@ public void setContext(@Nullable String context) {
* By default, redactedKeys is set to "password"
*/
@NonNull
public Set<String> getRedactedKeys() {
public Set<Pattern> getRedactedKeys() {
return impl.getRedactedKeys();
}

Expand All @@ -653,7 +654,7 @@ public Set<String> getRedactedKeys() {
*
* By default, redactedKeys is set to "password"
*/
public void setRedactedKeys(@NonNull Set<String> redactedKeys) {
public void setRedactedKeys(@NonNull Set<Pattern> redactedKeys) {
if (CollectionUtils.containsNullElements(redactedKeys)) {
logNull("redactedKeys");
} else {
Expand All @@ -667,7 +668,7 @@ public void setRedactedKeys(@NonNull Set<String> redactedKeys) {
* match against the canonical class name.
*/
@NonNull
public Set<String> getDiscardClasses() {
public Set<Pattern> getDiscardClasses() {
return impl.getDiscardClasses();
}

Expand All @@ -676,7 +677,7 @@ public Set<String> getDiscardClasses() {
* before being sent to Bugsnag if they are detected. The notifier performs an exact
* match against the canonical class name.
*/
public void setDiscardClasses(@NonNull Set<String> discardClasses) {
public void setDiscardClasses(@NonNull Set<Pattern> discardClasses) {
if (CollectionUtils.containsNullElements(discardClasses)) {
logNull("discardClasses");
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
* An Event object represents a Throwable captured by Bugsnag and is available as a parameter on
Expand Down Expand Up @@ -418,7 +419,7 @@ EventInternal getImpl() {
return impl;
}

void setRedactedKeys(Collection<String> redactedKeys) {
void setRedactedKeys(Collection<Pattern> redactedKeys) {
impl.setRedactedKeys(redactedKeys);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.bugsnag.android.internal.InternalMetricsNoop
import com.bugsnag.android.internal.JsonHelper
import com.bugsnag.android.internal.TrimMetrics
import java.io.IOException
import java.util.regex.Pattern

internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, MetadataAware, UserAware {

Expand Down Expand Up @@ -39,7 +40,7 @@ internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, Metadata
apiKey: String,
logger: Logger,
breadcrumbs: MutableList<Breadcrumb> = mutableListOf(),
discardClasses: Set<String> = setOf(),
discardClasses: Set<Pattern> = setOf(),
errors: MutableList<Error> = mutableListOf(),
metadata: Metadata = Metadata(),
featureFlags: FeatureFlags = FeatureFlags(),
Expand All @@ -48,7 +49,7 @@ internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, Metadata
severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION),
threads: MutableList<Thread> = mutableListOf(),
user: User = User(),
redactionKeys: Set<String>? = null
redactionKeys: Set<Pattern>? = null
) {
this.logger = logger
this.apiKey = apiKey
Expand All @@ -74,7 +75,7 @@ internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, Metadata
val logger: Logger
val metadata: Metadata
val featureFlags: FeatureFlags
private val discardClasses: Set<String>
private val discardClasses: Set<Pattern>
internal var projectPackages: Collection<String>

private val jsonStreamer: ObjectJsonStreamer = ObjectJsonStreamer().apply {
Expand Down Expand Up @@ -105,7 +106,7 @@ internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, Metadata
var groupingHash: String? = null
var context: String? = null

var redactedKeys: Collection<String>
var redactedKeys: Collection<Pattern>
get() = jsonStreamer.redactedKeys
set(value) {
jsonStreamer.redactedKeys = value.toSet()
Expand All @@ -125,7 +126,11 @@ internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, Metadata
protected fun shouldDiscardClass(): Boolean {
return when {
errors.isEmpty() -> true
else -> errors.any { discardClasses.contains(it.errorClass) }
else -> errors.any { error ->
discardClasses.any { pattern ->
pattern.matcher(error.errorClass).matches()
}
}
}
}

Expand Down Expand Up @@ -304,7 +309,8 @@ internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, Metadata

override fun addFeatureFlag(name: String) = featureFlags.addFeatureFlag(name)

override fun addFeatureFlag(name: String, variant: String?) = featureFlags.addFeatureFlag(name, variant)
override fun addFeatureFlag(name: String, variant: String?) =
featureFlags.addFeatureFlag(name, variant)

override fun addFeatureFlags(featureFlags: Iterable<FeatureFlag>) =
this.featureFlags.addFeatureFlags(featureFlags)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.pm.PackageManager
import android.os.Bundle
import androidx.annotation.VisibleForTesting
import java.lang.IllegalArgumentException
import java.util.regex.Pattern

internal class ManifestConfigLoader {

Expand Down Expand Up @@ -135,9 +136,9 @@ internal class ManifestConfigLoader {
if (data.containsKey(ENABLED_RELEASE_STAGES)) {
enabledReleaseStages = getStrArray(data, ENABLED_RELEASE_STAGES, enabledReleaseStages)
}
discardClasses = getStrArray(data, DISCARD_CLASSES, discardClasses) ?: emptySet()
discardClasses = getPatternSet(data, DISCARD_CLASSES, discardClasses) ?: emptySet()
projectPackages = getStrArray(data, PROJECT_PACKAGES, emptySet()) ?: emptySet()
redactedKeys = getStrArray(data, REDACTED_KEYS, redactedKeys) ?: emptySet()
redactedKeys = getPatternSet(data, REDACTED_KEYS, redactedKeys) ?: emptySet()
}
}

Expand All @@ -153,4 +154,15 @@ internal class ManifestConfigLoader {
else -> ary.toSet()
}
}

private fun getPatternSet(
data: Bundle,
key: String,
default: Set<Pattern>?
): Set<Pattern>? {
val delimitedStr = data.getString(key) ?: return default
return delimitedStr.splitToSequence(',')
.map { Pattern.compile(it) }
.toSet()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.bugsnag.android.internal.StringUtils
import com.bugsnag.android.internal.TrimMetrics
import java.io.IOException
import java.util.concurrent.ConcurrentHashMap
import java.util.regex.Pattern

/**
* A container for additional diagnostic information you'd like to send with
Expand All @@ -19,7 +20,7 @@ internal data class Metadata @JvmOverloads constructor(

val jsonStreamer: ObjectJsonStreamer = ObjectJsonStreamer()

var redactedKeys: Set<String>
var redactedKeys: Set<Pattern>
get() = jsonStreamer.redactedKeys
set(value) {
jsonStreamer.redactedKeys = value
Expand Down
Loading

0 comments on commit dbe9492

Please sign in to comment.