WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit c370e05

Browse files
<xlocnum>: Defend against sprintf_s() failure in num_put::do_put() (#5925)
1 parent ca6b464 commit c370e05

File tree

1 file changed

+74
-20
lines changed

1 file changed

+74
-20
lines changed

stl/inc/xlocnum

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,35 +1312,67 @@ protected:
13121312
char _Buf[2 * _Max_int_dig];
13131313
char _Fmt[6];
13141314

1315-
return _Iput(_Dest, _Iosbase, _Fill, _Buf,
1316-
static_cast<size_t>(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "ld", _Iosbase.flags()), _Val)));
1315+
(void) _Ifmt(_Fmt, "ld", _Iosbase.flags());
1316+
1317+
const int _Count = _CSTD sprintf_s(_Buf, sizeof(_Buf), _Fmt, _Val);
1318+
1319+
if (_Count < 0) { // It should be impossible for sprintf_s() to fail here.
1320+
_STL_INTERNAL_CHECK(false); // In STL tests, report an error.
1321+
return _Dest; // In production, return early to avoid static_cast<size_t> of a negative _Count.
1322+
}
1323+
1324+
return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast<size_t>(_Count));
13171325
}
13181326

13191327
virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill,
13201328
unsigned long _Val) const { // put formatted unsigned long to _Dest
13211329
char _Buf[2 * _Max_int_dig];
13221330
char _Fmt[6];
13231331

1324-
return _Iput(_Dest, _Iosbase, _Fill, _Buf,
1325-
static_cast<size_t>(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "lu", _Iosbase.flags()), _Val)));
1332+
(void) _Ifmt(_Fmt, "lu", _Iosbase.flags());
1333+
1334+
const int _Count = _CSTD sprintf_s(_Buf, sizeof(_Buf), _Fmt, _Val);
1335+
1336+
if (_Count < 0) { // It should be impossible for sprintf_s() to fail here.
1337+
_STL_INTERNAL_CHECK(false); // In STL tests, report an error.
1338+
return _Dest; // In production, return early to avoid static_cast<size_t> of a negative _Count.
1339+
}
1340+
1341+
return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast<size_t>(_Count));
13261342
}
13271343

13281344
virtual _OutIt __CLR_OR_THIS_CALL do_put(
13291345
_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long long _Val) const { // put formatted long long to _Dest
13301346
char _Buf[2 * _Max_int_dig];
13311347
char _Fmt[8];
13321348

1333-
return _Iput(_Dest, _Iosbase, _Fill, _Buf,
1334-
static_cast<size_t>(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "Ld", _Iosbase.flags()), _Val)));
1349+
(void) _Ifmt(_Fmt, "Ld", _Iosbase.flags());
1350+
1351+
const int _Count = _CSTD sprintf_s(_Buf, sizeof(_Buf), _Fmt, _Val);
1352+
1353+
if (_Count < 0) { // It should be impossible for sprintf_s() to fail here.
1354+
_STL_INTERNAL_CHECK(false); // In STL tests, report an error.
1355+
return _Dest; // In production, return early to avoid static_cast<size_t> of a negative _Count.
1356+
}
1357+
1358+
return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast<size_t>(_Count));
13351359
}
13361360

13371361
virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill,
13381362
unsigned long long _Val) const { // put formatted unsigned long long to _Dest
13391363
char _Buf[2 * _Max_int_dig];
13401364
char _Fmt[8];
13411365

1342-
return _Iput(_Dest, _Iosbase, _Fill, _Buf,
1343-
static_cast<size_t>(_CSTD sprintf_s(_Buf, sizeof(_Buf), _Ifmt(_Fmt, "Lu", _Iosbase.flags()), _Val)));
1366+
(void) _Ifmt(_Fmt, "Lu", _Iosbase.flags());
1367+
1368+
const int _Count = _CSTD sprintf_s(_Buf, sizeof(_Buf), _Fmt, _Val);
1369+
1370+
if (_Count < 0) { // It should be impossible for sprintf_s() to fail here.
1371+
_STL_INTERNAL_CHECK(false); // In STL tests, report an error.
1372+
return _Dest; // In production, return early to avoid static_cast<size_t> of a negative _Count.
1373+
}
1374+
1375+
return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast<size_t>(_Count));
13441376
}
13451377

