text: /* TEMPLATE GENERATED TESTCASE FILE
  Filename: CWE23_Relative_Path_Traversal__char_file_fopen_22b.cpp
  Label Definition File: CWE23_Relative_Path_Traversal.label.xml
  Template File: sources-sink-22b.tmpl.cpp
  */
  /*
   * @description
   * CWE: 23 Relative Path Traversal
   * BadSource: file Read input from a file
   * GoodSource: Use a fixed file name
   * Sink: fopen
   *    BadSink : Open the file named in data using fopen()
   * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources.
   *
   * */
  
  #include "std_testcase.h"
  
  #ifdef _WIN32
  #define BASEPATH "c:\\temp\\"
  #else
  #include <wchar.h>
  #define BASEPATH "/tmp/"
  #endif
  
  #ifdef _WIN32
  #define FILENAME "C:\\temp\\file.txt"
  #else
  #define FILENAME "/tmp/file.txt"
  #endif
  
  namespace CWE23_Relative_Path_Traversal__char_file_fopen_22
  {
  
  #ifndef OMITBAD
  
  /* The global variable below is used to drive control flow in the source function. Since it is in
  a C++ namespace, it doesn't need a globally unique name. */
  extern int badGlobal;
  
  char * badSource(char * data)
  {
      if(badGlobal)
      {
          {
              /* Read input from a file */
              size_t dataLen = strlen(data);
              FILE * pFile;
              /* if there is room in data, attempt to read the input from a file */
              if (FILENAME_MAX-dataLen > 1)
              {
                  pFile = fopen(FILENAME, "r");
                  if (pFile != NULL)
                  {
                      /* POTENTIAL FLAW: Read data from a file */
                      if (fgets(data+dataLen, (int)(FILENAME_MAX-dataLen), pFile) == NULL)
                      {
                          printLine("fgets() failed");
                          /* Restore NUL terminator if fgets fails */
                          data[dataLen] = '\0';
                      }
                      fclose(pFile);
                  }
              }
          }
      }
      return data;
  }
  
  #endif /* OMITBAD */
  
  #ifndef OMITGOOD
  
  /* The global variables below are used to drive control flow in the source functions. Since they are in
  a C++ namespace, they don't need globally unique names. */
  extern int goodG2B1Global;
  extern int goodG2B2Global;
  
  /* goodG2B1() - use goodsource and badsink by setting the global variable to false instead of true */
  char * goodG2B1Source(char * data)
  {
      if(goodG2B1Global)
      {
          /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
          printLine("Benign, fixed string");
      }
      else
      {
          /* FIX: Use a fixed file name */
          strcat(data, "file.txt");
      }
      return data;
  }
  
  /* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */
  char * goodG2B2Source(char * data)
  {
      if(goodG2B2Global)
      {
          /* FIX: Use a fixed file name */
          strcat(data, "file.txt");
      }
      return data;
  }
  
  #endif /* OMITGOOD */
  
  } /* close namespace */
  