1 /** @file
2 
3   A brief file description
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22  */
23 
24 #include <iostream>
25 #include <cassert>
26 #include <string>
27 
28 #include "print_funcs.h"
29 #include "Utils.h"
30 
31 using std::cout;
32 using std::cerr;
33 using std::endl;
34 using std::string;
35 using namespace EsiLib;
36 
37 void
checkAttributes(const char * check_id,const AttributeList & attr_list,const char * attr_info[])38 checkAttributes(const char *check_id, const AttributeList &attr_list, const char *attr_info[])
39 {
40   cout << check_id << ": checking attributes" << endl;
41   AttributeList::const_iterator iter = attr_list.begin();
42   for (int i = 0; attr_info[i]; i += 2, ++iter) {
43     assert(iter->name_len == static_cast<int>(strlen(attr_info[i])));
44     assert(strncmp(iter->name, attr_info[i], iter->name_len) == 0);
45     assert(iter->value_len == static_cast<int>(strlen(attr_info[i + 1])));
46     assert(strncmp(iter->value, attr_info[i + 1], iter->value_len) == 0);
47   }
48   assert(iter == attr_list.end());
49 }
50 
51 int
main()52 main()
53 {
54   Utils::init(&Debug, &Error);
55 
56   AttributeList attr_list;
57 
58   string str1("pos=SKY spaceid=12123");
59   Utils::parseAttributes(str1, attr_list);
60   const char *expected_strs1[] = {"pos", "SKY", "spaceid", "12123", nullptr};
61   checkAttributes("test1", attr_list, expected_strs1);
62 
63   string str2("  pos=SKY	  spaceid=12123 ");
64   Utils::parseAttributes(str2, attr_list);
65   const char *expected_strs2[] = {"pos", "SKY", "spaceid", "12123", nullptr};
66   checkAttributes("test2", attr_list, expected_strs2);
67 
68   string str3("  pos=\"SKY\"	  spaceid=12123 ");
69   Utils::parseAttributes(str3, attr_list);
70   const char *expected_strs3[] = {"pos", "SKY", "spaceid", "12123", nullptr};
71   checkAttributes("test3", attr_list, expected_strs3);
72 
73   string str4("  pos=\" SKY BAR \"	  spaceid=12123 blah=\"foo");
74   Utils::parseAttributes(str4, attr_list);
75   const char *expected_strs4[] = {"pos", " SKY BAR ", "spaceid", "12123", nullptr};
76   checkAttributes("test4", attr_list, expected_strs4);
77 
78   string str5(R"(a="b & xyz"&c=d&e=f&g=h")");
79   Utils::parseAttributes(str5, attr_list, "&");
80   const char *expected_strs5[] = {"a", "b & xyz", "c", "d", "e", "f", nullptr};
81   checkAttributes("test5", attr_list, expected_strs5);
82 
83   string str6("abcd=&");
84   Utils::parseAttributes(str6, attr_list, "&");
85   const char *expected_strs6[] = {nullptr};
86   checkAttributes("test6", attr_list, expected_strs6);
87 
88   string str7("&& abcd=& key1=val1 &=val2&val3&&");
89   Utils::parseAttributes(str7, attr_list, "&");
90   const char *expected_strs7[] = {"key1", "val1", nullptr};
91   checkAttributes("test7", attr_list, expected_strs7);
92 
93   const char *escaped_sequence = R"({\"site-attribute\":\"content=no_expandable; ajax_cert_expandable\"})";
94   string str8(R"(pos="FPM1" spaceid=96584352 extra_mime=")");
95   str8.append(escaped_sequence);
96   str8.append(R"(" foo=bar a="b")");
97   const char *expected_strs8[] = {"pos", "FPM1", "spaceid", "96584352", "extra_mime", escaped_sequence,
98                                   "foo", "bar",  "a",       "b",        nullptr};
99   Utils::parseAttributes(str8, attr_list);
100   checkAttributes("test8", attr_list, expected_strs8);
101 
102   assert(Utils::unescape(escaped_sequence) == "{\"site-attribute\":\"content=no_expandable; ajax_cert_expandable\"}");
103   assert(Utils::unescape(nullptr) == "");
104   assert(Utils::unescape("\\", 0) == "");
105   assert(Utils::unescape("\\hello\"", 3) == "he");
106   assert(Utils::unescape("\\hello\"", -3) == "");
107   assert(Utils::unescape("hello") == "hello");
108 
109   string str9("n1=v1; n2=v2;, n3=v3, ;n4=v4=extrav4");
110   Utils::parseAttributes(str9, attr_list, ";,");
111   const char *expected_strs9[] = {"n1", "v1", "n2", "v2", "n3", "v3", "n4", "v4=extrav4", nullptr};
112   checkAttributes("test9", attr_list, expected_strs9);
113 
114   string str10("hello=world&test=萌萌&a=b");
115   Utils::parseAttributes(str10, attr_list, "&");
116   const char *expected_strs10[] = {"hello", "world", "test", "萌萌", "a", "b", nullptr};
117   checkAttributes("test10", attr_list, expected_strs10);
118 
119   cout << "Test 11 " << endl;
120   std::list<string> lines;
121   lines.push_back("allowlistCookie AGE");
122   lines.push_back("allowlistCookie GRADE");
123   lines.push_back("a b");
124   Utils::KeyValueMap kv;
125   Utils::HeaderValueList list;
126   Utils::parseKeyValueConfig(lines, kv, list);
127   assert(kv.find("a")->second == "b");
128   assert(list.back() == "GRADE");
129   list.pop_back();
130   assert(list.back() == "AGE");
131   list.pop_back();
132 
133   cout << endl << "All tests passed!" << endl;
134   return 0;
135 }
136