• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 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#import "GPBTestUtilities.h"
32
33#import "GPBUnknownField_PackagePrivate.h"
34#import "GPBUnknownFieldSet_PackagePrivate.h"
35#import "google/protobuf/Unittest.pbobjc.h"
36
37@interface GPBUnknownFieldSet (GPBUnknownFieldSetTest)
38- (void)getTags:(int32_t*)tags;
39@end
40
41@interface UnknownFieldSetTest : GPBTestCase {
42 @private
43  TestAllTypes* allFields_;
44  NSData* allFieldsData_;
45
46  // An empty message that has been parsed from allFieldsData.  So, it has
47  // unknown fields of every type.
48  TestEmptyMessage* emptyMessage_;
49  GPBUnknownFieldSet* unknownFields_;
50}
51
52@end
53
54@implementation UnknownFieldSetTest
55
56- (void)setUp {
57  allFields_ = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
58  allFieldsData_ = [allFields_ data];
59  emptyMessage_ = [TestEmptyMessage parseFromData:allFieldsData_ error:NULL];
60  unknownFields_ = emptyMessage_.unknownFields;
61}
62
63- (void)testInvalidFieldNumber {
64  GPBUnknownFieldSet *set = [[[GPBUnknownFieldSet alloc] init] autorelease];
65  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:0] autorelease];
66  XCTAssertThrowsSpecificNamed([set addField:field], NSException, NSInvalidArgumentException);
67}
68
69- (void)testEqualityAndHash {
70  // Empty
71
72  GPBUnknownFieldSet *set1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
73  XCTAssertTrue([set1 isEqual:set1]);
74  XCTAssertFalse([set1 isEqual:@"foo"]);
75  GPBUnknownFieldSet *set2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
76  XCTAssertEqualObjects(set1, set2);
77  XCTAssertEqual([set1 hash], [set2 hash]);
78
79  // Varint
80
81  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
82  [field1 addVarint:1];
83  [set1 addField:field1];
84  XCTAssertNotEqualObjects(set1, set2);
85  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
86  [field2 addVarint:1];
87  [set2 addField:field2];
88  XCTAssertEqualObjects(set1, set2);
89  XCTAssertEqual([set1 hash], [set2 hash]);
90
91  // Fixed32
92
93  field1 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
94  [field1 addFixed32:2];
95  [set1 addField:field1];
96  XCTAssertNotEqualObjects(set1, set2);
97  field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
98  [field2 addFixed32:2];
99  [set2 addField:field2];
100  XCTAssertEqualObjects(set1, set2);
101  XCTAssertEqual([set1 hash], [set2 hash]);
102
103  // Fixed64
104
105  field1 = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
106  [field1 addFixed64:3];
107  [set1 addField:field1];
108  XCTAssertNotEqualObjects(set1, set2);
109  field2 = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
110  [field2 addFixed64:3];
111  [set2 addField:field2];
112  XCTAssertEqualObjects(set1, set2);
113  XCTAssertEqual([set1 hash], [set2 hash]);
114
115  // LengthDelimited
116
117  field1 = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
118  [field1 addLengthDelimited:DataFromCStr("foo")];
119  [set1 addField:field1];
120  XCTAssertNotEqualObjects(set1, set2);
121  field2 = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
122  [field2 addLengthDelimited:DataFromCStr("foo")];
123  [set2 addField:field2];
124  XCTAssertEqualObjects(set1, set2);
125  XCTAssertEqual([set1 hash], [set2 hash]);
126
127  // Group
128
129  GPBUnknownFieldSet *group1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
130  GPBUnknownField* fieldGroup1 = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
131  [fieldGroup1 addVarint:1];
132  [group1 addField:fieldGroup1];
133  GPBUnknownFieldSet *group2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
134  GPBUnknownField* fieldGroup2 = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
135  [fieldGroup2 addVarint:1];
136  [group2 addField:fieldGroup2];
137
138  field1 = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
139  [field1 addGroup:group1];
140  [set1 addField:field1];
141  XCTAssertNotEqualObjects(set1, set2);
142  field2 = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
143  [field2 addGroup:group2];
144  [set2 addField:field2];
145  XCTAssertEqualObjects(set1, set2);
146  XCTAssertEqual([set1 hash], [set2 hash]);
147
148  // Exercise description for completeness.
149  XCTAssertTrue(set1.description.length > 10);
150}
151
152// Constructs a protocol buffer which contains fields with all the same
153// numbers as allFieldsData except that each field is some other wire
154// type.
155- (NSData*)getBizarroData {
156  GPBUnknownFieldSet* bizarroFields =
157      [[[GPBUnknownFieldSet alloc] init] autorelease];
158  NSUInteger count = [unknownFields_ countOfFields];
159  int32_t tags[count];
160  [unknownFields_ getTags:tags];
161  for (NSUInteger i = 0; i < count; ++i) {
162    int32_t tag = tags[i];
163    GPBUnknownField* field = [unknownFields_ getField:tag];
164    if (field.varintList.count == 0) {
165      // Original field is not a varint, so use a varint.
166      GPBUnknownField* varintField =
167          [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
168      [varintField addVarint:1];
169      [bizarroFields addField:varintField];
170    } else {
171      // Original field *is* a varint, so use something else.
172      GPBUnknownField* fixed32Field =
173          [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
174      [fixed32Field addFixed32:1];
175      [bizarroFields addField:fixed32Field];
176    }
177  }
178
179  return [bizarroFields data];
180}
181
182- (void)testSerialize {
183  // Check that serializing the UnknownFieldSet produces the original data
184  // again.
185  NSData* data = [emptyMessage_ data];
186  XCTAssertEqualObjects(allFieldsData_, data);
187}
188
189- (void)testCopyFrom {
190  TestEmptyMessage* message = [TestEmptyMessage message];
191  [message mergeFrom:emptyMessage_];
192
193  XCTAssertEqualObjects(emptyMessage_.data, message.data);
194}
195
196- (void)testMergeFrom {
197  GPBUnknownFieldSet* set1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
198  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
199  [field addVarint:2];
200  [set1 addField:field];
201  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
202  [field addVarint:4];
203  [set1 addField:field];
204  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
205  [field addFixed32:6];
206  [set1 addField:field];
207  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
208  [field addFixed64:20];
209  [set1 addField:field];
210  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
211  [field addLengthDelimited:DataFromCStr("data1")];
212  [set1 addField:field];
213
214  GPBUnknownFieldSet *group1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
215  GPBUnknownField* fieldGroup1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease];
216  [fieldGroup1 addVarint:100];
217  [group1 addField:fieldGroup1];
218
219  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
220  [field addGroup:group1];
221  [set1 addField:field];
222
223  GPBUnknownFieldSet* set2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
224  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
225  [field addVarint:1];
226  [set2 addField:field];
227  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
228  [field addVarint:3];
229  [set2 addField:field];
230  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
231  [field addFixed32:7];
232  [set2 addField:field];
233  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
234  [field addFixed64:30];
235  [set2 addField:field];
236  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
237  [field addLengthDelimited:DataFromCStr("data2")];
238  [set2 addField:field];
239
240  GPBUnknownFieldSet *group2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
241  GPBUnknownField* fieldGroup2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease];
242  [fieldGroup2 addVarint:99];
243  [group2 addField:fieldGroup2];
244
245  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
246  [field addGroup:group2];
247  [set2 addField:field];
248
249  GPBUnknownFieldSet* set3 = [[[GPBUnknownFieldSet alloc] init] autorelease];
250  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
251  [field addVarint:1];
252  [set3 addField:field];
253  field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
254  [field addVarint:2];
255  [set3 addField:field];
256  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
257  [field addVarint:4];
258  [set3 addField:field];
259  [field addVarint:3];
260  [set3 addField:field];
261  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
262  [field addFixed32:6];
263  [field addFixed32:7];
264  [set3 addField:field];
265  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
266  [field addFixed64:20];
267  [field addFixed64:30];
268  [set3 addField:field];
269  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
270  [field addLengthDelimited:DataFromCStr("data1")];
271  [field addLengthDelimited:DataFromCStr("data2")];
272  [set3 addField:field];
273
274  GPBUnknownFieldSet *group3a = [[[GPBUnknownFieldSet alloc] init] autorelease];
275  GPBUnknownField* fieldGroup3a1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease];
276  [fieldGroup3a1 addVarint:100];
277  [group3a addField:fieldGroup3a1];
278  GPBUnknownFieldSet *group3b = [[[GPBUnknownFieldSet alloc] init] autorelease];
279  GPBUnknownField* fieldGroup3b2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease];
280  [fieldGroup3b2 addVarint:99];
281  [group3b addField:fieldGroup3b2];
282
283  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
284  [field addGroup:group1];
285  [field addGroup:group3b];
286  [set3 addField:field];
287
288  TestEmptyMessage* source1 = [TestEmptyMessage message];
289  [source1 setUnknownFields:set1];
290  TestEmptyMessage* source2 = [TestEmptyMessage message];
291  [source2 setUnknownFields:set2];
292  TestEmptyMessage* source3 = [TestEmptyMessage message];
293  [source3 setUnknownFields:set3];
294
295  TestEmptyMessage* destination1 = [TestEmptyMessage message];
296  [destination1 mergeFrom:source1];
297  [destination1 mergeFrom:source2];
298
299  TestEmptyMessage* destination2 = [TestEmptyMessage message];
300  [destination2 mergeFrom:source3];
301
302  XCTAssertEqualObjects(destination1.data, destination2.data);
303  XCTAssertEqualObjects(destination1.data, source3.data);
304  XCTAssertEqualObjects(destination2.data, source3.data);
305}
306
307- (void)testClearMessage {
308  TestEmptyMessage *message = [TestEmptyMessage message];
309  [message mergeFrom:emptyMessage_];
310  [message clear];
311  XCTAssertEqual(message.serializedSize, (size_t)0);
312}
313
314- (void)testParseKnownAndUnknown {
315  // Test mixing known and unknown fields when parsing.
316  GPBUnknownFieldSet *fields = [[unknownFields_ copy] autorelease];
317  GPBUnknownField *field =
318    [[[GPBUnknownField alloc] initWithNumber:123456] autorelease];
319  [field addVarint:654321];
320  [fields addField:field];
321
322  NSData* data = fields.data;
323  TestAllTypes* destination = [TestAllTypes parseFromData:data error:NULL];
324
325  [self assertAllFieldsSet:destination repeatedCount:kGPBDefaultRepeatCount];
326  XCTAssertEqual(destination.unknownFields.countOfFields, (NSUInteger)1);
327
328  GPBUnknownField* field2 = [destination.unknownFields getField:123456];
329  XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
330  XCTAssertEqual(654321ULL, [field2.varintList valueAtIndex:0]);
331}
332
333- (void)testWrongTypeTreatedAsUnknown {
334  // Test that fields of the wrong wire type are treated like unknown fields
335  // when parsing.
336
337  NSData* bizarroData = [self getBizarroData];
338  TestAllTypes* allTypesMessage =
339      [TestAllTypes parseFromData:bizarroData error:NULL];
340  TestEmptyMessage* emptyMessage =
341      [TestEmptyMessage parseFromData:bizarroData error:NULL];
342
343  // All fields should have been interpreted as unknown, so the debug strings
344  // should be the same.
345  XCTAssertEqualObjects(emptyMessage.data, allTypesMessage.data);
346}
347
348- (void)testUnknownExtensions {
349  // Make sure fields are properly parsed to the UnknownFieldSet even when
350  // they are declared as extension numbers.
351
352  TestEmptyMessageWithExtensions* message =
353      [TestEmptyMessageWithExtensions parseFromData:allFieldsData_ error:NULL];
354
355  XCTAssertEqual(unknownFields_.countOfFields,
356                 message.unknownFields.countOfFields);
357  XCTAssertEqualObjects(allFieldsData_, message.data);
358}
359
360- (void)testWrongExtensionTypeTreatedAsUnknown {
361  // Test that fields of the wrong wire type are treated like unknown fields
362  // when parsing extensions.
363
364  NSData* bizarroData = [self getBizarroData];
365  TestAllExtensions* allExtensionsMessage =
366      [TestAllExtensions parseFromData:bizarroData error:NULL];
367  TestEmptyMessage* emptyMessage =
368      [TestEmptyMessage parseFromData:bizarroData error:NULL];
369
370  // All fields should have been interpreted as unknown, so the debug strings
371  // should be the same.
372  XCTAssertEqualObjects(emptyMessage.data, allExtensionsMessage.data);
373}
374
375- (void)testLargeVarint {
376  GPBUnknownFieldSet* fields = [[unknownFields_ copy] autorelease];
377  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
378  [field addVarint:0x7FFFFFFFFFFFFFFFL];
379  [fields addField:field];
380
381  NSData* data = [fields data];
382
383  GPBUnknownFieldSet* parsed = [[[GPBUnknownFieldSet alloc] init] autorelease];
384  [parsed mergeFromData:data];
385  GPBUnknownField* field2 = [parsed getField:1];
386  XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
387  XCTAssertEqual(0x7FFFFFFFFFFFFFFFULL, [field2.varintList valueAtIndex:0]);
388}
389
390#pragma mark - Field tests
391// Some tests directly on fields since the dictionary in FieldSet can gate
392// testing some of these.
393
394- (void)testFieldEqualityAndHash {
395  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
396  XCTAssertTrue([field1 isEqual:field1]);
397  XCTAssertFalse([field1 isEqual:@"foo"]);
398  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
399  XCTAssertNotEqualObjects(field1, field2);
400
401  field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
402  XCTAssertEqualObjects(field1, field2);
403  XCTAssertEqual([field1 hash], [field2 hash]);
404
405  // Varint
406
407  [field1 addVarint:10];
408  XCTAssertNotEqualObjects(field1, field2);
409  [field2 addVarint:10];
410  XCTAssertEqualObjects(field1, field2);
411  XCTAssertEqual([field1 hash], [field2 hash]);
412  [field1 addVarint:11];
413  XCTAssertNotEqualObjects(field1, field2);
414  [field2 addVarint:11];
415  XCTAssertEqualObjects(field1, field2);
416  XCTAssertEqual([field1 hash], [field2 hash]);
417
418  // Fixed32
419
420  [field1 addFixed32:20];
421  XCTAssertNotEqualObjects(field1, field2);
422  [field2 addFixed32:20];
423  XCTAssertEqualObjects(field1, field2);
424  XCTAssertEqual([field1 hash], [field2 hash]);
425  [field1 addFixed32:21];
426  XCTAssertNotEqualObjects(field1, field2);
427  [field2 addFixed32:21];
428  XCTAssertEqualObjects(field1, field2);
429  XCTAssertEqual([field1 hash], [field2 hash]);
430
431  // Fixed64
432
433  [field1 addFixed64:30];
434  XCTAssertNotEqualObjects(field1, field2);
435  [field2 addFixed64:30];
436  XCTAssertEqualObjects(field1, field2);
437  XCTAssertEqual([field1 hash], [field2 hash]);
438  [field1 addFixed64:31];
439  XCTAssertNotEqualObjects(field1, field2);
440  [field2 addFixed64:31];
441  XCTAssertEqualObjects(field1, field2);
442  XCTAssertEqual([field1 hash], [field2 hash]);
443
444  // LengthDelimited
445
446  [field1 addLengthDelimited:DataFromCStr("foo")];
447  XCTAssertNotEqualObjects(field1, field2);
448  [field2 addLengthDelimited:DataFromCStr("foo")];
449  XCTAssertEqualObjects(field1, field2);
450  XCTAssertEqual([field1 hash], [field2 hash]);
451  [field1 addLengthDelimited:DataFromCStr("bar")];
452  XCTAssertNotEqualObjects(field1, field2);
453  [field2 addLengthDelimited:DataFromCStr("bar")];
454  XCTAssertEqualObjects(field1, field2);
455  XCTAssertEqual([field1 hash], [field2 hash]);
456
457  // Group
458
459  GPBUnknownFieldSet *group = [[[GPBUnknownFieldSet alloc] init] autorelease];
460  GPBUnknownField* fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease];
461  [fieldGroup addVarint:100];
462  [group addField:fieldGroup];
463  [field1 addGroup:group];
464  XCTAssertNotEqualObjects(field1, field2);
465  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
466  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease];
467  [fieldGroup addVarint:100];
468  [group addField:fieldGroup];
469  [field2 addGroup:group];
470  XCTAssertEqualObjects(field1, field2);
471  XCTAssertEqual([field1 hash], [field2 hash]);
472
473  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
474  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease];
475  [fieldGroup addVarint:101];
476  [group addField:fieldGroup];
477  [field1 addGroup:group];
478  XCTAssertNotEqualObjects(field1, field2);
479  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
480  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease];
481  [fieldGroup addVarint:101];
482  [group addField:fieldGroup];
483  [field2 addGroup:group];
484  XCTAssertEqualObjects(field1, field2);
485  XCTAssertEqual([field1 hash], [field2 hash]);
486
487  // Exercise description for completeness.
488  XCTAssertTrue(field1.description.length > 10);
489}
490
491- (void)testMergingFields {
492  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
493  [field1 addVarint:1];
494  [field1 addFixed32:2];
495  [field1 addFixed64:3];
496  [field1 addLengthDelimited:[NSData dataWithBytes:"hello" length:5]];
497  [field1 addGroup:[[unknownFields_ copy] autorelease]];
498  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
499  [field2 mergeFromField:field1];
500}
501
502@end
503