> Hi, Please don't forget to include Otto's license to the code, that > you modified. >
Thanks for this reminder. Please accept my apologies, I'm not very familiar with the customs of licencing which doesn't exist in my profession. Would this be a satisfactory way of fulfilling your request? Index: Makefile =================================================================== RCS file: /cvs/src/bin/ksh/Makefile,v retrieving revision 1.29 diff -u -p -r1.29 Makefile --- Makefile 2 Dec 2013 20:41:01 -0000 1.29 +++ Makefile 23 May 2015 12:56:30 -0000 @@ -6,7 +6,7 @@ SRCS= alloc.c c_ksh.c c_sh.c c_test.c c_ misc.c path.c shf.c syn.c table.c trap.c tree.c tty.c var.c \ version.c vi.c -DEFS= -Wall +DEFS= -Wall -Wunused-function CFLAGS+=${DEFS} -I. -I${.CURDIR} -I${.CURDIR}/../../lib/libc/gen MAN= ksh.1 sh.1 Index: alloc.c =================================================================== RCS file: /cvs/src/bin/ksh/alloc.c,v retrieving revision 1.8 diff -u -p -r1.8 alloc.c --- alloc.c 21 Jul 2008 17:30:08 -0000 1.8 +++ alloc.c 23 May 2015 12:56:30 -0000 @@ -25,6 +25,22 @@ */ /* + * Copyright (c) 2008 Otto Moerbeek <o...@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* * area-based allocation built on malloc/free */ @@ -74,6 +90,62 @@ alloc(size_t size, Area *ap) return L2P(l); } +/* + * From libc/stdlib/allocarray.c + * + * This is sqrt(SIZE_MAX+1), as s1 * s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) +/* + * Generous upper bound for sqrt(sizeof(struct link)). + */ +#define SQRT_SIZ_STR_LINK (sizeof(struct link) / 2) + +void * +allocarray(size_t nmemb, size_t size, Area *ap) +{ + /* + * Ensure that `sizeof(struct link) + size * nmemb' doesn't overflow. + * If overflow occurs, at least one of `size' and `nmemb' must be + * larger than sqrt(SIZE_MAX - sizeof(struct link)). + * Note: sqrt(a - b) > sqrt(a) - sqrt(b) for a > b. + */ + if ((nmemb >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK || + size >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK) && + nmemb > 0 && (SIZE_MAX - sizeof(struct link)) / nmemb < size) + internal_errorf(1, "unable to allocate memory"); + + return (alloc(size * nmemb, ap)); +} + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) +/* + * Generous upper bound for sqrt(sizeof(struct link)). + */ +#define SQRT_SIZ_STR_LINK (sizeof(struct link) / 2) + +void * +allocarray(size_t nmemb, size_t size, Area *ap) +{ + /* + * Ensure that `sizeof(struct link) + size * nmemb' doesn't overflow. + * If overflow occurs, at least one of `size' and `nmemb' must be + * larger than sqrt(SIZE_MAX - sizeof(struct link)). + * Note: sqrt(a - b) > sqrt(a) - sqrt(b) for a > b. + */ + if ((nmemb >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK || + size >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK) && + nmemb > 0 && (SIZE_MAX - sizeof(struct link)) / nmemb < size) + internal_errorf(1, "unable to allocate memory"); + + return (alloc(size * nmemb, ap)); +} + void * aresize(void *ptr, size_t size, Area *ap) { @@ -97,6 +169,30 @@ aresize(void *ptr, size_t size, Area *ap lnext->prev = l2; return L2P(l2); +} + +void * +aresizearray(void *ptr, size_t nmemb, size_t size, Area *ap) +{ + /* Ensure that `sizeof(struct link) + size * nmemb' doesn't overflow. */ + if ((size >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK || + nmemb >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK) && + nmemb > 0 && (SIZE_MAX - sizeof(struct link)) / nmemb < size) + internal_errorf(1, "unable to allocate memory"); + + return (aresize(ptr, size * nmemb, ap)); +} + +void * +aresizearray(void *ptr, size_t nmemb, size_t size, Area *ap) +{ + /* Ensure that `sizeof(struct link) + size * nmemb' doesn't overflow. */ + if ((size >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK || + nmemb >= MUL_NO_OVERFLOW - SQRT_SIZ_STR_LINK) && + nmemb > 0 && (SIZE_MAX - sizeof(struct link)) / nmemb < size) + internal_errorf(1, "unable to allocate memory"); + + return (aresize(ptr, size * nmemb, ap)); } void Index: proto.h =================================================================== RCS file: /cvs/src/bin/ksh/proto.h,v retrieving revision 1.35 diff -u -p -r1.35 proto.h --- proto.h 4 Sep 2013 15:49:19 -0000 1.35 +++ proto.h 23 May 2015 12:56:30 -0000 @@ -10,7 +10,9 @@ Area * ainit(Area *); void afreeall(Area *); void * alloc(size_t, Area *); +void * allocarray(size_t, size_t, Area *); void * aresize(void *, size_t, Area *); +void * aresizearray(void *, size_t, size_t, Area *); void afree(void *, Area *); /* c_ksh.c */ int c_hash(char **); Index: sh.h =================================================================== RCS file: /cvs/src/bin/ksh/sh.h,v retrieving revision 1.33 diff -u -p -r1.33 sh.h --- sh.h 18 Dec 2013 13:53:12 -0000 1.33 +++ sh.h 23 May 2015 12:56:30 -0000 @@ -15,6 +15,7 @@ #include <setjmp.h> #include <stdbool.h> #include <stddef.h> +#include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <string.h>