// Copyright (c) OWASP Project (https://www.owasp.org), 2011. All rights reserved. // Licensed under the MIT License. #include "TestMain.h" #include "TestCase.h" #if defined(__GNUC__) # include #endif #if !defined(CHAR_BIT) # include #endif namespace mod_verify { template std::string type_name() { std::ostringstream ostm; ostm << (std::numeric_limits::is_signed ? "int" : "uint"); ostm << (sizeof(T) == 1 ? 8 : sizeof(T) * 8); return ostm.str(); } // ModVerifyTest2 tests (x) % (0). template struct ModVerifyTest1 { ModVerifyTest1() { const size_t width = sizeof(T); const size_t shift = width * CHAR_BIT - 1; const bool expected = true; bool divzero; SafeInt x = (T)((std::uint64_t)1 << shift); SafeInt m(0); /////////////////////////////////////////////// try { T r; r = x % m; divzero = false; } catch(SafeIntException&) { divzero = true; } if(divzero != expected) { std::cerr << "Error in case " << type_name() << ": "; std::cerr << to_hex((T)x) << ", " << to_hex((T)m) << ", "; std::cerr << "expected = " << (expected ? "divzero" : "no divzero") << std::endl; } /////////////////////////////////////////////// try { T r = x; r %= m; divzero = false; } catch(SafeIntException&) { divzero = true; } if(divzero != expected) { std::cerr << "Error in case " << type_name() << ": "; std::cerr << to_hex((T)x) << ", " << to_hex((T)m) << ", "; std::cerr << "expected = " << (expected ? "divzero" : "no divzero") << std::endl; } } }; // ModVerifyTest2 tests (INT_MIN) % (-1). template struct ModVerifyTest2 { ModVerifyTest2() { const size_t width = sizeof(T); const size_t shift = width * CHAR_BIT - 1; // GCC using a native built-in int will raise SIGFPE or // #DE. However, according to LeBlanc, SafeInt's contract // is to return the correct mathematical result or throw. // const bool expected = (s == Signed ? true : false); const bool expected = false; bool overflow; SafeInt x = (T)((std::uint64_t)1 << shift); SafeInt m((T)-1); /////////////////////////////////////////////// try { T r; r = x % m; overflow = false; } catch(SafeIntException&) { overflow = true; } if(overflow != expected) { std::cerr << "Error in case " << type_name() << ": "; std::cerr << to_hex((T)x) << ", " << to_hex((T)m) << ", "; std::cerr << "expected = " << (expected ? "overflow" : "no overflow") << std::endl; } /////////////////////////////////////////////// try { T r = x; r %= m; overflow = false; } catch(SafeIntException&) { overflow = true; } if(overflow != expected) { std::cerr << "Error in case " << type_name() << ": "; std::cerr << to_hex((T)x) << ", " << to_hex((T)m) << ", "; std::cerr << "expected = " << (expected ? "overflow" : "no overflow") << std::endl; } } }; void ModVerify() { std::cout << "Verifying Reduction:" << std::endl; ModVerifyTest1 t11; ModVerifyTest1 t12; ModVerifyTest1 t13; ModVerifyTest1 t14; ModVerifyTest1 t15; ModVerifyTest1 t16; ModVerifyTest1 t17; ModVerifyTest1 t18; ModVerifyTest2 t21; ModVerifyTest2 t22; ModVerifyTest2 t23; ModVerifyTest2 t24; ModVerifyTest2 t25; ModVerifyTest2 t26; ModVerifyTest2 t27; ModVerifyTest2 t28; // Lets see..... ModVerifyTest1 t50; ModVerifyTest2 t51; } }