Author: tfaber
Date: Sun Jul 26 08:03:02 2015
New Revision: 68573
URL:
http://svn.reactos.org/svn/reactos?rev=68573&view=rev
Log:
[PSDK]
- Add support for intsafe signed Add functions
- Guard signed math in ENABLE_INTSAFE_SIGNED_FUNCTIONS
CORE-9947 #resolve
Modified:
trunk/reactos/include/psdk/intsafe.h
trunk/rostests/kmtests/rtl/RtlIntSafe.c
Modified: trunk/reactos/include/psdk/intsafe.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/intsafe.h?rev…
==============================================================================
--- trunk/reactos/include/psdk/intsafe.h [iso-8859-1] (original)
+++ trunk/reactos/include/psdk/intsafe.h [iso-8859-1] Sun Jul 26 08:03:02 2015
@@ -433,6 +433,7 @@
DEFINE_SAFE_CONVERT_STOS(LongPtrToInt, LONG_PTR, INT)
DEFINE_SAFE_CONVERT_STOS(LongPtrToLong, LONG_PTR, LONG)
DEFINE_SAFE_CONVERT_STOS(LongPtrToIntPtr, LONG_PTR, INT_PTR)
+DEFINE_SAFE_CONVERT_STOS(LongLongToInt, LONGLONG, INT)
DEFINE_SAFE_CONVERT_STOS(LongLongToLong, LONGLONG, LONG)
DEFINE_SAFE_CONVERT_STOS(LongLongToIntPtr, LONGLONG, INT_PTR)
DEFINE_SAFE_CONVERT_STOS(LongLongToLongPtr, LONGLONG, LONG_PTR)
@@ -582,6 +583,55 @@
DEFINE_SAFE_SUB(SIZETSub, SIZE_T)
DEFINE_SAFE_SUB(ULongLongSub, ULONGLONG)
+#ifdef ENABLE_INTSAFE_SIGNED_FUNCTIONS
+_Must_inspect_result_
+__forceinline
+INTSAFE_RESULT
+INTSAFE_NAME(LongLongAdd)(
+ _In_ LONGLONG Augend,
+ _In_ LONGLONG Addend,
+ _Out_ _Deref_out_range_(==, Augend + Addend) LONGLONG* pResult)
+{
+ LONGLONG Result = Augend + Addend;
+
+ /* The only way the result can overflow, is when the sign of the augend
+ and the addend are the same. In that case the result is expected to
+ have the same sign as the two, otherwise it overflowed.
+ Sign equality is checked with a binary xor operation. */
+ if ( ((Augend ^ Addend) >= 0) && ((Augend ^ Result) < 0) )
+ {
+ *pResult = LONGLONG_ERROR;
+ return INTSAFE_E_ARITHMETIC_OVERFLOW;
+ }
+ else
+ {
+ *pResult = Result;
+ return INTSAFE_SUCCESS;
+ }
+}
+
+
+#define DEFINE_SAFE_ADD_S(_Name, _Type1, _Type2, _Convert) \
+C_ASSERT(sizeof(_Type2) > sizeof(_Type1)); \
+_Must_inspect_result_ \
+__forceinline \
+INTSAFE_RESULT \
+INTSAFE_NAME(_Name)( \
+ _In_ _Type1 Augend, \
+ _In_ _Type1 Addend, \
+ _Out_ _Deref_out_range_(==, Augend + Addend) _Type1* pOutput) \
+{ \
+ return INTSAFE_NAME(_Convert)(((_Type2)Augend) + ((_Type2)Addend), pOutput); \
+}
+
+DEFINE_SAFE_ADD_S(Int8Add, INT8, SHORT, ShortToInt8)
+DEFINE_SAFE_ADD_S(ShortAdd, SHORT, INT, IntToShort)
+DEFINE_SAFE_ADD_S(IntAdd, INT, LONGLONG, LongLongToInt)
+DEFINE_SAFE_ADD_S(LongAdd, LONG, LONGLONG, LongLongToLong)
+#ifndef _WIN64
+DEFINE_SAFE_ADD_S(IntPtrAdd, INT_PTR, LONGLONG, LongLongToIntPtr)
+DEFINE_SAFE_ADD_S(LongPtrAdd, LONG_PTR, LONGLONG, LongLongToLongPtr)
+#endif
_Must_inspect_result_
__forceinline
@@ -611,6 +661,7 @@
#define DEFINE_SAFE_SUB_S(_Name, _Type1, _Type2, _Convert) \
+C_ASSERT(sizeof(_Type2) > sizeof(_Type1)); \
_Must_inspect_result_ \
__forceinline \
INTSAFE_RESULT \
@@ -628,6 +679,7 @@
DEFINE_SAFE_SUB_S(LongPtrSub, LONG_PTR, LONGLONG, LongLongToLongPtr)
#endif
+#endif /* ENABLE_INTSAFE_SIGNED_FUNCTIONS */
_Must_inspect_result_
__forceinline
@@ -741,6 +793,8 @@
#define RtlUInt16Mult RtlUShortMult
#define RtlWordMult RtlUShortMult
#ifdef _WIN64
+#define RtlIntPtrAdd RtlLongLongAdd
+#define RtlLongPtrAdd RtlLongLongAdd
#define RtlIntPtrSub RtlLongLongSub
#define RtlLongPtrSub RtlLongLongSub
#define RtlSizeTMult RtlULongLongMult
@@ -769,6 +823,8 @@
#define UInt16Mult UShortMult
#define WordMult UShortMult
#ifdef _WIN64
+#define IntPtrAdd LongLongAdd
+#define LongPtrAdd LongLongAdd
#define IntPtrSub LongLongSub
#define LongPtrSub LongLongSub
#define SizeTMult ULongLongMult
Modified: trunk/rostests/kmtests/rtl/RtlIntSafe.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/rtl/RtlIntSafe.c?…
==============================================================================
--- trunk/rostests/kmtests/rtl/RtlIntSafe.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/rtl/RtlIntSafe.c [iso-8859-1] Sun Jul 26 08:03:02 2015
@@ -111,4 +111,36 @@
TEST_ADD(UInt8, UINT8, uint, UINT8_MAX - 1, 1,
UINT8_MAX, STATUS_SUCCESS);
TEST_ADD(UInt8, UINT8, uint, UINT8_MAX, 1,
(UINT8)-1, STATUS_INTEGER_OVERFLOW);
TEST_ADD(UInt8, UINT8, uint, UINT8_MAX, UINT8_MAX,
(UINT8)-1, STATUS_INTEGER_OVERFLOW);
+
+ TEST_ADD(Int8, INT8, int, 0, 0, 0,
STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, 5, 5, 10,
STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, 0, INT8_MAX,
INT8_MAX, STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, INT8_MAX, 0,
INT8_MAX, STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, INT8_MAX - 1, 1,
INT8_MAX, STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, INT8_MAX, 1,
(INT8)-1, STATUS_INTEGER_OVERFLOW);
+ TEST_ADD(Int8, INT8, int, INT8_MAX, INT8_MAX,
(INT8)-1, STATUS_INTEGER_OVERFLOW);
+ TEST_ADD(Int8, INT8, int, 0, -1, -1,
STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, -1, 0, -1,
STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, 0, INT8_MIN,
INT8_MIN, STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, INT8_MIN, 0,
INT8_MIN, STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, INT8_MAX, INT8_MIN,
(INT8)-1, STATUS_SUCCESS);
+ TEST_ADD(Int8, INT8, int, INT8_MIN, -1,
(INT8)-1, STATUS_INTEGER_OVERFLOW);
+ TEST_ADD(Int8, INT8, int, INT8_MIN, INT8_MIN,
(INT8)-1, STATUS_INTEGER_OVERFLOW);
+
+ TEST_ADD(LongLong, LONGLONG, longlong, 0, 0, 0,
STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, 5, 5, 10,
STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, 0, LONGLONG_MAX,
LONGLONG_MAX, STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, 0,
LONGLONG_MAX, STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX - 1, 1,
LONGLONG_MAX, STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, 1,
(LONGLONG)-1, STATUS_INTEGER_OVERFLOW);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, INT8_MAX,
(LONGLONG)-1, STATUS_INTEGER_OVERFLOW);
+ TEST_ADD(LongLong, LONGLONG, longlong, 0, -1, -1,
STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, -1, 0, -1,
STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, 0, LONGLONG_MIN,
LONGLONG_MIN, STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MIN, 0,
LONGLONG_MIN, STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, LONGLONG_MIN,
(LONGLONG)-1, STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MIN, -1,
(LONGLONG)-1, STATUS_INTEGER_OVERFLOW);
+ TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MIN, LONGLONG_MIN,
(LONGLONG)-1, STATUS_INTEGER_OVERFLOW);
+ TEST_ADD(LongLong, LONGLONG, longlong, ULONG_MAX, 1,
0x100000000LL, STATUS_SUCCESS);
+ TEST_ADD(LongLong, LONGLONG, longlong, ULONG_MAX, ULONG_MAX,
0x1fffffffeLL, STATUS_SUCCESS);
}