File tree Expand file tree Collapse file tree 2 files changed +22
-6
lines changed Expand file tree Collapse file tree 2 files changed +22
-6
lines changed Original file line number Diff line number Diff line change @@ -230,7 +230,16 @@ friend std::strong_ordering operator<=>(const TString &s1, const TString &s2) {
230230
231231 enum { kAlignment = 16 };
232232 static Ssiz_t Align (Ssiz_t s) { return (s + (kAlignment -1 )) & ~(kAlignment -1 ); }
233- static Ssiz_t Recommend (Ssiz_t s) { return (s < kMinCap ? kMinCap : Align (s+1 )) - 1 ; }
233+ // `s` is expected to be <= MaxSize() = (kMaxInt-1) ; `s + 1` includes the terminating nullchar
234+ static Ssiz_t Recommend (Ssiz_t s)
235+ {
236+ if (s < kMinCap )
237+ return kMinCap ;
238+ else if (s > MaxSize () - (kAlignment - 1 ))
239+ return s;
240+ else
241+ return Align (s + 1 ) - 1 ;
242+ }
234243 static Ssiz_t AdjustCapacity (Ssiz_t oldCap, Ssiz_t newCap);
235244
236245private:
@@ -255,9 +264,9 @@ friend std::strong_ordering operator<=>(const TString &s1, const TString &s2) {
255264 char *GetPointer () { return IsLong () ? GetLongPointer () : GetShortPointer (); }
256265 const char *GetPointer () const { return IsLong () ? GetLongPointer () : GetShortPointer (); }
257266#ifdef R__BYTESWAP
258- static Ssiz_t MaxSize () { return kMaxInt - 1 ; }
267+ static constexpr Ssiz_t MaxSize () { return kMaxInt - 1 ; }
259268#else
260- static Ssiz_t MaxSize () { return (kMaxInt >> 1 ) - 1 ; }
269+ static constexpr Ssiz_t MaxSize () { return (kMaxInt >> 1 ) - 1 ; }
261270#endif
262271 void UnLink () const { if (IsLong ()) delete [] fRep .fLong .fData ; }
263272 void Zero () {
Original file line number Diff line number Diff line change @@ -23,6 +23,14 @@ strings (<15 on 64-bit and <11 on 32-bit) are contained in the
2323TString internal data structure without the need for mallocing the
2424required space.
2525
26+ \note TString can store a maximum of MaxSize()=2147483646 characters; ie 2147483647 bytes if you include the terminating null.
27+ Trying to allocate larger buffers might throw std::bad_alloc or raise
28+ Fatal errors or lead to undefined behavior. Likewise, there is no safety
29+ check if you pass a Long64_t to the class functions, they will be silently
30+ rounded to Int_t and lead to an integer overflow (negative value).
31+ For future designs, consider using std::string instead, which has a larger
32+ maximum size.
33+
2634Substring operations are provided by the TSubString class, which
2735holds a reference to the original string and its data, along with
2836the offset and length of the substring. To retrieve the substring
@@ -1220,12 +1228,11 @@ void TString::AssertElement(Ssiz_t i) const
12201228Ssiz_t TString::AdjustCapacity (Ssiz_t oldCap, Ssiz_t newCap)
12211229{
12221230 Ssiz_t ms = MaxSize ();
1223- if (newCap > ms - 1 ) {
1231+ if (newCap > ms) {
12241232 Fatal (" TString::AdjustCapacity" , " capacity too large (%d, max = %d)" ,
12251233 newCap, ms);
12261234 }
1227- Ssiz_t cap = oldCap < ms / 2 - kAlignment ?
1228- Recommend (std::max (newCap, 2 * oldCap)) : ms - 1 ;
1235+ Ssiz_t cap = oldCap <= ms / 2 ? Recommend (std::max (newCap, 2 * oldCap)) : ms;
12291236 return cap;
12301237}
12311238
You can’t perform that action at this time.
0 commit comments