These changes were committed to trunk.
From: Robert Dubner <[email protected]>
Date: Wed, 30 Jul 2025 09:54:13 -0400
Subject: [PATCH] cobol: Eliminate various errors. [PR120244]
The following coding errors were located by running extended tests
through valgrind. These changes repair the errors.
gcc/cobol/ChangeLog:
PR cobol/120244
* genapi.cc (get_level_88_domain): Increase array size for final
byte.
(psa_FldLiteralA): Use correct length in build_string_literal
call.
* scan.l: Use a loop instead of std:transform to avoid EOF
overrun.
* scan_ante.h (binary_integer_usage): Use a variable-length
buffer.
---
gcc/cobol/genapi.cc | 12 ++++++++++--
gcc/cobol/scan.l | 21 +++++++++++----------
gcc/cobol/scan_ante.h | 5 ++++-
3 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index 666802ea137..20341643182 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -531,6 +531,14 @@ get_level_88_domain(size_t parent_capacity,
cbl_field_t *var, size_t &returned_s
free(stream);
domain += 1;
}
+
+ if( returned_size >= retval_capacity)
+ {
+ retval_capacity *= 2;
+ retval = static_cast<char *>(xrealloc(retval, retval_capacity));
+ }
+
+ gcc_assert(returned_size < retval_capacity);
retval[returned_size++] = '\0';
return retval;
}
@@ -16765,9 +16773,9 @@ psa_FldLiteralA(struct cbl_field_t *field )
vs_file_static);
actually_create_the_static_field(
field,
- build_string_literal(field->data.capacity+1,
+ build_string_literal(field->data.capacity,
buffer),
- field->data.capacity+1,
+ field->data.capacity,
field->data.initial,
NULL_TREE,
field->var_decl_node);
diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l
index 2da38d82a2e..ba4c044e15e 100644
--- a/gcc/cobol/scan.l
+++ b/gcc/cobol/scan.l
@@ -1673,16 +1673,17 @@ B-SHIFT-RC
p += 2;
while( ISSPACE(*p) ) p++;
cbl_name_t name2;
- std::transform( p, p + sizeof(name2), name2,
- []( char ch ) {
- switch(ch) {
- case '-':
- case '_': return ch;
- default:
- if( ISALNUM(ch) ) return ch;
- }
- return '\0';
- } );
+ const char *pend = p + sizeof(name2);
+ char *pout = name2;
+ while( p < pend ) {
+ char ch = *p++;
+ if( ISALNUM(ch) || ch == '-' || ch == '_' ) {
+ *pout++ = ch;
+ } else {
+ *pout++ = '\0';
+ break;
+ }
+ }
symbol_elem_t *e = symbol_file(PROGRAM, name2);
/*
* For NAME IN FILENAME, we want the parser to handle
it.
diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index 19ceb2b4a08..c00826d652f 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -609,7 +609,9 @@ static const std::map <std::string, bint_t >
binary_integers {
static int
binary_integer_usage( const char name[]) {
- cbl_name_t uname = {};
+ // uname can't be cbl_name_t, because at this point name[] might have
more
+ // than sizeof(cbl_name_t) characters. The length check comes later.
+ char *uname = xstrdup(name);
std::transform(name, name + strlen(name), uname, ftoupper);
dbgmsg("%s:%d: checking %s in %zu keyword_aliases",
@@ -628,6 +630,7 @@ binary_integer_usage( const char name[]) {
yylval.computational.signable = p->second.signable;
dbgmsg("%s:%d: %s has type %d", __func__, __LINE__,
uname, p->second.type );
+ free(uname);
return p->second.token;
}
--
2.34.1