Overview
Context
Changes
Modified src/OFFile.m
from [6bda5c55f7]
to [8cbc43a8f0].
︙ | | |
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
|
-
+
+
-
+
|
bytesWritten: 0
errNo: errno];
#endif
return (size_t)bytesWritten;
}
- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
whence: (int)whence
{
OFFileOffset ret;
OFStreamOffset ret;
if (_handle == OFInvalidFileHandle)
@throw [OFNotOpenException exceptionWithObject: self];
#ifndef OF_AMIGAOS
# if defined(OF_WINDOWS)
ret = _lseeki64(_handle, offset, whence);
|
︙ | | |
Modified src/OFFileURLHandler.m
from [50a5ea9a56]
to [9f18f4fcb5].
︙ | | |
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
-
+
|
# ifdef OF_AMIGAOS4
# define DeleteFile(path) Delete(path)
# endif
#endif
#if defined(OF_WINDOWS) || defined(OF_AMIGAOS)
typedef struct {
OFFileOffset st_size;
OFStreamOffset st_size;
unsigned int st_mode;
OFTimeInterval st_atime, st_mtime, st_ctime;
# ifdef OF_WINDOWS
# define HAVE_STRUCT_STAT_ST_BIRTHTIME
OFTimeInterval st_birthtime;
DWORD fileAttributes;
# endif
|
︙ | | |
Modified src/OFLHAArchive.m
from [39715cb197]
to [16be8d0f67].
︙ | | |
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
-
+
|
OF_DIRECT_MEMBERS
@interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving>
{
OFMutableLHAArchiveEntry *_entry;
OFStringEncoding _encoding;
OFSeekableStream *_stream;
OFFileOffset _headerOffset;
OFStreamOffset _headerOffset;
uint32_t _bytesWritten;
uint16_t _CRC16;
}
- (instancetype)of_initWithStream: (OFSeekableStream *)stream
entry: (OFLHAArchiveEntry *)entry
encoding: (OFStringEncoding)encoding;
|
︙ | | |
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
-
-
+
+
|
toRead =
_entry.compressedSize - decompressingStream.bytesConsumed;
stream = _stream;
}
if ([stream isKindOfClass: [OFSeekableStream class]] &&
(sizeof(OFFileOffset) > 4 || toRead != (OFFileOffset)toRead))
[(OFSeekableStream *)stream seekToOffset: (OFFileOffset)toRead
(sizeof(OFStreamOffset) > 4 || toRead != (OFStreamOffset)toRead))
[(OFSeekableStream *)stream seekToOffset: (OFStreamOffset)toRead
whence: SEEK_CUR];
else {
while (toRead > 0) {
char buffer[512];
unsigned long long min = toRead;
if (min > 512)
|
︙ | | |
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
|
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
|
-
+
|
{
return ((id <OFReadyForWritingObserving>)_stream)
.fileDescriptorForWriting;
}
- (void)close
{
OFFileOffset offset;
OFStreamOffset offset;
if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
_entry.uncompressedSize = _bytesWritten;
_entry.compressedSize = _bytesWritten;
_entry.CRC16 = _CRC16;
|
︙ | | |
Modified src/OFMemoryStream.m
from [1697ea3e2b]
to [0ce810b341].
︙ | | |
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
-
+
|
- (instancetype)initWithMemoryAddress: (void *)address
size: (size_t)size
writable: (bool)writable
{
self = [super init];
@try {
if (size > SSIZE_MAX || (ssize_t)size != (OFFileOffset)size)
if (size > SSIZE_MAX || (ssize_t)size != (OFStreamOffset)size)
@throw [OFOutOfRangeException exception];
_address = address;
_size = size;
_writable = writable;
} @catch (id e) {
[self release];
|
︙ | | |
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
-
+
+
-
+
-
+
-
+
-
+
|
}
- (bool)lowlevelIsAtEndOfStream
{
return (_position == _size);
}
- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
whence: (int)whence
{
OFFileOffset new;
OFStreamOffset new;
switch (whence) {
case SEEK_SET:
new = offset;
break;
case SEEK_CUR:
new = (OFFileOffset)_position + offset;
new = (OFStreamOffset)_position + offset;
break;
case SEEK_END:
new = (OFFileOffset)_size + offset;
new = (OFStreamOffset)_size + offset;
break;
default:
@throw [OFInvalidArgumentException exception];
}
if (new < 0 || new > (OFFileOffset)_size)
if (new < 0 || new > (OFStreamOffset)_size)
@throw [OFSeekFailedException exceptionWithStream: self
offset: offset
whence: whence
errNo: EINVAL];
return (_position = (size_t)new);
}
@end
|
Modified src/OFSeekableStream.h
from [dfe5585e9c]
to [7f5f12c98e].
︙ | | |
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
|
#endif
#import "OFStream.h"
OF_ASSUME_NONNULL_BEGIN
#if defined(OF_WINDOWS)
typedef __int64 OFFileOffset;
typedef __int64 OFStreamOffset;
#elif defined(OF_ANDROID)
typedef long long OFFileOffset;
typedef long long OFStreamOffset;
#elif defined(OF_MORPHOS)
typedef signed long long OFFileOffset;
typedef signed long long OFStreamOffset;
#elif defined(OF_HAVE_OFF64_T)
typedef off64_t OFFileOffset;
typedef off64_t OFStreamOffset;
#else
typedef off_t OFFileOffset;
typedef off_t OFStreamOffset;
#endif
/**
* @class OFSeekableStream OFSeekableStream.h ObjFW/OFSeekableStream.h
*
* @brief A stream that supports seeking.
*
* @note If you want to subclass this, override
* @ref lowlevelSeekToOffset:whence:. OFSeekableStream uses this method
* and makes it work together with the caching of OFStream. If you
* override this methods without the `lowlevel` prefix, you *will* break
* caching, get broken results and seek to the wrong position!
*/
@interface OFSeekableStream: OFStream
{
OF_RESERVE_IVARS(OFSeekableStream, 4)
}
/**
* @brief Seeks to the specified absolute offset.
* @brief Seeks to the specified offset.
*
* @param offset The offset in bytes
* @param whence From where to seek.@n
* Possible values are:
* Value | Description
* -----------|---------------------------------------
* `SEEK_SET` | Seek to the specified byte
* `SEEK_CUR` | Seek to the current location + offset
* `SEEK_END` | Seek to the end of the stream + offset
* @return The new offset form the start of the file
*/
- (OFFileOffset)seekToOffset: (OFFileOffset)offset whence: (int)whence;
- (OFStreamOffset)seekToOffset: (OFStreamOffset)offset whence: (int)whence;
/**
* @brief Seek the stream on the lowlevel.
*
* @warning Do not call this directly!
*
* @note Override this method with your actual seek implementation when
* subclassing!
*
* @param offset The offset to seek to
* @param whence From where to seek.@n
* Possible values are:
* Value | Description
* -----------|---------------------------------------
* `SEEK_SET` | Seek to the specified byte
* `SEEK_CUR` | Seek to the current location + offset
* `SEEK_END` | Seek to the end of the stream + offset
* @return The new offset from the start of the file
*/
- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence;
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
whence: (int)whence;
@end
OF_ASSUME_NONNULL_END
|
Modified src/OFSeekableStream.m
from [9e766aeca1]
to [562c4a07bd].
︙ | | |
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
-
+
+
-
+
|
@throw e;
}
}
return [super init];
}
- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
whence: (int)whence
{
OF_UNRECOGNIZED_SELECTOR
}
- (OFFileOffset)seekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)seekToOffset: (OFStreamOffset)offset whence: (int)whence
{
if (whence == SEEK_CUR)
offset -= _readBufferLength;
offset = [self lowlevelSeekToOffset: offset whence: whence];
OFFreeMemory(_readBufferMemory);
|
︙ | | |
Modified src/OFTarArchive.m
from [90c0fe7151]
to [d41a5109d6].
︙ | | |
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
|
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
-
+
+
-
-
+
+
+
|
- (void)of_skip
{
if (_stream == nil || _skipped)
return;
if ([_stream isKindOfClass: [OFSeekableStream class]] &&
_toRead <= INT64_MAX && (OFFileOffset)_toRead == (int64_t)_toRead) {
_toRead <= INT64_MAX &&
(OFStreamOffset)_toRead == (int64_t)_toRead) {
uint64_t size;
[(OFSeekableStream *)_stream seekToOffset: (OFFileOffset)_toRead
whence: SEEK_CUR];
[(OFSeekableStream *)_stream
seekToOffset: (OFStreamOffset)_toRead
whence: SEEK_CUR];
_toRead = 0;
size = _entry.size;
if (size % 512 != 0)
[(OFSeekableStream *)_stream
|
︙ | | |
Modified src/OFZIPArchive.m
from [e9a337a52f]
to [6a0897ace1].
︙ | | |
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
-
+
|
*size -= 8;
return field;
}
static void
seekOrThrowInvalidFormat(OFSeekableStream *stream,
OFFileOffset offset, int whence)
OFStreamOffset offset, int whence)
{
@try {
[stream seekToOffset: offset whence: whence];
} @catch (OFSeekFailedException *e) {
if (e.errNo == EINVAL)
@throw [OFInvalidFormatException exception];
|
︙ | | |
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
-
+
|
[self of_readZIPInfo];
[self of_readEntries];
}
if (_mode == modeAppend) {
_offset = _centralDirectoryOffset;
seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
(OFFileOffset)_offset, SEEK_SET);
(OFStreamOffset)_offset, SEEK_SET);
}
} @catch (id e) {
/*
* If we are in write or append mode, we do not want -[close]
* to write anything to it on error - after all, it might not
* be a ZIP file which we would destroy otherwise.
*/
|
︙ | | |
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
|
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
|
-
+
|
[super dealloc];
}
- (void)of_readZIPInfo
{
void *pool = objc_autoreleasePoolPush();
uint16_t commentLength;
OFFileOffset offset = -22;
OFStreamOffset offset = -22;
bool valid = false;
do {
seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
offset, SEEK_END);
if ([_stream readLittleEndianInt32] == 0x06054B50) {
|
︙ | | |
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
-
+
-
+
|
/*
* FIXME: Handle number of the disk containing ZIP64 end of
* central directory record.
*/
[_stream readLittleEndianInt32];
offset64 = [_stream readLittleEndianInt64];
if (offset64 < 0 || (OFFileOffset)offset64 != offset64)
if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
@throw [OFOutOfRangeException exception];
seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
(OFFileOffset)offset64, SEEK_SET);
(OFStreamOffset)offset64, SEEK_SET);
if ([_stream readLittleEndianInt32] != 0x06064B50)
@throw [OFInvalidFormatException exception];
size = [_stream readLittleEndianInt64];
if (size < 44)
@throw [OFInvalidFormatException exception];
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
|
_centralDirectoryEntriesInDisk =
[_stream readLittleEndianInt64];
_centralDirectoryEntries = [_stream readLittleEndianInt64];
_centralDirectorySize = [_stream readLittleEndianInt64];
_centralDirectoryOffset = [_stream readLittleEndianInt64];
if (_centralDirectoryOffset < 0 ||
(OFFileOffset)_centralDirectoryOffset !=
(OFStreamOffset)_centralDirectoryOffset !=
_centralDirectoryOffset)
@throw [OFOutOfRangeException exception];
}
objc_autoreleasePoolPop(pool);
}
- (void)of_readEntries
{
void *pool = objc_autoreleasePoolPush();
if (_centralDirectoryOffset < 0 ||
(OFFileOffset)_centralDirectoryOffset != _centralDirectoryOffset)
(OFStreamOffset)_centralDirectoryOffset != _centralDirectoryOffset)
@throw [OFOutOfRangeException exception];
seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
(OFFileOffset)_centralDirectoryOffset, SEEK_SET);
(OFStreamOffset)_centralDirectoryOffset, SEEK_SET);
for (size_t i = 0; i < _centralDirectoryEntries; i++) {
OFZIPArchiveEntry *entry = [[[OFZIPArchiveEntry alloc]
of_initWithStream: _stream] autorelease];
if ([_pathToEntryMap objectForKey: entry.fileName] != nil)
@throw [OFInvalidFormatException exception];
|
︙ | | |
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
|
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
|
-
+
-
+
|
@throw [OFOpenItemFailedException exceptionWithPath: path
mode: @"r"
errNo: ENOENT];
[self of_closeLastReturnedStream];
offset64 = entry.of_localFileHeaderOffset;
if (offset64 < 0 || (OFFileOffset)offset64 != offset64)
if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
@throw [OFOutOfRangeException exception];
seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
(OFFileOffset)offset64, SEEK_SET);
(OFStreamOffset)offset64, SEEK_SET);
localFileHeader = [[[OFZIPArchiveLocalFileHeader alloc]
initWithStream: _stream] autorelease];
if (![localFileHeader matchesEntry: entry])
@throw [OFInvalidFormatException exception];
if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) {
|
︙ | | |
Modified src/exceptions/OFSeekFailedException.h
from [f6a3b56229]
to [f1d3a39ff6].
︙ | | |
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
-
+
-
+
|
* OFSeekFailedException.h ObjFW/OFSeekFailedException.h
*
* @brief An exception indicating that seeking in a stream failed.
*/
@interface OFSeekFailedException: OFException
{
OFSeekableStream *_stream;
OFFileOffset _offset;
OFStreamOffset _offset;
int _whence, _errNo;
}
/**
* @brief The stream for which seeking failed.
*/
@property (readonly, nonatomic) OFSeekableStream *stream;
/**
* @brief The offset to which seeking failed.
*/
@property (readonly, nonatomic) OFFileOffset offset;
@property (readonly, nonatomic) OFStreamOffset offset;
/**
* @brief To what the offset is relative.
*/
@property (readonly, nonatomic) int whence;
/**
|
︙ | | |
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
-
+
-
+
|
* @param stream The stream for which seeking failed
* @param offset The offset to which seeking failed
* @param whence To what the offset is relative
* @param errNo The errno of the error that occurred
* @return A new, autoreleased seek failed exception
*/
+ (instancetype)exceptionWithStream: (OFSeekableStream *)stream
offset: (OFFileOffset)offset
offset: (OFStreamOffset)offset
whence: (int)whence
errNo: (int)errNo;
+ (instancetype)exception OF_UNAVAILABLE;
/**
* @brief Initializes an already allocated seek failed exception.
*
* @param stream The stream for which seeking failed
* @param offset The offset to which seeking failed
* @param whence To what the offset is relative
* @param errNo The errno of the error that occurred
* @return An initialized seek failed exception
*/
- (instancetype)initWithStream: (OFSeekableStream *)stream
offset: (OFFileOffset)offset
offset: (OFStreamOffset)offset
whence: (int)whence
errNo: (int)errNo OF_DESIGNATED_INITIALIZER;
- (instancetype)init OF_UNAVAILABLE;
@end
OF_ASSUME_NONNULL_END
|
Modified src/exceptions/OFSeekFailedException.m
from [8afbb45d54]
to [1550412068].
︙ | | |
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
-
+
-
+
|
+ (instancetype)exception
{
OF_UNRECOGNIZED_SELECTOR
}
+ (instancetype)exceptionWithStream: (OFSeekableStream *)stream
offset: (OFFileOffset)offset
offset: (OFStreamOffset)offset
whence: (int)whence
errNo: (int)errNo
{
return [[[self alloc] initWithStream: stream
offset: offset
whence: whence
errNo: errNo] autorelease];
}
- (instancetype)init
{
OF_INVALID_INIT_METHOD
}
- (instancetype)initWithStream: (OFSeekableStream *)stream
offset: (OFFileOffset)offset
offset: (OFStreamOffset)offset
whence: (int)whence
errNo: (int)errNo
{
self = [super init];
_stream = [stream retain];
_offset = offset;
|
︙ | | |