Skip to content

Commit 6fb5f49

Browse files
author
Зишан Мирза
committed
update tests for ctime and localtime
1 parent 2849681 commit 6fb5f49

File tree

7 files changed

+53
-6
lines changed

7 files changed

+53
-6
lines changed

clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ If *Annex K.* is not available, replacements are suggested only for the
4141
following functions from the previous list:
4242

4343
- ``asctime``, ``asctime_r``, suggested replacement: ``strftime``
44+
- ``ctime``, ``ctime_r``, suggested replacement: ``ctime_s``
45+
- ``localtime``, ``localtime_r``, suggested replacement: ``localtime_s``
4446
- ``gets``, suggested replacement: ``fgets``
4547

4648
The following functions are always checked, regardless of *Annex K* availability:

clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ void f3(char *S, FILE *F) {
105105

106106
typedef int time_t;
107107
char *ctime(const time_t *Timer);
108-
struct tm *localtime(const time_t *Timer);
109108

110109
void f4(const time_t *Timer) {
111110
ctime(Timer);

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3532,10 +3532,20 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
35323532
Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
35333533
Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
35343534

3535-
// struct tm *localtime_r(const time_t *restrict timer,
3536-
// struct tm *restrict result);
3535+
// struct tm *localtime_r(const time_t *timer,
3536+
// struct tm *result);
35373537
addToFunctionSummaryMap(
35383538
"localtime_r",
3539+
Signature(ArgTypes{ConstTime_tPtrTy, StructTmPtrTy},
3540+
RetType{StructTmPtrTy}),
3541+
Summary(NoEvalCall)
3542+
.ArgConstraint(NotNull(ArgNo(0)))
3543+
.ArgConstraint(NotNull(ArgNo(1))));
3544+
3545+
// struct tm *localtime_s(const time_t *restrict timer,
3546+
// struct tm *restrict result);
3547+
addToFunctionSummaryMap(
3548+
"localtime_s",
35393549
Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
35403550
RetType{StructTmPtrTy}),
35413551
Summary(NoEvalCall)
@@ -3564,6 +3574,17 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
35643574
/*Buffer=*/ArgNo(1),
35653575
/*MinBufSize=*/BVF.getValue(26, IntTy))));
35663576

3577+
// char *ctime_r(char *buf, rsize_t buf_size, const time_t *timep);
3578+
addToFunctionSummaryMap(
3579+
"ctime_s",
3580+
Signature(ArgTypes{CharPtrTy, BufferSize(ArgNo(1), BVF.getValue(26, IntTy)), ConstTime_tPtrTy}, RetType{CharPtrTy}),
3581+
Summary(NoEvalCall)
3582+
.ArgConstraint(NotNull(ArgNo(0)))
3583+
.ArgConstraint(NotNull(ArgNo(1)))
3584+
.ArgConstraint(BufferSize(
3585+
/*Buffer=*/ArgNo(1),
3586+
/*MinBufSize=*/BVF.getValue(26, IntTy))));
3587+
35673588
// struct tm *gmtime_r(const time_t *restrict timer,
35683589
// struct tm *restrict result);
35693590
addToFunctionSummaryMap(

clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,8 +2032,8 @@ SYMBOL(locale, std::, <locale>)
20322032
SYMBOL(localeconv, std::, <clocale>)
20332033
SYMBOL(localeconv, None, <clocale>)
20342034
SYMBOL(localeconv, None, <locale.h>)
2035-
SYMBOL(localtime, std::, <ctime>)
2036-
SYMBOL(localtime, None, <ctime>)
2035+
SYMBOL(localtime, std::, <localtime>)
2036+
SYMBOL(localtime, None, <localtime>)
20372037
SYMBOL(localtime, None, <time.h>)
20382038
SYMBOL(lock, std::, <mutex>)
20392039
SYMBOL(lock_guard, std::, <mutex>)

clang/test/Analysis/cert/env34-c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ void ctime_test(void) {
329329
// expected-note@-2{{dereferencing an invalid pointer}}
330330
}
331331

332-
void time_test(void) {
332+
void localtime_test(void) {
333333
const time_t *t;
334334
const time_t *tt;
335335

compiler-rt/lib/dfsan/libc_ubuntu1404_abilist.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,6 +1547,7 @@ fun:ctanl=uninstrumented
15471547
fun:ctermid=uninstrumented
15481548
fun:ctime=uninstrumented
15491549
fun:ctime_r=uninstrumented
1550+
fun:ctime_s=uninstrumented
15501551
fun:cuserid=uninstrumented
15511552
fun:daemon=uninstrumented
15521553
fun:dcgettext=uninstrumented
@@ -2205,6 +2206,7 @@ fun:llseek=uninstrumented
22052206
fun:localeconv=uninstrumented
22062207
fun:localtime=uninstrumented
22072208
fun:localtime_r=uninstrumented
2209+
fun:localtime_s=uninstrumented
22082210
fun:lockf=uninstrumented
22092211
fun:lockf64=uninstrumented
22102212
fun:log=uninstrumented

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,16 @@ INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
13751375
}
13761376
return res;
13771377
}
1378+
INTERCEPTOR(__sanitizer_tm *, localtime_s, unsigned long *timep, void *result) {
1379+
void *ctx;
1380+
COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
1381+
__sanitizer_tm *res = REAL(localtime_r)(timep, result);
1382+
if (res) {
1383+
COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1384+
unpoison_tm(ctx, res);
1385+
}
1386+
return res;
1387+
}
13781388
INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
13791389
void *ctx;
13801390
COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
@@ -1421,6 +1431,19 @@ INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
14211431
}
14221432
return res;
14231433
}
1434+
INTERCEPTOR(char *, ctime_s, char* result, size_t result_size, unsigned long *timep) {
1435+
void *ctx;
1436+
COMMON_INTERCEPTOR_ENTER(ctx, ctime_s, result, result_size, timep);
1437+
// FIXME: under ASan the call below may write to freed memory and corrupt
1438+
// its metadata. See
1439+
// https://github.com/google/sanitizers/issues/321.
1440+
char *res = REAL(ctime_r)(result, result_size, timep);
1441+
if (res) {
1442+
COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1443+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1444+
}
1445+
return res;
1446+
}
14241447
INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
14251448
void *ctx;
14261449
COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);

0 commit comments

Comments
 (0)