ObjFW  Check-in [6085d4f6a4]

Overview
Comment:OFMapTable: More overflow checks.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6085d4f6a4756ba510e143e807029b1b64e92503eb54c5883931919ac30b2ade
User & Date: js on 2013-12-01 11:51:03
Other Links: manifest | tags
Context
2013-12-01
12:12
Make OFMapTableEnumeratorWrapper private. check-in: d7b691c402 user: js tags: trunk
11:51
OFMapTable: More overflow checks. check-in: 6085d4f6a4 user: js tags: trunk
11:51
OFException: Do not show <??+offset>. check-in: 353b3ba81d user: js tags: trunk
Changes

Modified src/OFMapTable.m from [74b5d78ed2] to [484e7b21c8].

135
136
137
138
139
140
141
142
143

144
145
146
147







148

149

150
151
152
153
154
155
156
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







-
-
+



-
+
+
+
+
+
+
+

+
-
+







		SET_DEFAULT(_valueFunctions.retain, default_retain);
		SET_DEFAULT(_valueFunctions.release, default_release);
		SET_DEFAULT(_valueFunctions.hash, default_hash);
		SET_DEFAULT(_valueFunctions.equal, default_equal);

#undef SET_DEFAULT

		if (capacity > UINT32_MAX ||
		    capacity > UINT32_MAX / sizeof(*_buckets) ||
		if (capacity > UINT32_MAX / sizeof(*_buckets) ||
		    capacity > UINT32_MAX / 8)
			@throw [OFOutOfRangeException exception];

		for (_capacity = 1; _capacity < capacity; _capacity *= 2);
		for (_capacity = 1; _capacity < capacity;) {
			if (_capacity > UINT32_MAX / 2)
				@throw [OFOutOfRangeException exception];

			_capacity *= 2;
		}

		if (capacity * 8 / _capacity >= 6)
			if (_capacity <= UINT32_MAX / 2)
			_capacity *= 2;
				_capacity *= 2;

		if (_capacity < MIN_CAPACITY)
			_capacity = MIN_CAPACITY;

		_buckets = [self allocMemoryWithSize: sizeof(*_buckets)
					       count: _capacity];

292
293
294
295
296
297
298
299

300
301
302
303
304
305




306
307

308
309
310
311
312
313
314
298
299
300
301
302
303
304

305

306
307
308
309

310
311
312
313
314

315
316
317
318
319
320
321
322







-
+
-




-
+
+
+
+

-
+







}

- (void)OF_resizeForCount: (uint32_t)count
{
	uint32_t i, fullness, capacity;
	struct of_map_table_bucket **buckets;

	if (count > UINT32_MAX || count > UINT32_MAX / sizeof(*_buckets) ||
	if (count > UINT32_MAX / sizeof(*_buckets) || count > UINT32_MAX / 8)
	    count > UINT32_MAX / 8)
		@throw [OFOutOfRangeException exception];

	fullness = count * 8 / _capacity;

	if (fullness >= 6)
	if (fullness >= 6) {
		if (_capacity > UINT32_MAX / 2)
			return;

		capacity = _capacity * 2;
	else if (fullness <= 1)
	} else if (fullness <= 1)
		capacity = _capacity / 2;
	else
		return;

	/*
	 * Don't downsize if we have an initial capacity or if we would fall
	 * below the minimum capacity.
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
342
343
344
345
346
347
348


349
350
351
352
353
354
355







-
-







			if (j >= last) {
				last = _buckets[i]->hash & (capacity - 1);

				for (j = 0; j < last &&
				    buckets[j] != NULL; j++);
			}

			assert(j < last);

			buckets[j] = _buckets[i];
		}
	}

	[self freeMemory: _buckets];
	_buckets = buckets;
	_capacity = capacity;
456
457
458
459
460
461
462


463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

478
479
480
481
482
483
484







+
+







-







	last = _capacity;

	for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
		if (_buckets[i] == &deleted)
			continue;

		if (_keyFunctions.equal(_buckets[i]->key, key)) {
			_mutations++;

			_keyFunctions.release(_buckets[i]->key);
			_valueFunctions.release(_buckets[i]->value);

			[self freeMemory: _buckets[i]];
			_buckets[i] = &deleted;

			_count--;
			_mutations++;
			[self OF_resizeForCount: _count];

			return;
		}
	}

	if (i < last)