From 3f8d82485742dea40e584a197235bc8bfb4c727e Mon Sep 17 00:00:00 2001 From: bala Date: Sat, 31 Aug 2002 19:05:39 +0000 Subject: ChangeLogTag: Sat Aug 31 13:55:52 2002 Balachandran Natarajan --- ChangeLog | 10 +++++++++ ChangeLogs/ChangeLog-03a | 10 +++++++++ ace/OS.i | 34 ++++++++++++++++------------- tests/OS_Test.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81079951cc1..d3ca8ff7413 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Sat Aug 31 13:55:52 2002 Balachandran Natarajan + + * ace/OS.i (ctime_r): This fixes a problem on Linux for the call + to ::ctime_r where the pointer returned (result) is the same as + the pointer (buf) passed in, causing the buffer to get clobbed + if strsncpy is used subsequently to move the result back to the + caller's buffer. + + * tests/OS_Test.cpp: Added a test for ACE_OS::ctime_r (). + Sat Aug 31 17:45:12 UTC 2002 Johnny Willemsen * ace/config-borland-common.h: diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index 81079951cc1..d3ca8ff7413 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,3 +1,13 @@ +Sat Aug 31 13:55:52 2002 Balachandran Natarajan + + * ace/OS.i (ctime_r): This fixes a problem on Linux for the call + to ::ctime_r where the pointer returned (result) is the same as + the pointer (buf) passed in, causing the buffer to get clobbed + if strsncpy is used subsequently to move the result back to the + caller's buffer. + + * tests/OS_Test.cpp: Added a test for ACE_OS::ctime_r (). + Sat Aug 31 17:45:12 UTC 2002 Johnny Willemsen * ace/config-borland-common.h: diff --git a/ace/OS.i b/ace/OS.i index baccaa91c4f..d98d66bc6ad 100644 --- a/ace/OS.i +++ b/ace/OS.i @@ -8471,6 +8471,9 @@ ACE_OS::difftime (time_t t1, time_t t0) } #endif /* ! ACE_LACKS_DIFFTIME */ +// Magic number declaration and definition for ctime and ctime_r () +static int ctime_buf_size = 26; + ACE_INLINE ACE_TCHAR * ACE_OS::ctime (const time_t *t) { @@ -8480,8 +8483,10 @@ ACE_OS::ctime (const time_t *t) #elif defined(ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME) return "ctime-return"; #elif defined (ACE_HAS_WINCE) - static ACE_TCHAR buf[26]; // 26 is a "magic number" ;) - return ACE_OS::ctime_r (t, buf, 26); + static ACE_TCHAR buf [ctime_buf_size]; + return ACE_OS::ctime_r (t, + buf, + ctime_buf_size); #elif defined (ACE_USES_WCHAR) ACE_OSCALL_RETURN (::_wctime (t), wchar_t *, 0); #else @@ -8493,19 +8498,20 @@ ACE_OS::ctime (const time_t *t) ACE_INLINE ACE_TCHAR * ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen) { - ACE_OS_TRACE ("ACE_OS::ctime_r"); +ACE_OS_TRACE ("ACE_OS::ctime_r"); + #if defined (ACE_HAS_REENTRANT_FUNCTIONS) # if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R) - ACE_TCHAR *result; + ACE_TCHAR *result ; + ACE_TCHAR result_buf[ctime_buf_size]; + # if defined (DIGITAL_UNIX) - ACE_OSCALL (::_Pctime_r (t, buf), ACE_TCHAR *, 0, result); + ACE_OSCALL (::_Pctime_r (t, result_buf), ACE_TCHAR *, 0, result); # else /* DIGITAL_UNIX */ - ACE_OSCALL (::ctime_r (t, buf), ACE_TCHAR *, 0, result); + ACE_OSCALL (::ctime_r (t, result_buf), ACE_TCHAR *, 0, result); # endif /* DIGITAL_UNIX */ if (result != 0) - // This needs to be rather than - // to avoid problems on certain platforms. - ACE_OS::strncpy (buf, result, buflen); + ACE_OS::strsncpy (buf, result, buflen); return buf; # else /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */ @@ -8517,8 +8523,8 @@ ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen) # endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */ #else /* ACE_HAS_REENTRANT_FUNCTIONS */ -# if defined (ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME) - ACE_OS::strsncpy (buf, "ctime-return", buflen); +# if defined(ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME) + ACE_OS::strsncpy(buf, "ctime-return", buflen); return buf; # else /* ACE_PSOS && !ACE_PSOS_HAS_TIME */ @@ -8526,12 +8532,10 @@ ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen) # if defined (ACE_USES_WCHAR) ACE_OSCALL (::_wctime (t), wchar_t *, 0, result); # else /* ACE_WIN32 */ - ACE_OSCALL (::ctime (t), char *, 0, result); +ACE_OSCALL (::ctime (t), char *, 0, result); # endif /* ACE_WIN32 */ if (result != 0) - // This needs to be rather than - // to avoid problems on certain platforms. - ACE_OS::strncpy (buf, result, buflen); + ACE_OS::strsncpy (buf, result, buflen); return buf; # endif /* ACE_PSOS && !ACE_PSOS_HAS_TIME */ #endif /* ACE_HAS_REENTRANT_FUNCTIONS */ diff --git a/tests/OS_Test.cpp b/tests/OS_Test.cpp index 243f40ce846..e1c66e3fb61 100644 --- a/tests/OS_Test.cpp +++ b/tests/OS_Test.cpp @@ -473,6 +473,60 @@ string_emulation_test (void) return 0; } + +static int +ctime_r_test (void) +{ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing ctime_r\n"))); + + int result = 0; + + // test 'normal' buffer + ACE_TCHAR buf[27]; + buf[26] = 'Z'; + + ACE_Time_Value cur_time = + ACE_OS::gettimeofday (); + + time_t secs = cur_time.sec (); + ACE_OS::ctime_r (&secs, buf, 26); + + if (buf[0] == '\0') + { + result = -1; + + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Truncated input buffer\n"))); + } + else if (buf[26] != 'Z') + { + result = -1; + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Wrote past end of input buffer\n"))); + } + + // test small buffer + if (result == 0) + { + buf[10] = 'Z'; + ACE_OS::ctime_r (&secs, + buf, + 10); + + if ((buf[9] != '\0') || + (buf[10] != 'Z')) + { + result = -1; + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%p|%t) Buffer length limit error\n"))); + } + } + + + return result; +} + + int ACE_TMAIN (int, ACE_TCHAR *[]) { @@ -487,6 +541,9 @@ ACE_TMAIN (int, ACE_TCHAR *[]) if ((result = string_emulation_test ()) != 0) status = result; + if ((result = ctime_r_test ()) != 0) + status = result; + ACE_END_TEST; return status; } -- cgit v1.2.1