ObjFW  Check-in [f9cd4f9cab]

Overview
Comment:OFStream: Don't throw when at end of stream

Instead, let reads return 0 and let writes append after the end.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f9cd4f9cab7be99a2180b722afdd52e65c0a346d442d17fe506a30fa9ccd705b
User & Date: js on 2017-06-05 15:51:48
Other Links: manifest | tags
Context
2017-06-05
17:36
Clean up exceptions a little check-in: 4f36894ce7 user: js tags: trunk
15:51
OFStream: Don't throw when at end of stream check-in: f9cd4f9cab user: js tags: trunk
12:50
OFStream: More range checks check-in: 577f0a744b user: js tags: trunk
Changes

Modified src/OFDeflateStream.m from [95db2a693c] to [f38e0e21e0].

29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44







+

-







# import "OFDeflate64Stream.h"
# define OFDeflateStream OFDeflate64Stream
#endif
#import "OFDataArray.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidFormatException.h"
#import "OFNotOpenException.h"
#import "OFOutOfMemoryException.h"
#import "OFReadFailedException.h"

#define BUFFER_SIZE		  OF_INFLATE_STREAM_BUFFER_SIZE

#define MAX_BITS 15

enum state {
	BLOCK_HEADER,
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316







-
+







	_stream = [stream retain];

	return self;
}

