ObjFW  Diff

Differences From Artifact [728d6fb127]:

To Artifact [1983c233dd]:


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
132
133
134
135

136
137
138
139
140
141
142

143
144
145
146
147
148
149
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
132

133

134
135
136
137
138
139

140
141
142
143
144
145
146
147
148







-
+

-
+

















-

-
+





-

+







		    (version & 0xFF) / 10, (version & 0xFF) % 10, attrCompat];
	else
		return [OFString stringWithFormat:
		    @"%u.%u, unknown %02X",
		    (version % 0xFF) / 10, (version & 0xFF) % 10, version >> 8];
}

void
size_t
of_zip_archive_entry_extra_field_find(OFData *extraField, uint16_t tag,
    const uint8_t **data, uint16_t *size)
    uint16_t *size)
{
	const uint8_t *bytes = [extraField items];
	size_t count = [extraField count];

	for (size_t i = 0; i < count;) {
		uint16_t currentTag, currentSize;

		if (i + 3 >= count)
			@throw [OFInvalidFormatException exception];

		currentTag = (bytes[i + 1] << 8) | bytes[i];
		currentSize = (bytes[i + 3] << 8) | bytes[i + 2];

		if (i + 3 + currentSize >= count)
			@throw [OFInvalidFormatException exception];

		if (currentTag == tag) {
			*data = bytes + i + 4;
			*size = currentSize;
			return;
			return i + 4;
		}

		i += 4 + currentSize;
	}

	*data = NULL;
	*size = 0;
	return OF_NOT_FOUND;
}

@implementation OFZIPArchiveEntry
+ (instancetype)entryWithFileName: (OFString *)fileName
{
	return [[[self alloc] initWithFileName: fileName] autorelease];
}
176
177
178
179
180
181
182

183
184
185

186
187
188
189
190
191
192
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192







+


-
+








- (instancetype)of_initWithStream: (OFStream *)stream
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMutableData *extraField = nil;
		uint16_t fileNameLength, extraFieldLength, fileCommentLength;
		of_string_encoding_t encoding;
		const uint8_t *ZIP64 = NULL;
		size_t ZIP64Index;
		uint16_t ZIP64Size;

		if ([stream readLittleEndianInt32] != 0x02014B50)
			@throw [OFInvalidFormatException exception];

		_versionMadeBy = [stream readLittleEndianInt16];
		_minVersionNeeded = [stream readLittleEndianInt16];
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
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
258
259







-
-
+
+





-
-
+
+

-
+
+
+
+
















-
-
+
+
+
+
+
+
+
+







		encoding = (_generalPurposeBitFlag & (1 << 11)
		    ? OF_STRING_ENCODING_UTF_8
		    : OF_STRING_ENCODING_CODEPAGE_437);

		_fileName = [[stream readStringWithLength: fileNameLength
						 encoding: encoding] copy];
		if (extraFieldLength > 0)
			_extraField =
			    [[stream readDataWithCount: extraFieldLength] copy];
			extraField = [[[stream readDataWithCount:
			    extraFieldLength] mutableCopy] autorelease];
		if (fileCommentLength > 0)
			_fileComment = [[stream
			    readStringWithLength: fileCommentLength
					encoding: encoding] copy];

		of_zip_archive_entry_extra_field_find(_extraField,
		    OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64, &ZIP64, &ZIP64Size);
		ZIP64Index = of_zip_archive_entry_extra_field_find(_extraField,
		    OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64, &ZIP64Size);

		if (ZIP64 != NULL) {
		if (ZIP64Index != OF_NOT_FOUND) {
			const uint8_t *ZIP64 =
			    [_extraField itemAtIndex: ZIP64Index];

			if (_uncompressedSize == 0xFFFFFFFF)
				_uncompressedSize = of_zip_archive_read_field64(
				    &ZIP64, &ZIP64Size);
			if (_compressedSize == 0xFFFFFFFF)
				_compressedSize = of_zip_archive_read_field64(
				    &ZIP64, &ZIP64Size);
			if (_localFileHeaderOffset == 0xFFFFFFFF)
				_localFileHeaderOffset =
				    of_zip_archive_read_field64(&ZIP64,
				    &ZIP64Size);
			if (_startDiskNumber == 0xFFFF)
				_startDiskNumber = of_zip_archive_read_field32(
				    &ZIP64, &ZIP64Size);

			if (ZIP64Size > 0 || _localFileHeaderOffset < 0)
				@throw [OFInvalidFormatException exception];
		}


			[extraField removeItemsInRange:
			    of_range(ZIP64Index - 4, ZIP64Size + 4)];
		}

		[extraField makeImmutable];
		_extraField = [extraField copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;