@@ -1355,7 +1355,73 @@ void TString::ReadBuffer(char *&buffer)
13551355
13561356 char *data = Init (nchars, nchars);
13571357
1358- for (int i = 0 ; i < nchars; i++) frombuf (buffer, &data[i]);
1358+ memcpy (data, buffer, nchars);
1359+ buffer += nchars;
1360+ }
1361+
1362+ // //////////////////////////////////////////////////////////////////////////////
1363+ // / Safer version of ReadBuffer(char *&buffer), doing bound checks on the given buffer.
1364+ // / This overload should be preferred over the other, which should be considered unsafe.
1365+ // / \return The amount of bytes read from the buffer, or 0 in case of errors.
1366+
1367+ std::size_t TString::ReadBuffer (char *&buffer, std::size_t bufsize)
1368+ {
1369+ // NOTE: this is not a lambda because we want [[nodiscard]].
1370+ struct {
1371+ TString *fOuter ;
1372+ std::size_t fRemainingBufSize ;
1373+
1374+ [[nodiscard]] bool operator ()(std::size_t additionalBytesNeeded)
1375+ {
1376+ if (R__unlikely (additionalBytesNeeded > fRemainingBufSize )) {
1377+ Error (" TString::ReadBuffer" , " given buffer is too small (%zu B remaining, need at least %zu more)" ,
1378+ fRemainingBufSize , additionalBytesNeeded);
1379+ fOuter ->UnLink ();
1380+ fOuter ->Zero ();
1381+ return false ;
1382+ }
1383+ fRemainingBufSize -= additionalBytesNeeded;
1384+ return true ;
1385+ }
1386+ } ConsumeBufCapacity{this , bufsize};
1387+
1388+ if (!ConsumeBufCapacity (1 )) {
1389+ return 0 ;
1390+ }
1391+
1392+ UnLink ();
1393+ Zero ();
1394+
1395+ UChar_t strLength;
1396+ Int_t nchars;
1397+
1398+ // frombuf needs a non-const buffer, although it actually doesn't modify it.
1399+ char *buf = const_cast <char *>(buffer);
1400+ frombuf (buf, &strLength);
1401+ if (strLength == 255 ) {
1402+ if (!ConsumeBufCapacity (sizeof (nchars))) {
1403+ return 0 ;
1404+ }
1405+ frombuf (buf, &nchars);
1406+ } else {
1407+ nchars = strLength;
1408+ }
1409+
1410+ if (nchars < 0 ) {
1411+ Error (" TString::ReadBuffer" , " found case with nwh=%d and nchars=%d" , strLength, nchars);
1412+ return 0 ;
1413+ }
1414+
1415+ char *data = Init (nchars, nchars);
1416+
1417+ if (!ConsumeBufCapacity (nchars)) {
1418+ return 0 ;
1419+ }
1420+ memcpy (data, buf, nchars);
1421+
1422+ std::size_t nbytesRead = bufsize - ConsumeBufCapacity.fRemainingBufSize ;
1423+ buffer += nbytesRead;
1424+ return nbytesRead;
13591425}
13601426
13611427// //////////////////////////////////////////////////////////////////////////////
0 commit comments