aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-11-18 16:10:24 -0800
committerGravatar Craig Tiller <ctiller@google.com>2016-11-18 16:10:24 -0800
commit03cdd3e2de886659761878ea877f6ad5d51f6319 (patch)
tree138a626389f4e0cd9525febd81a361a381f69af3
parent5ae3ffb3676de640598e675f2670ef8695559fbf (diff)
Fix timeout decoding
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.c15
-rw-r--r--src/core/lib/transport/metadata.c1
-rw-r--r--src/core/lib/transport/timeout_encoding.c15
-rw-r--r--src/core/lib/transport/timeout_encoding.h3
-rw-r--r--test/core/transport/timeout_encoding_test.c7
5 files changed, 21 insertions, 20 deletions
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 670ce51b72..12f850791d 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -470,23 +470,24 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT) == 0) {
gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
- if (!cached_timeout) {
+ gpr_timespec timeout;
+ if (cached_timeout == NULL) {
/* not already parsed: parse it now, and store the result away */
cached_timeout = gpr_malloc(sizeof(gpr_timespec));
- if (!grpc_http2_decode_timeout(GRPC_SLICE_START_PTR(GRPC_MDVALUE(md)),
- GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)),
- cached_timeout)) {
+ if (!grpc_http2_decode_timeout(GRPC_MDVALUE(md), cached_timeout)) {
char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
gpr_free(val);
*cached_timeout = gpr_inf_future(GPR_TIMESPAN);
}
- cached_timeout =
- grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ timeout = *cached_timeout;
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ } else {
+ timeout = *cached_timeout;
}
grpc_chttp2_incoming_metadata_buffer_set_deadline(
&s->metadata_buffer[0],
- gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
+ gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), timeout));
GRPC_MDELEM_UNREF(exec_ctx, md);
} else {
const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index f3f6b1311f..2082d1bac2 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -496,6 +496,7 @@ void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) {
if (a.payload == b.payload) return true;
+ if (GRPC_MDISNULL(a) || GRPC_MDISNULL(b)) return false;
return 0 == grpc_slice_cmp(GRPC_MDKEY(a), GRPC_MDKEY(b)) &&
0 == grpc_slice_cmp(GRPC_MDVALUE(a), GRPC_MDVALUE(b));
}
diff --git a/src/core/lib/transport/timeout_encoding.c b/src/core/lib/transport/timeout_encoding.c
index b2060be59e..0d4d7e5a7e 100644
--- a/src/core/lib/transport/timeout_encoding.c
+++ b/src/core/lib/transport/timeout_encoding.c
@@ -131,16 +131,15 @@ void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer) {
}
}
-static int is_all_whitespace(const char *p) {
- while (*p == ' ') p++;
- return *p == 0;
+static int is_all_whitespace(const char *p, const char *end) {
+ while (p != end && *p == ' ') p++;
+ return p == end;
}
-int grpc_http2_decode_timeout(const uint8_t *buffer, size_t length,
- gpr_timespec *timeout) {
+int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout) {
int32_t x = 0;
- const uint8_t *p = buffer;
- const uint8_t *end = p + length;
+ const uint8_t *p = GRPC_SLICE_START_PTR(text);
+ const uint8_t *end = GRPC_SLICE_END_PTR(text);
int have_digit = 0;
/* skip whitespace */
for (; p != end && *p == ' '; p++)
@@ -187,5 +186,5 @@ int grpc_http2_decode_timeout(const uint8_t *buffer, size_t length,
return 0;
}
p++;
- return is_all_whitespace((const char *)p);
+ return is_all_whitespace((const char *)p, (const char *)end);
}
diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h
index 838892595f..9b34cec373 100644
--- a/src/core/lib/transport/timeout_encoding.h
+++ b/src/core/lib/transport/timeout_encoding.h
@@ -42,7 +42,6 @@
/* Encode/decode timeouts to the GRPC over HTTP/2 format;
encoding may round up arbitrarily */
void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer);
-int grpc_http2_decode_timeout(const uint8_t *buffer, size_t length,
- gpr_timespec *timeout);
+int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout);
#endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */
diff --git a/test/core/transport/timeout_encoding_test.c b/test/core/transport/timeout_encoding_test.c
index 23b1eb577b..10e1804995 100644
--- a/test/core/transport/timeout_encoding_test.c
+++ b/test/core/transport/timeout_encoding_test.c
@@ -88,8 +88,8 @@ void test_encoding(void) {
static void assert_decodes_as(const char *buffer, gpr_timespec expected) {
gpr_timespec got;
gpr_log(GPR_INFO, "check decoding '%s'", buffer);
- GPR_ASSERT(1 == grpc_http2_decode_timeout((const uint8_t *)buffer,
- strlen(buffer), &got));
+ GPR_ASSERT(1 == grpc_http2_decode_timeout(
+ grpc_slice_from_static_string(buffer), &got));
GPR_ASSERT(0 == gpr_time_cmp(got, expected));
}
@@ -137,7 +137,8 @@ void test_decoding(void) {
static void assert_decoding_fails(const char *s) {
gpr_timespec x;
- GPR_ASSERT(0 == grpc_http2_decode_timeout((const uint8_t *)s, strlen(s), &x));
+ GPR_ASSERT(0 ==
+ grpc_http2_decode_timeout(grpc_slice_from_static_string(s), &x));
}
void test_decoding_fails(void) {