MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pfs_connect_attr-t.cc
1 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #include <my_global.h>
17 #include <my_pthread.h>
18 #include <pfs_server.h>
19 #include <pfs_instr_class.h>
20 #include <pfs_instr.h>
21 #include <pfs_global.h>
22 #include <tap.h>
23 
24 
25 #include <string.h>
26 #include <memory.h>
27 
28 /* test helpers, to inspect data */
29 bool read_nth_attr(const char *connect_attrs, uint connect_attrs_length,
30  const CHARSET_INFO *connect_attrs_cs,
31  uint ordinal,
32  char *attr_name, uint max_attr_name,
33  uint *attr_name_length,
34  char *attr_value, uint max_attr_value,
35  uint *attr_value_length);
36 
37 void test_blob_parser()
38 {
39  char name[100], value[4096];
40  unsigned char packet[10000], *ptr;
41  uint name_len, value_len, idx, packet_length;
42  bool result;
43  const CHARSET_INFO *cs= &my_charset_utf8_bin;
44 
45  diag("test_blob_parser");
46 
47  result= read_nth_attr("", 0, cs, 0,
48  name, 32, &name_len, value, 1024, &value_len);
49  ok(result == false, "zero length blob");
50 
51 
52  result= read_nth_attr("\x1", 1, cs, 0,
53  name, 32, &name_len, value, 1024, &value_len);
54  ok(result == false, "invalid key length");
55 
56 
57  result= read_nth_attr("\x2k1\x1", 4, cs, 0,
58  name, 32, &name_len, value, 1024, &value_len);
59  ok(result == false, "invalid value length");
60 
61 
62  result= read_nth_attr("\x2k1\x2v1", 6, cs, 0,
63  name, 32, &name_len, value, 1024, &value_len);
64  ok(result == true, "one pair return");
65  ok(name_len == 2, "one pair attr name length");
66  ok(!strncmp(name, "k1", name_len), "one pair attr name");
67  ok(value_len == 2, "one pair value length");
68  ok(!strncmp(value, "v1", value_len), "one pair value");
69 
70  result= read_nth_attr("\x2k1\x2v1", 6, cs, 1,
71  name, 32, &name_len, value, 1024, &value_len);
72  ok(result == false, "no second arg");
73 
74  result= read_nth_attr("\x2k1\x2v1\x2k2\x2v2", 12, cs, 1,
75  name, 32, &name_len, value, 1024, &value_len);
76  ok(result == true, "two pairs return");
77  ok(name_len == 2, "two pairs attr name length");
78  ok(!strncmp(name, "k2", name_len), "two pairs attr name");
79  ok(value_len == 2, "two pairs value length");
80  ok(!strncmp(value, "v2", value_len), "two pairs value");
81 
82  result= read_nth_attr("\x2k1\xff\x2k2\x2v2", 12, cs, 1,
83  name, 32, &name_len, value, 1024, &value_len);
84  ok(result == false, "two pairs first value bad return");
85 
86  result= read_nth_attr("\x2k1\x2v1\x2k2\x2v2", 10, cs, 1,
87  name, 32, &name_len, value, 1024, &value_len);
88  ok(result == false, "two pairs wrong global length");
89 
90  result= read_nth_attr("\x21z123456789z123456789z123456789z12\x2v1", 37, cs, 0,
91  name, 32, &name_len, value, 1024, &value_len);
92  ok(result == true, "attr name overflow");
93  ok(name_len == 32, "attr name overflow length");
94  ok(!strncmp(name, "z123456789z123456789z123456789z1", name_len),
95  "attr name overflow name");
96  ok(value_len == 2, "attr name overflow value length");
97  ok(!strncmp(value, "v1", value_len), "attr name overflow value");
98 
99  packet[0]= 2;
100  packet[1]= 'k';
101  packet[2]= '1';
102  ptr= net_store_length(packet + 3, 1025);
103  for (idx= 0; idx < 1025; idx++)
104  *ptr++= '0' + (idx % 10);
105  packet_length= (uint) (ptr - packet);
106  result= read_nth_attr((char *) packet, packet_length, cs, 0,
107  name, 32, &name_len, value, 1024, &value_len);
108  ok(result == true, "attr value overflow");
109  ok(name_len == 2, "attr value overflow length");
110  ok(!strncmp(name, "k1", name_len), "attr value overflow name");
111  ok(value_len == 1024, "attr value overflow value length");
112  for (idx= 0; idx < 1024; idx++)
113  {
114  if (value[idx] != (char) ('0' + (idx % 10)))
115  break;
116  }
117  ok (idx == 1024, "attr value overflow value");
118 
119  result= read_nth_attr("\x21z123456789z123456789z123456789z12\x2v1\x2k2\x2v2",
120  43, cs, 1,
121  name, 32, &name_len, value, 1024, &value_len);
122  ok(result == true, "prev attr name overflow");
123  ok(name_len == 2, "prev attr name overflow length");
124  ok(!strncmp(name, "k2", name_len),
125  "prev attr name overflow name");
126  ok(value_len == 2, "prev attr name overflow value length");
127  ok(!strncmp(value, "v2", value_len), "prev attr name overflow value");
128 
129 
130  packet[1]= 'k';
131  packet[2]= '1';
132  packet[3]= 2;
133  packet[4]= 'v';
134  packet[5]= '1';
135 
136  for(idx= 251; idx < 256; idx++)
137  {
138  packet[0]= idx;
139  result= read_nth_attr((char *) packet, 6, cs, 0,
140  name, 32, &name_len, value, 1024, &value_len);
141  ok(result == false, "invalid string length %d", idx);
142  }
143 
144  memset(packet, 0, sizeof(packet));
145  for (idx=0; idx < 1660 /* *6 = 9960 */; idx++)
146  memcpy(packet + idx * 6, "\x2k1\x2v1", 6);
147  result= read_nth_attr((char *) packet, 8192, cs, 1364,
148  name, 32, &name_len, value, 1024, &value_len);
149  ok(result == true, "last valid attribute %d", 1364);
150  result= read_nth_attr((char *) packet, 8192, cs, 1365,
151  name, 32, &name_len, value, 1024, &value_len);
152  ok(result == false, "first attribute that's cut %d", 1365);
153 }
154 
155 void test_multibyte_lengths()
156 {
157  char name[100], value[4096];
158  uint name_len, value_len;
159  bool result;
160  const CHARSET_INFO *cs= &my_charset_utf8_bin;
161 
162  unsigned char var_len_packet[] = {
163  252, 2, 0, 'k', '1',
164  253, 2, 0, 0, 'v', '1',
165  254, 2, 0, 0, 0, 0, 0, 0, 0, 'k', '2',
166  254, 2, 0, 0, 0, 0, 0, 0, 0, 'v', '2'
167  };
168 
169  result= read_nth_attr((char *) var_len_packet, sizeof(var_len_packet), cs, 0,
170  name, 32, &name_len, value, 1024, &value_len);
171  ok(result == true, "multibyte lengths return");
172  ok(name_len == 2, "multibyte lengths name length");
173  ok(!strncmp(name, "k1", name_len), "multibyte lengths attr name");
174  ok(value_len == 2, "multibyte lengths value length");
175  ok(!strncmp(value, "v1", value_len), "multibyte lengths value");
176 
177  result= read_nth_attr((char *) var_len_packet, sizeof(var_len_packet), cs, 1,
178  name, 32, &name_len, value, 1024, &value_len);
179  ok(result == true, "multibyte lengths second attr return");
180  ok(name_len == 2, "multibyte lengths second attr name length");
181  ok(!strncmp(name, "k2", name_len), "multibyte lengths second attr attr name");
182  ok(value_len == 2, "multibyte lengths value length");
183  ok(!strncmp(value, "v2", value_len), "multibyte lengths second attr value");
184 }
185 
186 
187 void test_utf8_parser()
188 {
189  /* utf8 max byte length per character is 6 */
190  char name[33 * 6], value[1024 * 6], packet[1500 * 6], *ptr;
191  uint name_len, value_len;
192  bool result;
193  const CHARSET_INFO *cs= &my_charset_utf8_bin;
194 
195  /* note : this is encoded in utf-8 */
196  const char *attr1= "Георги";
197  const char *val1= "Кодинов";
198  const char *attr2= "Пловдив";
199  const char *val2= "България";
200 
201  ptr= packet;
202  *ptr++= strlen(attr1);
203  memcpy(ptr, attr1, strlen(attr1));
204  ptr+= strlen(attr1);
205  *ptr++= strlen(val1);
206  memcpy(ptr, val1, strlen(val1));
207  ptr+= strlen(val1);
208 
209  *ptr++= strlen(attr2);
210  memcpy(ptr, attr2, strlen(attr2));
211  ptr+= strlen(attr2);
212  *ptr++= strlen(val2);
213  memcpy(ptr, val2, strlen(val2));
214  ptr+= strlen(val2);
215 
216  diag("test_utf8_parser attr pair #1");
217 
218  result= read_nth_attr((char *) packet, ptr - packet, cs, 0,
219  name, sizeof(name), &name_len,
220  value, sizeof(value), &value_len);
221  ok(result == true, "return");
222  ok(name_len == strlen(attr1), "name length");
223  ok(!strncmp(name, attr1, name_len), "attr name");
224  ok(value_len == strlen(val1), "value length");
225  ok(!strncmp(value, val1, value_len), "value");
226 
227  diag("test_utf8_parser attr pair #2");
228  result= read_nth_attr((char *) packet, ptr - packet, cs, 1,
229  name, sizeof(name), &name_len,
230  value, sizeof(value), &value_len);
231  ok(result == true, "return");
232  ok(name_len == strlen(attr2), "name length");
233  ok(!strncmp(name, attr2, name_len), "attr name");
234  ok(value_len == strlen(val2), "value length");
235  ok(!strncmp(value, val2, value_len), "value");
236 }
237 
238 
239 void test_utf8_parser_bad_encoding()
240 {
241  /* utf8 max byte length per character is 3*/
242  char name[33 * 3], value[1024 * 3], packet[1500 * 3], *ptr;
243  uint name_len, value_len;
244  bool result;
245  const CHARSET_INFO *cs= &my_charset_utf8_bin;
246 
247  /* note : this is encoded in utf-8 */
248  const char *attr= "Георги";
249  const char *val= "Кодинов";
250 
251  ptr= packet;
252  *ptr++= strlen(attr);
253  memcpy(ptr, attr, strlen(attr));
254  ptr[0]= 0xFA; // invalid UTF-8 char
255  ptr+= strlen(attr);
256  *ptr++= strlen(val);
257  memcpy(ptr, val, strlen(val));
258  ptr+= strlen(val);
259 
260  diag("test_utf8_parser_bad_encoding");
261 
262  result= read_nth_attr((char *) packet, ptr - packet, cs, 0,
263  name, sizeof(name), &name_len,
264  value, sizeof(value), &value_len);
265  ok(result == false, "return");
266 }
267 
268 const CHARSET_INFO *cs_cp1251;
269 
270 void test_cp1251_parser()
271 {
272  /* utf8 max byte length per character is 3*/
273  char name[33 * 3], value[1024 * 3], packet[1500 * 3], *ptr;
274  uint name_len, value_len;
275  bool result;
276 
277  /* note : this is Георги in windows-1251 */
278  const char *attr1= "\xc3\xe5\xee\xf0\xe3\xe8";
279  /* note : this is Кодинов in windows-1251 */
280  const char *val1= "\xca\xee\xe4\xe8\xed\xee\xe2";
281  /* note : this is Пловдив in windows-1251 */
282  const char *attr2= "\xcf\xeb\xee\xe2\xe4\xe8\xe2";
283  /* note : this is България in windows-1251 */
284  const char *val2= "\xc1\xfa\xeb\xe3\xe0\xf0\xe8\xff";
285 
286  ptr= packet;
287  *ptr++= strlen(attr1);
288  memcpy(ptr, attr1, strlen(attr1));
289  ptr+= strlen(attr1);
290  *ptr++= strlen(val1);
291  memcpy(ptr, val1, strlen(val1));
292  ptr+= strlen(val1);
293 
294  *ptr++= strlen(attr2);
295  memcpy(ptr, attr2, strlen(attr2));
296  ptr+= strlen(attr2);
297  *ptr++= strlen(val2);
298  memcpy(ptr, val2, strlen(val2));
299  ptr+= strlen(val2);
300 
301  diag("test_cp1251_parser attr pair #1");
302 
303  result= read_nth_attr((char *) packet, ptr - packet, cs_cp1251, 0,
304  name, sizeof(name), &name_len,
305  value, sizeof(value), &value_len);
306  ok(result == true, "return");
307  /* need to compare to the UTF-8 equivalents */
308  ok(name_len == strlen("Георги"), "name length");
309  ok(!strncmp(name, "Георги", name_len), "attr name");
310  ok(value_len == strlen("Кодинов"), "value length");
311  ok(!strncmp(value, "Кодинов", value_len), "value");
312 
313  diag("test_cp1251_parser attr pair #2");
314  result= read_nth_attr((char *) packet, ptr - packet, cs_cp1251, 1,
315  name, sizeof(name), &name_len,
316  value, sizeof(value), &value_len);
317  ok(result == true, "return");
318  /* need to compare to the UTF-8 equivalents */
319  ok(name_len == strlen("Пловдив"), "name length");
320  ok(!strncmp(name, "Пловдив", name_len), "attr name");
321  ok(value_len == strlen("България"), "value length");
322  ok(!strncmp(value, "България", value_len), "value");
323 }
324 
325 
326 void do_all_tests()
327 {
328  test_blob_parser();
329  test_multibyte_lengths();
330  test_utf8_parser();
331  test_utf8_parser_bad_encoding();
332  test_cp1251_parser();
333 }
334 
335 int main(int, char **)
336 {
337  MY_INIT("pfs_connect_attr-t");
338 
339  cs_cp1251= get_charset_by_csname("cp1251", MY_CS_PRIMARY, MYF(0));
340  if (!cs_cp1251)
341  diag("skipping the cp1251 tests : missing character set");
342  plan(59 + (cs_cp1251 ? 10 : 0));
343  do_all_tests();
344  return 0;
345 }