From 91be4c1af44eb104b0feae69c80291b40bbb000b Mon Sep 17 00:00:00 2001
From: "James K. Lowden" <jklowden@symas.com>
Date: Fri, 27 Dec 2024 15:18:53 -0500
Subject: [PATCH] free a buffer

---
 gcc/cobol/cdf-copy.cc    |  10 +-
 gcc/cobol/copybook-old.h | 213 ---------------------------------------
 gcc/cobol/copybook.h     |  25 ++---
 gcc/cobol/lexio.cc       |  13 +--
 gcc/cobol/util.cc        |   1 +
 5 files changed, 22 insertions(+), 240 deletions(-)
 delete mode 100644 gcc/cobol/copybook-old.h

diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc
index 8cde94ec4bd9..df535bcc528f 100644
--- a/gcc/cobol/cdf-copy.cc
+++ b/gcc/cobol/cdf-copy.cc
@@ -273,19 +273,21 @@ copybook_elem_t::open_file( const char directory[], bool literally ) {
     if( 0 == strcmp(".", directory) ) directory = NULL;
   }
 
-  static char path[PATH_MAX];
+  char *path = NULL;
 
   if( directory || library ) {
     if( directory && library ) {
-      snprintf( path, sizeof(path), "%s/%s/%s", directory, library, source );
+      path = xasprintf( "%s/%s/%s", directory, library, source );
     } else {
       const char *dir = directory? directory : library;
-      snprintf( path, sizeof(path), "%s/%s", dir, source );
+      path = xasprintf( "%s/%s", dir, source );
     }  
   } else {
-    snprintf( path, sizeof(path), "%s", source );
+    path = xasprintf( "%s", source );
   }
 
