1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2014 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h> 32 #include <google/protobuf/testing/googletest.h> 33 #include <gtest/gtest.h> 34 35 namespace google { 36 namespace protobuf { 37 namespace compiler { 38 namespace objectivec { 39 namespace { 40 41 TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { 42 string input_for_decode("abcdefghIJ"); 43 string desired_output_for_decode; 44 string expected; 45 string result; 46 47 // Different data, can't transform. 48 49 desired_output_for_decode = "zbcdefghIJ"; 50 expected = string("\0zbcdefghIJ\0", 12); 51 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 52 desired_output_for_decode); 53 EXPECT_EQ(expected, result); 54 55 desired_output_for_decode = "abcdezghIJ"; 56 expected = string("\0abcdezghIJ\0", 12); 57 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 58 desired_output_for_decode); 59 EXPECT_EQ(expected, result); 60 61 // Shortened data, can't transform. 62 63 desired_output_for_decode = "abcdefghI"; 64 expected = string("\0abcdefghI\0", 11); 65 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 66 desired_output_for_decode); 67 EXPECT_EQ(expected, result); 68 69 // Extra data, can't transform. 70 71 desired_output_for_decode = "abcdefghIJz"; 72 expected = string("\0abcdefghIJz\0", 13); 73 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 74 desired_output_for_decode); 75 EXPECT_EQ(expected, result); 76 } 77 78 TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) { 79 string input_for_decode("abcdefghIJ"); 80 string desired_output_for_decode; 81 string expected; 82 string result; 83 84 desired_output_for_decode = "abcdefghIJ"; 85 expected = string("\x0A\x0", 2); 86 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 87 desired_output_for_decode); 88 EXPECT_EQ(expected, result); 89 90 desired_output_for_decode = "_AbcdefghIJ"; 91 expected = string("\xCA\x0", 2); 92 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 93 desired_output_for_decode); 94 EXPECT_EQ(expected, result); 95 96 desired_output_for_decode = "ABCD__EfghI_j"; 97 expected = string("\x64\x80\xC5\xA1\x0", 5); 98 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 99 desired_output_for_decode); 100 EXPECT_EQ(expected, result); 101 102 // Long name so multiple decode ops are needed. 103 104 input_for_decode = 105 "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000"; 106 desired_output_for_decode = 107 "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000"; 108 expected = string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9); 109 result = TextFormatDecodeData::DecodeDataForString(input_for_decode, 110 desired_output_for_decode); 111 EXPECT_EQ(expected, result); 112 } 113 114 // Death tests do not work on Windows as of yet. 115 #ifdef PROTOBUF_HAS_DEATH_TEST 116 TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) { 117 // Empty inputs. 118 119 EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", ""), 120 ::testing::KilledBySignal(SIGABRT), 121 "error: got empty string for making TextFormat data, input:"); 122 EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("a", ""), 123 ::testing::KilledBySignal(SIGABRT), 124 "error: got empty string for making TextFormat data, input:"); 125 EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", "a"), 126 ::testing::KilledBySignal(SIGABRT), 127 "error: got empty string for making TextFormat data, input:"); 128 129 // Null char in the string. 130 131 string str_with_null_char("ab\0c", 4); 132 EXPECT_EXIT( 133 TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"), 134 ::testing::KilledBySignal(SIGABRT), 135 "error: got a null char in a string for making TextFormat data, input:"); 136 EXPECT_EXIT( 137 TextFormatDecodeData::DecodeDataForString("def", str_with_null_char), 138 ::testing::KilledBySignal(SIGABRT), 139 "error: got a null char in a string for making TextFormat data, input:"); 140 } 141 #endif // PROTOBUF_HAS_DEATH_TEST 142 143 TEST(ObjCHelper, TextFormatDecodeData_RawStrings) { 144 TextFormatDecodeData decode_data; 145 146 // Different data, can't transform. 147 decode_data.AddString(1, "abcdefghIJ", "zbcdefghIJ"); 148 decode_data.AddString(3, "abcdefghIJ", "abcdezghIJ"); 149 // Shortened data, can't transform. 150 decode_data.AddString(2, "abcdefghIJ", "abcdefghI"); 151 // Extra data, can't transform. 152 decode_data.AddString(4, "abcdefghIJ", "abcdefghIJz"); 153 154 EXPECT_EQ(4, decode_data.num_entries()); 155 156 uint8 expected_data[] = { 157 0x4, 158 0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0, 159 0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0, 160 0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0, 161 0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0, 162 }; 163 string expected((const char*)expected_data, sizeof(expected_data)); 164 165 EXPECT_EQ(expected, decode_data.Data()); 166 } 167 168 TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) { 169 TextFormatDecodeData decode_data; 170 171 decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ"); 172 decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ"); 173 decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ"); 174 decode_data.AddString(4, "abcdefghIJ", "ABCD__EfghI_j"); 175 decode_data.AddString(1000, 176 "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000", 177 "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000"); 178 179 EXPECT_EQ(5, decode_data.num_entries()); 180 181 uint8 expected_data[] = { 182 0x5, 183 // All as is (00 op) 184 0x1, 0x0A, 0x0, 185 // Underscore, upper + 9 (10 op) 186 0x3, 0xCA, 0x0, 187 // Upper + 3 (10 op), underscore, upper + 5 (10 op) 188 0x2, 0x44, 0xC6, 0x0, 189 // All Upper for 4 (11 op), underscore, underscore, upper + 5 (10 op), 190 // underscore, lower + 0 (01 op) 191 0x4, 0x64, 0x80, 0xC5, 0xA1, 0x0, 192 // 2 byte key: as is + 3 (00 op), underscore, lower + 4 (01 op), 193 // underscore, lower + 3 (01 op), underscore, lower + 1 (01 op), 194 // underscore, lower + 30 (01 op), as is + 30 (00 op), as is + 13 (00 195 // op), 196 // underscore, as is + 3 (00 op) 197 0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0, 198 }; 199 string expected((const char*)expected_data, sizeof(expected_data)); 200 201 EXPECT_EQ(expected, decode_data.Data()); 202 } 203 204 205 // Death tests do not work on Windows as of yet. 206 #ifdef PROTOBUF_HAS_DEATH_TEST 207 TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) { 208 TextFormatDecodeData decode_data; 209 210 // Empty inputs. 211 212 EXPECT_EXIT(decode_data.AddString(1, "", ""), 213 ::testing::KilledBySignal(SIGABRT), 214 "error: got empty string for making TextFormat data, input:"); 215 EXPECT_EXIT(decode_data.AddString(1, "a", ""), 216 ::testing::KilledBySignal(SIGABRT), 217 "error: got empty string for making TextFormat data, input:"); 218 EXPECT_EXIT(decode_data.AddString(1, "", "a"), 219 ::testing::KilledBySignal(SIGABRT), 220 "error: got empty string for making TextFormat data, input:"); 221 222 // Null char in the string. 223 224 string str_with_null_char("ab\0c", 4); 225 EXPECT_EXIT( 226 decode_data.AddString(1, str_with_null_char, "def"), 227 ::testing::KilledBySignal(SIGABRT), 228 "error: got a null char in a string for making TextFormat data, input:"); 229 EXPECT_EXIT( 230 decode_data.AddString(1, "def", str_with_null_char), 231 ::testing::KilledBySignal(SIGABRT), 232 "error: got a null char in a string for making TextFormat data, input:"); 233 234 // Duplicate keys 235 236 decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ"); 237 decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ"); 238 decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ"); 239 EXPECT_EXIT(decode_data.AddString(2, "xyz", "x_yz"), 240 ::testing::KilledBySignal(SIGABRT), 241 "error: duplicate key \\(2\\) making TextFormat data, input:"); 242 } 243 #endif // PROTOBUF_HAS_DEATH_TEST 244 245 // TODO(thomasvl): Should probably add some unittests for all the special cases 246 // of name mangling (class name, field name, enum names). Rather than doing 247 // this with an ObjC test in the objectivec directory, we should be able to 248 // use src/google/protobuf/compiler/importer* (like other tests) to support a 249 // virtual file system to feed in protos, once we have the Descriptor tree, the 250 // tests could use the helper methods for generating names and validate the 251 // right things are happening. 252 253 } // namespace 254 } // namespace objectivec 255 } // namespace compiler 256 } // namespace protobuf 257 } // namespace google 258