12a53b785Smrg/*	$OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $	*/
22a53b785Smrg/*
32a53b785Smrg * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
42a53b785Smrg *
52a53b785Smrg * Permission to use, copy, modify, and distribute this software for any
62a53b785Smrg * purpose with or without fee is hereby granted, provided that the above
72a53b785Smrg * copyright notice and this permission notice appear in all copies.
82a53b785Smrg *
92a53b785Smrg * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
102a53b785Smrg * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
112a53b785Smrg * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
122a53b785Smrg * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
132a53b785Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
142a53b785Smrg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
152a53b785Smrg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
162a53b785Smrg */
172a53b785Smrg
182a53b785Smrg#ifdef HAVE_CONFIG_H
192a53b785Smrg#include <config.h>
202a53b785Smrg#endif
212a53b785Smrg
222a53b785Smrg#include <sys/types.h>
232a53b785Smrg#include <errno.h>
242a53b785Smrg#include <stdint.h>
252a53b785Smrg#include <stdlib.h>
262a53b785Smrg#include "reallocarray.h"
272a53b785Smrg
282a53b785Smrg/*
292a53b785Smrg * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
302a53b785Smrg * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
312a53b785Smrg */
322a53b785Smrg#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
332a53b785Smrg
342a53b785Smrgvoid *
352a53b785Smrgxreallocarray(void *optr, size_t nmemb, size_t size)
362a53b785Smrg{
372a53b785Smrg	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
382a53b785Smrg	    nmemb > 0 && SIZE_MAX / nmemb < size) {
392a53b785Smrg		errno = ENOMEM;
402a53b785Smrg		return NULL;
412a53b785Smrg	}
422a53b785Smrg	return realloc(optr, size * nmemb);
432a53b785Smrg}
44