Merge pull request #4776 from jtattermusch/fix_32bit_artifacts

Improve grpc_chttp2_decode_timeout implementation
pull/4784/merge
Jan Tattermusch 9 years ago
commit 4c70fe7187
  1. 17
      src/core/transport/chttp2/timeout_encoding.c
  2. 7
      test/core/transport/chttp2/timeout_encoding_test.c

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -137,7 +137,7 @@ static int is_all_whitespace(const char *p) {
}
int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) {
uint32_t x = 0;
int32_t x = 0;
const uint8_t *p = (const uint8_t *)buffer;
int have_digit = 0;
/* skip whitespace */
@ -145,13 +145,16 @@ int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) {
;
/* decode numeric part */
for (; *p >= '0' && *p <= '9'; p++) {
uint32_t xp = x * 10u + (uint32_t)*p - (uint32_t)'0';
int32_t digit = (int32_t)(*p - (uint8_t)'0');
have_digit = 1;
if (xp < x) {
*timeout = gpr_inf_future(GPR_CLOCK_REALTIME);
return 1;
/* spec allows max. 8 digits, but we allow values up to 1,000,000,000 */
if (x >= (100 * 1000 * 1000)) {
if (x != (100 * 1000 * 1000) || digit != 0) {
*timeout = gpr_inf_future(GPR_CLOCK_REALTIME);
return 1;
}
}
x = xp;
x = x * 10 + digit;
}
if (!have_digit) return 0;
/* skip whitespace */

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -126,8 +126,13 @@ void test_decoding(void) {
decode_suite('S', gpr_time_from_seconds);
decode_suite('M', gpr_time_from_minutes);
decode_suite('H', gpr_time_from_hours);
assert_decodes_as("1000000000S",
gpr_time_from_seconds(1000 * 1000 * 1000, GPR_TIMESPAN));
assert_decodes_as("1000000000000000000000u",
gpr_inf_future(GPR_CLOCK_REALTIME));
assert_decodes_as("1000000001S", gpr_inf_future(GPR_CLOCK_REALTIME));
assert_decodes_as("2000000001S", gpr_inf_future(GPR_CLOCK_REALTIME));
assert_decodes_as("9999999999S", gpr_inf_future(GPR_CLOCK_REALTIME));
}
void test_decoding_fails(void) {

Loading…
Cancel
Save