- (void)dealloc
{
	[_stream release];
	[self close];

	if (_decompression != NULL && _decompression->state == HUFFMAN_TREE)
		if (_decompression->context.huffmanTree.codeLenTree != NULL)
			releaseTree(
			    _decompression->context.huffmanTree.codeLenTree);

	if (_decompression != NULL && (_decompression->state == HUFFMAN_TREE ||
347
348
349
350
351
352
353



354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362


363
364
365
366
367
368
369
370







+
+
+






-
-
+







	uint8_t *buffer = buffer_;
	uint16_t bits, tmp;
	uint16_t value;
	size_t bytesWritten = 0;
	uint8_t *slidingWindow;
	uint16_t slidingWindowIndex;

	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (ivars == NULL) {
		[self of_initDecompression];
		ivars = _decompression;
	}

	if (ivars->atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
		return 0;

start:
	switch ((enum state)ivars->state) {
	case BLOCK_HEADER:
		if OF_UNLIKELY (ivars->inLastBlock) {
			[_stream unreadFromBuffer: ivars->buffer +
						   ivars->bufferIndex
819
820
821
822
823
824
825
826
827


828
829
830
831
832
833
834
835
836
837
838
839
840
841








842
821
822
823
824
825
826
827


828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852







-
-
+
+














+
+
+
+
+
+
+
+


	OF_UNREACHABLE
}

#ifndef DEFLATE64
- (bool)lowlevelIsAtEndOfStream
{
	if (_decompression == NULL)
		return false;
	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	return _decompression->atEndOfStream;
}

- (int)fileDescriptorForReading
{
	return [_stream fileDescriptorForReading];
}

- (bool)hasDataInReadBuffer
{
	return ([super hasDataInReadBuffer] || [_stream hasDataInReadBuffer]);
}
#endif

- (void)close
{
	[_stream release];
	_stream = nil;

	[super close];
}
@end

Modified src/OFFile.m from [4cea821d7a] to [c3e373372b].

31
32
33
34
35
36
37

38
39
40
41
42
43
44
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45







+







#import "OFFile.h"
#import "OFString.h"
#import "OFLocalization.h"
#import "OFDataArray.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFNotOpenException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSeekFailedException.h"
#import "OFWriteFailedException.h"

#ifdef OF_WINDOWS
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
331
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322


323
324

325
326
327
328
329
330
331







-
+









-
-
+
+
-








	return self;
}

- (bool)lowlevelIsAtEndOfStream
{
	if (!OF_FILE_HANDLE_IS_VALID(_handle))
		return true;
		@throw [OFNotOpenException exceptionWithObject: self];

	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	ssize_t ret;

	if (!OF_FILE_HANDLE_IS_VALID(_handle) || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
	if (!OF_FILE_HANDLE_IS_VALID(_handle))
		@throw [OFNotOpenException exceptionWithObject: self];
						  requestedLength: length];

#if defined(OF_WINDOWS)
	if (length > UINT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((ret = read(_handle, buffer, (unsigned int)length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
350
351
352
353
354
355
356
357
358


359
360
361
362
363
364
365
366
350
351
352
353
354
355
356


357
358

359
360
361
362
363
364
365







-
-
+
+
-








	return ret;
}

- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
	if (!OF_FILE_HANDLE_IS_VALID(_handle) || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
	if (!OF_FILE_HANDLE_IS_VALID(_handle))
		@throw [OFNotOpenException exceptionWithObject: self];
						   requestedLength: length];

#if defined(OF_WINDOWS)
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if (write(_handle, buffer, (int)length) != (int)length)
		@throw [OFWriteFailedException exceptionWithObject: self
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
392
393
394
395
396
397
398

399


400
401
402
403
404
405
406







-
+
-
-








- (of_offset_t)lowlevelSeekToOffset: (of_offset_t)offset
			     whence: (int)whence
{
	of_offset_t ret;

	if (!OF_FILE_HANDLE_IS_VALID(_handle))
		@throw [OFSeekFailedException exceptionWithStream: self
		@throw [OFNotOpenException exceptionWithObject: self];
							   offset: offset
							   whence: whence];

#ifndef OF_MORPHOS
# if defined(OF_WINDOWS)
	ret = _lseeki64(_handle, offset, whence);
# elif defined(OF_HAVE_OFF64_T)
	ret = lseek64(_handle, offset, whence);
# else

Modified src/OFGZIPStream.m from [1028d48dc9] to [4efebeb9c7].

20
21
22
23
24
25
26


27
28
29
30
31
32
33
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35







+
+







#import "OFDeflateStream.h"
#import "OFDate.h"

#import "crc32.h"

#import "OFChecksumFailedException.h"
#import "OFInvalidFormatException.h"
#import "OFNotOpenException.h"
#import "OFTruncatedDataException.h"

@implementation OFGZIPStream
+ (instancetype)streamWithStream: (OFStream *)stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

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
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







+
-
+









+
+
+
+
-
+

+
+
+
-
+
+
+
+







	}

	return self;
}

- (void)dealloc
{
	[self close];
	[_stream release];

	[_inflateStream release];
	[_modificationDate release];

	[super dealloc];
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	for (;;) {
	uint8_t byte;
		uint8_t byte;

		if ([_stream isAtEndOfStream]) {
			if (_state != OF_GZIP_STREAM_ID1)
				@throw [OFTruncatedDataException exception];
	for (;;) {

			return 0;
		}

		switch (_state) {
		case OF_GZIP_STREAM_ID1:
		case OF_GZIP_STREAM_ID2:
		case OF_GZIP_STREAM_COMPRESSION_METHOD:
			if ([_stream readIntoBuffer: &byte
					     length: 1] < 1)
				return 0;
93
94
95
96
97
98
99



100
101
102
103
104
105
106
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122







+
+
+







		case OF_GZIP_STREAM_MODIFICATION_TIME:
			_bytesRead += [_stream
			    readIntoBuffer: _buffer + _bytesRead
				    length: 4 - _bytesRead];

			if (_bytesRead < 4)
				return 0;

			[_modificationDate release];
			_modificationDate = nil;

			_modificationDate = [[OFDate alloc]
			    initWithTimeIntervalSince1970:
			    (_buffer[3] << 24) | (_buffer[2] << 16) |
			    (_buffer[1] << 8) | _buffer[0]];

			_bytesRead = 0;
258
259
260
261
262
263
264



265
266
267
268
269
270
271
272
273
274
275








276
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303







+
+
+











+
+
+
+
+
+
+
+

			break;
		}
	}
}

- (bool)lowlevelIsAtEndOfStream
{
	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	return [_stream isAtEndOfStream];
}

- (bool)hasDataInReadBuffer
{
	if (_state == OF_GZIP_STREAM_DATA)
		return ([super hasDataInReadBuffer] ||
		    [_inflateStream hasDataInReadBuffer]);

	return ([super hasDataInReadBuffer] || [_stream hasDataInReadBuffer]);
}

- (void)close
{
	[_stream release];
	_stream = nil;

	[super close];
}
@end

Modified src/OFHTTPClient.m from [530dbe6279] to [aa5274f753].

29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45







+


-







#import "OFDataArray.h"

#import "OFHTTPRequestFailedException.h"
#import "OFInvalidEncodingException.h"
#import "OFInvalidFormatException.h"
#import "OFInvalidServerReplyException.h"
#import "OFNotImplementedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFTruncatedDataException.h"
#import "OFUnsupportedProtocolException.h"
#import "OFUnsupportedVersionException.h"
#import "OFWriteFailedException.h"

static OF_INLINE void
normalizeKey(char *str_)
124
125
126
127
128
129
130
131
132
133
134





135
136
137
138
139
140
141
124
125
126
127
128
129
130




131
132
133
134
135
136
137
138
139
140
141
142







-
-
-
-
+
+
+
+
+







		}
	}
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	if (_atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length
							    errNo: ENOTCONN];
	if (_socket == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;

	if (!_hasContentLength && !_chunked)
		return [_socket readIntoBuffer: buffer
					length: length];

	/* Content-Length */
	if (!_chunked) {
227
228
229
230
231
232
233



234
235
236
237
238
239
240
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244







+
+
+








		return 0;
	}
}

- (bool)lowlevelIsAtEndOfStream
{
	if (_socket == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (!_hasContentLength && !_chunked)
		return [_socket isAtEndOfStream];

	return _atEndOfStream;
}

- (int)fileDescriptorForReading

Modified src/OFProcess.m from [5a7b7eae60] to [ea4c0fa50a].

34
35
36
37
38
39
40

41
42
43
44
45
46
47
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48







+







#import "OFString.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFDataArray.h"
#import "OFLocalization.h"

#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"

#ifdef OF_WINDOWS
# include <windows.h>
#endif
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453


454
455
456
457
458
459
460
461
462
463
464
465
466
467


468
469
470
471
472
473
474
475
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452


453
454

455
456
457
458
459
460
461
462
463
464
465


466
467

468
469
470
471
472
473
474







-
+










-
-
+
+
-











-
-
+
+
-







- (bool)lowlevelIsAtEndOfStream
{
#ifndef OF_WINDOWS
	if (_readPipe[0] == -1)
#else
	if (_readPipe[0] == NULL)
#endif
		return true;
		@throw [OFNotOpenException exceptionWithObject: self];

	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
#ifndef OF_WINDOWS
	ssize_t ret;

	if (_readPipe[0] == -1 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
	if (_readPipe[0] == -1)
		@throw [OFNotOpenException exceptionWithObject: self];
						  requestedLength: length];

	if ((ret = read(_readPipe[0], buffer, length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length
							    errNo: errno];
#else
	DWORD ret;

	if (length > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	if (_readPipe[0] == NULL || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
	if (_readPipe[0] == NULL)
		@throw [OFNotOpenException exceptionWithObject: self];
						  requestedLength: length];

	if (!ReadFile(_readPipe[0], buffer, (DWORD)length, &ret, NULL)) {
		if (GetLastError() == ERROR_BROKEN_PIPE) {
			_atEndOfStream = true;
			return 0;
		}

484
485
486
487
488
489
490
491
492


493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509


510
511
512
513
514
515
516
517
483
484
485
486
487
488
489


490
491

492
493
494
495
496
497
498
499
500
501
502
503
504
505


506
507

508
509
510
511
512
513
514







-
-
+
+
-














-
-
+
+
-







	return ret;
}

- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
#ifndef OF_WINDOWS
	if (_writePipe[1] == -1 || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
	if (_writePipe[1] == -1)
		@throw [OFNotOpenException exceptionWithObject: self];
						   requestedLength: length];

	if (length > SSIZE_MAX)
		@throw [OFOutOfRangeException exception];

	if (write(_writePipe[1], buffer, length) != (ssize_t)length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
							     errNo: errno];
#else
	DWORD ret;

	if (length > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	if (_writePipe[1] == NULL || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
	if (_writePipe[1] == NULL)
		@throw [OFNotOpenException exceptionWithObject: self];
						   requestedLength: length];

	if (!WriteFile(_writePipe[1], buffer, (DWORD)length, &ret, NULL) ||
	    ret != (DWORD)length) {
		int errNo = 0;

		if (GetLastError() == ERROR_BROKEN_PIPE)
			errNo = EPIPE;

Modified src/OFStdIOStream.m from [87d19ba681] to [fac79ea11f].

31
32
33
34
35
36
37

38
39
40
41
42
43
44
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45







+







#import "OFStdIOStream+Private.h"
#import "OFDate.h"
#import "OFApplication.h"
#ifdef OF_WINDOWS
# include "OFStdIOStream_Win32Console.h"
#endif

#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"

#ifdef OF_MORPHOS
# define BOOL EXEC_BOOL
# include <proto/exec.h>
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227


228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249


250
251
252
253
254
255
256
257
164
165
166
167
168
169
170

171
172

173
174
175
176
177
178
179
180
181
182
183
184


185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202


203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223


224
225

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244


245
246

247
248
249
250
251
252
253







-


-

+










-
-
+
+
-
















-
-
+
+
-



















-
-
+
+
-



















-
-
+
+
-







	[super dealloc];
}

- (bool)lowlevelIsAtEndOfStream
{
#ifndef OF_MORPHOS
	if (_fd == -1)
		return true;
#else
	if (_handle == 0)
		return true;
#endif
		@throw [OFNotOpenException exceptionWithObject: self];

	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	ssize_t ret;

#ifndef OF_MORPHOS
	if (_fd == -1 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
	if (_fd == -1)
		@throw [OFNotOpenException exceptionWithObject: self];
						  requestedLength: length];

# ifndef OF_WINDOWS
	if ((ret = read(_fd, buffer, length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length
							    errNo: errno];
# else
	if (length > UINT_MAX)
		@throw [OFOutOfRangeException exception];

	if ((ret = read(_fd, buffer, (unsigned int)length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length
							    errNo: errno];
# endif
#else
	if (_handle == 0 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
	if (_handle == 0)
		@throw [OFNotOpenException exceptionWithObject: self];
						  requestedLength: length];

	if (length > LONG_MAX)
		@throw [OFOutOfRangeException exception];

	if ((ret = Read(_handle, buffer, length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
#endif

	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
#ifndef OF_MORPHOS
	if (_fd == -1 || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
	if (_fd == -1)
		@throw [OFNotOpenException exceptionWithObject: self];
						   requestedLength: length];

# ifndef OF_WINDOWS
	if (length > SSIZE_MAX)
		@throw [OFOutOfRangeException exception];

	if (write(_fd, buffer, length) != (ssize_t)length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
							     errNo: errno];
# else
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exception];

	if (write(_fd, buffer, (int)length) != (int)length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
							     errNo: errno];
# endif
#else
	if (_handle == 0 || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
	if (_handle == 0)
		@throw [OFNotOpenException exceptionWithObject: self];
						   requestedLength: length];

	if (length > SSIZE_MAX)
		@throw [OFOutOfRangeException exception];

	if (Write(_handle, (void *)buffer, length) != (LONG)length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];

Modified src/OFStream.m from [3e8867dc7e] to [7e042e0447].

44
45
46
47
48
49
50

51
52
53
54
55
56
57
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58







+







#import "OFRunLoop+Private.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"
#import "OFSetOptionFailedException.h"
#import "OFTruncatedDataException.h"

#import "of_asprintf.h"

#define MIN_READ_SIZE 512

@implementation OFStream
@synthesize of_waitingForDelimiter = _waitingForDelimiter;
172
173
174
175
176
177
178
179




180
181

182
183
184
185
186
187
188
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193







-
+
+
+
+


+







}

- (void)readIntoBuffer: (void *)buffer
	   exactLength: (size_t)length
{
	size_t readLength = 0;

	while (readLength < length)
	while (readLength < length) {
		if ([self isAtEndOfStream])
			@throw [OFTruncatedDataException exception];

		readLength += [self readIntoBuffer: (char *)buffer + readLength
					    length: length - readLength];
	}
}

#ifdef OF_HAVE_SOCKETS
- (void)asyncReadIntoBuffer: (void *)buffer
		     length: (size_t)length
		     target: (id)target
		   selector: (SEL)selector

Modified src/OFStreamSocket.m from [c248fb563e] to [eec652ecb7].

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
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







+
+
+











-
-
-
-
-







+ (instancetype)socket
{
	return [[[self alloc] init] autorelease];
}

- (bool)lowlevelIsAtEndOfStream
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	ssize_t ret;

	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length
							    errNo: ENOTCONN];

#ifndef OF_WINDOWS
	if ((ret = recv(_socket, buffer, length, 0)) < 0)
		@throw [OFReadFailedException
		    exceptionWithObject: self
			requestedLength: length
				  errNo: of_socket_errno()];
#else
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
89
90
91
92
93
94
95





96
97
98
99
100
101
102







-
-
-
-
-








- (void)lowlevelWriteBuffer: (const void *)buffer
		     length: (size_t)length
{
	if (_socket == INVALID_SOCKET)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
							     errNo: ENOTCONN];

#ifndef OF_WINDOWS
	if (length > SSIZE_MAX)
		@throw [OFOutOfRangeException exception];

	if (send(_socket, buffer, length, 0) != (ssize_t)length)
		@throw [OFWriteFailedException
		    exceptionWithObject: self

Modified src/OFTarArchiveEntry.m from [0b52b84545] to [e3da7730a5].

21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36







+

-







#include <inttypes.h>

#import "OFTarArchiveEntry.h"
#import "OFTarArchiveEntry+Private.h"
#import "OFStream.h"
#import "OFDate.h"

#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"

static OFString *
stringFromBuffer(const char *buffer, size_t length)
{
	for (size_t i = 0; i < length; i++)
		if (buffer[i] == '\0')
			length = i;
111
112
113
114
115
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
152



153
154
155
156
157
158
159
160
161
162

163

164
165
166
167
168
169
170
111
112
113
114
115
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







+
-
+














-
-
-
+
+
+
+
+

















+
+
+










+
-
+







	}

	return self;
}

- (void)dealloc
{
	[self close];
	[_stream release];

	[_fileName release];
	[_modificationDate release];
	[_targetFileName release];
	[_owner release];
	[_group release];

	[super dealloc];
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	size_t ret;

	if (_atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;

	if ((uint64_t)length > _toRead)
		length = (size_t)_toRead;

	ret = [_stream readIntoBuffer: buffer
			       length: length];

	if (ret == 0)
		_atEndOfStream = true;

	_toRead -= ret;

	return ret;
}

- (bool)lowlevelIsAtEndOfStream
{
	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	return _atEndOfStream;
}

- (bool)hasDataInReadBuffer
{
	return ([super hasDataInReadBuffer] || [_stream hasDataInReadBuffer]);
}

- (void)close
{
	[_stream release];
	_atEndOfStream = true;
	_stream = nil;

	[super close];
}

- (void)of_skip
{
	char buffer[512];

Modified src/OFZIPArchive.m from [af4fea4ffc] to [4f8a23b8a4].

33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49







+


-








#import "crc32.h"

#import "OFChecksumFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFNotOpenException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFSeekFailedException.h"
#import "OFUnsupportedVersionException.h"

/*
 * FIXME: Current limitations:
 *  - Split archives are not supported.
 *  - Write support is missing.
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+







@interface OFZIPArchive_FileStream: OFStream
{
	OFStream *_stream, *_decompressedStream;
	OFZIPArchive_LocalFileHeader *_localFileHeader;
	bool _hasDataDescriptor;
	uint64_t _size;
	uint32_t _CRC32;
	bool _atEndOfStream, _closed;
	bool _atEndOfStream;
}

-  initWithStream: (OFStream *)path
  localFileHeader: (OFZIPArchive_LocalFileHeader *)localFileHeader;
@end

uint32_t
489
490
491
492
493
494
495

496

497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515





516
517
518
519
520
521
522
489
490
491
492
493
494
495
496

497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513



514
515
516
517
518
519
520
521
522
523
524
525







+
-
+
















-
-
-
+
+
+
+
+







	}

	return self;
}

- (void)dealloc
{
	[self close];
	[_stream release];

	[_decompressedStream release];
	[_localFileHeader release];

	[super dealloc];
}

- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
			  length: (size_t)length
{
	size_t min, ret;

	if (_atEndOfStream || _closed)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;

	if (_hasDataDescriptor) {
		if ([_decompressedStream isAtEndOfStream]) {
			uint32_t CRC32;

			_atEndOfStream = true;

556
557
558
559
560
561
562

563

564
565
566
567
559
560
561
562
563
564
565
566

567
568
569
570
571







+
-
+




	_CRC32 = of_crc32(_CRC32, buffer, ret);

	return ret;
}

- (void)close
{
	[_stream release];
	_closed = true;
	_stream = nil;

	[super close];
}
@end