10760f5d2Smrg/*	$OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $	*/
20760f5d2Smrg/*
30760f5d2Smrg * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
40760f5d2Smrg *
50760f5d2Smrg * Permission to use, copy, modify, and distribute this software for any
60760f5d2Smrg * purpose with or without fee is hereby granted, provided that the above
70760f5d2Smrg * copyright notice and this permission notice appear in all copies.
80760f5d2Smrg *
90760f5d2Smrg * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
100760f5d2Smrg * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
110760f5d2Smrg * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
120760f5d2Smrg * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
130760f5d2Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
140760f5d2Smrg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
150760f5d2Smrg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
160760f5d2Smrg */
170760f5d2Smrg
180760f5d2Smrg#ifdef HAVE_CONFIG_H
190760f5d2Smrg#include <config.h>
200760f5d2Smrg#endif
210760f5d2Smrg
220760f5d2Smrg#include <sys/types.h>
230760f5d2Smrg#include <errno.h>
240760f5d2Smrg#include <stdint.h>
250760f5d2Smrg#include <stdlib.h>
260760f5d2Smrg#include "reallocarray.h"
270760f5d2Smrg
280760f5d2Smrg/*
290760f5d2Smrg * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
300760f5d2Smrg * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
310760f5d2Smrg */
320760f5d2Smrg#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
330760f5d2Smrg
340760f5d2Smrgvoid *
350760f5d2Smrgxreallocarray(void *optr, size_t nmemb, size_t size)
360760f5d2Smrg{
370760f5d2Smrg	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
380760f5d2Smrg	    nmemb > 0 && SIZE_MAX / nmemb < size) {
390760f5d2Smrg		errno = ENOMEM;
400760f5d2Smrg		return NULL;
410760f5d2Smrg	}
420760f5d2Smrg	return realloc(optr, size * nmemb);
430760f5d2Smrg}
44