1 /*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <grpc/support/port_platform.h>
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include <grpc/grpc.h>
25 #include <grpc/support/alloc.h>
26
27 #include "src/core/lib/iomgr/error.h"
28 #include "src/core/lib/slice/slice_internal.h"
29 #include "src/core/lib/slice/slice_string_helpers.h"
30 #include "src/core/lib/surface/validate_metadata.h"
31
conforms_to(grpc_slice slice,const uint8_t * legal_bits,const char * err_desc)32 static grpc_error* conforms_to(grpc_slice slice, const uint8_t* legal_bits,
33 const char* err_desc) {
34 const uint8_t* p = GRPC_SLICE_START_PTR(slice);
35 const uint8_t* e = GRPC_SLICE_END_PTR(slice);
36 for (; p != e; p++) {
37 int idx = *p;
38 int byte = idx / 8;
39 int bit = idx % 8;
40 if ((legal_bits[byte] & (1 << bit)) == 0) {
41 char* dump = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
42 grpc_error* error = grpc_error_set_str(
43 grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc),
44 GRPC_ERROR_INT_OFFSET,
45 p - GRPC_SLICE_START_PTR(slice)),
46 GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(dump));
47 gpr_free(dump);
48 return error;
49 }
50 }
51 return GRPC_ERROR_NONE;
52 }
53
error2int(grpc_error * error)54 static int error2int(grpc_error* error) {
55 int r = (error == GRPC_ERROR_NONE);
56 GRPC_ERROR_UNREF(error);
57 return r;
58 }
59
grpc_validate_header_key_is_legal(grpc_slice slice)60 grpc_error* grpc_validate_header_key_is_legal(grpc_slice slice) {
61 static const uint8_t legal_header_bits[256 / 8] = {
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00,
63 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
65 if (GRPC_SLICE_LENGTH(slice) == 0) {
66 return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
67 "Metadata keys cannot be zero length");
68 }
69 if (GRPC_SLICE_START_PTR(slice)[0] == ':') {
70 return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
71 "Metadata keys cannot start with :");
72 }
73 return conforms_to(slice, legal_header_bits, "Illegal header key");
74 }
75
grpc_header_key_is_legal(grpc_slice slice)76 int grpc_header_key_is_legal(grpc_slice slice) {
77 return error2int(grpc_validate_header_key_is_legal(slice));
78 }
79
grpc_validate_header_nonbin_value_is_legal(grpc_slice slice)80 grpc_error* grpc_validate_header_nonbin_value_is_legal(grpc_slice slice) {
81 static const uint8_t legal_header_bits[256 / 8] = {
82 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
83 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
85 return conforms_to(slice, legal_header_bits, "Illegal header value");
86 }
87
grpc_header_nonbin_value_is_legal(grpc_slice slice)88 int grpc_header_nonbin_value_is_legal(grpc_slice slice) {
89 return error2int(grpc_validate_header_nonbin_value_is_legal(slice));
90 }
91
grpc_is_binary_header(grpc_slice slice)92 int grpc_is_binary_header(grpc_slice slice) {
93 if (GRPC_SLICE_LENGTH(slice) < 5) return 0;
94 return 0 == memcmp(GRPC_SLICE_END_PTR(slice) - 4, "-bin", 4);
95 }
96