diff options
author | Craig Tiller <ctiller@google.com> | 2016-01-06 16:38:12 -0800 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2016-01-06 16:38:12 -0800 |
commit | 160a690a4cdbb8b359580564bfda215259dc0d52 (patch) | |
tree | 311cc8df38536b5b76f67354e2e1b8ccc039a5d1 /src | |
parent | 296ae72581f17438e9355d4862c3ad5c66d49807 (diff) | |
parent | 36187ab66b562a536d13999ee31c36cdee760d48 (diff) |
Merge pull request #4633 from murgatroid99/core_validate_metadata
Expose core metadata validation functions in public headers
Diffstat (limited to 'src')
-rw-r--r-- | src/core/surface/call.c | 13 | ||||
-rw-r--r-- | src/core/surface/validate_metadata.c | 70 | ||||
-rw-r--r-- | src/core/transport/chttp2/bin_encoder.c | 7 | ||||
-rw-r--r-- | src/core/transport/chttp2/bin_encoder.h | 4 | ||||
-rw-r--r-- | src/core/transport/chttp2/hpack_encoder.c | 7 | ||||
-rw-r--r-- | src/core/transport/chttp2/hpack_parser.c | 7 | ||||
-rw-r--r-- | src/core/transport/metadata.c | 34 | ||||
-rw-r--r-- | src/core/transport/metadata.h | 2 |
8 files changed, 95 insertions, 49 deletions
diff --git a/src/core/surface/call.c b/src/core/surface/call.c index a162d99193..2782c1a4dd 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.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 @@ -37,6 +37,7 @@ #include <string.h> #include <grpc/compression.h> +#include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> @@ -562,12 +563,16 @@ static int prepare_application_metadata(grpc_call *call, int count, GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data)); l->md = grpc_mdelem_from_string_and_buffer( md->key, (const gpr_uint8 *)md->value, md->value_length); - if (!grpc_mdstr_is_legal_header(l->md->key)) { + if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key), + GRPC_MDSTR_LENGTH(l->md->key))) { gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", grpc_mdstr_as_c_string(l->md->key)); return 0; - } else if (!grpc_mdstr_is_bin_suffixed(l->md->key) && - !grpc_mdstr_is_legal_nonbin_header(l->md->value)) { + } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key), + GRPC_MDSTR_LENGTH(l->md->key)) && + !grpc_header_nonbin_value_is_legal( + grpc_mdstr_as_c_string(l->md->value), + GRPC_MDSTR_LENGTH(l->md->value))) { gpr_log(GPR_ERROR, "attempt to send invalid metadata value"); return 0; } diff --git a/src/core/surface/validate_metadata.c b/src/core/surface/validate_metadata.c new file mode 100644 index 0000000000..94fb3963b2 --- /dev/null +++ b/src/core/surface/validate_metadata.c @@ -0,0 +1,70 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include <grpc/support/port_platform.h> + +static int conforms_to(const char *s, size_t len, const gpr_uint8 *legal_bits) { + const char *p = s; + const char *e = s + len; + for (; p != e; p++) { + int idx = *p; + int byte = idx / 8; + int bit = idx % 8; + if ((legal_bits[byte] & (1 << bit)) == 0) return 0; + } + return 1; +} + +int grpc_header_key_is_legal(const char *key, size_t length) { + static const gpr_uint8 legal_header_bits[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + return conforms_to(key, length, legal_header_bits); +} + +int grpc_header_nonbin_value_is_legal(const char *value, size_t length) { + static const gpr_uint8 legal_header_bits[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + return conforms_to(value, length, legal_header_bits); +} + +int grpc_is_binary_header(const char *key, size_t length) { + if (length < 5) return 0; + return 0 == memcmp(key + length - 4, "-bin", 4); +} diff --git a/src/core/transport/chttp2/bin_encoder.c b/src/core/transport/chttp2/bin_encoder.c index 9c9070ede4..53ea9ac609 100644 --- a/src/core/transport/chttp2/bin_encoder.c +++ b/src/core/transport/chttp2/bin_encoder.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 @@ -283,8 +283,3 @@ gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input) { GPR_ASSERT(in == GPR_SLICE_END_PTR(input)); return output; } - -int grpc_is_binary_header(const char *key, size_t length) { - if (length < 5) return 0; - return 0 == memcmp(key + length - 4, "-bin", 4); -} diff --git a/src/core/transport/chttp2/bin_encoder.h b/src/core/transport/chttp2/bin_encoder.h index d3e5a855dd..036fddf998 100644 --- a/src/core/transport/chttp2/bin_encoder.h +++ b/src/core/transport/chttp2/bin_encoder.h @@ -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 @@ -51,6 +51,4 @@ gpr_slice grpc_chttp2_huffman_compress(gpr_slice input); return y; */ gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input); -int grpc_is_binary_header(const char *key, size_t length); - #endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */ diff --git a/src/core/transport/chttp2/hpack_encoder.c b/src/core/transport/chttp2/hpack_encoder.c index 6c558bc1cb..303b8f332a 100644 --- a/src/core/transport/chttp2/hpack_encoder.c +++ b/src/core/transport/chttp2/hpack_encoder.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 @@ -36,6 +36,11 @@ #include <assert.h> #include <string.h> +/* This is here for grpc_is_binary_header + * TODO(murgatroid99): Remove this + */ +#include <grpc/grpc.h> + #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/useful.h> diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c index fea0000896..48790c2ef2 100644 --- a/src/core/transport/chttp2/hpack_parser.c +++ b/src/core/transport/chttp2/hpack_parser.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 @@ -38,6 +38,11 @@ #include <string.h> #include <assert.h> +/* This is here for grpc_is_binary_header + * TODO(murgatroid99): Remove this + */ +#include <grpc/grpc.h> + #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/port_platform.h> diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c index df05d1a302..e645ef9d8c 100644 --- a/src/core/transport/metadata.c +++ b/src/core/transport/metadata.c @@ -688,37 +688,3 @@ gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) { gpr_mu_unlock(&shard->mu); return slice; } - -static int conforms_to(grpc_mdstr *s, const gpr_uint8 *legal_bits) { - const gpr_uint8 *p = GPR_SLICE_START_PTR(s->slice); - const gpr_uint8 *e = GPR_SLICE_END_PTR(s->slice); - for (; p != e; p++) { - int idx = *p; - int byte = idx / 8; - int bit = idx % 8; - if ((legal_bits[byte] & (1 << bit)) == 0) return 0; - } - return 1; -} - -int grpc_mdstr_is_legal_header(grpc_mdstr *s) { - static const gpr_uint8 legal_header_bits[256 / 8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - return conforms_to(s, legal_header_bits); -} - -int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s) { - static const gpr_uint8 legal_header_bits[256 / 8] = { - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - return conforms_to(s, legal_header_bits); -} - -int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s) { - /* TODO(ctiller): consider caching this */ - return grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(s->slice), - GPR_SLICE_LENGTH(s->slice)); -} diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h index 3d3efc682d..829c8a0873 100644 --- a/src/core/transport/metadata.h +++ b/src/core/transport/metadata.h @@ -142,6 +142,8 @@ void grpc_mdelem_unref(grpc_mdelem *md); Does not promise that the returned string has no embedded nulls however. */ const char *grpc_mdstr_as_c_string(grpc_mdstr *s); +#define GRPC_MDSTR_LENGTH(s) (GPR_SLICE_LENGTH(s->slice)) + int grpc_mdstr_is_legal_header(grpc_mdstr *s); int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s); int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s); |