13461378
virtual _OutIt __CLR_OR_THIS_CALL do_put(
@@ -1364,10 +1396,17 @@ protected:
13641396
const bool _Is_finite = (_STD isfinite) (_Val);
13651397
const auto _Adjusted_flags = // TRANSITION, DevCom-10519861
13661398
_Is_finite ? _Iosbase.flags() : _Iosbase.flags() & ~ios_base::showpoint;
1367-
const auto _Ngen = static_cast<size_t>(_CSTD sprintf_s(
1368-
&_Buf[0], _Buf.size(), _Ffmt(_Fmt, 0, _Adjusted_flags), static_cast<int>(_Precision), _Val));
13691399

1370-
return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, _Is_finite);
1400+
(void) _Ffmt(_Fmt, 0, _Adjusted_flags);
1401+
1402+
const int _Count = _CSTD sprintf_s(&_Buf[0], _Buf.size(), _Fmt, static_cast<int>(_Precision), _Val);
1403+
1404+
if (_Count < 0) { // It should be impossible for sprintf_s() to fail here.
1405+
_STL_INTERNAL_CHECK(false); // In STL tests, report an error.
1406+
return _Dest; // In production, return early to avoid static_cast<size_t> of a negative _Count.
1407+
}
1408+
1409+
return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), static_cast<size_t>(_Count), _Is_finite);
13711410
}
13721411

13731412
virtual _OutIt __CLR_OR_THIS_CALL do_put(
@@ -1391,24 +1430,38 @@ protected:
13911430
const bool _Is_finite = (_STD isfinite) (_Val);
13921431
const auto _Adjusted_flags = // TRANSITION, DevCom-10519861
13931432
_Is_finite ? _Iosbase.flags() : _Iosbase.flags() & ~ios_base::showpoint;
1394-
const auto _Ngen = static_cast<size_t>(_CSTD sprintf_s(
1395-
&_Buf[0], _Buf.size(), _Ffmt(_Fmt, 'L', _Adjusted_flags), static_cast<int>(_Precision), _Val));
13961433

1397-
return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, _Is_finite);
1434+
(void) _Ffmt(_Fmt, 'L', _Adjusted_flags);
1435+
1436+
const int _Count = _CSTD sprintf_s(&_Buf[0], _Buf.size(), _Fmt, static_cast<int>(_Precision), _Val);
1437+
1438+
if (_Count < 0) { // It should be impossible for sprintf_s() to fail here.
1439+
_STL_INTERNAL_CHECK(false); // In STL tests, report an error.
1440+
return _Dest; // In production, return early to avoid static_cast<size_t> of a negative _Count.
1441+
}
1442+
1443+
return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), static_cast<size_t>(_Count), _Is_finite);
13981444
}
13991445
#pragma warning(pop)
14001446

14011447
virtual _OutIt __CLR_OR_THIS_CALL do_put(
14021448
_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const void* _Val) const { // put formatted void pointer to _Dest
14031449
char _Buf[2 * _Max_int_dig];
14041450

1405-
return _Iput(
1406-
_Dest, _Iosbase, _Fill, _Buf, static_cast<size_t>(_CSTD sprintf_s(_Buf, sizeof(_Buf), "%p", _Val)));
1451+
const int _Count = _CSTD sprintf_s(_Buf, sizeof(_Buf), "%p", _Val);
1452+
1453+
if (_Count < 0) { // It should be impossible for sprintf_s() to fail here.
1454+
_STL_INTERNAL_CHECK(false); // In STL tests, report an error.
1455+
return _Dest; // In production, return early to avoid static_cast<size_t> of a negative _Count.
1456+
}
1457+
1458+
return _Iput(_Dest, _Iosbase, _Fill, _Buf, static_cast<size_t>(_Count));
14071459
}
14081460

14091461
private:
1410-
char* __CLRCALL_OR_CDECL _Ffmt(
1411-
char* _Fmt, char _Spec, ios_base::fmtflags _Flags) const { // generate sprintf format for floating-point
1462+
// TRANSITION, ABI: This always returns _Fmt, which is now ignored.
1463+
char* __CLRCALL_OR_CDECL _Ffmt(char* _Fmt, char _Spec, ios_base::fmtflags _Flags) const {
1464+
// generate sprintf format for floating-point
14121465
char* _Ptr = _Fmt;
14131466
*_Ptr++ = '%';
14141467

@@ -1530,8 +1583,9 @@ private:
15301583
return _Rep(_Dest, _Fill, _Fillcount); // put trailing fill
15311584
}
15321585

1533-
char* __CLRCALL_OR_CDECL _Ifmt(
1534-
char* _Fmt, const char* _Spec, ios_base::fmtflags _Flags) const { // generate sprintf format for integer
1586+
// TRANSITION, ABI: This always returns _Fmt, which is now ignored.
1587+
char* __CLRCALL_OR_CDECL _Ifmt(char* _Fmt, const char* _Spec, ios_base::fmtflags _Flags) const {
1588+
// generate sprintf format for integer
15351589
char* _Ptr = _Fmt;
15361590
*_Ptr++ = '%';
15371591

0 commit comments

Comments
 (0)