Skip to content

Commit 0d909b9

Browse files
committed
Fix out-of-bounds check in std::string operator[]
1 parent 9c2de99 commit 0d909b9

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

libcxx/include/string

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,15 +1342,15 @@ public:
13421342
}
13431343

13441344
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT {
1345-
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
1345+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string index out of bounds");
13461346
if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
13471347
return *(__get_long_pointer() + __pos);
13481348
}
13491349
return *(data() + __pos);
13501350
}
13511351

13521352
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT {
1353-
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds");
1353+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string index out of bounds");
13541354
if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) {
13551355
return *(__get_long_pointer() + __pos);
13561356
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <string>
10+
11+
// Index string out of bounds.
12+
13+
// REQUIRES: has-unix-headers
14+
// UNSUPPORTED: c++03
15+
// UNSUPPORTED: libcpp-hardening-mode=none
16+
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
17+
18+
#include <string>
19+
#include <cassert>
20+
21+
#include "check_assertion.h"
22+
#include "min_allocator.h"
23+
24+
int main(int, char**) {
25+
// Test the const overloads.
26+
{
27+
using C = std::basic_string<char, std::char_traits<char>, safe_allocator<char> >;
28+
const C c;
29+
TEST_LIBCPP_ASSERT_FAILURE(c[0], "string index out of bounds");
30+
TEST_LIBCPP_ASSERT_FAILURE(c[1], "string index out of bounds");
31+
}
32+
{
33+
using C = std::basic_string<char, std::char_traits<char>, safe_allocator<char> >;
34+
const C c = "abc";
35+
TEST_LIBCPP_ASSERT_FAILURE(c[3], "string index out of bounds");
36+
TEST_LIBCPP_ASSERT_FAILURE(c[4], "string index out of bounds");
37+
TEST_LIBCPP_ASSERT_FAILURE(c[100], "string index out of bounds");
38+
}
39+
40+
// Test the nonconst overloads.
41+
{
42+
using C = std::basic_string<char, std::char_traits<char>, safe_allocator<char> >;
43+
C c;
44+
TEST_LIBCPP_ASSERT_FAILURE(c[0], "string index out of bounds");
45+
TEST_LIBCPP_ASSERT_FAILURE(c[1], "string index out of bounds");
46+
}
47+
{
48+
using C = std::basic_string<char, std::char_traits<char>, safe_allocator<char> >;
49+
C c = "abc";
50+
TEST_LIBCPP_ASSERT_FAILURE(c[3], "string index out of bounds");
51+
TEST_LIBCPP_ASSERT_FAILURE(c[4], "string index out of bounds");
52+
TEST_LIBCPP_ASSERT_FAILURE(c[100], "string index out of bounds");
53+
}
54+
55+
return 0;
56+
}

0 commit comments

Comments
 (0)