
// library types, functions etc
typedef unsigned long size_t;
void *malloc(size_t size);
void *realloc(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
void free(void *ptr);
wchar_t *wcscpy(wchar_t *s1, const wchar_t *s2);
int snprintf(char *s, size_t n, const char *format, ...);

// --- Semmle tests ---

void tests2() {
  wchar_t *buffer;

  buffer = (wchar_t *)malloc(2 * sizeof(wchar_t));
  wcscpy(buffer, L"1"); // GOOD
  wcscpy(buffer, L"12"); // $ Alert[cpp/very-likely-overrunning-write] // BAD: buffer overflow
  free(buffer);

  buffer = (wchar_t *)malloc(3 * sizeof(wchar_t));
  wcscpy(buffer, L"12"); // GOOD
  wcscpy(buffer, L"123"); // $ Alert[cpp/very-likely-overrunning-write] // BAD: buffer overflow
  free(buffer);

  buffer = (wchar_t *)realloc(0, 4 * sizeof(wchar_t));
  wcscpy(buffer, L"123"); // GOOD
  wcscpy(buffer, L"1234"); // $ Alert[cpp/very-likely-overrunning-write] // BAD: buffer overflow

  buffer = (wchar_t *)realloc(buffer, 5 * sizeof(wchar_t));
  wcscpy(buffer, L"1234"); // GOOD
  wcscpy(buffer, L"12345"); // $ Alert[cpp/very-likely-overrunning-write] // BAD: buffer overflow
  free(buffer);

  buffer = (wchar_t *)calloc(6, sizeof(wchar_t));
  wcscpy(buffer, L"12345"); // GOOD
  wcscpy(buffer, L"123456"); // $ Alert[cpp/very-likely-overrunning-write] // BAD: buffer overflow
  free(buffer);

  buffer = (wchar_t *)calloc(sizeof(wchar_t), 7);
  wcscpy(buffer, L"123456"); // GOOD
  wcscpy(buffer, L"1234567"); // $ Alert[cpp/very-likely-overrunning-write] // BAD: buffer overflow
  free(buffer);

  buffer = new wchar_t[8];
  wcscpy(buffer, L"1234567"); // GOOD
  wcscpy(buffer, L"12345678"); // $ Alert[cpp/very-likely-overrunning-write] // BAD: buffer overflow
  delete [] buffer;
}

char* dest1 = "a";
char* dest2 = "abcdefghijklmnopqrstuvwxyz";

void test3() {
  const char src[] = "abcdefghijkl";
  dest1 = (char*)malloc(sizeof(src));
  if (!dest1)
    return;
  snprintf(dest1, sizeof(src), "%s", src); // GOOD
  dest2 = (char*)malloc(3);
  if (!dest2)
    return;
  snprintf(dest2, sizeof(src), "%s", src); // $ MISSING: Alert // BAD [NOT DETECTED]
}
