Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle null values in MetaData.mergeMaps, preventing potential NPE #386

Merged
merged 4 commits into from
Nov 29, 2018

Conversation

fractalwrench
Copy link
Contributor

Goal

Prevent NPE crash when attempting to deliver error reports.

Design

MetaData tab values can be HashMaps, whose entries can be null. MetaData.mergeMaps seemed to assume that the Map was always a ConcurrentHashMap, whose entries cannot be null.

On React Native this manifested as a NPE when merging config.metaData and report.metaData due to app.activeScreen being intermittently recorded as null. This can occur on any platform which uses bugsnag-android, however.

Changeset

Added a null check when adding the base value to the merged map.

Tests

Wrote unit test + mazerunner scenario, and manually verified that valid reports are sent from a React Native example app using a local bugsnag-android artefact.

Review

For the submitter, initial self-review:

  • Commented on code changes inline explain the reasoning behind the approach
  • Reviewed the test cases added for completeness and possible points for discussion
  • A changelog entry was added for the goal of this pull request
  • Check the scope of the changeset - is everything in the diff required for the pull request?
  • This pull request is ready for:
    • Initial review of the intended approach, not yet feature complete
    • Structural review of the classes, functions, and properties modified
    • Final review

For the pull request reviewer(s), this changeset has been reviewed for:

  • Consistency across platforms for structures or concepts added or modified
  • Consistency between the changeset and the goal stated above
  • Internal consistency with the rest of the library - is there any overlap between existing interfaces and any which have been added?
  • Usage friction - is the proposed change in usage cumbersome or complicated?
  • Performance and complexity - are there any cases of unexpected O(n^3) when iterating, recursing, flat mapping, etc?
  • Concurrency concerns - if components are accessed asynchronously, what issues will arise
  • Thoroughness of added tests and any missing edge cases
  • Idiomatic use of the language

MetaData tab values can be HashMaps, whose entries can be null. MetaData.mergeMaps seemed to assume
that the Map was always a ConcurrentHashMap, whose values cannot be null, which could lead to a NPE
when merging config.metaData and report.metaData for nullable values, such as activeScreen. Adding a
null check and conditionally adding values fixes this behaviour.
@fractalwrench fractalwrench changed the title Handle null values in MetaData.mergeMaps Handle null values in MetaData.mergeMaps, preventing potential NPE Nov 26, 2018
if (baseValue != null
&& baseValue instanceof Map
&& overridesValue instanceof Map) {
if (baseValue instanceof Map && overridesValue instanceof Map) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

baseValue != null is redundant when also using instanceof

@fractalwrench fractalwrench requested a review from a team November 26, 2018 13:00
bengourley
bengourley previously approved these changes Nov 26, 2018
Copy link
Contributor

@bengourley bengourley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM. I haven't run it yet but the automated test looks good.

At which line would it error before? The Bugsnag.addToTab("Custom", "foo", configMap) or the notify() call? (or both?)

@fractalwrench
Copy link
Contributor Author

This was originally discovered when setting the codeBundleId in React Native, which in turn sets metadata on the native layer: bugsnag/bugsnag-react-native#291

kattrali
kattrali previously approved these changes Nov 27, 2018
metaData.addToTab("foo", "bar", nestedMap);
nestedMap.put("whoops", null);

Map<String, Object> mergedMap = MetaData.merge(metaData, metaData).store;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we merge a different metadata? Its weird to read otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the test to generate two different MetaData objects.

nestedMap.put("whoops", null);

Map<String, Object> mergedMap = MetaData.merge(metaData, metaData).store;
assertFalse(mergedMap.containsKey("whoops"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this assertion is incorrect. Can you undo the changes to the sdk and check that this fails as you would expect? I would never expect the whoops key to be in this map from reading the test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the changes, this test fails due to a NPE within MetaData.mergeMaps, which is expected. I have removed the assertFalse statement as I can see it might be confusing. Were there any additional concerns around the assertions?

Copy link
Contributor

@snmaynard snmaynard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address my comments plz

@fractalwrench
Copy link
Contributor Author

@snmaynard I believe I have addressed the comments, are you happy with the updates?

@snmaynard
Copy link
Contributor

I pinged you with my concerns - we can discuss tomorrow!

@fractalwrench fractalwrench merged commit a8eaa15 into master Nov 29, 2018
@fractalwrench fractalwrench deleted the metadata-merge-fix branch November 29, 2018 14:40
lemnik added a commit that referenced this pull request Jun 2, 2021
fix(gradle): replaced jcenter with mavenCentral
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants