• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2015 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 "src/core/lib/slice/b64.h"
20 
21 #include <string.h>
22 
23 #include <grpc/grpc.h>
24 #include <grpc/slice.h>
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include "src/core/lib/iomgr/exec_ctx.h"
28 #include "src/core/lib/slice/slice_internal.h"
29 #include "test/core/util/test_config.h"
30 
buffers_are_equal(const unsigned char * buf1,const unsigned char * buf2,size_t size)31 static int buffers_are_equal(const unsigned char* buf1,
32                              const unsigned char* buf2, size_t size) {
33   size_t i;
34   for (i = 0; i < size; i++) {
35     if (buf1[i] != buf2[i]) {
36       gpr_log(GPR_ERROR, "buf1 and buf2 differ: buf1[%d] = %x vs buf2[%d] = %x",
37               static_cast<int>(i), buf1[i], static_cast<int>(i), buf2[i]);
38       return 0;
39     }
40   }
41   return 1;
42 }
43 
test_simple_encode_decode_b64(int url_safe,int multiline)44 static void test_simple_encode_decode_b64(int url_safe, int multiline) {
45   const char* hello = "hello";
46   char* hello_b64 =
47       grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
48   grpc_core::ExecCtx exec_ctx;
49   grpc_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
50   GPR_ASSERT(GRPC_SLICE_LENGTH(hello_slice) == strlen(hello));
51   GPR_ASSERT(strncmp((const char*)GRPC_SLICE_START_PTR(hello_slice), hello,
52                      GRPC_SLICE_LENGTH(hello_slice)) == 0);
53 
54   grpc_slice_unref_internal(hello_slice);
55 
56   gpr_free(hello_b64);
57 }
58 
test_full_range_encode_decode_b64(int url_safe,int multiline)59 static void test_full_range_encode_decode_b64(int url_safe, int multiline) {
60   unsigned char orig[256];
61   size_t i;
62   char* b64;
63   grpc_slice orig_decoded;
64   for (i = 0; i < sizeof(orig); i++) orig[i] = static_cast<uint8_t>(i);
65 
66   /* Try all the different paddings. */
67   for (i = 0; i < 3; i++) {
68     grpc_core::ExecCtx exec_ctx;
69     b64 = grpc_base64_encode(orig, sizeof(orig) - i, url_safe, multiline);
70     orig_decoded = grpc_base64_decode(b64, url_safe);
71     GPR_ASSERT(GRPC_SLICE_LENGTH(orig_decoded) == (sizeof(orig) - i));
72     GPR_ASSERT(buffers_are_equal(orig, GRPC_SLICE_START_PTR(orig_decoded),
73                                  sizeof(orig) - i));
74     grpc_slice_unref_internal(orig_decoded);
75     gpr_free(b64);
76   }
77 }
78 
test_simple_encode_decode_b64_no_multiline(void)79 static void test_simple_encode_decode_b64_no_multiline(void) {
80   test_simple_encode_decode_b64(0, 0);
81 }
82 
test_simple_encode_decode_b64_multiline(void)83 static void test_simple_encode_decode_b64_multiline(void) {
84   test_simple_encode_decode_b64(0, 1);
85 }
86 
test_simple_encode_decode_b64_urlsafe_no_multiline(void)87 static void test_simple_encode_decode_b64_urlsafe_no_multiline(void) {
88   test_simple_encode_decode_b64(1, 0);
89 }
90 
test_simple_encode_decode_b64_urlsafe_multiline(void)91 static void test_simple_encode_decode_b64_urlsafe_multiline(void) {
92   test_simple_encode_decode_b64(1, 1);
93 }
94 
test_full_range_encode_decode_b64_no_multiline(void)95 static void test_full_range_encode_decode_b64_no_multiline(void) {
96   test_full_range_encode_decode_b64(0, 0);
97 }
98 
test_full_range_encode_decode_b64_multiline(void)99 static void test_full_range_encode_decode_b64_multiline(void) {
100   test_full_range_encode_decode_b64(0, 1);
101 }
102 
test_full_range_encode_decode_b64_urlsafe_no_multiline(void)103 static void test_full_range_encode_decode_b64_urlsafe_no_multiline(void) {
104   test_full_range_encode_decode_b64(1, 0);
105 }
106 
test_full_range_encode_decode_b64_urlsafe_multiline(void)107 static void test_full_range_encode_decode_b64_urlsafe_multiline(void) {
108   test_full_range_encode_decode_b64(1, 1);
109 }
110 
test_url_safe_unsafe_mismatch_failure(void)111 static void test_url_safe_unsafe_mismatch_failure(void) {
112   unsigned char orig[256];
113   size_t i;
114   char* b64;
115   grpc_slice orig_decoded;
116   int url_safe = 1;
117   for (i = 0; i < sizeof(orig); i++) orig[i] = static_cast<uint8_t>(i);
118 
119   grpc_core::ExecCtx exec_ctx;
120   b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0);
121   orig_decoded = grpc_base64_decode(b64, !url_safe);
122   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
123   gpr_free(b64);
124   grpc_slice_unref_internal(orig_decoded);
125 
126   b64 = grpc_base64_encode(orig, sizeof(orig), !url_safe, 0);
127   orig_decoded = grpc_base64_decode(b64, url_safe);
128   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
129   gpr_free(b64);
130   grpc_slice_unref_internal(orig_decoded);
131 }
132 
test_rfc4648_test_vectors(void)133 static void test_rfc4648_test_vectors(void) {
134   char* b64;
135 
136   b64 = grpc_base64_encode("", 0, 0, 0);
137   GPR_ASSERT(strcmp("", b64) == 0);
138   gpr_free(b64);
139 
140   b64 = grpc_base64_encode("f", 1, 0, 0);
141   GPR_ASSERT(strcmp("Zg==", b64) == 0);
142   gpr_free(b64);
143 
144   b64 = grpc_base64_encode("fo", 2, 0, 0);
145   GPR_ASSERT(strcmp("Zm8=", b64) == 0);
146   gpr_free(b64);
147 
148   b64 = grpc_base64_encode("foo", 3, 0, 0);
149   GPR_ASSERT(strcmp("Zm9v", b64) == 0);
150   gpr_free(b64);
151 
152   b64 = grpc_base64_encode("foob", 4, 0, 0);
153   GPR_ASSERT(strcmp("Zm9vYg==", b64) == 0);
154   gpr_free(b64);
155 
156   b64 = grpc_base64_encode("fooba", 5, 0, 0);
157   GPR_ASSERT(strcmp("Zm9vYmE=", b64) == 0);
158   gpr_free(b64);
159 
160   b64 = grpc_base64_encode("foobar", 6, 0, 0);
161   GPR_ASSERT(strcmp("Zm9vYmFy", b64) == 0);
162   gpr_free(b64);
163 }
164 
test_unpadded_decode(void)165 static void test_unpadded_decode(void) {
166   grpc_slice decoded;
167 
168   grpc_core::ExecCtx exec_ctx;
169   decoded = grpc_base64_decode("Zm9vYmFy", 0);
170   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
171   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foobar") == 0);
172   grpc_slice_unref(decoded);
173 
174   decoded = grpc_base64_decode("Zm9vYmE", 0);
175   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
176   GPR_ASSERT(grpc_slice_str_cmp(decoded, "fooba") == 0);
177   grpc_slice_unref(decoded);
178 
179   decoded = grpc_base64_decode("Zm9vYg", 0);
180   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
181   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foob") == 0);
182   grpc_slice_unref(decoded);
183 
184   decoded = grpc_base64_decode("Zm9v", 0);
185   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
186   GPR_ASSERT(grpc_slice_str_cmp(decoded, "foo") == 0);
187   grpc_slice_unref(decoded);
188 
189   decoded = grpc_base64_decode("Zm8", 0);
190   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
191   GPR_ASSERT(grpc_slice_str_cmp(decoded, "fo") == 0);
192   grpc_slice_unref(decoded);
193 
194   decoded = grpc_base64_decode("Zg", 0);
195   GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
196   GPR_ASSERT(grpc_slice_str_cmp(decoded, "f") == 0);
197   grpc_slice_unref(decoded);
198 
199   decoded = grpc_base64_decode("", 0);
200   GPR_ASSERT(GRPC_SLICE_IS_EMPTY(decoded));
201 }
202 
main(int argc,char ** argv)203 int main(int argc, char** argv) {
204   grpc_test_init(argc, argv);
205   grpc_init();
206   test_simple_encode_decode_b64_no_multiline();
207   test_simple_encode_decode_b64_multiline();
208   test_simple_encode_decode_b64_urlsafe_no_multiline();
209   test_simple_encode_decode_b64_urlsafe_multiline();
210   test_full_range_encode_decode_b64_no_multiline();
211   test_full_range_encode_decode_b64_multiline();
212   test_full_range_encode_decode_b64_urlsafe_no_multiline();
213   test_full_range_encode_decode_b64_urlsafe_multiline();
214   test_url_safe_unsafe_mismatch_failure();
215   test_rfc4648_test_vectors();
216   test_unpadded_decode();
217   grpc_shutdown();
218   return 0;
219 }
220