+  gcc_assert(path);
+  
   if( literally ) {
     if( yydebug ) {
       cbl_warnx("copybook_elem_t::open_file: trying %s", path);
diff --git a/gcc/cobol/copybook-old.h b/gcc/cobol/copybook-old.h
deleted file mode 100644
index 56bbc36ce08e..000000000000
--- a/gcc/cobol/copybook-old.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2021-2024 Symas Corporation
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following disclaimer
- *   in the documentation and/or other materials provided with the
- *   distribution.
- * * Neither the name of the Symas Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from
- *   this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <algorithm>
-#include <deque>
-#include <list>
-#include <stack>
-
-#include <assert.h>
-#include <ctype.h>
-#include <libgen.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-FILE * copy_mode_start();
-
-const char * cobol_filename();
-bool cobol_filename( const char *name, ino_t inode );
-
-void scanner_parsing( int token, bool tf );
-void scanner_parsing_toggle();
-void scanner_parsing_pop();
-
-/*
- * COPY support On encountering a COPY statement, the parser continues
- * to parse, collecting the replacement values, if any.  At statement
- * end (at the period), the system rearranges input to apply the
- * replacements before the input text is read by the lexer.
- */
-
-enum replace_type_t { string_e, token_e, pseudo_e };
-
-struct copybook_replace_t {
-  replace_type_t type;
-  const char *src, *tgt;
-};
-
-struct copybook_elem_t {
-  bool suppress;
-  const char *source, *library;
-  static const char *extensions;
-  struct { bool source, library; } literally;
-  int  fd;
-  size_t nsubexpr;
-  std::deque<copybook_replace_t> replacements;
-
-  copybook_elem_t()
-    : suppress(false)
-    , source(NULL)
-    , library(NULL)
-    , fd(-1)
-    , nsubexpr(0)
-    , regex_text(NULL)
-  {
-    literally = {};
-  }
-  explicit copybook_elem_t( char src[] )
-    : suppress(false)
-    , source(src)
-    , library(NULL)
-    , fd(-1)
-    , nsubexpr(0)
-    , regex_text(NULL)
-  {
-    literally = {};
-  }
-
-  void clear() {
-    suppress = false;
-    nsubexpr = 0;
-    if( fd ) close(fd);
-    fd = -1;
-    // TODO: free src & tgt
-    replacements.clear();
-  }
-
-  int open_file( const char dir[], bool literally = false );
-  void extensions_add( const char ext[], const char alt[] );
-  
-  static inline bool is_quote( const char ch ) {
-    return ch == '\'' || ch == '"';
-  }
-  static inline bool quoted( const char name[] ) {
-    assert(name);
-    return is_quote(name[0]);
-  }
-  static char * dequote( const char orig[] ) {
-    assert(quoted(orig));
-    auto name = (char*)calloc(1, strlen(orig));
-    assert(name);
-    char *tgt = name;
-
-    // For a literal name, we de-quote it and try to open it in the
-    // current working directory.  The COBOL literal could include
-    // (escaped) doubled quotes, which we reduce to one.
-    for( const char *src = orig; src < orig + strlen(orig); ) {
-      if( is_quote(src[0]) ) {
-        if( src[0] == src[1] ) {
-          *tgt++ = *src++; // copy one of doubled quote
-        }
-        src++; // skip quote
-        continue;
-      }
-      *tgt++ = *src++;
-    }
-    *tgt = '\0';
-
-    return name;
-  }
-
-private:
-  char *regex_text;
-};
-
-class copybook_t {
-  std::list<const char *> directories;
-  copybook_elem_t book;
-
-  static const char * transform_name( const char input[] ) {
-    static char path[PATH_MAX];
-    const char *output = getenv(input);
-    if( !output ) {
-      auto einput = input + std::min(sizeof(path), strlen(input));
-      std::transform( input, einput, path,
-                      []( char ch ) { return toupper(ch); } );
-      output = getenv(path); // try uppercase of envar output
-      if( !output ) output = input; // keep original unmodified
-    }
-    if( false && output != path ) {
-      cbl_warnx("using copybook file '%s' from environment variable ''%s",
-            output, input);
-    }
-    return strdup(output);
-  }
-
- public:
-  copybook_t() { directories.push_back(NULL); }
-
-  void suppress( bool tf = true  ) { book.suppress = tf; }
-  bool suppressed()                { return book.suppress; }
-  void source( const char name[] ) {
-    book.literally.source = copybook_elem_t::quoted(name);
-    book.source = book.literally.source?
-      copybook_elem_t::dequote(name) : transform_name(name);
-  }
-  void library( const char name[] ) {
-    book.literally.library = copybook_elem_t::quoted(name);
-    book.library = book.literally.library?
-      copybook_elem_t::dequote(name) : transform_name(name);
-  }
-  bool replacement( replace_type_t type, const char src[], const char tgt[] ) {
-    copybook_replace_t elem = { type, src, tgt };
-    book.replacements.push_back(elem);
-    return true;
-  }
-
-  copybook_elem_t *current() { return &book; }
-
-  int open(const char name[]) {
-    int fd = -1;
-    book.clear();
-    this->source(name);
-
-    for( auto dir : directories ) {
-      if( false ) {
-        cbl_warnx("copybook_t::open( '%s' OF '%s' %s",
-              book.source, dir, book.literally.source? ", literally" : "" );
-      }
-      if( (fd = book.open_file(dir, book.literally.source)) != -1 ) break;
-    }
-    return fd;
-  }
-
-  const char * directory_add( const char name[] ) {
-    directories.push_back(name);
-    return name;
-  }
-  void extensions_add( const char ext[], const char alt[] );
-};
-
-extern copybook_t copybook;
-
diff --git a/gcc/cobol/copybook.h b/gcc/cobol/copybook.h
index 897be5707ab9..1cf32c5a0079 100644
--- a/gcc/cobol/copybook.h
+++ b/gcc/cobol/copybook.h
@@ -134,21 +134,22 @@ class copybook_t {
   std::list<const char *> directories;
   copybook_elem_t book;
 
-  static const char * transform_name( const char input[] ) {
-    static char path[PATH_MAX];
-    const char *output = getenv(input);
-    if( !output ) {
-      auto einput = input + std::min(sizeof(path), strlen(input));
-      std::transform( input, einput, path,
+  // Take copybook name from the environment, if defined, else use it verbatim.
+  static const char * transform_name( const char name[] ) {
+    char uname[ strlen(name) ];
+    const char *value = getenv(name);
+    if( !value ) {
+      auto ename = name + strlen(name);
+      std::transform( name, ename, uname,
                       []( char ch ) { return TOUPPER(ch); } );
-      output = getenv(path); // try uppercase of envar output
-      if( !output ) output = input; // keep original unmodified
+      value = getenv(uname); // try uppercase of envar name
+      if( !value ) value = name; // keep original unmodified
     }
-    if( false && output != path ) {
-      cbl_warnx("using copybook file '%s' from environment variable ''%s",
-            output, input);
+    if( false && value != uname ) {
+      cbl_warnx("using copybook file '%s' from environment variable '%s'",
+            value, name);
     }
-    return xstrdup(output);
+    return xstrdup(value);
   }
 
  public:
diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc
index 0c0a54dc1207..66197c766296 100644
--- a/gcc/cobol/lexio.cc
+++ b/gcc/cobol/lexio.cc
@@ -1256,12 +1256,6 @@ lexer_input( char buf[], int max_size, FILE *input ) {
   return output.size();
 }
 
-// The following code was originally in a cdf_text.h file.  But the only place
-// it was accessed was right here.  So I copied it here, and eliminated the
-// .h file.  RJD.
-
-// #include "cdf_text.h"
-
 static const char *
 find_filter( const char filter[] ) {
 
@@ -1277,9 +1271,7 @@ find_filter( const char filter[] ) {
     auto pend = std::find( p, eopath, ':' );
     if( *pend == ':' ) *pend++ = '\0';
 
-    static char name[PATH_MAX];
-
-    snprintf( name, sizeof(name), "%s/%s", p, filter );
+    char *name = xasprintf( "%s/%s", p, filter );
 
     if( 0 == access(name, X_OK) ) {
       return name;
@@ -1462,12 +1454,11 @@ cdftext::open_input( const char filename[] ) {
 
 int
 cdftext::open_output() {
-  static char stem[PATH_MAX];
   char *name = getenv("GCOBOL_TEMPDIR");
   int fd;
 
   if( name && 0 != strcmp(name, "/") ) {
-    sprintf(stem, "%sXXXXXX", name);
+    char * stem = xasprintf("%sXXXXXX", name);
     if( -1 == (fd = mkstemp(stem)) ) {
       cbl_err(EXIT_FAILURE,
           "error: could not open temporary file '%s' (%s)", 
diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc
index 0e93778c5a8a..db1c5fd0c96e 100644
--- a/gcc/cobol/util.cc
+++ b/gcc/cobol/util.cc
@@ -1971,6 +1971,7 @@ class unique_stack : public std::stack<input_file_t>
       } else {
 	cbl_warnx("warning: %s:%d: %m", __func__, __LINE__);
       }
+      free(wd);
     }
     return false;
   }
-- 
GitLab