ObjFW  Diff

Differences From Artifact [35e510f89b]:

To Artifact [0d247504f2]:


116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144

145
146
147
148
149
150
151
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143

144
145
146
147
148
149
150
151







-
+

















-
+


-
+







{
	uint16_t mode;

	if (extension.count != 3)
		@throw [OFInvalidFormatException exception];

	memcpy(&mode, (char *)extension.items + 1, 2);
	mode = OF_BSWAP16_IF_BE(mode);
	mode = OFFromLittleEndian16(mode);

	[entry->_mode release];
	entry->_mode = nil;

	entry->_mode = [[OFNumber alloc] initWithUnsignedShort: mode];
}

static void
parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension,
    OFStringEncoding encoding)
{
	uint16_t UID, GID;

	if (extension.count != 5)
		@throw [OFInvalidFormatException exception];

	memcpy(&GID, (char *)extension.items + 1, 2);
	GID = OF_BSWAP16_IF_BE(GID);
	GID = OFFromLittleEndian16(GID);

	memcpy(&UID, (char *)extension.items + 3, 2);
	UID = OF_BSWAP16_IF_BE(UID);
	UID = OFFromLittleEndian16(UID);

	[entry->_GID release];
	entry->_GID = nil;

	[entry->_UID release];
	entry->_UID = nil;

185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199







-
+







{
	uint32_t modificationDate;

	if (extension.count != 5)
		@throw [OFInvalidFormatException exception];

	memcpy(&modificationDate, (char *)extension.items + 1, 4);
	modificationDate = OF_BSWAP32_IF_BE(modificationDate);
	modificationDate = OFFromLittleEndian32(modificationDate);

	[entry->_modificationDate release];
	entry->_modificationDate = nil;

	entry->_modificationDate = [[OFDate alloc]
	    initWithTimeIntervalSince1970: modificationDate];
}
341
342
343
344
345
346
347
348

349
350
351

352
353
354

355
356
357
358
359
360
361
341
342
343
344
345
346
347

348
349
350

351
352
353

354
355
356
357
358
359
360
361







-
+


-
+


-
+








		_compressionMethod = [[OFString alloc]
		    initWithCString: header + 2
			   encoding: OFStringEncodingASCII
			     length: 5];

		memcpy(&_compressedSize, header + 7, 4);
		_compressedSize = OF_BSWAP32_IF_BE(_compressedSize);
		_compressedSize = OFFromLittleEndian32(_compressedSize);

		memcpy(&_uncompressedSize, header + 11, 4);
		_uncompressedSize = OF_BSWAP32_IF_BE(_uncompressedSize);
		_uncompressedSize = OFFromLittleEndian32(_uncompressedSize);

		memcpy(&date, header + 15, 4);
		date = OF_BSWAP32_IF_BE(date);
		date = OFFromLittleEndian32(date);

		_headerLevel = header[20];
		_extensions = [[OFMutableArray alloc] init];

		switch (_headerLevel) {
		case 0:
		case 1:;
578
579
580
581
582
583
584
585

586
587
588

589
590
591

592
593
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608

609
610
611
612
613

614
615
616
617
618
619

620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640

641
642
643
644

645
646
647
648
649
650
651
652

653
654
655
656

657
658
659

660
661
662
663
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692

693
694
695
696

697
698
699
700
701
702
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728

729
730
731
732
733
734
735
578
579
580
581
582
583
584

585
586
587

588
589
590

591
592
593
594
595
596
597
598
599
600

601
602
603
604
605
606
607

608
609
610
611
612

613
614
615
616
617
618

619
620
621
622
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639

640
641
642
643

644
645
646
647
648
649
650
651

652
653
654
655

656
657
658

659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682
683

684
685
686
687
688
689
690
691

692
693
694
695

696
697
698
699
700
701
702
703
704
705
706
707
708
709

710
711
712
713
714
715
716
717
718
719
720
721
722
723

724
725
726
727

728
729
730
731
732
733
734
735







-
+


-
+


-
+









-
+






-
+




-
+





-
+












-
+







-
+



-
+







-
+



-
+


-
+










-
+













-
+







-
+



-
+













-
+













-
+



-
+







	/* Length. Filled in after we're done. */
	[data increaseCountBy: 2];

	[data addItems: [_compressionMethod
			    cStringWithEncoding: OFStringEncodingASCII]
		 count: 5];

	tmp32 = OF_BSWAP32_IF_BE(_compressedSize);
	tmp32 = OFToLittleEndian32(_compressedSize);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	tmp32 = OF_BSWAP32_IF_BE(_uncompressedSize);
	tmp32 = OFToLittleEndian32(_uncompressedSize);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	tmp32 = OF_BSWAP32_IF_BE((uint32_t)_date.timeIntervalSince1970);
	tmp32 = OFToLittleEndian32((uint32_t)_date.timeIntervalSince1970);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	/* Reserved */
	[data increaseCountBy: 1];

	/* Header level */
	[data addItem: "\x02"];

	/* CRC16 */
	tmp16 = OF_BSWAP16_IF_BE(_CRC16);
	tmp16 = OFToLittleEndian16(_CRC16);
	[data addItems: &tmp16 count: sizeof(tmp16)];

	/* Operating system identifier */
	[data addItem: "U"];

	/* Common header. Contains CRC16, which is written at the end. */
	tmp16 = OF_BSWAP16_IF_BE(5);
	tmp16 = OFToLittleEndian16(5);
	[data addItems: &tmp16 count: sizeof(tmp16)];
	[data addItem: "\x00"];
	[data increaseCountBy: 2];

	tmp16 = OF_BSWAP16_IF_BE((uint16_t)fileNameLength + 3);
	tmp16 = OFToLittleEndian16((uint16_t)fileNameLength + 3);
	[data addItems: &tmp16 count: sizeof(tmp16)];
	[data addItem: "\x01"];
	[data addItems: fileName count: fileNameLength];

	if (directoryNameLength > 0) {
		tmp16 = OF_BSWAP16_IF_BE((uint16_t)directoryNameLength + 3);
		tmp16 = OFToLittleEndian16((uint16_t)directoryNameLength + 3);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItem: "\x02"];
		[data addItems: directoryName count: directoryNameLength];
	}

	if (_fileComment != nil) {
		size_t fileCommentLength =
		    [_fileComment cStringLengthWithEncoding: encoding];

		if (fileCommentLength > UINT16_MAX - 3)
			@throw [OFOutOfRangeException exception];

		tmp16 = OF_BSWAP16_IF_BE((uint16_t)fileCommentLength + 3);
		tmp16 = OFToLittleEndian16((uint16_t)fileCommentLength + 3);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItem: "\x3F"];
		[data addItems: [_fileComment cStringWithEncoding: encoding]
			 count: fileCommentLength];
	}

	if (_mode != nil) {
		tmp16 = OF_BSWAP16_IF_BE(5);
		tmp16 = OFToLittleEndian16(5);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItem: "\x50"];

		tmp16 = OF_BSWAP16_IF_BE(_mode.unsignedShortValue);
		tmp16 = OFToLittleEndian16(_mode.unsignedShortValue);
		[data addItems: &tmp16 count: sizeof(tmp16)];
	}

	if (_UID != nil || _GID != nil) {
		if (_UID == nil || _GID == nil)
			@throw [OFInvalidArgumentException exception];

		tmp16 = OF_BSWAP16_IF_BE(7);
		tmp16 = OFToLittleEndian16(7);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItem: "\x51"];

		tmp16 = OF_BSWAP16_IF_BE(_GID.unsignedShortValue);
		tmp16 = OFToLittleEndian16(_GID.unsignedShortValue);
		[data addItems: &tmp16 count: sizeof(tmp16)];

		tmp16 = OF_BSWAP16_IF_BE(_UID.unsignedShortValue);
		tmp16 = OFToLittleEndian16(_UID.unsignedShortValue);
		[data addItems: &tmp16 count: sizeof(tmp16)];
	}

	if (_group != nil) {
		size_t groupLength =
		    [_group cStringLengthWithEncoding: encoding];

		if (groupLength > UINT16_MAX - 3)
			@throw [OFOutOfRangeException exception];

		tmp16 = OF_BSWAP16_IF_BE((uint16_t)groupLength + 3);
		tmp16 = OFToLittleEndian16((uint16_t)groupLength + 3);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItem: "\x52"];
		[data addItems: [_group cStringWithEncoding: encoding]
			 count: groupLength];
	}

	if (_owner != nil) {
		size_t ownerLength =
		    [_owner cStringLengthWithEncoding: encoding];

		if (ownerLength > UINT16_MAX - 3)
			@throw [OFOutOfRangeException exception];

		tmp16 = OF_BSWAP16_IF_BE((uint16_t)ownerLength + 3);
		tmp16 = OFToLittleEndian16((uint16_t)ownerLength + 3);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItem: "\x53"];
		[data addItems: [_owner cStringWithEncoding: encoding]
			 count: ownerLength];
	}

	if (_modificationDate != nil) {
		tmp16 = OF_BSWAP16_IF_BE(7);
		tmp16 = OFToLittleEndian16(7);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItem: "\x54"];

		tmp32 = OF_BSWAP32_IF_BE(
		tmp32 = OFToLittleEndian32(
		    (uint32_t)_modificationDate.timeIntervalSince1970);
		[data addItems: &tmp32 count: sizeof(tmp32)];
	}

	for (OFData *extension in _extensions) {
		size_t extensionLength = extension.count;

		if (extension.itemSize != 1)
			@throw [OFInvalidArgumentException exception];

		if (extensionLength > UINT16_MAX - 2)
			@throw [OFOutOfRangeException exception];

		tmp16 = OF_BSWAP16_IF_BE((uint16_t)extensionLength + 2);
		tmp16 = OFToLittleEndian16((uint16_t)extensionLength + 2);
		[data addItems: &tmp16 count: sizeof(tmp16)];
		[data addItems: extension.items count: extension.count];
	}

	/* Zero-length extension to terminate */
	[data increaseCountBy: 2];

	headerSize = data.count;

	if (headerSize > UINT16_MAX)
		@throw [OFOutOfRangeException exception];

	/* Now fill in the size and CRC16 for the entire header */
	tmp16 = OF_BSWAP16_IF_BE(headerSize);
	tmp16 = OFToLittleEndian16(headerSize);
	memcpy([data mutableItemAtIndex: 0], &tmp16, sizeof(tmp16));

	tmp16 = of_crc16(0, data.items, data.count);
	tmp16 = OF_BSWAP16_IF_BE(tmp16);
	tmp16 = OFToLittleEndian16(tmp16);
	memcpy([data mutableItemAtIndex: 27], &tmp16, sizeof(tmp16));

	[stream writeData: data];

	objc_autoreleasePoolPop(pool);
}