Skip to content

Commit ea62b8f

Browse files
kawadakksdroege
authored andcommitted
glib: Fix overflow in StrV::extend_from_slice when checking capacity
The left hand side of the condition `self.len + other.len() + 1 <= self. capacity` could overflow and wrap around if `other` contained a large number of elements, causing it to proceed to the copying code without calling `reserve`.
1 parent 2921ca6 commit ea62b8f

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

glib/src/collections/strv.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ impl StrV {
772772
#[inline]
773773
pub fn extend_from_slice<S: AsRef<str>>(&mut self, other: &[S]) {
774774
// Nothing new to reserve as there's still enough space
775-
if self.len + other.len() + 1 > self.capacity {
775+
if other.len() >= self.capacity - self.len {
776776
self.reserve(other.len());
777777
}
778778

@@ -1791,4 +1791,26 @@ mod test {
17911791
// additional + 1 <= self.capacity`, which was prone to overflow
17921792
strv.reserve(usize::MAX - 3);
17931793
}
1794+
1795+
#[test]
1796+
#[should_panic]
1797+
fn test_extend_from_slice_overflow() {
1798+
// We need a zero-sized type because only a slice of ZST can legally
1799+
// contain up to `usize::MAX` elements.
1800+
#[derive(Clone, Copy)]
1801+
struct ImplicitStr;
1802+
1803+
impl AsRef<str> for ImplicitStr {
1804+
fn as_ref(&self) -> &str {
1805+
""
1806+
}
1807+
}
1808+
1809+
let mut strv = StrV::from(&[crate::gstr!(""); 3][..]);
1810+
1811+
// An old implementation of `extend_from_slice` used the condition
1812+
// `self.len + other.len() + 1 <= self.capacity`, which was prone to
1813+
// overflow
1814+
strv.extend_from_slice(&[ImplicitStr; usize::MAX - 3]);
1815+
}
17941816
}

0 commit comments

Comments
 (0)