SafeIntLibUintnIntnUnitTests64.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /** @file
  2. x64-specific functions for unit-testing INTN and UINTN functions in
  3. SafeIntLib.
  4. Copyright (c) Microsoft Corporation.<BR>
  5. Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
  6. SPDX-License-Identifier: BSD-2-Clause-Patent
  7. **/
  8. #include <gtest/gtest.h>
  9. extern "C" {
  10. #include <Base.h>
  11. #include <Library/SafeIntLib.h>
  12. }
  13. TEST(ConversionTestSuite, TestSafeInt32ToUintn) {
  14. RETURN_STATUS Status;
  15. INT32 Operand;
  16. UINTN Result;
  17. //
  18. // If Operand is non-negative, then it's a cast
  19. //
  20. Operand = 0x5bababab;
  21. Result = 0;
  22. Status = SafeInt32ToUintn (Operand, &Result);
  23. ASSERT_EQ (Status, RETURN_SUCCESS);
  24. ASSERT_EQ ((UINTN)0x5bababab, Result);
  25. //
  26. // Otherwise should result in an error status
  27. //
  28. Operand = (-1537977259);
  29. Status = SafeInt32ToUintn (Operand, &Result);
  30. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  31. }
  32. TEST(ConversionTestSuite, TestSafeUint32ToIntn) {
  33. RETURN_STATUS Status;
  34. UINT32 Operand;
  35. INTN Result;
  36. //
  37. // For x64, INTN is same as INT64 which is a superset of INT32
  38. // This is just a cast then, and it'll never fail
  39. //
  40. //
  41. // If Operand is non-negative, then it's a cast
  42. //
  43. Operand = 0xabababab;
  44. Result = 0;
  45. Status = SafeUint32ToIntn (Operand, &Result);
  46. ASSERT_EQ (Status, RETURN_SUCCESS);
  47. ASSERT_EQ (0xabababab, Result);
  48. }
  49. TEST(ConversionTestSuite, TestSafeIntnToInt32) {
  50. RETURN_STATUS Status;
  51. INTN Operand;
  52. INT32 Result;
  53. //
  54. // If Operand is between MIN_INT32 and MAX_INT32 inclusive, then it's a cast
  55. //
  56. Operand = 0x5bababab;
  57. Result = 0;
  58. Status = SafeIntnToInt32 (Operand, &Result);
  59. ASSERT_EQ (Status, RETURN_SUCCESS);
  60. ASSERT_EQ (0x5bababab, Result);
  61. Operand = (-1537977259);
  62. Status = SafeIntnToInt32 (Operand, &Result);
  63. ASSERT_EQ (Status, RETURN_SUCCESS);
  64. ASSERT_EQ ((-1537977259), Result);
  65. //
  66. // Otherwise should result in an error status
  67. //
  68. Operand = (0x5babababefefefef);
  69. Status = SafeIntnToInt32 (Operand, &Result);
  70. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  71. Operand = (-6605562033422200815);
  72. Status = SafeIntnToInt32 (Operand, &Result);
  73. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  74. }
  75. TEST(ConversionTestSuite, TestSafeIntnToUint32) {
  76. RETURN_STATUS Status;
  77. INTN Operand;
  78. UINT32 Result;
  79. //
  80. // If Operand is between 0 and MAX_UINT32 inclusive, then it's a cast
  81. //
  82. Operand = 0xabababab;
  83. Result = 0;
  84. Status = SafeIntnToUint32 (Operand, &Result);
  85. ASSERT_EQ (Status, RETURN_SUCCESS);
  86. ASSERT_EQ (0xabababab, Result);
  87. //
  88. // Otherwise should result in an error status
  89. //
  90. Operand = (0x5babababefefefef);
  91. Status = SafeIntnToUint32 (Operand, &Result);
  92. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  93. Operand = (-6605562033422200815);
  94. Status = SafeIntnToUint32 (Operand, &Result);
  95. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  96. }
  97. TEST(ConversionTestSuite, TestSafeUintnToUint32) {
  98. RETURN_STATUS Status;
  99. UINTN Operand;
  100. UINT32 Result;
  101. //
  102. // If Operand is <= MAX_UINT32, then it's a cast
  103. //
  104. Operand = 0xabababab;
  105. Result = 0;
  106. Status = SafeUintnToUint32 (Operand, &Result);
  107. ASSERT_EQ (Status, RETURN_SUCCESS);
  108. ASSERT_EQ (0xabababab, Result);
  109. //
  110. // Otherwise should result in an error status
  111. //
  112. Operand = (0xababababefefefef);
  113. Status = SafeUintnToUint32 (Operand, &Result);
  114. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  115. }
  116. TEST(ConversionTestSuite, TestSafeUintnToIntn) {
  117. RETURN_STATUS Status;
  118. UINTN Operand;
  119. INTN Result;
  120. //
  121. // If Operand is <= MAX_INTN (0x7fff_ffff_ffff_ffff), then it's a cast
  122. //
  123. Operand = 0x5babababefefefef;
  124. Result = 0;
  125. Status = SafeUintnToIntn (Operand, &Result);
  126. ASSERT_EQ (Status, RETURN_SUCCESS);
  127. ASSERT_EQ (0x5babababefefefef, Result);
  128. //
  129. // Otherwise should result in an error status
  130. //
  131. Operand = (0xababababefefefef);
  132. Status = SafeUintnToIntn (Operand, &Result);
  133. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  134. }
  135. TEST(ConversionTestSuite, TestSafeUintnToInt64) {
  136. RETURN_STATUS Status;
  137. UINTN Operand;
  138. INT64 Result;
  139. //
  140. // If Operand is <= MAX_INT64, then it's a cast
  141. //
  142. Operand = 0x5babababefefefef;
  143. Result = 0;
  144. Status = SafeUintnToInt64 (Operand, &Result);
  145. ASSERT_EQ (Status, RETURN_SUCCESS);
  146. ASSERT_EQ (0x5babababefefefef, Result);
  147. //
  148. // Otherwise should result in an error status
  149. //
  150. Operand = (0xababababefefefef);
  151. Status = SafeUintnToInt64 (Operand, &Result);
  152. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  153. }
  154. TEST(ConversionTestSuite, TestSafeInt64ToIntn) {
  155. RETURN_STATUS Status;
  156. INT64 Operand;
  157. INTN Result;
  158. //
  159. // INTN is same as INT64 in x64, so this is just a cast
  160. //
  161. Operand = 0x5babababefefefef;
  162. Result = 0;
  163. Status = SafeInt64ToIntn (Operand, &Result);
  164. ASSERT_EQ (Status, RETURN_SUCCESS);
  165. ASSERT_EQ (0x5babababefefefef, Result);
  166. }
  167. TEST(ConversionTestSuite, TestSafeInt64ToUintn) {
  168. RETURN_STATUS Status;
  169. INT64 Operand;
  170. UINTN Result;
  171. //
  172. // If Operand is non-negative, then it's a cast
  173. //
  174. Operand = 0x5babababefefefef;
  175. Result = 0;
  176. Status = SafeInt64ToUintn (Operand, &Result);
  177. ASSERT_EQ (Status, RETURN_SUCCESS);
  178. ASSERT_EQ ((UINTN)0x5babababefefefef, Result);
  179. //
  180. // Otherwise should result in an error status
  181. //
  182. Operand = (-6605562033422200815);
  183. Status = SafeInt64ToUintn (Operand, &Result);
  184. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  185. }
  186. TEST(ConversionTestSuite, TestSafeUint64ToIntn) {
  187. RETURN_STATUS Status;
  188. UINT64 Operand;
  189. INTN Result;
  190. //
  191. // If Operand is <= MAX_INTN (0x7fff_ffff_ffff_ffff), then it's a cast
  192. //
  193. Operand = 0x5babababefefefef;
  194. Result = 0;
  195. Status = SafeUint64ToIntn (Operand, &Result);
  196. ASSERT_EQ (Status, RETURN_SUCCESS);
  197. ASSERT_EQ (0x5babababefefefef, Result);
  198. //
  199. // Otherwise should result in an error status
  200. //
  201. Operand = (0xababababefefefef);
  202. Status = SafeUint64ToIntn (Operand, &Result);
  203. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  204. }
  205. TEST(ConversionTestSuite, TestSafeUint64ToUintn) {
  206. RETURN_STATUS Status;
  207. UINT64 Operand;
  208. UINTN Result;
  209. //
  210. // UINTN is same as UINT64 in x64, so this is just a cast
  211. //
  212. Operand = 0xababababefefefef;
  213. Result = 0;
  214. Status = SafeUint64ToUintn (Operand, &Result);
  215. ASSERT_EQ (Status, RETURN_SUCCESS);
  216. ASSERT_EQ (0xababababefefefef, Result);
  217. }
  218. TEST(AdditionSubtractionTestSuite, TestSafeUintnAdd) {
  219. RETURN_STATUS Status;
  220. UINTN Augend;
  221. UINTN Addend;
  222. UINTN Result;
  223. //
  224. // If the result of addition doesn't overflow MAX_UINTN, then it's addition
  225. //
  226. Augend = 0x3a3a3a3a12121212;
  227. Addend = 0x3a3a3a3a12121212;
  228. Result = 0;
  229. Status = SafeUintnAdd (Augend, Addend, &Result);
  230. ASSERT_EQ (Status, RETURN_SUCCESS);
  231. ASSERT_EQ ((UINTN)0x7474747424242424, Result);
  232. //
  233. // Otherwise should result in an error status
  234. //
  235. Augend = 0xababababefefefef;
  236. Addend = 0xbcbcbcbcdededede;
  237. Status = SafeUintnAdd (Augend, Addend, &Result);
  238. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  239. }
  240. TEST(AdditionSubtractionTestSuite, TestSafeIntnAdd) {
  241. RETURN_STATUS Status;
  242. INTN Augend;
  243. INTN Addend;
  244. INTN Result;
  245. //
  246. // If the result of addition doesn't overflow MAX_INTN
  247. // and doesn't underflow MIN_INTN, then it's addition
  248. //
  249. Augend = 0x3a3a3a3a3a3a3a3a;
  250. Addend = 0x3a3a3a3a3a3a3a3a;
  251. Result = 0;
  252. Status = SafeIntnAdd (Augend, Addend, &Result);
  253. ASSERT_EQ (Status, RETURN_SUCCESS);
  254. ASSERT_EQ (0x7474747474747474, Result);
  255. Augend = (-4195730024608447034);
  256. Addend = (-4195730024608447034);
  257. Status = SafeIntnAdd (Augend, Addend, &Result);
  258. ASSERT_EQ (Status, RETURN_SUCCESS);
  259. ASSERT_EQ ((-8391460049216894068), Result);
  260. //
  261. // Otherwise should result in an error status
  262. //
  263. Augend = 0x5a5a5a5a5a5a5a5a;
  264. Addend = 0x5a5a5a5a5a5a5a5a;
  265. Status = SafeIntnAdd (Augend, Addend, &Result);
  266. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  267. Augend = (-6510615555426900570);
  268. Addend = (-6510615555426900570);
  269. Status = SafeIntnAdd (Augend, Addend, &Result);
  270. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  271. }
  272. TEST(AdditionSubtractionTestSuite, TestSafeUintnSub) {
  273. RETURN_STATUS Status;
  274. UINTN Minuend;
  275. UINTN Subtrahend;
  276. UINTN Result;
  277. //
  278. // If Minuend >= Subtrahend, then it's subtraction
  279. //
  280. Minuend = 0x5a5a5a5a5a5a5a5a;
  281. Subtrahend = 0x3b3b3b3b3b3b3b3b;
  282. Result = 0;
  283. Status = SafeUintnSub (Minuend, Subtrahend, &Result);
  284. ASSERT_EQ (Status, RETURN_SUCCESS);
  285. ASSERT_EQ ((UINTN)0x1f1f1f1f1f1f1f1f, Result);
  286. //
  287. // Otherwise should result in an error status
  288. //
  289. Minuend = 0x5a5a5a5a5a5a5a5a;
  290. Subtrahend = 0x6d6d6d6d6d6d6d6d;
  291. Status = SafeUintnSub (Minuend, Subtrahend, &Result);
  292. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  293. }
  294. TEST(AdditionSubtractionTestSuite, TestSafeIntnSub) {
  295. RETURN_STATUS Status;
  296. INTN Minuend;
  297. INTN Subtrahend;
  298. INTN Result;
  299. //
  300. // If the result of subtractions doesn't overflow MAX_INTN or
  301. // underflow MIN_INTN, then it's subtraction
  302. //
  303. Minuend = 0x5a5a5a5a5a5a5a5a;
  304. Subtrahend = 0x3a3a3a3a3a3a3a3a;
  305. Result = 0;
  306. Status = SafeIntnSub (Minuend, Subtrahend, &Result);
  307. ASSERT_EQ (Status, RETURN_SUCCESS);
  308. ASSERT_EQ (0x2020202020202020, Result);
  309. Minuend = 0x3a3a3a3a3a3a3a3a;
  310. Subtrahend = 0x5a5a5a5a5a5a5a5a;
  311. Status = SafeIntnSub (Minuend, Subtrahend, &Result);
  312. ASSERT_EQ (Status, RETURN_SUCCESS);
  313. ASSERT_EQ ((-2314885530818453536), Result);
  314. //
  315. // Otherwise should result in an error status
  316. //
  317. Minuend = (-8825501086245354106);
  318. Subtrahend = 8825501086245354106;
  319. Status = SafeIntnSub (Minuend, Subtrahend, &Result);
  320. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  321. Minuend = (8825501086245354106);
  322. Subtrahend = (-8825501086245354106);
  323. Status = SafeIntnSub (Minuend, Subtrahend, &Result);
  324. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  325. }
  326. TEST(MultiplicationTestSuite, TestSafeUintnMult) {
  327. RETURN_STATUS Status;
  328. UINTN Multiplicand;
  329. UINTN Multiplier;
  330. UINTN Result;
  331. //
  332. // If the result of multiplication doesn't overflow MAX_UINTN, it will succeed
  333. //
  334. Multiplicand = 0x123456789a;
  335. Multiplier = 0x1234567;
  336. Result = 0;
  337. Status = SafeUintnMult (Multiplicand, Multiplier, &Result);
  338. ASSERT_EQ (Status, RETURN_SUCCESS);
  339. ASSERT_EQ ((UINTN)0x14b66db9745a07f6, Result);
  340. //
  341. // Otherwise should result in an error status
  342. //
  343. Multiplicand = 0x123456789a;
  344. Multiplier = 0x12345678;
  345. Status = SafeUintnMult (Multiplicand, Multiplier, &Result);
  346. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  347. }
  348. TEST(MultiplicationTestSuite, TestSafeIntnMult) {
  349. RETURN_STATUS Status;
  350. INTN Multiplicand;
  351. INTN Multiplier;
  352. INTN Result;
  353. //
  354. // If the result of multiplication doesn't overflow MAX_INTN and doesn't
  355. // underflow MIN_UINTN, it will succeed
  356. //
  357. Multiplicand = 0x123456789;
  358. Multiplier = 0x6789abcd;
  359. Result = 0;
  360. Status = SafeIntnMult (Multiplicand, Multiplier, &Result);
  361. ASSERT_EQ (Status, RETURN_SUCCESS);
  362. ASSERT_EQ (0x75cd9045220d6bb5, Result);
  363. //
  364. // Otherwise should result in an error status
  365. //
  366. Multiplicand = 0x123456789;
  367. Multiplier = 0xa789abcd;
  368. Status = SafeIntnMult (Multiplicand, Multiplier, &Result);
  369. ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
  370. }