What is the 'banned.h' file in git?

Published on: 04 November 2025


In the git source code you can find a file called banned.h. I was curious about what this file was, so I investigated further. Here is the content (as of today).

#ifndef BANNED_H
#define BANNED_H

/*
 * This header lists functions that have been banned from our code base,
 * because they're too easy to misuse (and even if used correctly,
 * complicate audits). Including this header turns them into compile-time
 * errors.
 */

#define BANNED(func) sorry_##func##_is_a_banned_function

#undef strcpy
#define strcpy(x,y) BANNED(strcpy)
#undef strcat
#define strcat(x,y) BANNED(strcat)
#undef strncpy
#define strncpy(x,y,n) BANNED(strncpy)
#undef strncat
#define strncat(x,y,n) BANNED(strncat)
#undef strtok
#define strtok(x,y) BANNED(strtok)
#undef strtok_r
#define strtok_r(x,y,z) BANNED(strtok_r)

#undef sprintf
#undef vsprintf
#define sprintf(...) BANNED(sprintf)
#define vsprintf(...) BANNED(vsprintf)

#undef gmtime
#define gmtime(t) BANNED(gmtime)
#undef localtime
#define localtime(t) BANNED(localtime)
#undef ctime
#define ctime(t) BANNED(ctime)
#undef ctime_r
#define ctime_r(t, buf) BANNED(ctime_r)
#undef asctime
#define asctime(t) BANNED(asctime)
#undef asctime_r
#define asctime_r(t, buf) BANNED(asctime_r)

#endif /* BANNED_H */

As the comment explains, this is a list of functions that the git developers don't want to have in the source code because they are easy to be misused and they they can trigger nasty bugs.

It works such that each banned function is replaced with an invalid string. For example, whenever strcpy is used it replaces is with sorry_strcpy_is_a_banned_function which will trigger a compiler error and from the error message a developer should be able to understand that this is a banned function and you should use another function for that use case.

As mentioned in the original commit, using this way to ban a function has various advantages:

  1. It is portable. This is important since git supports various operating systems, compilers and architectures.
  2. It generates a readable error.
  3. It is better than a static analyzer because this is part of the build cycle and it can not be skipped or missed.

The major disadvantage is that it is not triggered if this file is not included in the build. To make sure this is going to be used in almost all files, this file is imported directly in git-compat-util.h which is one of the main header file imported in most files.

If you are a C developer you can immaediately spot why some (or all) of these functions can lead to unexpected behaviors, but I want to dig deeper about what the git developers suggest as better alternatives. Thankfully we have detailed git commits to help us.

Here are all the commits that were made to this file.

60ff56f503 banned.h: mark `strtok()` and `strtok_r()` as banned - Taylor Blau Mon Apr 24 18:20:26 2023 -0400
56a29d2c97 C99: remove hardcoded-out !HAVE_VARIADIC_MACROS code - Ævar Arnfjörð Bjarmason Mon Feb 21 17:05:27 2022 +0100
91aef03015 banned.h: mark ctime_r() and asctime_r() as banned - Jeff King Tue Dec 1 13:11:38 2020 -0800
1fbfdf556f banned.h: mark non-reentrant gmtime, etc as banned - Jeff King Tue Dec 1 13:11:37 2020 -0800
60d198d022 banned.h: fix vsprintf()'s ban message - Taylor Blau Sun Aug 25 15:42:13 2019 -0400
ace5707a80 banned.h: mark strncat() as banned - Eric Wong Wed Jan 2 09:38:46 2019 +0000
e488b7aba7 banned.h: mark strncpy() as banned - Jeff King Tue Jul 24 05:28:28 2018 -0400
cc8fdaee1e banned.h: mark sprintf() as banned - Jeff King Tue Jul 24 05:27:19 2018 -0400
1b11b64b81 banned.h: mark strcat() as banned - Jeff King Tue Jul 24 05:26:39 2018 -0400
c8af66ab8a automatically ban strcpy() - Jeff King Thu Jul 26 03:21:05 2018 -0400

Most of the functions that have been banned are related to string management: strcpy(), strcat(), strncpy(), strncat(), strtok(), strtok_r(), sprintf() and vsprintf(). To do string manipulation in git they developed a nice library called strbuf which is mostly used for dynamic strings but it also has some robust functions to make static strings manipulation safer.

But in one commit they also mention a function called xsnprintf() and I was curious how it works to make snprintf() more robust. Here is the whole function (defined in wrapper.c).

int xsnprintf(char *dst, size_t max, const char *fmt, ...)
{
        va_list ap;
        int len;

        va_start(ap, fmt);
        len = vsnprintf(dst, max, fmt, ap);
        va_end(ap);

        if (len < 0)
                die(_("unable to format message: %s"), fmt);
        if (len >= max)
                BUG("attempt to snprintf into too-small buffer");
        return len;
}

I didn't know that vsnprintf() returns the total length of the formatted string and not the truncated version. So if you use this function you are going to immediately trigger the BUG() function, while snprintf() will silently fail. This is much better.

And then there are multiple functions related to time management. gmtime(), localtime(), ctime() and asctime() have been banned because they are not thread-safe. The reason why they are not thread-safe is because they all return a pointer to an internal static object that is shared between all these functions. To fix that there are gmtime_r(), localtime_r(), ctime_r() and asctime_r().

But you can see that also ctime_r() and asctime_r() have been banned, and here is the reason for it (from the commit).

The ctime_r() and asctime_r() functions are reentrant, but have no check that the buffer we pass in is long enough (the manpage says it "should have room for at least 26 bytes"). Since this is such an easy-to-get-wrong interface, and since we have the much safer strftime() as well as its more convenient strbuf_addftime() wrapper, let's ban both of those.

I didn't know about this either, and it makes sense to use internal safer functions instead these which could be easy to misuse.

It is now very clear why git banned these functions, especially now that they have developed safer alternatives. It's always important to remember the quirkiness of libc and use safer alternatives whenever possible.