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