@@ -1527,6 +1527,12 @@ fn test_try_reserve() {
1527
1527
const MAX_CAP : usize = isize:: MAX as usize ;
1528
1528
const MAX_USIZE : usize = usize:: MAX ;
1529
1529
1530
+ // On 16/32-bit, we check that allocations don't exceed isize::MAX,
1531
+ // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
1532
+ // Any platform that succeeds for these requests is technically broken with
1533
+ // ptr::offset because LLVM is the worst.
1534
+ let guards_against_isize = usize:: BITS < 64 ;
1535
+
1530
1536
{
1531
1537
// Note: basic stuff is checked by test_reserve
1532
1538
let mut empty_bytes: Vec < u8 > = Vec :: new ( ) ;
@@ -1540,19 +1546,35 @@ fn test_try_reserve() {
1540
1546
panic ! ( "isize::MAX shouldn't trigger an overflow!" ) ;
1541
1547
}
1542
1548
1543
- // Check isize::MAX + 1 does count as overflow
1544
- assert_matches ! (
1545
- empty_bytes. try_reserve( MAX_CAP + 1 ) . map_err( |e| e. kind( ) ) ,
1546
- Err ( CapacityOverflow ) ,
1547
- "isize::MAX + 1 should trigger an overflow!"
1548
- ) ;
1549
-
1550
- // Check usize::MAX does count as overflow
1551
- assert_matches ! (
1552
- empty_bytes. try_reserve( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
1553
- Err ( CapacityOverflow ) ,
1554
- "usize::MAX should trigger an overflow!"
1555
- ) ;
1549
+ if guards_against_isize {
1550
+ // Check isize::MAX + 1 does count as overflow
1551
+ assert_matches ! (
1552
+ empty_bytes. try_reserve( MAX_CAP + 1 ) . map_err( |e| e. kind( ) ) ,
1553
+ Err ( CapacityOverflow ) ,
1554
+ "isize::MAX + 1 should trigger an overflow!"
1555
+ ) ;
1556
+
1557
+ // Check usize::MAX does count as overflow
1558
+ assert_matches ! (
1559
+ empty_bytes. try_reserve( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
1560
+ Err ( CapacityOverflow ) ,
1561
+ "usize::MAX should trigger an overflow!"
1562
+ ) ;
1563
+ } else {
1564
+ // Check isize::MAX + 1 is an OOM
1565
+ assert_matches ! (
1566
+ empty_bytes. try_reserve( MAX_CAP + 1 ) . map_err( |e| e. kind( ) ) ,
1567
+ Err ( AllocError { .. } ) ,
1568
+ "isize::MAX + 1 should trigger an OOM!"
1569
+ ) ;
1570
+
1571
+ // Check usize::MAX is an OOM
1572
+ assert_matches ! (
1573
+ empty_bytes. try_reserve( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
1574
+ Err ( AllocError { .. } ) ,
1575
+ "usize::MAX should trigger an OOM!"
1576
+ ) ;
1577
+ }
1556
1578
}
1557
1579
1558
1580
{
@@ -1565,13 +1587,19 @@ fn test_try_reserve() {
1565
1587
if let Err ( CapacityOverflow ) = ten_bytes. try_reserve ( MAX_CAP - 10 ) . map_err ( |e| e. kind ( ) ) {
1566
1588
panic ! ( "isize::MAX shouldn't trigger an overflow!" ) ;
1567
1589
}
1568
-
1569
- assert_matches ! (
1570
- ten_bytes. try_reserve( MAX_CAP - 9 ) . map_err( |e| e. kind( ) ) ,
1571
- Err ( CapacityOverflow ) ,
1572
- "isize::MAX + 1 should trigger an overflow!"
1573
- ) ;
1574
-
1590
+ if guards_against_isize {
1591
+ assert_matches ! (
1592
+ ten_bytes. try_reserve( MAX_CAP - 9 ) . map_err( |e| e. kind( ) ) ,
1593
+ Err ( CapacityOverflow ) ,
1594
+ "isize::MAX + 1 should trigger an overflow!"
1595
+ ) ;
1596
+ } else {
1597
+ assert_matches ! (
1598
+ ten_bytes. try_reserve( MAX_CAP - 9 ) . map_err( |e| e. kind( ) ) ,
1599
+ Err ( AllocError { .. } ) ,
1600
+ "isize::MAX + 1 should trigger an OOM!"
1601
+ ) ;
1602
+ }
1575
1603
// Should always overflow in the add-to-len
1576
1604
assert_matches ! (
1577
1605
ten_bytes. try_reserve( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
@@ -1592,13 +1620,19 @@ fn test_try_reserve() {
1592
1620
{
1593
1621
panic ! ( "isize::MAX shouldn't trigger an overflow!" ) ;
1594
1622
}
1595
-
1596
- assert_matches ! (
1597
- ten_u32s. try_reserve( MAX_CAP / 4 - 9 ) . map_err( |e| e. kind( ) ) ,
1598
- Err ( CapacityOverflow ) ,
1599
- "isize::MAX + 1 should trigger an overflow!"
1600
- ) ;
1601
-
1623
+ if guards_against_isize {
1624
+ assert_matches ! (
1625
+ ten_u32s. try_reserve( MAX_CAP / 4 - 9 ) . map_err( |e| e. kind( ) ) ,
1626
+ Err ( CapacityOverflow ) ,
1627
+ "isize::MAX + 1 should trigger an overflow!"
1628
+ ) ;
1629
+ } else {
1630
+ assert_matches ! (
1631
+ ten_u32s. try_reserve( MAX_CAP / 4 - 9 ) . map_err( |e| e. kind( ) ) ,
1632
+ Err ( AllocError { .. } ) ,
1633
+ "isize::MAX + 1 should trigger an OOM!"
1634
+ ) ;
1635
+ }
1602
1636
// Should fail in the mul-by-size
1603
1637
assert_matches ! (
1604
1638
ten_u32s. try_reserve( MAX_USIZE - 20 ) . map_err( |e| e. kind( ) ) ,
@@ -1618,6 +1652,8 @@ fn test_try_reserve_exact() {
1618
1652
const MAX_CAP : usize = isize:: MAX as usize ;
1619
1653
const MAX_USIZE : usize = usize:: MAX ;
1620
1654
1655
+ let guards_against_isize = size_of :: < usize > ( ) < 8 ;
1656
+
1621
1657
{
1622
1658
let mut empty_bytes: Vec < u8 > = Vec :: new ( ) ;
1623
1659
@@ -1630,17 +1666,31 @@ fn test_try_reserve_exact() {
1630
1666
panic ! ( "isize::MAX shouldn't trigger an overflow!" ) ;
1631
1667
}
1632
1668
1633
- assert_matches ! (
1634
- empty_bytes. try_reserve_exact( MAX_CAP + 1 ) . map_err( |e| e. kind( ) ) ,
1635
- Err ( CapacityOverflow ) ,
1636
- "isize::MAX + 1 should trigger an overflow!"
1637
- ) ;
1638
-
1639
- assert_matches ! (
1640
- empty_bytes. try_reserve_exact( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
1641
- Err ( CapacityOverflow ) ,
1642
- "usize::MAX should trigger an overflow!"
1643
- ) ;
1669
+ if guards_against_isize {
1670
+ assert_matches ! (
1671
+ empty_bytes. try_reserve_exact( MAX_CAP + 1 ) . map_err( |e| e. kind( ) ) ,
1672
+ Err ( CapacityOverflow ) ,
1673
+ "isize::MAX + 1 should trigger an overflow!"
1674
+ ) ;
1675
+
1676
+ assert_matches ! (
1677
+ empty_bytes. try_reserve_exact( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
1678
+ Err ( CapacityOverflow ) ,
1679
+ "usize::MAX should trigger an overflow!"
1680
+ ) ;
1681
+ } else {
1682
+ assert_matches ! (
1683
+ empty_bytes. try_reserve_exact( MAX_CAP + 1 ) . map_err( |e| e. kind( ) ) ,
1684
+ Err ( AllocError { .. } ) ,
1685
+ "isize::MAX + 1 should trigger an OOM!"
1686
+ ) ;
1687
+
1688
+ assert_matches ! (
1689
+ empty_bytes. try_reserve_exact( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
1690
+ Err ( AllocError { .. } ) ,
1691
+ "usize::MAX should trigger an OOM!"
1692
+ ) ;
1693
+ }
1644
1694
}
1645
1695
1646
1696
{
@@ -1656,13 +1706,19 @@ fn test_try_reserve_exact() {
1656
1706
{
1657
1707
panic ! ( "isize::MAX shouldn't trigger an overflow!" ) ;
1658
1708
}
1659
-
1660
- assert_matches ! (
1661
- ten_bytes. try_reserve_exact( MAX_CAP - 9 ) . map_err( |e| e. kind( ) ) ,
1662
- Err ( CapacityOverflow ) ,
1663
- "isize::MAX + 1 should trigger an overflow!"
1664
- ) ;
1665
-
1709
+ if guards_against_isize {
1710
+ assert_matches ! (
1711
+ ten_bytes. try_reserve_exact( MAX_CAP - 9 ) . map_err( |e| e. kind( ) ) ,
1712
+ Err ( CapacityOverflow ) ,
1713
+ "isize::MAX + 1 should trigger an overflow!"
1714
+ ) ;
1715
+ } else {
1716
+ assert_matches ! (
1717
+ ten_bytes. try_reserve_exact( MAX_CAP - 9 ) . map_err( |e| e. kind( ) ) ,
1718
+ Err ( AllocError { .. } ) ,
1719
+ "isize::MAX + 1 should trigger an OOM!"
1720
+ ) ;
1721
+ }
1666
1722
assert_matches ! (
1667
1723
ten_bytes. try_reserve_exact( MAX_USIZE ) . map_err( |e| e. kind( ) ) ,
1668
1724
Err ( CapacityOverflow ) ,
@@ -1683,13 +1739,19 @@ fn test_try_reserve_exact() {
1683
1739
{
1684
1740
panic ! ( "isize::MAX shouldn't trigger an overflow!" ) ;
1685
1741
}
1686
-
1687
- assert_matches ! (
1688
- ten_u32s. try_reserve_exact( MAX_CAP / 4 - 9 ) . map_err( |e| e. kind( ) ) ,
1689
- Err ( CapacityOverflow ) ,
1690
- "isize::MAX + 1 should trigger an overflow!"
1691
- ) ;
1692
-
1742
+ if guards_against_isize {
1743
+ assert_matches ! (
1744
+ ten_u32s. try_reserve_exact( MAX_CAP / 4 - 9 ) . map_err( |e| e. kind( ) ) ,
1745
+ Err ( CapacityOverflow ) ,
1746
+ "isize::MAX + 1 should trigger an overflow!"
1747
+ ) ;
1748
+ } else {
1749
+ assert_matches ! (
1750
+ ten_u32s. try_reserve_exact( MAX_CAP / 4 - 9 ) . map_err( |e| e. kind( ) ) ,
1751
+ Err ( AllocError { .. } ) ,
1752
+ "isize::MAX + 1 should trigger an OOM!"
1753
+ ) ;
1754
+ }
1693
1755
assert_matches ! (
1694
1756
ten_u32s. try_reserve_exact( MAX_USIZE - 20 ) . map_err( |e| e. kind( ) ) ,
1695
1757
Err ( CapacityOverflow ) ,
0 commit comments