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:
Lauri Nurmi
2024-03-12 14:08:03 +01:00
committed by Vadim Zeitlin
parent 3b3a72e3e7
commit abe5da9875
2 changed files with 28 additions and 0 deletions
+18
View File
@@ -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();
}
+10
View File
@@ -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