mirror of
https://github.com/lcn2/calc.git
synced 2025-08-19 01:13:27 +03:00
checkpoint on string realloc bug fix attempt
In preparation to fix issue #47, we: Fix a minor typo in `Makefile.config`. Move `stringindex(char *format, char *test)` from `str.c` into `codegen.c` as static function. Expand `STR_TABLECHUNK` from `1<<10` to `1<<16`. Identify with an XXX comment, a problematic `realloc()` call in the `addstr(STRINGHEAD *hp, char *str)` function of `str.c`. Move the `charstr(int ch)` in `str.c` above the only function that uses it, `addliteral(char *str)`, and make it a static function. Improved comments about return values for `str.c` functions that work on STRINGHEAD pointers.
This commit is contained in:
@@ -1358,7 +1358,7 @@ COMMON_LDFLAGS= ${EXTRA_LDFLAGS}
|
|||||||
# For more info see: https://github.com/google/sanitizers/wiki/AddressSanitizer
|
# For more info see: https://github.com/google/sanitizers/wiki/AddressSanitizer
|
||||||
# See also: https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early
|
# See also: https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early
|
||||||
#
|
#
|
||||||
# The following Address Sanitizer (ASAN) are common to both REHL9.2 (Linux) and macOS 14.0.
|
# The following Address Sanitizer (ASAN) are common to both RHEL9.2 (Linux) and macOS 14.0.
|
||||||
#
|
#
|
||||||
# By default, the Address Sanitizer is NOT enabled, not compiled into calc.
|
# By default, the Address Sanitizer is NOT enabled, not compiled into calc.
|
||||||
# To enable the Address Sanitizer, uncomment the appropriate lines in Makefile.local !!!
|
# To enable the Address Sanitizer, uncomment the appropriate lines in Makefile.local !!!
|
||||||
|
36
codegen.c
36
codegen.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* codegen - module to generate opcodes from the input tokens
|
* codegen - module to generate opcodes from the input tokens
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999-2007,2017,2021-2023 David I. Bell and Ernest Bowen
|
* Copyright (C) 1999-2007,2017,2021-2023,2025 David I. Bell and Ernest Bowen
|
||||||
*
|
*
|
||||||
* Primary author: David I. Bell
|
* Primary author: David I. Bell
|
||||||
*
|
*
|
||||||
@@ -2425,6 +2425,40 @@ getfilename(char *name, size_t namelen, bool *once)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Useful routine to return the index of one string within another one
|
||||||
|
* which has the format: "str1\000str2\000str3\000...strn\0\0". Index starts
|
||||||
|
* at one for the first string. Returns zero if the string being checked
|
||||||
|
* is not contained in the formatted string.
|
||||||
|
*
|
||||||
|
* Be sure to use \000 instead of \0. ANSI-C compilers interpret "foo\0foo..."
|
||||||
|
* as "foo\017oo...".
|
||||||
|
*
|
||||||
|
* given:
|
||||||
|
* format string formatted into substrings
|
||||||
|
* test string to be found in formatted string
|
||||||
|
*/
|
||||||
|
S_FUNC long
|
||||||
|
stringindex(char *format, char *test)
|
||||||
|
{
|
||||||
|
long index; /* found index */
|
||||||
|
size_t len; /* length of current piece of string */
|
||||||
|
size_t testlen; /* length of test string */
|
||||||
|
|
||||||
|
testlen = strlen(test);
|
||||||
|
index = 1;
|
||||||
|
while (*format) {
|
||||||
|
len = strlen(format);
|
||||||
|
if ((len == testlen) && (*format == *test) &&
|
||||||
|
(strcmp(format, test) == 0))
|
||||||
|
return index;
|
||||||
|
format += (len + 1);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the show command to display useful information
|
* Read the show command to display useful information
|
||||||
*/
|
*/
|
||||||
|
98
str.c
98
str.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* str - string list routines
|
* str - string list routines
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999-2007,2021-2023 David I. Bell and Ernest Bowen
|
* Copyright (C) 1999-2007,2021-2023,2025 David I. Bell and Ernest Bowen
|
||||||
*
|
*
|
||||||
* Primary author: David I. Bell
|
* Primary author: David I. Bell
|
||||||
*
|
*
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
#include "banned.h" /* include after system header <> includes */
|
#include "banned.h" /* include after system header <> includes */
|
||||||
|
|
||||||
|
|
||||||
#define STR_TABLECHUNK (1<<10) /* how often to reallocate string table */
|
#define STR_TABLECHUNK (1<<16) /* how often to reallocate string literal table */
|
||||||
#define STR_CHUNK (1<<16) /* size of string storage allocation */
|
#define STR_CHUNK (1<<16) /* size of string storage allocation */
|
||||||
#define OCTET_VALUES 256 /* number of different values in a OCTET */
|
#define OCTET_VALUES 256 /* number of different values in a OCTET */
|
||||||
#define STR_UNIQUE (1<<7) /* size of string to allocate separately */
|
#define STR_UNIQUE (1<<7) /* size of string to allocate separately */
|
||||||
@@ -97,6 +97,10 @@ initstr(STRINGHEAD *hp)
|
|||||||
* given:
|
* given:
|
||||||
* hp header of string storage
|
* hp header of string storage
|
||||||
* str string to be added
|
* str string to be added
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* != NULL ==> pointer to newly added string
|
||||||
|
* NULL ==> unable to add string
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
addstr(STRINGHEAD *hp, char *str)
|
addstr(STRINGHEAD *hp, char *str)
|
||||||
@@ -113,6 +117,10 @@ addstr(STRINGHEAD *hp, char *str)
|
|||||||
/* alloc + 1 guard paranoia */
|
/* alloc + 1 guard paranoia */
|
||||||
newsize = len + STR_CHUNK + hp->h_used + hp->h_avail + 1;
|
newsize = len + STR_CHUNK + hp->h_used + hp->h_avail + 1;
|
||||||
/* alloc + 1 guard paranoia */
|
/* alloc + 1 guard paranoia */
|
||||||
|
/*
|
||||||
|
* XXX - doing a realloc can cause problems if the larger list has to be
|
||||||
|
* relocated due the recalloc() call and stuff point to old location
|
||||||
|
*/
|
||||||
list = (char *)realloc(hp->h_list, newsize + 1);
|
list = (char *)realloc(hp->h_list, newsize + 1);
|
||||||
if (list == NULL)
|
if (list == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -130,35 +138,6 @@ addstr(STRINGHEAD *hp, char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return a null-terminated string which consists of a single character.
|
|
||||||
* The table is initialized on the first call.
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
charstr(int ch)
|
|
||||||
{
|
|
||||||
char *cp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (chartable == NULL) {
|
|
||||||
/* alloc + 1 guard paranoia */
|
|
||||||
cp = (char *)malloc((OCTET_VALUES + 1)*2);
|
|
||||||
if (cp == NULL) {
|
|
||||||
math_error("Cannot allocate character table");
|
|
||||||
not_reached();
|
|
||||||
}
|
|
||||||
for (i = 0; i < OCTET_VALUES; i++) {
|
|
||||||
*cp++ = (char)i;
|
|
||||||
*cp++ = '\0';
|
|
||||||
}
|
|
||||||
chartable = cp - (OCTET_VALUES*2);
|
|
||||||
*cp++ = '\0'; /* guard paranoia */
|
|
||||||
*cp++ = '\0'; /* guard paranoia */
|
|
||||||
}
|
|
||||||
return &chartable[(ch & 0xff) * 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a string with the specified name and return its number in the
|
* Find a string with the specified name and return its number in the
|
||||||
* string list. The first string is numbered zero. Minus one is returned
|
* string list. The first string is numbered zero. Minus one is returned
|
||||||
@@ -166,7 +145,11 @@ charstr(int ch)
|
|||||||
*
|
*
|
||||||
* given:
|
* given:
|
||||||
* hp header of string storage
|
* hp header of string storage
|
||||||
* str string to be added
|
* str string to be searched for
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* >= 0 ==> index of string
|
||||||
|
* -1 ==> unable to find string
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
findstr(STRINGHEAD *hp, char *str)
|
findstr(STRINGHEAD *hp, char *str)
|
||||||
@@ -200,6 +183,10 @@ findstr(STRINGHEAD *hp, char *str)
|
|||||||
* given:
|
* given:
|
||||||
* hp header of string storage
|
* hp header of string storage
|
||||||
* n string index
|
* n string index
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* non-empty string ==> string at index n
|
||||||
|
* "" ==> no strings or string at index n
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
namestr(STRINGHEAD *hp, long n)
|
namestr(STRINGHEAD *hp, long n)
|
||||||
@@ -219,36 +206,31 @@ namestr(STRINGHEAD *hp, long n)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Useful routine to return the index of one string within another one
|
* Return a null-terminated string which consists of a single character.
|
||||||
* which has the format: "str1\000str2\000str3\000...strn\0\0". Index starts
|
* The table is initialized on the first call.
|
||||||
* at one for the first string. Returns zero if the string being checked
|
|
||||||
* is not contained in the formatted string.
|
|
||||||
*
|
|
||||||
* Be sure to use \000 instead of \0. ANSI-C compilers interpret "foo\0foo..."
|
|
||||||
* as "foo\017oo...".
|
|
||||||
*
|
|
||||||
* given:
|
|
||||||
* format string formatted into substrings
|
|
||||||
* test string to be found in formatted string
|
|
||||||
*/
|
*/
|
||||||
long
|
S_FUNC char *
|
||||||
stringindex(char *format, char *test)
|
charstr(int ch)
|
||||||
{
|
{
|
||||||
long index; /* found index */
|
char *cp;
|
||||||
size_t len; /* length of current piece of string */
|
int i;
|
||||||
size_t testlen; /* length of test string */
|
|
||||||
|
|
||||||
testlen = strlen(test);
|
if (chartable == NULL) {
|
||||||
index = 1;
|
/* alloc + 1 guard paranoia */
|
||||||
while (*format) {
|
cp = (char *)malloc((OCTET_VALUES + 1)*2);
|
||||||
len = strlen(format);
|
if (cp == NULL) {
|
||||||
if ((len == testlen) && (*format == *test) &&
|
math_error("Cannot allocate character table");
|
||||||
(strcmp(format, test) == 0))
|
not_reached();
|
||||||
return index;
|
}
|
||||||
format += (len + 1);
|
for (i = 0; i < OCTET_VALUES; i++) {
|
||||||
index++;
|
*cp++ = (char)i;
|
||||||
|
*cp++ = '\0';
|
||||||
|
}
|
||||||
|
chartable = cp - (OCTET_VALUES*2);
|
||||||
|
*cp++ = '\0'; /* guard paranoia */
|
||||||
|
*cp++ = '\0'; /* guard paranoia */
|
||||||
}
|
}
|
||||||
return 0;
|
return &chartable[(ch & 0xff) * 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
4
str.h
4
str.h
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* str - string list routines
|
* str - string list routines
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999-2007,2014 David I. Bell
|
* Copyright (C) 1999-2007,2014,2025 David I. Bell
|
||||||
*
|
*
|
||||||
* Calc is open software; you can redistribute it and/or modify it under
|
* Calc is open software; you can redistribute it and/or modify it under
|
||||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||||
@@ -59,9 +59,7 @@ E_FUNC void initstr(STRINGHEAD *hp);
|
|||||||
E_FUNC char *addstr(STRINGHEAD *hp, char *str);
|
E_FUNC char *addstr(STRINGHEAD *hp, char *str);
|
||||||
E_FUNC char *namestr(STRINGHEAD *hp, long n);
|
E_FUNC char *namestr(STRINGHEAD *hp, long n);
|
||||||
E_FUNC int findstr(STRINGHEAD *hp, char *str);
|
E_FUNC int findstr(STRINGHEAD *hp, char *str);
|
||||||
E_FUNC char *charstr(int ch);
|
|
||||||
E_FUNC char *addliteral(char *str);
|
E_FUNC char *addliteral(char *str);
|
||||||
E_FUNC long stringindex(char *str1, char *str2);
|
|
||||||
E_FUNC STRING *stralloc(void);
|
E_FUNC STRING *stralloc(void);
|
||||||
E_FUNC long addstring(char *str, size_t len);
|
E_FUNC long addstring(char *str, size_t len);
|
||||||
E_FUNC STRING *charstring(int ch);
|
E_FUNC STRING *charstring(int ch);
|
||||||
|
Reference in New Issue
Block a user