aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/ext/transport/chttp2
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ext/transport/chttp2')
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_decoder.cc26
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_decoder.h3
2 files changed, 29 insertions, 0 deletions
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.cc b/src/core/ext/transport/chttp2/transport/bin_decoder.cc
index 91980e6974..831a36961e 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.cc
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.cc
@@ -75,6 +75,32 @@ static bool input_is_valid(uint8_t* input_ptr, size_t length) {
#define COMPOSE_OUTPUT_BYTE_2(input_ptr) \
(uint8_t)((decode_table[input_ptr[2]] << 6) | decode_table[input_ptr[3]])
+// By RFC 4648, if the length of the encoded string without padding is 4n+r,
+// the length of decoded string is: 1) 3n if r = 0, 2) 3n + 1 if r = 2, 3, or
+// 3) invalid if r = 1.
+size_t grpc_chttp2_base64_infer_length_after_decode(const grpc_slice& slice) {
+ size_t len = GRPC_SLICE_LENGTH(slice);
+ const uint8_t* bytes = GRPC_SLICE_START_PTR(slice);
+ while (len > 0 && bytes[len - 1] == '=') {
+ len--;
+ }
+ if (GRPC_SLICE_LENGTH(slice) - len > 2) {
+ gpr_log(GPR_ERROR,
+ "Base64 decoding failed. Input has more than 2 paddings.");
+ return 0;
+ }
+ size_t tuples = len / 4;
+ size_t tail_case = len % 4;
+ if (tail_case == 1) {
+ gpr_log(GPR_ERROR,
+ "Base64 decoding failed. Input has a length of %zu (without"
+ " padding), which is invalid.\n",
+ len);
+ return 0;
+ }
+ return tuples * 3 + tail_xtra[tail_case];
+}
+
bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx) {
size_t input_tail;
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h
index 9cb75ccd81..a0d74fb20d 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h
@@ -48,4 +48,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input);
grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
size_t output_length);
+/* Infer the length of decoded data from encoded data. */
+size_t grpc_chttp2_base64_infer_length_after_decode(const grpc_slice& slice);
+
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */