ObjFW  Diff

Differences From Artifact [1e7711c5fc]:

To Artifact [0138d44106]:


1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *

|







1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
20
21
22
23
24
25
26

27
28
29
30
31
32
33
#import "OFLHAArchiveEntry.h"
#import "OFLHAArchiveEntry+Private.h"
#import "OFArray.h"
#import "OFCRC16.h"
#import "OFData.h"
#import "OFDate.h"
#import "OFNumber.h"

#import "OFStream.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"
#import "OFUnsupportedVersionException.h"







>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#import "OFLHAArchiveEntry.h"
#import "OFLHAArchiveEntry+Private.h"
#import "OFArray.h"
#import "OFCRC16.h"
#import "OFData.h"
#import "OFDate.h"
#import "OFNumber.h"
#import "OFSeekableStream.h"
#import "OFStream.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"
#import "OFUnsupportedVersionException.h"
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367



368
369
370
371
372
373
374
375
376
377
378



379




380
381







382







383




384




385
386
387
388
389
390
391
			 encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		uint32_t date;

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

		if (_compressedSize > UINT32_MAX ||
		    _uncompressedSize > UINT32_MAX)
			@throw [OFOutOfRangeException exception];

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

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

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

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

		switch (_headerLevel) {
		case 0:
		case 1:;
			void *pool = objc_autoreleasePoolPush();

			uint8_t fileNameLength;
			OFString *tmp;




			_modificationDate = [parseMSDOSDate(date) retain];

			fileNameLength = [stream readInt8];
			tmp = [stream readStringWithLength: fileNameLength
						  encoding: encoding];
			tmp = [tmp stringByReplacingOccurrencesOfString: @"\\"
							     withString: @"/"];
			_fileName = [tmp copy];

			_CRC16 = [stream readLittleEndianInt16];




			if (_headerLevel == 1) {




				_operatingSystemIdentifier = [stream readInt8];








				readExtensions(self, stream, encoding, false);







			}









			objc_autoreleasePoolPop(pool);
			break;
		case 2:
			_modificationDate = [[OFDate alloc]
			    initWithTimeIntervalSince1970: date];

			_CRC16 = [stream readLittleEndianInt16];







<
<
<
<
<
<
<
<
<


















>



>
>
>











>
>
>

>
>
>
>


>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>







332
333
334
335
336
337
338









339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
			 encoding: (OFStringEncoding)encoding
{
	self = [super init];

	@try {
		uint32_t date;










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

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

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

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

		switch (_headerLevel) {
		case 0:
		case 1:;
			void *pool = objc_autoreleasePoolPush();
			uint8_t extendedAreaSize;
			uint8_t fileNameLength;
			OFString *tmp;

			if (header[0] < (21 - 2) + 1 + 2)
				@throw [OFInvalidFormatException exception];

			_modificationDate = [parseMSDOSDate(date) retain];

			fileNameLength = [stream readInt8];
			tmp = [stream readStringWithLength: fileNameLength
						  encoding: encoding];
			tmp = [tmp stringByReplacingOccurrencesOfString: @"\\"
							     withString: @"/"];
			_fileName = [tmp copy];

			_CRC16 = [stream readLittleEndianInt16];

			extendedAreaSize =
			    header[0] - (21 - 2) - 1 - fileNameLength - 2;

			if (_headerLevel == 1) {
				if (extendedAreaSize < 3)
					@throw [OFInvalidFormatException
					    exception];

				_operatingSystemIdentifier = [stream readInt8];

				/*
				 * 1 for the operating system identifier, 2
				 * because we don't want to skip the size of
				 * the next extended header.
				 */
				extendedAreaSize -= 1 + 2;
			}

			/* Skip extended area. */
			if ([stream isKindOfClass: [OFSeekableStream class]])
				[(OFSeekableStream *)stream
				    seekToOffset: extendedAreaSize
					  whence: OFSeekCurrent];
			else {
				char buffer[256];

				while (extendedAreaSize > 0)
					extendedAreaSize -= [stream
					    readIntoBuffer: buffer
						    length: extendedAreaSize];
			}

			if (_headerLevel == 1)
				readExtensions(self, stream, encoding, false);

			objc_autoreleasePoolPop(pool);
			break;
		case 2:
			_modificationDate = [[OFDate alloc]
			    initWithTimeIntervalSince1970: date];

			_CRC16 = [stream readLittleEndianInt16];
400
401
402
403
404
405
406





407
408
409
410
411
412
413

			@throw [OFUnsupportedVersionException
			    exceptionWithVersion: version];
		}

		if (_fileName == nil)
			@throw [OFInvalidFormatException exception];






		[_extensions makeImmutable];
	} @catch (id e) {
		[self release];
		@throw e;
	}








>
>
>
>
>







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

			@throw [OFUnsupportedVersionException
			    exceptionWithVersion: version];
		}

		if (_fileName == nil)
			@throw [OFInvalidFormatException exception];

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

		[_extensions makeImmutable];
	} @catch (id e) {
		[self release];
		@throw e;
	}