-
Notifications
You must be signed in to change notification settings - Fork 116
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
Fix crash caused by ResponseJson::MarkCompleted() failing to set application_data_ if parsing the JSON body fails #692
Conversation
…plication_data_ if parsing the JSON body fails
❌ Integration test FAILEDRequested by @dconeybe on commit ef28f10
Add flaky tests to go/fpl-cpp-flake-tracker |
app/rest/response_json.h
Outdated
@@ -74,12 +74,26 @@ class ResponseJson : public Response { | |||
// Parse and verify JSON string in body. FlatBuffer parser does not support | |||
// online parsing. So we only parse the body when we get everything. | |||
bool parse_status = parser_->Parse(GetBody()); | |||
FIREBASE_ASSERT_RETURN_VOID(parse_status); | |||
FIREBASE_ASSERT_MESSAGE(parse_status, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With FIREBASE_ASSERT_MESSAGE, it will assert in C++ and throw an exception in Unity. Is that the behavior we want? Maybe this should just be a LogError. Same below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if LogError() would be more appropriate. Assert in C++ and throw in Unity sounds reasonable though.
Note that both FIREBASE_ASSERT_RETURN_VOID and FIREBASE_ASSERT_MESSAGE use firebase::LogAssert() under the hood to log the assertion and crash/throw/ignore the failed assertion. So the change made in this PR does not change that behavior. If that should be changed then I think that should be a separate PR since I don't know the right answer and only learned enough about this Auth code to fix the bug at hand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, what I'm saying is, asserting at all (in C++) on bad data coming in (outside the app's control) seems like a bad idea, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally agree. It's an inappropriate use of assertions since the data is out of the app's control. I guess the rationale is that using assertions makes it VERY visible what's going wrong. Otherwise, if we change it to just LogError(), it would be more difficult to correlate the ultimate failure with the root cause of a parsing failure. But I guess the fact that checking for a zero-length body earlier in the method and not even logging anything gives merit to the argument that we shouldn't crash. Ok, I'll change it to LogError().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - yeah this fulfills the software robustness principle: "Be conservative in what you do, be liberal in what you accept from others."
@@ -576,6 +576,9 @@ code. | |||
- Messaging (Android): Fixes an issue to receive token when | |||
initialize the app. | |||
([#667](https://github.com/firebase/firebase-cpp-sdk/pull/667)). | |||
- Auth (Desktop): Fix a crash that would occur if parsing the JSON | |||
response from the server failed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The period occurs after the PR link on line 581.
🍞 Dismissed stale approval on external PR.
Description
When parsing the JSON response body in
ResponseJson::MarkCompleted()
, if parsing failed then, if assertions were disabled, the method would return without setting theapplication_data_
member to a valid value. Then, later on, if a method likeAuthResponse::error_code()
is invoked then it would accessapplication_data_
assuming it was valid. If, however,MarkCompleted()
failed to initialize it then it would not be valid and result in a crash, such asEXC_BAD_ACCESS
.The problem was that the success of the JSON parsing was being "asserted" by calling
FIREBASE_ASSERT_RETURN_VOID
. So if assertions did not cause a crash thenMarkCompleted()
would return without settingapplication_data_
or calling the superclass'MarkCompleted()
method. As you can see from earlier in the method when it checks for a zero-length response body, if such an error occurs then it should do both of these things.The fix in this PR is to replace
FIREBASE_ASSERT_RETURN_VOID
withLogError()
and make sure to perform these two critical steps before returning. We decided that asserting on the correctness of external data over which the app does not have control is inappropriate, and it is better to log the error and carry on.Testing
This fix was tested by creating a custom build and having the customer who reported the issue (#615) test out the fix.
Type of Change
Place an
x
the applicable box:Fixes #615