1c7b4381aSmrg/*	$OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $	*/
2c7b4381aSmrg/*
3c7b4381aSmrg * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
4c7b4381aSmrg *
5c7b4381aSmrg * Permission to use, copy, modify, and distribute this software for any
6c7b4381aSmrg * purpose with or without fee is hereby granted, provided that the above
7c7b4381aSmrg * copyright notice and this permission notice appear in all copies.
8c7b4381aSmrg *
9c7b4381aSmrg * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10c7b4381aSmrg * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11c7b4381aSmrg * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12c7b4381aSmrg * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13c7b4381aSmrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14c7b4381aSmrg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15c7b4381aSmrg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16c7b4381aSmrg */
17c7b4381aSmrg
18c7b4381aSmrg#ifdef HAVE_CONFIG_H
19c7b4381aSmrg#include <config.h>
20c7b4381aSmrg#endif
21c7b4381aSmrg
22c7b4381aSmrg#include <sys/types.h>
23c7b4381aSmrg#include <errno.h>
24c7b4381aSmrg#include <stdint.h>
25c7b4381aSmrg#include <stdlib.h>
26c7b4381aSmrg#include "src/util/replace.h"
27c7b4381aSmrg
28c7b4381aSmrg/*
29c7b4381aSmrg * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
30c7b4381aSmrg * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
31c7b4381aSmrg */
32c7b4381aSmrg#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
33c7b4381aSmrg
34c7b4381aSmrgvoid *
35c7b4381aSmrgreallocarray(void *optr, size_t nmemb, size_t size)
36c7b4381aSmrg{
37c7b4381aSmrg	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
38c7b4381aSmrg	    nmemb > 0 && SIZE_MAX / nmemb < size) {
39c7b4381aSmrg		errno = ENOMEM;
40c7b4381aSmrg		return NULL;
41c7b4381aSmrg	}
42c7b4381aSmrg	return realloc(optr, size * nmemb);
43c7b4381aSmrg}
44