Extracts out a helper method to determine whether a chunk extension character is valid.
There is a very small change in behavior, in that the `last_char_was_slash_r_` member will be updated even if `HttpValidationPolicy::disallow_lone_cr_in_chunk_extension` is not set.
Protected by refactoring, no functional change intended; not protected.
PiperOrigin-RevId: 704499760
diff --git a/quiche/balsa/balsa_frame.cc b/quiche/balsa/balsa_frame.cc
index c93ff94..8098d36 100644
--- a/quiche/balsa/balsa_frame.cc
+++ b/quiche/balsa/balsa_frame.cc
@@ -1249,22 +1249,12 @@
return current - input;
}
const char c = *current;
- if (http_validation_policy_.disallow_lone_cr_in_chunk_extension) {
- // This is a CR character and the next one is not LF.
- const bool cr_followed_by_non_lf =
- c == '\r' && current + 1 < end && *(current + 1) != '\n';
- // The last character processed by the last ProcessInput() call was
- // CR, this is the first character of the current ProcessInput()
- // call, and it is not LF.
- const bool previous_cr_followed_by_non_lf =
- last_char_was_slash_r_ && current == input && c != '\n';
- if (cr_followed_by_non_lf || previous_cr_followed_by_non_lf) {
- HandleError(BalsaFrameEnums::INVALID_CHUNK_EXTENSION);
- return current - input;
- }
- if (current + 1 == end) {
- last_char_was_slash_r_ = c == '\r';
- }
+ if (!IsValidChunkExtensionCharacter(c, current, input, end)) {
+ HandleError(BalsaFrameEnums::INVALID_CHUNK_EXTENSION);
+ return current - input;
+ }
+ if (current + 1 == end) {
+ last_char_was_slash_r_ = c == '\r';
}
if (c == '\r' || c == '\n') {
extensions_length = (extensions_start == current)
@@ -1501,6 +1491,25 @@
HandleError(BalsaFrameEnums::HEADERS_TOO_LONG);
}
+bool BalsaFrame::IsValidChunkExtensionCharacter(char c, const char* current,
+ const char* begin,
+ const char* end) {
+ if (http_validation_policy_.disallow_lone_cr_in_chunk_extension) {
+ // This is a CR character and the next one is not LF.
+ const bool cr_followed_by_non_lf =
+ c == '\r' && current + 1 < end && *(current + 1) != '\n';
+ // The last character processed by the last ProcessInput() call was
+ // CR, this is the first character of the current ProcessInput()
+ // call, and it is not LF.
+ const bool previous_cr_followed_by_non_lf =
+ last_char_was_slash_r_ && current == begin && c != '\n';
+ if (cr_followed_by_non_lf || previous_cr_followed_by_non_lf) {
+ return false;
+ }
+ }
+ return true;
+}
+
const int32_t BalsaFrame::kValidTerm1;
const int32_t BalsaFrame::kValidTerm1Mask;
const int32_t BalsaFrame::kValidTerm2;
diff --git a/quiche/balsa/balsa_frame.h b/quiche/balsa/balsa_frame.h
index 73c266d..4902ab8 100644
--- a/quiche/balsa/balsa_frame.h
+++ b/quiche/balsa/balsa_frame.h
@@ -266,6 +266,10 @@
void HandleHeadersTooLongError();
+ inline bool IsValidChunkExtensionCharacter(char c, const char* current,
+ const char* begin,
+ const char* end);
+
BalsaVisitorInterface* visitor_;
BalsaHeaders* continue_headers_; // This is not reset to nullptr in Reset().
BalsaHeaders* headers_; // This is not reset to nullptr in Reset().