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
		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) ||
		    capacity > UINT32_MAX / 8)
			@throw [OFOutOfRangeException exception];

		for (_capacity = 1; _capacity < capacity; _capacity *= 2);






		if (capacity * 8 / _capacity >= 6)

			_capacity *= 2;

		if (_capacity < MIN_CAPACITY)
			_capacity = MIN_CAPACITY;

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








<
|



|
>
>
>
>
>
>

>
|







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 / sizeof(*_buckets) ||
		    capacity > UINT32_MAX / 8)
			@throw [OFOutOfRangeException exception];

		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;

		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
}

- (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) ||
	    count > UINT32_MAX / 8)
		@throw [OFOutOfRangeException exception];

	fullness = count * 8 / _capacity;

	if (fullness >= 6)



		capacity = _capacity * 2;
	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.







|
<




|
>
>
>

|







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 / sizeof(*_buckets) || count > UINT32_MAX / 8)

		@throw [OFOutOfRangeException exception];

	fullness = count * 8 / _capacity;

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

		capacity = _capacity * 2;
	} 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
			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;







<
<







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++);
			}



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


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







>
>







<







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

			[self OF_resizeForCount: _count];

			return;
		}
	}

	if (i < last)