mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-28 15:50:17 +08:00
Restore value of errno after wxString::ToInt()/Long()/etc.
Such functions modifying errno is undocumented, and may come
as a surprise to the caller. Consequently also a call to
wxString::Format() would modify errno.
See #23113.
(cherry picked from commit ed897d9641)
This commit is contained in:
committed by
Vadim Zeitlin
parent
3b3a72e3e7
commit
abe5da9875
@@ -1666,6 +1666,7 @@ int wxString::Find(wxUniChar ch, bool bFromEnd) const
|
||||
|
||||
#define WX_STRING_TO_X_TYPE_START \
|
||||
wxCHECK_MSG( pVal, false, wxT("NULL output pointer") ); \
|
||||
int errnoWas = errno; \
|
||||
errno = 0; \
|
||||
const wxStringCharType *start = wx_str(); \
|
||||
wxStringCharType *end;
|
||||
@@ -1675,8 +1676,12 @@ int wxString::Find(wxUniChar ch, bool bFromEnd) const
|
||||
// parse something successfully but not the entire string
|
||||
#define WX_STRING_TO_X_TYPE_END \
|
||||
if ( end == start || errno == ERANGE ) \
|
||||
{ \
|
||||
errno = errnoWas; \
|
||||
return false; \
|
||||
} \
|
||||
*pVal = val; \
|
||||
errno = errnoWas; \
|
||||
return !*end;
|
||||
|
||||
bool wxString::ToInt(int *pVal, int base) const
|
||||
@@ -1687,7 +1692,10 @@ bool wxString::ToInt(int *pVal, int base) const
|
||||
wxLongLong_t lval = wxStrtoll(start, &end, base);
|
||||
|
||||
if (lval < INT_MIN || lval > INT_MAX)
|
||||
{
|
||||
errno = errnoWas;
|
||||
return false;
|
||||
}
|
||||
int val = (int)lval;
|
||||
|
||||
WX_STRING_TO_X_TYPE_END
|
||||
@@ -1700,7 +1708,11 @@ bool wxString::ToUInt(unsigned int *pVal, int base) const
|
||||
WX_STRING_TO_X_TYPE_START
|
||||
wxULongLong_t lval = wxStrtoull(start, &end, base);
|
||||
if (lval > UINT_MAX)
|
||||
{
|
||||
errno = errnoWas;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int val = (unsigned int)lval;
|
||||
WX_STRING_TO_X_TYPE_END
|
||||
}
|
||||
@@ -2033,6 +2045,7 @@ static int DoStringPrintfV(wxString& str,
|
||||
const wxString& format, va_list argptr)
|
||||
{
|
||||
size_t size = 1024;
|
||||
int errnoWas = errno;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
@@ -2085,6 +2098,7 @@ static int DoStringPrintfV(wxString& str,
|
||||
{
|
||||
// If errno was set to one of the two well-known hard errors
|
||||
// then fail immediately to avoid an infinite loop.
|
||||
errno = errnoWas;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2100,7 +2114,10 @@ static int DoStringPrintfV(wxString& str,
|
||||
static const size_t MAX_BUFFER_SIZE = 128*1024*1024;
|
||||
|
||||
if ( size >= MAX_BUFFER_SIZE )
|
||||
{
|
||||
errno = errnoWas;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Note that doubling the size here will never overflow for size
|
||||
// less than the limit.
|
||||
@@ -2121,6 +2138,7 @@ static int DoStringPrintfV(wxString& str,
|
||||
// we could have overshot
|
||||
str.Shrink();
|
||||
|
||||
errno = errnoWas;
|
||||
return str.length();
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,16 @@ void StringTestCase::Format()
|
||||
CPPUNIT_ASSERT_EQUAL( len, wxString::Format(wxT("%s"), s.c_str()).length());
|
||||
}
|
||||
|
||||
int errnoWas = errno;
|
||||
// wxString::Format() should not modify errno
|
||||
errno = 1234;
|
||||
wxString::Format("abc %d %d", 1, 1);
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(
|
||||
1234,
|
||||
errno
|
||||
);
|
||||
errno = errnoWas;
|
||||
|
||||
// Positional parameters tests:
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
|
||||
Reference in New Issue
Block a user