• 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 = malloc(count * sizeof(int32_t));
160  if (!tags) {
161    XCTFail(@"Failed to make scratch buffer for testing");
162    return [NSData data];
163  }
164  @try {
165    [unknownFields_ getTags:tags];
166    for (NSUInteger i = 0; i < count; ++i) {
167      int32_t tag = tags[i];
168      GPBUnknownField* field = [unknownFields_ getField:tag];
169      if (field.varintList.count == 0) {
170        // Original field is not a varint, so use a varint.
171        GPBUnknownField* varintField =
172            [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
173        [varintField addVarint:1];
174        [bizarroFields addField:varintField];
175      } else {
176        // Original field *is* a varint, so use something else.
177        GPBUnknownField* fixed32Field =
178            [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
179        [fixed32Field addFixed32:1];
180        [bizarroFields addField:fixed32Field];
181      }
182    }
183  }
184  @finally {
185    free(tags);
186  }
187
188  return [bizarroFields data];
189}
190
191- (void)testSerialize {
192  // Check that serializing the UnknownFieldSet produces the original data
193  // again.
194  NSData* data = [emptyMessage_ data];
195  XCTAssertEqualObjects(allFieldsData_, data);
196}
197
198- (void)testCopyFrom {
199  TestEmptyMessage* message = [TestEmptyMessage message];
200  [message mergeFrom:emptyMessage_];
201
202  XCTAssertEqualObjects(emptyMessage_.data, message.data);
203}
204
205- (void)testMergeFrom {
206  GPBUnknownFieldSet* set1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
207  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
208  [field addVarint:2];
209  [set1 addField:field];
210  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
211  [field addVarint:4];
212  [set1 addField:field];
213  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
214  [field addFixed32:6];
215  [set1 addField:field];
216  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
217  [field addFixed64:20];
218  [set1 addField:field];
219  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
220  [field addLengthDelimited:DataFromCStr("data1")];
221  [set1 addField:field];
222
223  GPBUnknownFieldSet *group1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
224  GPBUnknownField* fieldGroup1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease];
225  [fieldGroup1 addVarint:100];
226  [group1 addField:fieldGroup1];
227
228  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
229  [field addGroup:group1];
230  [set1 addField:field];
231
232  GPBUnknownFieldSet* set2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
233  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
234  [field addVarint:1];
235  [set2 addField:field];
236  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
237  [field addVarint:3];
238  [set2 addField:field];
239  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
240  [field addFixed32:7];
241  [set2 addField:field];
242  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
243  [field addFixed64:30];
244  [set2 addField:field];
245  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
246  [field addLengthDelimited:DataFromCStr("data2")];
247  [set2 addField:field];
248
249  GPBUnknownFieldSet *group2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
250  GPBUnknownField* fieldGroup2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease];
251  [fieldGroup2 addVarint:99];
252  [group2 addField:fieldGroup2];
253
254  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
255  [field addGroup:group2];
256  [set2 addField:field];
257
258  GPBUnknownFieldSet* set3 = [[[GPBUnknownFieldSet alloc] init] autorelease];
259  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
260  [field addVarint:1];
261  [set3 addField:field];
262  field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
263  [field addVarint:2];
264  [set3 addField:field];
265  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
266  [field addVarint:4];
267  [set3 addField:field];
268  [field addVarint:3];
269  [set3 addField:field];
270  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
271  [field addFixed32:6];
272  [field addFixed32:7];
273  [set3 addField:field];
274  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
275  [field addFixed64:20];
276  [field addFixed64:30];
277  [set3 addField:field];
278  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
279  [field addLengthDelimited:DataFromCStr("data1")];
280  [field addLengthDelimited:DataFromCStr("data2")];
281  [set3 addField:field];
282
283  GPBUnknownFieldSet *group3a = [[[GPBUnknownFieldSet alloc] init] autorelease];
284  GPBUnknownField* fieldGroup3a1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease];
285  [fieldGroup3a1 addVarint:100];
286  [group3a addField:fieldGroup3a1];
287  GPBUnknownFieldSet *group3b = [[[GPBUnknownFieldSet alloc] init] autorelease];
288  GPBUnknownField* fieldGroup3b2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease];
289  [fieldGroup3b2 addVarint:99];
290  [group3b addField:fieldGroup3b2];
291
292  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
293  [field addGroup:group1];
294  [field addGroup:group3b];
295  [set3 addField:field];
296
297  TestEmptyMessage* source1 = [TestEmptyMessage message];
298  [source1 setUnknownFields:set1];
299  TestEmptyMessage* source2 = [TestEmptyMessage message];
300  [source2 setUnknownFields:set2];
301  TestEmptyMessage* source3 = [TestEmptyMessage message];
302  [source3 setUnknownFields:set3];
303
304  TestEmptyMessage* destination1 = [TestEmptyMessage message];
305  [destination1 mergeFrom:source1];
306  [destination1 mergeFrom:source2];
307
308  TestEmptyMessage* destination2 = [TestEmptyMessage message];
309  [destination2 mergeFrom:source3];
310
311  XCTAssertEqualObjects(destination1.data, destination2.data);
312  XCTAssertEqualObjects(destination1.data, source3.data);
313  XCTAssertEqualObjects(destination2.data, source3.data);
314}
315
316- (void)testClearMessage {
317  TestEmptyMessage *message = [TestEmptyMessage message];
318  [message mergeFrom:emptyMessage_];
319  [message clear];
320  XCTAssertEqual(message.serializedSize, (size_t)0);
321}
322
323- (void)testParseKnownAndUnknown {
324  // Test mixing known and unknown fields when parsing.
325  GPBUnknownFieldSet *fields = [[unknownFields_ copy] autorelease];
326  GPBUnknownField *field =
327    [[[GPBUnknownField alloc] initWithNumber:123456] autorelease];
328  [field addVarint:654321];
329  [fields addField:field];
330
331  NSData* data = fields.data;
332  TestAllTypes* destination = [TestAllTypes parseFromData:data error:NULL];
333
334  [self assertAllFieldsSet:destination repeatedCount:kGPBDefaultRepeatCount];
335  XCTAssertEqual(destination.unknownFields.countOfFields, (NSUInteger)1);
336
337  GPBUnknownField* field2 = [destination.unknownFields getField:123456];
338  XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
339  XCTAssertEqual(654321ULL, [field2.varintList valueAtIndex:0]);
340}
341
342- (void)testWrongTypeTreatedAsUnknown {
343  // Test that fields of the wrong wire type are treated like unknown fields
344  // when parsing.
345
346  NSData* bizarroData = [self getBizarroData];
347  TestAllTypes* allTypesMessage =
348      [TestAllTypes parseFromData:bizarroData error:NULL];
349  TestEmptyMessage* emptyMessage =
350      [TestEmptyMessage parseFromData:bizarroData error:NULL];
351
352  // All fields should have been interpreted as unknown, so the debug strings
353  // should be the same.
354  XCTAssertEqualObjects(emptyMessage.data, allTypesMessage.data);
355}
356
357- (void)testUnknownExtensions {
358  // Make sure fields are properly parsed to the UnknownFieldSet even when
359  // they are declared as extension numbers.
360
361  TestEmptyMessageWithExtensions* message =
362      [TestEmptyMessageWithExtensions parseFromData:allFieldsData_ error:NULL];
363
364  XCTAssertEqual(unknownFields_.countOfFields,
365                 message.unknownFields.countOfFields);
366  XCTAssertEqualObjects(allFieldsData_, message.data);
367}
368
369- (void)testWrongExtensionTypeTreatedAsUnknown {
370  // Test that fields of the wrong wire type are treated like unknown fields
371  // when parsing extensions.
372
373  NSData* bizarroData = [self getBizarroData];
374  TestAllExtensions* allExtensionsMessage =
375      [TestAllExtensions parseFromData:bizarroData error:NULL];
376  TestEmptyMessage* emptyMessage =
377      [TestEmptyMessage parseFromData:bizarroData error:NULL];
378
379  // All fields should have been interpreted as unknown, so the debug strings
380  // should be the same.
381  XCTAssertEqualObjects(emptyMessage.data, allExtensionsMessage.data);
382}
383
384- (void)testLargeVarint {
385  GPBUnknownFieldSet* fields = [[unknownFields_ copy] autorelease];
386  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
387  [field addVarint:0x7FFFFFFFFFFFFFFFL];
388  [fields addField:field];
389
390  NSData* data = [fields data];
391
392  GPBUnknownFieldSet* parsed = [[[GPBUnknownFieldSet alloc] init] autorelease];
393  [parsed mergeFromData:data];
394  GPBUnknownField* field2 = [parsed getField:1];
395  XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
396  XCTAssertEqual(0x7FFFFFFFFFFFFFFFULL, [field2.varintList valueAtIndex:0]);
397}
398
399#pragma mark - Field tests
400// Some tests directly on fields since the dictionary in FieldSet can gate
401// testing some of these.
402
403- (void)testFieldEqualityAndHash {
404  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
405  XCTAssertTrue([field1 isEqual:field1]);
406  XCTAssertFalse([field1 isEqual:@"foo"]);
407  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
408  XCTAssertNotEqualObjects(field1, field2);
409
410  field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
411  XCTAssertEqualObjects(field1, field2);
412  XCTAssertEqual([field1 hash], [field2 hash]);
413
414  // Varint
415
416  [field1 addVarint:10];
417  XCTAssertNotEqualObjects(field1, field2);
418  [field2 addVarint:10];
419  XCTAssertEqualObjects(field1, field2);
420  XCTAssertEqual([field1 hash], [field2 hash]);
421  [field1 addVarint:11];
422  XCTAssertNotEqualObjects(field1, field2);
423  [field2 addVarint:11];
424  XCTAssertEqualObjects(field1, field2);
425  XCTAssertEqual([field1 hash], [field2 hash]);
426
427  // Fixed32
428
429  [field1 addFixed32:20];
430  XCTAssertNotEqualObjects(field1, field2);
431  [field2 addFixed32:20];
432  XCTAssertEqualObjects(field1, field2);
433  XCTAssertEqual([field1 hash], [field2 hash]);
434  [field1 addFixed32:21];
435  XCTAssertNotEqualObjects(field1, field2);
436  [field2 addFixed32:21];
437  XCTAssertEqualObjects(field1, field2);
438  XCTAssertEqual([field1 hash], [field2 hash]);
439
440  // Fixed64
441
442  [field1 addFixed64:30];
443  XCTAssertNotEqualObjects(field1, field2);
444  [field2 addFixed64:30];
445  XCTAssertEqualObjects(field1, field2);
446  XCTAssertEqual([field1 hash], [field2 hash]);
447  [field1 addFixed64:31];
448  XCTAssertNotEqualObjects(field1, field2);
449  [field2 addFixed64:31];
450  XCTAssertEqualObjects(field1, field2);
451  XCTAssertEqual([field1 hash], [field2 hash]);
452
453  // LengthDelimited
454
455  [field1 addLengthDelimited:DataFromCStr("foo")];
456  XCTAssertNotEqualObjects(field1, field2);
457  [field2 addLengthDelimited:DataFromCStr("foo")];
458  XCTAssertEqualObjects(field1, field2);
459  XCTAssertEqual([field1 hash], [field2 hash]);
460  [field1 addLengthDelimited:DataFromCStr("bar")];
461  XCTAssertNotEqualObjects(field1, field2);
462  [field2 addLengthDelimited:DataFromCStr("bar")];
463  XCTAssertEqualObjects(field1, field2);
464  XCTAssertEqual([field1 hash], [field2 hash]);
465
466  // Group
467
468  GPBUnknownFieldSet *group = [[[GPBUnknownFieldSet alloc] init] autorelease];
469  GPBUnknownField* fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease];
470  [fieldGroup addVarint:100];
471  [group addField:fieldGroup];
472  [field1 addGroup:group];
473  XCTAssertNotEqualObjects(field1, field2);
474  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
475  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease];
476  [fieldGroup addVarint:100];
477  [group addField:fieldGroup];
478  [field2 addGroup:group];
479  XCTAssertEqualObjects(field1, field2);
480  XCTAssertEqual([field1 hash], [field2 hash]);
481
482  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
483  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease];
484  [fieldGroup addVarint:101];
485  [group addField:fieldGroup];
486  [field1 addGroup:group];
487  XCTAssertNotEqualObjects(field1, field2);
488  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
489  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease];
490  [fieldGroup addVarint:101];
491  [group addField:fieldGroup];
492  [field2 addGroup:group];
493  XCTAssertEqualObjects(field1, field2);
494  XCTAssertEqual([field1 hash], [field2 hash]);
495
496  // Exercise description for completeness.
497  XCTAssertTrue(field1.description.length > 10);
498}
499
500- (void)testMergingFields {
501  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
502  [field1 addVarint:1];
503  [field1 addFixed32:2];
504  [field1 addFixed64:3];
505  [field1 addLengthDelimited:[NSData dataWithBytes:"hello" length:5]];
506  [field1 addGroup:[[unknownFields_ copy] autorelease]];
507  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
508  [field2 mergeFromField:field1];
509}
510
511@end
512