717717< a href ="#716 " id ="716 "> 716</ a >
718718< a href ="#717 " id ="717 "> 717</ a >
719719< a href ="#718 " id ="718 "> 718</ a >
720+ < a href ="#719 " id ="719 "> 719</ a >
721+ < a href ="#720 " id ="720 "> 720</ a >
722+ < a href ="#721 " id ="721 "> 721</ a >
723+ < a href ="#722 " id ="722 "> 722</ a >
724+ < a href ="#723 " id ="723 "> 723</ a >
725+ < a href ="#724 " id ="724 "> 724</ a >
726+ < a href ="#725 " id ="725 "> 725</ a >
727+ < a href ="#726 " id ="726 "> 726</ a >
728+ < a href ="#727 " id ="727 "> 727</ a >
729+ < a href ="#728 " id ="728 "> 728</ a >
730+ < a href ="#729 " id ="729 "> 729</ a >
731+ < a href ="#730 " id ="730 "> 730</ a >
732+ < a href ="#731 " id ="731 "> 731</ a >
733+ < a href ="#732 " id ="732 "> 732</ a >
734+ < a href ="#733 " id ="733 "> 733</ a >
735+ < a href ="#734 " id ="734 "> 734</ a >
736+ < a href ="#735 " id ="735 "> 735</ a >
737+ < a href ="#736 " id ="736 "> 736</ a >
738+ < a href ="#737 " id ="737 "> 737</ a >
739+ < a href ="#738 " id ="738 "> 738</ a >
740+ < a href ="#739 " id ="739 "> 739</ a >
741+ < a href ="#740 " id ="740 "> 740</ a >
742+ < a href ="#741 " id ="741 "> 741</ a >
743+ < a href ="#742 " id ="742 "> 742</ a >
744+ < a href ="#743 " id ="743 "> 743</ a >
745+ < a href ="#744 " id ="744 "> 744</ a >
746+ < a href ="#745 " id ="745 "> 745</ a >
747+ < a href ="#746 " id ="746 "> 746</ a >
748+ < a href ="#747 " id ="747 "> 747</ a >
749+ < a href ="#748 " id ="748 "> 748</ a >
750+ < a href ="#749 " id ="749 "> 749</ a >
751+ < a href ="#750 " id ="750 "> 750</ a >
752+ < a href ="#751 " id ="751 "> 751</ a >
753+ < a href ="#752 " id ="752 "> 752</ a >
754+ < a href ="#753 " id ="753 "> 753</ a >
755+ < a href ="#754 " id ="754 "> 754</ a >
756+ < a href ="#755 " id ="755 "> 755</ a >
757+ < a href ="#756 " id ="756 "> 756</ a >
758+ < a href ="#757 " id ="757 "> 757</ a >
759+ < a href ="#758 " id ="758 "> 758</ a >
760+ < a href ="#759 " id ="759 "> 759</ a >
761+ < a href ="#760 " id ="760 "> 760</ a >
762+ < a href ="#761 " id ="761 "> 761</ a >
763+ < a href ="#762 " id ="762 "> 762</ a >
764+ < a href ="#763 " id ="763 "> 763</ a >
765+ < a href ="#764 " id ="764 "> 764</ a >
766+ < a href ="#765 " id ="765 "> 765</ a >
767+ < a href ="#766 " id ="766 "> 766</ a >
768+ < a href ="#767 " id ="767 "> 767</ a >
769+ < a href ="#768 " id ="768 "> 768</ a >
770+ < a href ="#769 " id ="769 "> 769</ a >
771+ < a href ="#770 " id ="770 "> 770</ a >
772+ < a href ="#771 " id ="771 "> 771</ a >
773+ < a href ="#772 " id ="772 "> 772</ a >
720774</ pre > </ div > < pre class ="rust "> < code > < span class ="kw "> use </ span > std::{
721775 error, fmt,
722776 ops::{Bound, Deref, DerefMut, Range, RangeBounds},
9611015 /// end of the buffer.
9621016 </ span > < span class ="kw "> pub fn </ span > slice<S: RangeBounds<BufferAddress>>(< span class ="kw-2 "> &</ span > < span class ="self "> self</ span > , bounds: S) -> BufferSlice<< span class ="lifetime "> '_</ span > > {
9631017 < span class ="kw "> let </ span > (offset, size) = range_to_offset_size(bounds);
1018+ check_buffer_bounds(< span class ="self "> self</ span > .size, offset, size);
9641019 BufferSlice {
9651020 buffer: < span class ="self "> self</ span > ,
9661021 offset,
13921447 }
13931448}
13941449
1450+ < span class ="kw "> fn </ span > check_buffer_bounds(
1451+ buffer_size: BufferAddress,
1452+ offset: BufferAddress,
1453+ size: < span class ="prelude-ty "> Option</ span > <BufferSize>,
1454+ ) {
1455+ < span class ="comment "> // A slice of length 0 is invalid, so the offset must not be equal to or greater than the buffer size.
1456+ </ span > < span class ="kw "> if </ span > offset >= buffer_size {
1457+ < span class ="macro "> panic!</ span > (
1458+ < span class ="string "> "slice offset {} is out of range for buffer of size {}"</ span > ,
1459+ offset, buffer_size
1460+ );
1461+ }
1462+
1463+ < span class ="kw "> if let </ span > < span class ="prelude-val "> Some</ span > (size) = size {
1464+ < span class ="comment "> // Detect integer overflow.
1465+ </ span > < span class ="kw "> let </ span > end = offset.checked_add(size.get());
1466+ < span class ="kw "> if </ span > end.map_or(< span class ="bool-val "> true</ span > , |end| end > buffer_size) {
1467+ < span class ="macro "> panic!</ span > (
1468+ < span class ="string "> "slice offset {} size {} is out of range for buffer of size {}"</ span > ,
1469+ offset, size, buffer_size
1470+ );
1471+ }
1472+ }
1473+ }
1474+
13951475< span class ="kw "> fn </ span > range_to_offset_size<S: RangeBounds<BufferAddress>>(
13961476 bounds: S,
13971477) -> (BufferAddress, < span class ="prelude-ty "> Option</ span > <BufferSize>) {
14091489
14101490 (offset, size)
14111491}
1492+
14121493< span class ="attr "> #[cfg(test)]
14131494</ span > < span class ="kw "> mod </ span > tests {
1414- < span class ="kw "> use super</ span > ::{range_to_offset_size, BufferSize};
1495+ < span class ="kw "> use super</ span > ::{check_buffer_bounds, range_to_offset_size, BufferSize};
14151496
14161497 < span class ="attr "> #[test]
14171498 </ span > < span class ="kw "> fn </ span > range_to_offset_size_works() {
14341515 </ span > < span class ="kw "> fn </ span > range_to_offset_size_panics_for_unbounded_empty_range() {
14351516 range_to_offset_size(..< span class ="number "> 0</ span > );
14361517 }
1518+
1519+ < span class ="attr "> #[test]
1520+ #[should_panic]
1521+ </ span > < span class ="kw "> fn </ span > check_buffer_bounds_panics_for_offset_at_size() {
1522+ check_buffer_bounds(< span class ="number "> 100</ span > , < span class ="number "> 100</ span > , < span class ="prelude-val "> None</ span > );
1523+ }
1524+
1525+ < span class ="attr "> #[test]
1526+ </ span > < span class ="kw "> fn </ span > check_buffer_bounds_works_for_end_in_range() {
1527+ check_buffer_bounds(< span class ="number "> 200</ span > , < span class ="number "> 100</ span > , BufferSize::new(< span class ="number "> 50</ span > ));
1528+ check_buffer_bounds(< span class ="number "> 200</ span > , < span class ="number "> 100</ span > , BufferSize::new(< span class ="number "> 100</ span > ));
1529+ check_buffer_bounds(u64::MAX, u64::MAX - < span class ="number "> 100</ span > , BufferSize::new(< span class ="number "> 100</ span > ));
1530+ check_buffer_bounds(u64::MAX, < span class ="number "> 0</ span > , BufferSize::new(u64::MAX));
1531+ check_buffer_bounds(u64::MAX, < span class ="number "> 1</ span > , BufferSize::new(u64::MAX - < span class ="number "> 1</ span > ));
1532+ }
1533+
1534+ < span class ="attr "> #[test]
1535+ #[should_panic]
1536+ </ span > < span class ="kw "> fn </ span > check_buffer_bounds_panics_for_end_over_size() {
1537+ check_buffer_bounds(< span class ="number "> 200</ span > , < span class ="number "> 100</ span > , BufferSize::new(< span class ="number "> 101</ span > ));
1538+ }
1539+
1540+ < span class ="attr "> #[test]
1541+ #[should_panic]
1542+ </ span > < span class ="kw "> fn </ span > check_buffer_bounds_panics_for_end_wraparound() {
1543+ check_buffer_bounds(u64::MAX, < span class ="number "> 1</ span > , BufferSize::new(u64::MAX));
1544+ }
14371545}
14381546</ code > </ pre > </ div > </ section > </ main > </ body > </ html >
0 commit comments