diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..499c813 --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +# +# safe_iop - Makefile +# +# Author:: Will Drewry +# Copyright 2007,2008 redpig@dataspill.org +# Some portions copyright 2008 Google Inc. +# +# Unless required by applicable law or agreed to in writing, software +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +# OF ANY KIND, either express or implied. +# + +CC = gcc +VERSION = 0.3 +TESTNAME = safe_iop_test +# For sparc64, _only_ use -O1 or -O0 +CFLAGS = -Wall -O2 -Iinclude +SOURCES = src/safe_iop.c + +all: $(TESTNAME) + +# This may be built as a library or directly included in source. +# Unless support for safe_iopf is needed, header inclusion is enough. + +$(TESTNAME): src/safe_iop.c include/safe_iop.h + $(CC) $(CFLAGS) -DNDEBUG=1 -DSAFE_IOP_TEST=1 $(SOURCES) -o $@ + +askme: examples/askme.c include/safe_iop.h + $(CC) $(CFLAGS) examples/askme.c -o $@ + +so: src/safe_iop.c include/safe_iop.h + $(CC) -shared -Wl,-soname,libsafe_iop.so.$(VERSION) $(CFLAGS) $(SOURCES) -o libsafe_iop.so.$(VERSION) + +dylib: src/safe_iop.c include/safe_iop.h + $(CC) -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,$(VERSION),-current_version,$(VERSION),-install_name,/usr/local/lib/libsafe_iop.$(VERSION).dylib $(CFLAGS) $(SOURCES) -o libsafe_iop.$(VERSION).dylib + + +test: $(TESTNAME) + @./$(TESTNAME) + @rm $(TESTNAME) + +clean: + rm $(TESTNAME) + diff --git a/README b/README new file mode 100644 index 0000000..daf5c2d --- /dev/null +++ b/README @@ -0,0 +1,136 @@ +safe_iop - a safe integer operation library for C +Will Drewry + += Copyright and Licensing +Copyright 2007-2008, Will Drewry +Some portions copyright 2008 Google Inc +Released into the public domain with no warranty and no guarantees + += Introduction + +Unsafe integer operations are a major cause of software defects even in modern +day software. C is the underlying language for most high level languages +(Ruby, Python, Java, etc) in addition to being in widespread general use. +C is a preferred language for high performance programming and is +often used for media file parsing and manipulation. + +Integer overflows occur when the calculated integer requires more storage from +the computing platform than is available. If a number is too large, not all of +its information can be stored. This has dangerous side effects. For a detailed +and thorough discussion on integer overflows, please check out CERT's website +on Secure Coding[1] and even Wikipedia[2]. + +[1] https://www.securecoding.cert.org/confluence/display/seccode/CERT+C+Secure+Coding+Standard +[2] http://en.wikipedia.org/wiki/Integer_overflow + + += Requirements + +safe_iop was designed explicitly with GNU GCC in mind and has only been tested +with it. Your mileage may vary. Please let me know if it works for you with +different compilers or on different platforms, and I'll update the Compatibility +section below! + +In addition, your system must supply limits.h and assert.h for safe_iop to +function as expected. It is possible to remove the dependence on both, but it +breaks general portability. + += Usage + +safe_iop comes in two pieces, safe_iop.h and safe_iop.c. safe_iop.h provides +extensive macros for performing safe integer operations quickly and easily. +safe_iop.c contains some testing code to make sure the package works on your +system and a preliminary format string interface, safe_iopf. safe_iopf is not +for the faint of heart as it is currently under development. The remainder of +this document will focus on safe_iop.h. + +In order to use safe_iop, you will need to place safe_iop.h in your compiler's +include path either by copying it somewhere like /usr/include, using an include +flag -I/opt/safe_iop/include, or whatever other way you prefer. You will then +need to include the header in the source file you will use the functions from. +E.g., #include + +safe_iop provides macros which check the validity of a given integer operation. +It supports the following operations: +- multiplication: safe_mul() +- division: safe_div() +- addition: safe_add() +- subtraction: safe_sub() + +All of these macros take a result pointer, or NULL, as the first argument. The +subsequent argument should be the two values to operate on. They then return +true or false depending on if the operation is safe or not. (If NULL is given, +a true or false value will be returned.) + + uint32_t a = 100, b = 200, c = 0; + if (safe_mul(&c, a, b)) printf("c is %u\n", c); + +In addition, there are versions of these functions for multiple sequential operations: + + uint32_t a = 100, b = 200, c = 300, d = 0; + if (safe_mul3(&d, a, b, c)) printf("d is %u\n", d); + +safe_3-5() are all available. + +It is important to note that if the types of integers passed to safe_iop do not +match, the operation will return false (0) with -DNDEBUG defined. If it is not +defined, assert() is called and the program will abort if these mismatch is +seen! + +For example, + uint32_t a = 100, c = 0; + uint8_t b = 20; + if (safe_add(&c, a, b)) /* I will return false! */ + + +Examples can be found in the examples/ directory. + +== safe_iopf + +If you'd like to use the format string function, do so at your own peril :-) +If you like it and would like to send me a patch to make it awesome, I'd +appreciate it! To use, just include the c file in your build, or build the +shared library and link it to your app: + make so # or make dylib for OS X + ... + gcc yourapp.c ... -lsafe_iop + +More to come! + += Compatibility + +Tests pass on the following platforms: + +- OS X Tiger, x86, GNU GCC 4.0.1 +- OS X Leopard, x86, GNU GCC 4.0.1 +- GNU/Linux, x86, GNU GCC 4.0.3 +- GNU/Linux, x86_64, GNU GCC 4.0.3 +- OpenBSD, VAX, GNU GCC 2.95.3 +- OpenBSD, sparc, GNU GCC 2.95.3 +- OpenBSD, alpha, GNU GCC 3.3.5 +- OpenBSD, sparc, GNU GCC 2.95.3 +- OpenBSD, macppc, GNU GCC 3.3.5 +- OpenBSD, arm, GNU GCC 3.3.5 +~ OpenBSD, sparc64, GNU GCC 3.3.5 [1] + +[1] For sparc64, there is an optimization bug which causes tests to fail if + -O exceeds 1. + += Credit where credit is do + +- The functions used in this library were largely drawn from the examples + provided in CERT's secure coding standard. +- Thanks to peter@valchev.net for reviews, comments, enthusiasm, and multiple + platform tests! +- Thanks to taviso@sdf.lonestar.org for the pointing out stupid API decisions + and cross-checking my logic. + += Changes + +The changes and todo list can be found in include/safe_iop.h + += Contributions, corrections, suggestions, flames . . . + +Please drop me an email if I'm doing something completely stupid, you love +using the library, you have a patch or recommendation, or for whatever other +reason. I hope this software helps out a bit! diff --git a/examples/askme.c b/examples/askme.c new file mode 100644 index 0000000..dcb4267 --- /dev/null +++ b/examples/askme.c @@ -0,0 +1,20 @@ +#include /* for printf, fgets */ +#include /* for atoi */ +#include /* for uint32_t */ +#include /* for awesomeness */ + +int main(int argc, char **argv) { + char buf[1024]; + uint32_t width = 0, height = 0, pixels = 0; + printf("Please specify the width of the new image: "); + width = strtoul(fgets(buf, 1023, stdin), NULL, 10); + printf("Please specify the height of the new image: "); + height = strtoul(fgets(buf, 1023, stdin), NULL, 10); + if (safe_mul(&pixels, width, height)) { + printf("The resulting image will have %u pixels.\n", pixels); + return 0; + } else { + printf("Image size specified exceeds maximum size!\n"); + return 1; + } +} diff --git a/include/safe_iop.h b/include/safe_iop.h new file mode 100644 index 0000000..bb3b8c4 --- /dev/null +++ b/include/safe_iop.h @@ -0,0 +1,699 @@ +/* safe_iop + * License:: released in to the public domain + * Author:: Will Drewry + * Copyright 2007,2008 redpig@dataspill.org + * Some portions copyright Google Inc, 2008. + * + * Unless required by applicable law or agreed to in writing, software + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + * OF ANY KIND, either express or implied. + * + * To Do: + * - Add varargs style interface for safe_() + * - Add support for safe conversion + * - Add additional sizes to safe_iopf (currently 32-bit only) + * (this will make use of the safe conversion above) + * - Add left shift support + * - Add more test cases for interfaces (op_mixed) + * - Add more tests for edge cases I've missed? and for thoroughness + * + * History: + * = 0.3 + * - solidified code into a smaller number of macros and functions + * - added typeless functions using gcc magic (typeof) + * - deprecrated old interfaces (-DSAFE_IOP_COMPAT) + * - discover size maximums automagically + * - separated test cases for easier understanding + * - significantly expanded test cases + * - derive type maximums and minimums internally (checked in testing) + * = 0.2 + * - Removed dependence on twos complement arithmetic to allow macro-ized + * definitions + * - Added (s)size_t support + * - Added (u)int8,16,64 support + * - Added portable inlining + * - Added support for NULL result pointers + * - Added support for header-only use (safe_iop.c only needed for safe_iopf) + * = 0.1 + * - Initial release + * + * Contributors & thanks: + * - peter@valchev.net for his review, comments, and enthusiasm + * - thanks to Google for contributing some time + */ + +/* This library supplies a set of standard functions for performing and + * checking safe integer operations. The code is based on examples from + * https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow + * + * Inline functions are available for specific operations. If the result + * pointer is NULL, the function will still return 1 or 0 if it would + * or would not overflow. If multiple operations need to be performed, + * safe_iopf provides a format-string driven model, but it does not yet support + * non-32 bit operations + * + * NOTE: This code assumes int32_t to be signed. + */ +#ifndef _SAFE_IOP_H +#define _SAFE_IOP_H +#include /* for CHAR_BIT */ +#include /* for type enforcement */ + +typedef enum { SAFE_IOP_TYPE_S32 = 1, + SAFE_IOP_TYPE_U32, + SAFE_IOP_TYPE_DEFAULT = SAFE_IOP_TYPE_S32, + } safe_type_t; + +#define SAFE_IOP_TYPE_PREFIXES "us" + +/* use a nice prefix :) */ +#define __sio(x) OPAQUE_SAFE_IOP_PREFIX_ ## x +#define OPAQUE_SAFE_IOP_PREFIX_var(x) __sio(VARIABLE_ ## x) +#define OPAQUE_SAFE_IOP_PREFIX_m(x) __sio(MACRO_ ## x) + + +/* A recursive macro which safely multiplies the given type together. + * _ptr may be NULL. + * mixed types or mixed sizes will unconditionally return 0; + */ +#define OPAQUE_SAFE_IOP_PREFIX_MACRO_smax(_a) \ + ((typeof(_a))(~((typeof(_a)) 1 << ((sizeof(typeof(_a)) * CHAR_BIT) - 1)))) +#define OPAQUE_SAFE_IOP_PREFIX_MACRO_smin(_a) \ + ((typeof(_a))(-__sio(m)(smax)(_a) - 1)) +#define OPAQUE_SAFE_IOP_PREFIX_MACRO_umax(_a) ((typeof(_a))(~((typeof(_a)) 0))) + +#define OPAQUE_SAFE_IOP_PREFIX_MACRO_type_enforce(__A, __B) \ + ((((__sio(m)(smin)(__A) <= ((typeof(__A))0)) && \ + (__sio(m)(smin)(__B) <= ((typeof(__B))0))) || \ + (((__sio(m)(smin)(__A) > ((typeof(__A))0))) && \ + (__sio(m)(smin)(__B) > ((typeof(__B))0)))) && \ + (sizeof(typeof(__A)) == sizeof(typeof(__B)))) + + +/* We use a non-void wrapper for assert(). This allows us to factor it away on + * -DNDEBUG but still have conditionals test the result (and optionally return + * false). + */ +#if defined(NDEBUG) +# define OPAQUE_SAFE_IOP_PREFIX_MACRO_assert(x) (x) +#else +# define OPAQUE_SAFE_IOP_PREFIX_MACRO_assert(x) ({ assert(x); 1; }) +#endif + + +/* Primary interface macros */ +/* type checking is compiled out if NDEBUG supplied. */ +#define safe_add(_ptr, __a, __b) \ + ({ int __sio(var)(ok) = 0; \ + typeof(__a) __sio(var)(_a) = (__a); \ + typeof(__b) __sio(var)(_b) = (__b); \ + typeof(_ptr) __sio(var)(p) = (_ptr); \ + if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \ + __sio(var)(_b)))) { \ + if (__sio(m)(smin)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \ + __sio(var)(ok) = safe_sadd(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } else { \ + __sio(var)(ok) = safe_uadd(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } \ + } \ + __sio(var)(ok); }) + +#define safe_add3(_ptr, _A, _B, _C) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_add(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_add((_ptr), __sio(var)(r), __sio(var)(c))); }) + +#define safe_add4(_ptr, _A, _B, _C, _D) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_add(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_add(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_add((_ptr), __sio(var)(r), (__sio(var)(d)))); }) + +#define safe_add5(_ptr, _A, _B, _C, _D, _E) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_E) __sio(var)(e) = (_E); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_add(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_add(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_add(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \ + safe_add((_ptr), __sio(var)(r), __sio(var)(e))); }) + +#define safe_sub(_ptr, __a, __b) \ + ({ int __sio(var)(ok) = 0; \ + typeof(__a) __sio(var)(_a) = (__a); \ + typeof(__b) __sio(var)(_b) = (__b); \ + typeof(_ptr) __sio(var)(p) = (_ptr); \ + if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \ + __sio(var)(_b)))) { \ + if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \ + __sio(var)(ok) = safe_ssub(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } else { \ + __sio(var)(ok) = safe_usub(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } \ + } \ + __sio(var)(ok); }) + +/* These are sequentially performed */ +#define safe_sub3(_ptr, _A, _B, _C) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_sub(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_sub((_ptr), __sio(var)(r), __sio(var)(c))); }) + +#define safe_sub4(_ptr, _A, _B, _C, _D) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_sub(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_sub(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_sub((_ptr), __sio(var)(r), (__sio(var)(d)))); }) + +#define safe_sub5(_ptr, _A, _B, _C, _D, _E) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_E) __sio(var)(e) = (_E); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_sub(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_sub(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_sub(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \ + safe_sub((_ptr), __sio(var)(r), __sio(var)(e))); }) + + + +#define safe_mul(_ptr, __a, __b) \ + ({ int __sio(var)(ok) = 0; \ + typeof(__a) __sio(var)(_a) = (__a); \ + typeof(__b) __sio(var)(_b) = (__b); \ + typeof(_ptr) __sio(var)(p) = (_ptr); \ + if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \ + __sio(var)(_b)))) { \ + if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \ + __sio(var)(ok) = safe_smul(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } else { \ + __sio(var)(ok) = safe_umul(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } \ + } \ + __sio(var)(ok); }) + +#define safe_mul3(_ptr, _A, _B, _C) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_mul(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_mul((_ptr), __sio(var)(r), __sio(var)(c))); }) + +#define safe_mul4(_ptr, _A, _B, _C, _D) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_mul(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_mul(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_mul((_ptr), __sio(var)(r), (__sio(var)(d)))); }) + +#define safe_mul5(_ptr, _A, _B, _C, _D, _E) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_E) __sio(var)(e) = (_E); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_mul(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_mul(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_mul(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \ + safe_mul((_ptr), __sio(var)(r), __sio(var)(e))); }) + +#define safe_div(_ptr, __a, __b) \ + ({ int __sio(var)(ok) = 0; \ + typeof(__a) __sio(var)(_a) = (__a); \ + typeof(__b) __sio(var)(_b) = (__b); \ + typeof(_ptr) __sio(var)(p) = (_ptr); \ + if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \ + __sio(var)(_b)))) { \ + if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \ + __sio(var)(ok) = safe_sdiv(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } else { \ + __sio(var)(ok) = safe_udiv(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } \ + } \ + __sio(var)(ok); }) + +#define safe_div3(_ptr, _A, _B, _C) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_div(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_div((_ptr), __sio(var)(r), __sio(var)(c))); }) + +#define safe_div4(_ptr, _A, _B, _C, _D) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_div(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_div(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_div((_ptr), __sio(var)(r), (__sio(var)(d)))); }) + +#define safe_div5(_ptr, _A, _B, _C, _D, _E) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_E) __sio(var)(e) = (_E); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_div(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_div(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_div(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \ + safe_div((_ptr), __sio(var)(r), __sio(var)(e))); }) + +#define safe_mod(_ptr, __a, __b) \ + ({ int __sio(var)(ok) = 0; \ + typeof(__a) __sio(var)(_a) = (__a); \ + typeof(__b) __sio(var)(_b) = (__b); \ + typeof(_ptr) __sio(var)(p) = (_ptr); \ + if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \ + __sio(var)(_b)))) { \ + if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \ + __sio(var)(ok) = safe_smod(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } else { \ + __sio(var)(ok) = safe_umod(__sio(var)(p), \ + __sio(var)(_a), \ + __sio(var)(_b)); \ + } \ + } \ + __sio(var)(ok); }) + +#define safe_mod3(_ptr, _A, _B, _C) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_mod(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_mod((_ptr), __sio(var)(r), __sio(var)(c))); }) + +#define safe_mod4(_ptr, _A, _B, _C, _D) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C); \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_mod(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_mod(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_mod((_ptr), __sio(var)(r), (__sio(var)(d)))); }) + +#define safe_mod5(_ptr, _A, _B, _C, _D, _E) \ +({ typeof(_A) __sio(var)(a) = (_A); \ + typeof(_B) __sio(var)(b) = (_B); \ + typeof(_C) __sio(var)(c) = (_C), \ + typeof(_D) __sio(var)(d) = (_D); \ + typeof(_E) __sio(var)(e) = (_E); \ + typeof(_A) __sio(var)(r) = 0; \ + (safe_mod(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \ + safe_mod(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \ + safe_mod(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \ + safe_mod((_ptr), __sio(var)(r), __sio(var)(e))); }) + +/*** Safe integer operation implementation macros ***/ + +#define safe_uadd(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if ((typeof(_a))(_b) <= (typeof(_a))(__sio(m)(umax)(_a) - (_a))) { \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) + (_b); } \ + __sio(var)(ok) = 1; \ + } __sio(var)(ok); }) + +#define safe_sadd(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 1; \ + if (((_b) > (typeof(_a))0) && ((_a) > (typeof(_a))0)) { /*>0*/ \ + if ((_a) > (typeof(_a))(__sio(m)(smax)(_a) - (_b))) __sio(var)(ok) = 0; \ + } else if (!((_b) > (typeof(_a))0) && !((_a) > (typeof(_a))0)) { /*<0*/ \ + if ((_a) < (typeof(_a))(__sio(m)(smin)(_a) - (_b))) __sio(var)(ok) = 0; \ + } \ + if (__sio(var)(ok) && (_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) + (_b); } \ + __sio(var)(ok); }) + +#define safe_usub(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if ((_a) >= (_b)) { \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) - (_b); } \ + __sio(var)(ok) = 1; \ + } \ + __sio(var)(ok); }) + +#define safe_ssub(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if (!((_b) <= 0 && (_a) > (__sio(m)(smax)(_a) + (_b))) && \ + !((_b) > 0 && (_a) < (__sio(m)(smin)(_a) + (_b)))) { \ + __sio(var)(ok) = 1; \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) - (_b); } \ + } \ + __sio(var)(ok); }) + +#define safe_umul(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if (!(_b) || (_a) <= (__sio(m)(umax)(_a) / (_b))) { \ + __sio(var)(ok) = 1; \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) * (_b); } \ + } \ + __sio(var)(ok); }) + +#define safe_smul(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 1; \ + if ((_a) > 0) { /* a is positive */ \ + if ((_b) > 0) { /* b and a are positive */ \ + if ((_a) > (__sio(m)(smax)(_a) / (_b))) { \ + __sio(var)(ok) = 0; \ + } \ + } /* end if a and b are positive */ \ + else { /* a positive, b non-positive */ \ + if ((_b) < (__sio(m)(smin)(_a) / (_a))) { \ + __sio(var)(ok) = 0; \ + } \ + } /* a positive, b non-positive */ \ + } /* end if a is positive */ \ + else { /* a is non-positive */ \ + if ((_b) > 0) { /* a is non-positive, b is positive */ \ + if ((_a) < (__sio(m)(smin)(_a) / (_b))) { \ + __sio(var)(ok) = 0; \ + } \ + } /* end if a is non-positive, b is positive */ \ + else { /* a and b are non-positive */ \ + if( ((_a) != 0) && ((_b) < (__sio(m)(smax)(_a) / (_a)))) { \ + __sio(var)(ok) = 0; \ + } \ + } /* end if a and b are non-positive */ \ + } /* end if a is non-positive */ \ + if (__sio(var)(ok) && (_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) * (_b); } \ + __sio(var)(ok); }) + +/* div-by-zero is the only thing addressed */ +#define safe_udiv(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if ((_b) != 0) { \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) / (_b); } \ + __sio(var)(ok) = 1; \ + } \ + __sio(var)(ok); }) + +/* Addreses div by zero and smin -1 */ +#define safe_sdiv(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if ((_b) != 0 && \ + (((_a) != __sio(m)(smin)(_a)) || ((_b) != (typeof(_b))-1))) { \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) / (_b); } \ + __sio(var)(ok) = 1; \ + } \ + __sio(var)(ok); }) + +#define safe_umod(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if ((_b) != 0) { \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) % (_b); } \ + __sio(var)(ok) = 1; \ + } \ + __sio(var)(ok); }) + +#define safe_smod(_ptr, _a, _b) \ + ({ int __sio(var)(ok) = 0; \ + if ((_b) != 0 && \ + (((_a) != __sio(m)(smin)(_a)) || ((_b) != (typeof(_b))-1))) { \ + if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) % (_b); } \ + __sio(var)(ok) = 1; \ + } \ + __sio(var)(ok); }) + +#if SAFE_IOP_COMPAT +/* These are used for testing for easy type enforcement */ +#include +#include + +#ifndef SAFE_IOP_INLINE +# if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define SAFE_IOP_INLINE __attribute__((always_inline)) static inline +# else +# define SAFE_IOP_INLINE static inline +# endif +#endif + +#define MAKE_UADD(_prefix, _bits, _type, _max) \ + SAFE_IOP_INLINE \ + int safe_add##_prefix##_bits (_type *result, _type value, _type a) { \ + return safe_uadd(result, value, a); \ + } + +#define MAKE_SADD(_prefix, _bits, _type, _max) \ + SAFE_IOP_INLINE \ + int safe_add##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_sadd(result, value, a); \ + } + +#define MAKE_USUB(_prefix, _bits, _type) \ + SAFE_IOP_INLINE \ + int safe_sub##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_usub(result, value, a); \ + } + +#define MAKE_SSUB(_prefix, _bits, _type, _min, _max) \ + SAFE_IOP_INLINE \ + int safe_sub##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_ssub(result, value, a); \ + } + +#define MAKE_UMUL(_prefix, _bits, _type, _max) \ + SAFE_IOP_INLINE \ + int safe_mul##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_umul(result, value, a); \ + } + + +#define MAKE_SMUL(_prefix, _bits, _type, _max, _min) \ + SAFE_IOP_INLINE \ + int safe_mul##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_smul(result, value, a); \ + } + +#define MAKE_UDIV(_prefix, _bits, _type) \ + SAFE_IOP_INLINE \ + int safe_div##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_udiv(result, value, a); \ + } + +#define MAKE_SDIV(_prefix, _bits, _type, _min) \ + SAFE_IOP_INLINE \ + int safe_div##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_sdiv(result, value, a); \ + } + +#define MAKE_UMOD(_prefix, _bits, _type) \ + SAFE_IOP_INLINE \ + int safe_mod##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_umod(result, value, a); \ + } + +#define MAKE_SMOD(_prefix, _bits, _type, _min) \ + SAFE_IOP_INLINE \ + int safe_mod##_prefix##_bits(_type *result, _type value, _type a) { \ + return safe_smod(result, value, a); \ + } + +/* __LP64__ is given by GCC. Without more work, this is bound to GCC. */ +#if __LP64__ == 1 || __SIZEOF_LONG__ > __SIZEOF_INT__ +# define SAFE_INT64_MAX 0x7fffffffffffffffL +# define SAFE_UINT64_MAX 0xffffffffffffffffUL +# define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1L) +#elif __SIZEOF_LONG__ == __SIZEOF_INT__ +# define SAFE_INT64_MAX 0x7fffffffffffffffLL +# define SAFE_UINT64_MAX 0xffffffffffffffffULL +# define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1LL) +#else +# warning "64-bit support disabled" +# define SAFE_IOP_NO_64 1 +#endif + +/* Assumes SSIZE_MAX */ +#ifndef SSIZE_MIN +# if SSIZE_MAX == LONG_MAX +# define SSIZE_MIN LONG_MIN +# elif SSIZE_MAX == LONG_LONG_MAX +# define SSIZE_MIN LONG_LONG_MIN +# else +# error "SSIZE_MIN is not defined and could not be guessed" +# endif +#endif + + + +#ifndef SAFE_IOP_NO_64 + MAKE_UADD(u, 64, u_int64_t, SAFE_UINT64_MAX) +#endif +MAKE_UADD(,szt, size_t, SIZE_MAX) +MAKE_UADD(u, 32, u_int32_t, UINT_MAX) +MAKE_UADD(u, 16, u_int16_t, USHRT_MAX) +MAKE_UADD(u, 8, u_int8_t, UCHAR_MAX) + +#ifndef SAFE_IOP_NO_64 + MAKE_SADD(s, 64, int64_t, SAFE_INT64_MAX) +#endif +MAKE_SADD(s, szt, ssize_t, SSIZE_MAX) +MAKE_SADD(s, 32, int32_t, INT_MAX) +MAKE_SADD(s, 16, int16_t, SHRT_MAX) +MAKE_SADD(s, 8, int8_t, SCHAR_MAX) + +#ifndef SAFE_IOP_NO_64 + MAKE_USUB(u, 64, u_int64_t) +#endif +MAKE_USUB(, szt, size_t) +MAKE_USUB(u, 32, u_int32_t) +MAKE_USUB(u, 16, u_int16_t) +MAKE_USUB(u, 8, u_int8_t) + +#ifndef SAFE_IOP_NO_64 + MAKE_SSUB(s, 64, int64_t, SAFE_INT64_MIN, SAFE_INT64_MAX) +#endif +MAKE_SSUB(s, szt, ssize_t, SSIZE_MIN, SSIZE_MAX) +MAKE_SSUB(s, 32, int32_t, INT_MIN, INT_MAX) +MAKE_SSUB(s, 16, int16_t, SHRT_MIN, SHRT_MAX) +MAKE_SSUB(s, 8, int8_t, SCHAR_MIN, SCHAR_MAX) + + +#ifndef SAFE_IOP_NO_64 + MAKE_UMUL(u, 64, u_int64_t, SAFE_UINT64_MAX) +#endif +MAKE_UMUL(, szt, size_t, SIZE_MAX) +MAKE_UMUL(u, 32, u_int32_t, UINT_MAX) +MAKE_UMUL(u, 16, u_int16_t, USHRT_MAX) +MAKE_UMUL(u, 8, u_int8_t, UCHAR_MAX) + +#ifndef SAFE_IOP_NO_64 + MAKE_SMUL(s, 64, int64_t, SAFE_INT64_MAX, SAFE_INT64_MIN) +#endif +MAKE_SMUL(s, szt, ssize_t, SSIZE_MAX, SSIZE_MIN) +MAKE_SMUL(s, 32, int32_t, INT_MAX, INT_MIN) +MAKE_SMUL(s, 16, int16_t, SHRT_MAX, SHRT_MIN) +MAKE_SMUL(s, 8, int8_t, SCHAR_MAX, SCHAR_MIN) + + +#ifndef SAFE_IOP_NO_64 + MAKE_UDIV(u, 64, u_int64_t) +#endif +MAKE_UDIV(, szt, size_t) +MAKE_UDIV(u, 32, u_int32_t) +MAKE_UDIV(u, 16, u_int16_t) +MAKE_UDIV(u, 8, u_int8_t) + +#ifndef SAFE_IOP_NO_64 + MAKE_SDIV(s, 64, int64_t, SAFE_INT64_MIN) +#endif +MAKE_SDIV(s, szt, ssize_t, SSIZE_MIN) +MAKE_SDIV(s, 32, int32_t, INT_MIN) +MAKE_SDIV(s, 16, int16_t, SHRT_MIN) +MAKE_SDIV(s, 8, int8_t, SCHAR_MIN) + + +#ifndef SAFE_IOP_NO_64 + MAKE_UMOD(u, 64, u_int64_t) +#endif +MAKE_UMOD(, szt, size_t) +MAKE_UMOD(u, 32, u_int32_t) +MAKE_UMOD(u, 16, u_int16_t) +MAKE_UMOD(u, 8, u_int8_t) + +#ifndef SAFE_IOP_NO_64 + MAKE_SMOD(s, 64, int64_t, SAFE_INT64_MIN) +#endif +MAKE_SMOD(s, szt, ssize_t, SSIZE_MIN) +MAKE_SMOD(s, 32, int32_t, INT_MIN) +MAKE_SMOD(s, 16, int16_t, SHRT_MIN) +MAKE_SMOD(s, 8, int8_t, SCHAR_MIN) + +/* Cleanup the macro spam */ +#undef MAKE_SMUL +#undef MAKE_UMUL +#undef MAKE_SSUB +#undef MAKE_USUB +#undef MAKE_SADD +#undef MAKE_UADD +#undef MAKE_UDIV +#undef MAKE_SDIV +#undef MAKE_UMOD +#undef MAKE_SMOD + +#endif /* SAFE_IOP_COMPAT */ + + + +/* safe_iopf + * + * Takes in a character array which specifies the operations + * to perform on a given value. The value will be assumed to be + * of the type specified for each operation. + * + * Currently accepted format syntax is: + * [type_marker]operation... + * The type marker may be any of the following: + * - s32 for signed int32 + * - u32 for unsigned int32 + * If no type_marker is specified, it is assumed to be s32. + * + * Currently, this only performs correctly with 32-bit integers. + * + * The operation must be one of the following: + * - * -- multiplication + * - / -- division + * - - -- subtraction + * - + -- addition + * - % -- modulo (remainder) + * + * Whitespace will be ignored. + * + * Args: + * - pointer to the final result (this must be at least the size of int32) + * - array of format characters + * - all remaining arguments are derived from the format + * Output: + * - Returns 1 on success leaving the result in value + * - Returns 0 on failure leaving the contents of value *unknown* + */ + +int safe_iopf(void *result, const char *const fmt, ...); + + +#endif /* _SAFE_IOP_H */ diff --git a/src/safe_iop.c b/src/safe_iop.c new file mode 100644 index 0000000..adbe37c --- /dev/null +++ b/src/safe_iop.c @@ -0,0 +1,1177 @@ +/* safe_iop + * License:: released in to the public domain + * Author:: Will Drewry + * Copyright 2007,2008 redpig@dataspill.org + * Some portions copyright Google Inc, 2008. + * + * Unless required by applicable law or agreed to in writing, software + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + * OF ANY KIND, either express or implied. + * + * See safe_iop.h for more info. + */ +#include +#include +#include +#include + +#include + +/* Read off the type if the first value matches a type prefix + * and consume characters if successful. + */ +static int _safe_op_read_type(safe_type_t *type, const char **c) { + if (type == NULL) { + return 0; + } + if (c == NULL || *c == NULL || **c == '\0') { + return 0; + } + /* Extract a type for the operation if there is one */ + if (strchr(SAFE_IOP_TYPE_PREFIXES, **c) != NULL) { + switch(**c) { + case 'u': + if ((*(*c+1) && *(*c+1) == '3') && + (*(*c+2) && *(*c+2) == '2')) { + *type = SAFE_IOP_TYPE_U32; + *c += 3; /* Advance past type */ + } + break; + case 's': + if ((*(*c+1) && *(*c+1) == '3') && + (*(*c+2) && *(*c+2) == '2')) { + *type = SAFE_IOP_TYPE_S32; + *c += 3; /* Advance past type */ + } + break; + default: + /* Unknown type */ + return 0; + } + } + return 1; +} + +#define _SAFE_IOP_TYPE_CASE(_type, _func) { \ + _type a = va_arg(ap, _type), value = *((_type *) result); \ + if (!baseline) { \ + value = a; \ + a = va_arg(ap, _type); \ + baseline = 1; \ + } \ + if (! _func( (_type *) result, value, a)) \ + return 0; \ +} +#define _SAFE_IOP_OP_CASE(u32func, s32func) \ + switch (type) { \ + case SAFE_IOP_TYPE_U32: \ + _SAFE_IOP_TYPE_CASE(u_int32_t, u32func); \ + break; \ + case SAFE_IOP_TYPE_S32: \ + _SAFE_IOP_TYPE_CASE(int32_t, s32func); \ + break; \ + default: \ + return 0; \ + } + +int safe_iopf(void *result, const char *const fmt, ...) { + va_list ap; + int baseline = 0; /* indicates if the base value is present */ + + const char *c = NULL; + safe_type_t type = SAFE_IOP_TYPE_DEFAULT; + /* Result should not be NULL */ + if (!result) + return 0; + + va_start(ap, fmt); + if (fmt == NULL || fmt[0] == '\0') + return 0; + for(c=fmt;(*c);c++) { + /* Read the type if specified */ + if (!_safe_op_read_type(&type, &c)) { + return 0; + } + + /* Process the the operations */ + switch(*c) { /* operation */ + case '+': /* add */ + _SAFE_IOP_OP_CASE(safe_uadd, safe_sadd); + break; + case '-': /* sub */ + _SAFE_IOP_OP_CASE(safe_usub, safe_ssub); + break; + case '*': /* mul */ + _SAFE_IOP_OP_CASE(safe_umul, safe_smul); + break; + case '/': /* div */ + _SAFE_IOP_OP_CASE(safe_udiv, safe_sdiv); + break; + case '%': /* mod */ + _SAFE_IOP_OP_CASE(safe_umod, safe_smod); + break; + default: + /* unknown op */ + return 0; + } + /* Reset the type */ + type = SAFE_IOP_TYPE_DEFAULT; + } + /* Success! */ + return 1; +} + +#ifdef SAFE_IOP_TEST +#include +#include +#include + +/* __LP64__ is given by GCC. Without more work, this is bound to GCC. */ +#if __LP64__ == 1 || __SIZEOF_LONG__ > __SIZEOF_INT__ +# define SAFE_INT64_MAX 0x7fffffffffffffffL +# define SAFE_UINT64_MAX 0xffffffffffffffffUL +# define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1L) +#elif __SIZEOF_LONG__ == __SIZEOF_INT__ +# define SAFE_INT64_MAX 0x7fffffffffffffffLL +# define SAFE_UINT64_MAX 0xffffffffffffffffULL +# define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1LL) +#else +# warning "64-bit support disabled" +# define SAFE_IOP_NO_64 1 +#endif + +/* Pull these from GNU's limit.h */ +#ifndef LLONG_MAX +# define LLONG_MAX 9223372036854775807LL +#endif +#ifndef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - 1LL) +#endif +#ifndef ULLONG_MAX +# define ULLONG_MAX 18446744073709551615ULL +#endif + +/* Assumes SSIZE_MAX */ +#ifndef SSIZE_MIN +# if SSIZE_MAX == LONG_MAX +# define SSIZE_MIN LONG_MIN +# elif SSIZE_MAX == LONG_LONG_MAX +# define SSIZE_MIN LONG_LONG_MIN +# else +# error "SSIZE_MIN is not defined and could not be guessed" +# endif +#endif + +#define EXPECT_FALSE(cmd) ({ \ + printf("%s: EXPECT_FALSE(" #cmd ") => ", __func__); \ + if ((cmd) != 0) { printf(" FAILED\n"); expect_fail++; r = 0; } \ + else { printf(" PASSED\n"); expect_succ++; } \ + expect++; \ + }) +#define EXPECT_TRUE(cmd) ({ \ + printf("%s: EXPECT_TRUE(" #cmd ") => ", __func__); \ + if ((cmd) != 1) { printf(" FAILED\n"); expect_fail++; r = 0; } \ + else { printf(" PASSED\n"); expect_succ++; } \ + expect++; \ + }) + +static int expect = 0, expect_succ = 0, expect_fail = 0; + +/***** ADD *****/ +int T_add_s8() { + int r=1; + int8_t a, b; + a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SCHAR_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=-10; b=-11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SCHAR_MIN; b=SCHAR_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SCHAR_MIN+1; b=-1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SCHAR_MAX/2; b=SCHAR_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_s16() { + int r=1; + int16_t a, b; + a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SHRT_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SHRT_MIN; b=SHRT_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SHRT_MAX/2; b=SHRT_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_s32() { + int r=1; + int32_t a, b; + a=INT_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=INT_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=INT_MIN; b=INT_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + a=INT_MAX/2; b=INT_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_s64() { + int r=1; + int64_t a, b; + a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SAFE_INT64_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SAFE_INT64_MIN; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SAFE_INT64_MAX/2; b=SAFE_INT64_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_long() { + int r=1; + long a, b; + a=LONG_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=LONG_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=LONG_MIN; b=LONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + a=LONG_MAX/2; b=LONG_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} +int T_add_longlong() { + int r=1; + long long a, b; + a=LLONG_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=LLONG_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=LLONG_MIN; b=LLONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + a=LLONG_MAX/2; b=LLONG_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} +int T_add_ssizet() { + int r=1; + ssize_t a, b; + a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SSIZE_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SSIZE_MIN; b=SSIZE_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SSIZE_MAX/2; b=SSIZE_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_u8() { + int r=1; + uint8_t a, b; + a=1; b=UCHAR_MAX; EXPECT_FALSE(safe_add(NULL, a, b)); + a=UCHAR_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b)); + a=UCHAR_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b)); + a=UCHAR_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_u16() { + int r=1; + uint16_t a, b; + a=1; b=USHRT_MAX; EXPECT_FALSE(safe_add(NULL, a, b)); + a=USHRT_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b)); + a=USHRT_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b)); + a=USHRT_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=0; b=USHRT_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_u32() { + int r=1; + uint32_t a, b; + a=1; b=UINT_MAX; EXPECT_FALSE(safe_add(NULL, a, b)); + a=UINT_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b)); + a=UINT_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b)); + a=UINT_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=0; b=UINT_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_u64() { + int r=1; + uint64_t a, b; + a=1; b=SAFE_UINT64_MAX; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SAFE_UINT64_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SAFE_UINT64_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SAFE_UINT64_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=0; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_ulong() { + int r=1; + unsigned long a, b; + a=1; b=ULONG_MAX; EXPECT_FALSE(safe_add(NULL, a, b)); + a=ULONG_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b)); + a=ULONG_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b)); + a=ULONG_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=0; b=ULONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_ulonglong() { + int r=1; + unsigned long long a, b; + a=1; b=ULLONG_MAX; EXPECT_FALSE(safe_add(NULL, a, b)); + a=ULLONG_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b)); + a=ULLONG_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b)); + a=ULLONG_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=0; b=ULLONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_sizet() { + int r=1; + size_t a, b; + a=1; b=SIZE_MAX; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SIZE_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b)); + a=SIZE_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b)); + a=SIZE_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b)); + a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b)); + a=0; b=SIZE_MAX; EXPECT_TRUE(safe_add(NULL, a, b)); + return r; +} + +int T_add_mixed() { + int r=1; + int8_t a = 1; + uint8_t b = 2; + uint16_t c = 3; + EXPECT_FALSE(safe_add(NULL, a, b)); + EXPECT_FALSE(safe_add(NULL, b, c)); + EXPECT_FALSE(safe_add(NULL, a, c)); + EXPECT_FALSE(safe_add3(NULL, a, b, c)); + return r; +} + +int T_add_increment() { + int r=1; + uint16_t a = 1, b = 2, c = 0, d[2]= {0}; + uint16_t *cur = d; + EXPECT_TRUE(safe_add(cur++, a++, b)); + EXPECT_TRUE(cur == &d[1]); + EXPECT_TRUE(d[0] == 3); + EXPECT_TRUE(a == 2); + a = 1; b = 2; c = 1; cur=d;d[0] = 0; + EXPECT_TRUE(safe_add3(cur++, a++, b++, c)); + EXPECT_TRUE(d[0] == 4); + EXPECT_TRUE(cur == &d[1]); + EXPECT_TRUE(a == 2); + EXPECT_TRUE(b == 3); + EXPECT_TRUE(c == 1); + return r; +} + + + +/***** SUB *****/ +int T_sub_s8() { + int r=1; + int8_t a, b; + a=SCHAR_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SCHAR_MIN; b=SCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SCHAR_MIN/2; b=SCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=-2; b=SCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SCHAR_MAX; b=SCHAR_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_s16() { + int r=1; + int16_t a, b; + a=SHRT_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SHRT_MIN; b=SHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SHRT_MIN/2; b=SHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=-2; b=SHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SHRT_MAX; b=SHRT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_s32() { + int r=1; + int32_t a, b; + a=INT_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=INT_MIN; b=INT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=INT_MIN/2; b=INT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=-2; b=INT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=INT_MAX; b=INT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_s64() { + int r=1; + int64_t a, b; + a=SAFE_INT64_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SAFE_INT64_MIN; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SAFE_INT64_MIN/2; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=-2; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SAFE_INT64_MAX; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_long() { + int r=1; + long a, b; + a=LONG_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=LONG_MIN; b=LONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=LONG_MIN/2; b=LONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=-2; b=LONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=LONG_MAX; b=LONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_longlong() { + int r=1; + long long a, b; + a=LLONG_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=LLONG_MIN; b=LLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=LLONG_MIN/2; b=LLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=-2; b=LLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=LLONG_MAX; b=LLONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_ssizet() { + int r=1; + ssize_t a, b; + a=SSIZE_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SSIZE_MIN; b=SSIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SSIZE_MIN/2; b=SSIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=-2; b=SSIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SSIZE_MAX; b=SSIZE_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_u8() { + int r=1; + uint8_t a, b; + a=0; b=UCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=UCHAR_MAX-1; b=UCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=UCHAR_MAX; b=UCHAR_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_u16() { + int r=1; + uint16_t a, b; + a=0; b=USHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=USHRT_MAX-1; b=USHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=USHRT_MAX; b=USHRT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_u32() { + int r=1; + uint32_t a, b; + a=UINT_MAX-1; b=UINT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=UINT_MAX; b=UINT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_u64() { + int r=1; + uint64_t a, b; + a=SAFE_UINT64_MAX-1; b=SAFE_UINT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SAFE_UINT64_MAX; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_ulong() { + int r=1; + unsigned long a, b; + a=ULONG_MAX-1; b=ULONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=ULONG_MAX; b=ULONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_ulonglong() { + int r=1; + unsigned long long a, b; + a=ULLONG_MAX-1; b=ULLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=ULLONG_MAX; b=ULLONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +int T_sub_sizet() { + int r=1; + size_t a, b; + a=SIZE_MAX-1; b=SIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=SIZE_MAX; b=SIZE_MAX; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b)); + return r; +} + +/***** MUL *****/ +int T_mul_s8() { + int r=1; + int8_t a, b; + a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SCHAR_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SCHAR_MAX; b=SCHAR_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SCHAR_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SCHAR_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SCHAR_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SCHAR_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SCHAR_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SCHAR_MIN; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_s16() { + int r=1; + int16_t a, b; + a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SHRT_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SHRT_MAX; b=SHRT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SHRT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SHRT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SHRT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SHRT_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SHRT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SHRT_MIN; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_s32() { + int r=1; + int32_t a, b; + a=INT_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=INT_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=INT_MAX; b=INT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=INT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=INT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=INT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=INT_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=INT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=INT_MIN; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_s64() { + int r=1; + int64_t a, b; + a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SAFE_INT64_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SAFE_INT64_MAX; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SAFE_INT64_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SAFE_INT64_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SAFE_INT64_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SAFE_INT64_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SAFE_INT64_MIN; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_long() { + int r=1; + long a, b; + a=LONG_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LONG_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LONG_MAX; b=LONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=LONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=LONG_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=LONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=LONG_MIN; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} +int T_mul_longlong() { + int r=1; + long long a, b; + a=LLONG_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LLONG_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LLONG_MAX; b=LLONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LLONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=LLONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=LLONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=LLONG_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=LLONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=LLONG_MIN; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} +int T_mul_ssizet() { + int r=1; + ssize_t a, b; + a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SSIZE_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SSIZE_MAX; b=SSIZE_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SSIZE_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SSIZE_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SSIZE_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SSIZE_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SSIZE_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SSIZE_MIN; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_u8() { + int r=1; + uint8_t a, b; + a=UCHAR_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=UCHAR_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=UCHAR_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=UCHAR_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=UCHAR_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=UCHAR_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=UCHAR_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=1; b=UCHAR_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=UCHAR_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=UCHAR_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_u16() { + int r=1; + uint16_t a, b; + a=USHRT_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=USHRT_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=USHRT_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=USHRT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=USHRT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=USHRT_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=USHRT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=USHRT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=1; b=USHRT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=USHRT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=USHRT_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_u32() { + int r=1; + uint32_t a, b; + a=UINT_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=UINT_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=UINT_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=UINT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=UINT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=UINT_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=UINT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=UINT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=1; b=UINT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=UINT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=UINT_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_u64() { + int r=1; + uint64_t a, b; + a=SAFE_UINT64_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=SAFE_UINT64_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SAFE_UINT64_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=SAFE_UINT64_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SAFE_UINT64_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=SAFE_UINT64_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SAFE_UINT64_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=1; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SAFE_UINT64_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SAFE_UINT64_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_ulong() { + int r=1; + unsigned long a, b; + a=ULONG_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=ULONG_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=ULONG_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=ULONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=ULONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=ULONG_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=ULONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=ULONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=1; b=ULONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=ULONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=ULONG_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_ulonglong() { + int r=1; + unsigned long long a, b; + a=ULLONG_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=ULLONG_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=ULLONG_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=ULLONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=ULLONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=ULLONG_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=ULLONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=ULLONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=1; b=ULLONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=ULLONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=ULLONG_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +int T_mul_sizet() { + int r=1; + size_t a, b; + a=SIZE_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=SIZE_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SIZE_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=SIZE_MAX; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SIZE_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=2; b=SIZE_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b)); + a=SIZE_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=0; b=SIZE_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=1; b=SIZE_MAX; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SIZE_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=SIZE_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b)); + return r; +} + +/***** MOD *****/ +int T_mod_s8() { + int r=1; + int8_t a, b; + a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_s16() { + int r=1; + int16_t a, b; + a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_s32() { + int r=1; + int32_t a, b; + a=INT_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_s64() { + int r=1; + int64_t a, b; + a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_long() { + int r=1; + long a, b; + a=LONG_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} +int T_mod_longlong() { + int r=1; + long long a, b; + a=LLONG_MIN; b=-1LL; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=100LL; b=0LL; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10LL; b=2LL; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} +int T_mod_ssizet() { + int r=1; + ssize_t a, b; + a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_u8() { + int r=1; + uint8_t a, b; + a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_u16() { + int r=1; + uint16_t a, b; + a=0; b=USHRT_MAX; EXPECT_TRUE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_u32() { + int r=1; + uint32_t a, b; + a=0; b=UINT_MAX; EXPECT_TRUE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_u64() { + int r=1; + uint64_t a, b; + a=0; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_ulong() { + int r=1; + unsigned long a, b; + a=0; b=LONG_MAX; EXPECT_TRUE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_ulonglong() { + int r=1; + unsigned long long a, b; + a=0ULL; b=~0ULL; EXPECT_TRUE(safe_mod(NULL, a, b)); + a=100ULL; b=0ULL; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10ULL; b=2ULL; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +int T_mod_sizet() { + int r=1; + size_t a, b; + a=0; b=SIZE_MAX; EXPECT_TRUE(safe_mod(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b)); + return r; +} + +/***** DIV *****/ +int T_div_s8() { + int r=1; + int8_t a, b; + a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_s16() { + int r=1; + int16_t a, b; + a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_s32() { + int r=1; + int32_t a, b; + a=INT_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_s64() { + int r=1; + int64_t a, b; + a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_long() { + int r=1; + long a, b; + a=LONG_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} +int T_div_longlong() { + int r=1; + long long a, b; + a=LLONG_MIN; b=-1LL; EXPECT_FALSE(safe_div(NULL, a, b)); + a=100LL; b=0LL; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10LL; b=2LL; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} +int T_div_ssizet() { + int r=1; + ssize_t a, b; + a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_u8() { + int r=1; + uint8_t a, b; + a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_u16() { + int r=1; + uint16_t a, b; + a=0; b=USHRT_MAX; EXPECT_TRUE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_u32() { + int r=1; + uint32_t a, b; + a=0; b=UINT_MAX; EXPECT_TRUE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_u64() { + int r=1; + uint64_t a, b; + a=0; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_ulong() { + int r=1; + unsigned long a, b; + a=0; b=LONG_MAX; EXPECT_TRUE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_ulonglong() { + int r=1; + unsigned long long a, b; + a=0ULL; b=~0ULL; EXPECT_TRUE(safe_div(NULL, a, b)); + a=100ULL; b=0ULL; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10ULL; b=2ULL; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_div_sizet() { + int r=1; + size_t a, b; + a=0; b=SIZE_MAX; EXPECT_TRUE(safe_div(NULL, a, b)); + a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b)); + a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b)); + return r; +} + +int T_magic_constants() { + int r=1; + EXPECT_TRUE(__sio(m)(smin)(((int8_t)0)) == SCHAR_MIN); + EXPECT_TRUE(__sio(m)(smax)(((int8_t)0)) == SCHAR_MAX); + EXPECT_TRUE(__sio(m)(umax)(((uint8_t)0)) == UCHAR_MAX); + + EXPECT_TRUE(__sio(m)(smin)(((int16_t)0)) == SHRT_MIN); + EXPECT_TRUE(__sio(m)(smax)(((int16_t)0)) == SHRT_MAX); + EXPECT_TRUE(__sio(m)(umax)(((uint16_t)0)) == USHRT_MAX); + + EXPECT_TRUE(__sio(m)(smin)(((int32_t)0)) == INT_MIN); + EXPECT_TRUE(__sio(m)(smax)(((int32_t)0)) == INT_MAX); + EXPECT_TRUE(__sio(m)(umax)(((uint32_t)0)) == UINT_MAX); + + EXPECT_TRUE(__sio(m)(smin)(((int64_t)0)) == SAFE_INT64_MIN); + EXPECT_TRUE(__sio(m)(smax)(((int64_t)0)) == SAFE_INT64_MAX); + EXPECT_TRUE(__sio(m)(umax)(((uint64_t)0)) == SAFE_UINT64_MAX); + + EXPECT_TRUE(__sio(m)(smin)(((ssize_t)0)) == SSIZE_MIN); + EXPECT_TRUE(__sio(m)(smax)(((ssize_t)0)) == SSIZE_MAX); + EXPECT_TRUE(__sio(m)(umax)(((size_t)0)) == SIZE_MAX); + + EXPECT_TRUE(__sio(m)(smin)(((long)0)) == LONG_MIN); + EXPECT_TRUE(__sio(m)(smax)(((long)0)) == LONG_MAX); + EXPECT_TRUE(__sio(m)(umax)(((unsigned long)0)) == ULONG_MAX); + + EXPECT_TRUE(__sio(m)(smin)(((long long)0)) == LLONG_MIN); + EXPECT_TRUE(__sio(m)(smax)(((long long)0)) == LLONG_MAX); + EXPECT_TRUE(__sio(m)(umax)(((unsigned long long)0)) == ULLONG_MAX); + + return r; +} + + + + +int main(int argc, char **argv) { + /* test inlines */ + int tests = 0, succ = 0, fail = 0; + tests++; if (T_div_s8()) succ++; else fail++; + tests++; if (T_div_s16()) succ++; else fail++; + tests++; if (T_div_s32()) succ++; else fail++; + tests++; if (T_div_s64()) succ++; else fail++; + tests++; if (T_div_long()) succ++; else fail++; + tests++; if (T_div_longlong()) succ++; else fail++; + tests++; if (T_div_ssizet()) succ++; else fail++; + tests++; if (T_div_u8()) succ++; else fail++; + tests++; if (T_div_u16()) succ++; else fail++; + tests++; if (T_div_u32()) succ++; else fail++; + tests++; if (T_div_u64()) succ++; else fail++; + tests++; if (T_div_ulong()) succ++; else fail++; + tests++; if (T_div_ulonglong()) succ++; else fail++; + tests++; if (T_div_sizet()) succ++; else fail++; + + tests++; if (T_mod_s8()) succ++; else fail++; + tests++; if (T_mod_s16()) succ++; else fail++; + tests++; if (T_mod_s32()) succ++; else fail++; + tests++; if (T_mod_s64()) succ++; else fail++; + tests++; if (T_mod_long()) succ++; else fail++; + tests++; if (T_mod_longlong()) succ++; else fail++; + tests++; if (T_mod_ssizet()) succ++; else fail++; + tests++; if (T_mod_u8()) succ++; else fail++; + tests++; if (T_mod_u16()) succ++; else fail++; + tests++; if (T_mod_u32()) succ++; else fail++; + tests++; if (T_mod_u64()) succ++; else fail++; + tests++; if (T_mod_ulong()) succ++; else fail++; + tests++; if (T_mod_ulonglong()) succ++; else fail++; + tests++; if (T_mod_sizet()) succ++; else fail++; + + tests++; if (T_mul_s8()) succ++; else fail++; + tests++; if (T_mul_s16()) succ++; else fail++; + tests++; if (T_mul_s32()) succ++; else fail++; + tests++; if (T_mul_s64()) succ++; else fail++; + tests++; if (T_mul_long()) succ++; else fail++; + tests++; if (T_mul_longlong()) succ++; else fail++; + tests++; if (T_mul_ssizet()) succ++; else fail++; + tests++; if (T_mul_u8()) succ++; else fail++; + tests++; if (T_mul_u16()) succ++; else fail++; + tests++; if (T_mul_u32()) succ++; else fail++; + tests++; if (T_mul_u64()) succ++; else fail++; + tests++; if (T_mul_ulong()) succ++; else fail++; + tests++; if (T_mul_ulonglong()) succ++; else fail++; + tests++; if (T_mul_sizet()) succ++; else fail++; + + tests++; if (T_sub_s8()) succ++; else fail++; + tests++; if (T_sub_s16()) succ++; else fail++; + tests++; if (T_sub_s32()) succ++; else fail++; + tests++; if (T_sub_s64()) succ++; else fail++; + tests++; if (T_sub_long()) succ++; else fail++; + tests++; if (T_sub_longlong()) succ++; else fail++; + tests++; if (T_sub_ssizet()) succ++; else fail++; + tests++; if (T_sub_u8()) succ++; else fail++; + tests++; if (T_sub_u16()) succ++; else fail++; + tests++; if (T_sub_u32()) succ++; else fail++; + tests++; if (T_sub_u64()) succ++; else fail++; + tests++; if (T_sub_ulong()) succ++; else fail++; + tests++; if (T_sub_ulonglong()) succ++; else fail++; + tests++; if (T_sub_sizet()) succ++; else fail++; + + tests++; if (T_add_s8()) succ++; else fail++; + tests++; if (T_add_s16()) succ++; else fail++; + tests++; if (T_add_s32()) succ++; else fail++; + tests++; if (T_add_s64()) succ++; else fail++; + tests++; if (T_add_long()) succ++; else fail++; + tests++; if (T_add_longlong()) succ++; else fail++; + tests++; if (T_add_ssizet()) succ++; else fail++; + tests++; if (T_add_u8()) succ++; else fail++; + tests++; if (T_add_u16()) succ++; else fail++; + tests++; if (T_add_u32()) succ++; else fail++; + tests++; if (T_add_u64()) succ++; else fail++; + tests++; if (T_add_ulong()) succ++; else fail++; + tests++; if (T_add_ulonglong()) succ++; else fail++; + tests++; if (T_add_sizet()) succ++; else fail++; + tests++; if (T_add_mixed()) succ++; else fail++; + tests++; if (T_add_increment()) succ++; else fail++; + + tests++; if (T_magic_constants()) succ++; else fail++; + + printf("%d/%d expects succeeded (%d failures)\n", + expect_succ, expect, expect_fail); + printf("%d/%d tests succeeded (%d failures)\n", succ, tests, fail); + /* TODO: Add tests for safe_iopf when upgraded */ + return fail; +} +#endif