gbranden pushed a commit to branch master
in repository groff.

commit 17883bb19d37a873d0a8f036dabfffaf489ff592
Author: Bruno Haible <[email protected]>
AuthorDate: Sun Aug 2 13:54:42 2026 +0200

    eqn: Fix undefined behaviour, part 2.
    
    This change fixes these two ASAN findings:
    
    ERROR: AddressSanitizer: alloc-dealloc-mismatch (malloc vs operator delete 
[]) on 0x751c9b5e1010
        #0 0x5943b9f60e9d in operator delete[](void*) 
/home/runner/work/llvm-project/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:179:46
        #1 0x5943b9f6fb6c in argument_macro_input::~argument_macro_input() 
/devel/groff/src/preproc/eqn/lex.cpp:558:5
        #2 0x5943b9f6fc14 in argument_macro_input::~argument_macro_input() 
/devel/groff/src/preproc/eqn/lex.cpp:556:1
        #3 0x5943b9f713b9 in get_char() 
/devel/groff/src/preproc/eqn/lex.cpp:619:7
        #4 0x5943b9f71c33 in get_token(int) 
/devel/groff/src/preproc/eqn/lex.cpp:817:11
        #5 0x5943b9f71979 in yylex() 
/devel/groff/src/preproc/eqn/lex.cpp:1198:14
        #6 0x5943b9fbbb20 in yyparse() 
/devel/groff/src/preproc/eqn/eqn.cpp:1390:16
        #7 0x5943b9f6533d in do_file(_IO_FILE*, char const*) 
/devel/groff/src/preproc/eqn/main.cpp:155:7
        #8 0x5943b9f63338 in main /devel/groff/src/preproc/eqn/main.cpp:483:5
    
    0x751c9b5e1010 is located 0 bytes inside of 35-byte region 
[0x751c9b5e1010,0x751c9b5e1033)
    allocated by thread T0 here:
        #0 0x5943b9f1d394 in malloc 
/home/runner/work/llvm-project/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:67:3
        #1 0x5943b9fd5497 in strsave(char const*) 
/devel/groff/src/libs/libgroff/strsave.cpp:36:33
        #2 0x5943b9f758c3 in interpolate_macro_with_args(char const*) 
/devel/groff/src/preproc/eqn/lex.cpp:790:17
        #3 0x5943b9f721e6 in get_token(int) 
/devel/groff/src/preproc/eqn/lex.cpp:876:8
        #4 0x5943b9f71979 in yylex() 
/devel/groff/src/preproc/eqn/lex.cpp:1198:14
        #5 0x5943b9fbbb20 in yyparse() 
/devel/groff/src/preproc/eqn/eqn.cpp:1390:16
        #6 0x5943b9f6533d in do_file(_IO_FILE*, char const*) 
/devel/groff/src/preproc/eqn/main.cpp:155:7
        #7 0x5943b9f63338 in main /devel/groff/src/preproc/eqn/main.cpp:483:5
    
    SUMMARY: AddressSanitizer: alloc-dealloc-mismatch 
/devel/groff/src/preproc/eqn/lex.cpp:558:5 in 
argument_macro_input::~argument_macro_input()
    
    ERROR: AddressSanitizer: alloc-dealloc-mismatch (malloc vs operator delete 
[]) on 0x7425fc5e3df0
        #0 0x5f7f9297fe9d in operator delete[](void*) 
/home/runner/work/llvm-project/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:179:46
        #1 0x5f7f9298ebab in argument_macro_input::~argument_macro_input() 
/devel/groff/src/preproc/eqn/lex.cpp:559:3
        #2 0x5f7f9298ec04 in argument_macro_input::~argument_macro_input() 
/devel/groff/src/preproc/eqn/lex.cpp:556:1
        #3 0x5f7f929903a9 in get_char() 
/devel/groff/src/preproc/eqn/lex.cpp:619:7
        #4 0x5f7f92990c23 in get_token(int) 
/devel/groff/src/preproc/eqn/lex.cpp:817:11
        #5 0x5f7f92990969 in yylex() 
/devel/groff/src/preproc/eqn/lex.cpp:1198:14
        #6 0x5f7f929dab10 in yyparse() 
/devel/groff/src/preproc/eqn/eqn.cpp:1390:16
        #7 0x5f7f9298433d in do_file(_IO_FILE*, char const*) 
/devel/groff/src/preproc/eqn/main.cpp:155:7
        #8 0x5f7f92982338 in main /devel/groff/src/preproc/eqn/main.cpp:483:5
    
    0x7425fc5e3df0 is located 0 bytes inside of 21-byte region 
[0x7425fc5e3df0,0x7425fc5e3e05)
    allocated by thread T0 here:
        #0 0x5f7f9293c394 in malloc 
/home/runner/work/llvm-project/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:67:3
        #1 0x5f7f929f4487 in strsave(char const*) 
/devel/groff/src/libs/libgroff/strsave.cpp:36:33
        #2 0x5f7f9298ded4 in argument_macro_input::argument_macro_input(char 
const*, unsigned long, char**, input*) 
/devel/groff/src/preproc/eqn/lex.cpp:542:11
        #3 0x5f7f92994ae7 in interpolate_macro_with_args(char const*) 
/devel/groff/src/preproc/eqn/lex.cpp:804:23
        #4 0x5f7f929911d6 in get_token(int) 
/devel/groff/src/preproc/eqn/lex.cpp:876:8
        #5 0x5f7f92990969 in yylex() 
/devel/groff/src/preproc/eqn/lex.cpp:1198:14
        #6 0x5f7f929dab10 in yyparse() 
/devel/groff/src/preproc/eqn/eqn.cpp:1390:16
        #7 0x5f7f9298433d in do_file(_IO_FILE*, char const*) 
/devel/groff/src/preproc/eqn/main.cpp:155:7
        #8 0x5f7f92982338 in main /devel/groff/src/preproc/eqn/main.cpp:483:5
    
    SUMMARY: AddressSanitizer: alloc-dealloc-mismatch 
/devel/groff/src/preproc/eqn/lex.cpp:559:3 in 
argument_macro_input::~argument_macro_input()
    
    * src/preproc/eqn/lex.cpp (argument_macro_input::~argument_macro_input): 
Free
    the s field and the elements of the argv field using free(), not delete[].
---
 src/preproc/eqn/lex.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/preproc/eqn/lex.cpp b/src/preproc/eqn/lex.cpp
index e14a49d04..652d2292b 100644
--- a/src/preproc/eqn/lex.cpp
+++ b/src/preproc/eqn/lex.cpp
@@ -380,11 +380,11 @@ class top_input : public macro_input {
 static const size_t eqn_macro_maximum_arg_count = 9;
 
 class argument_macro_input : public input {
-  char *s;
+  char *s;                                 // to be freed with free()
   char *p;
   char *ap;
   size_t argc;
-  char *argv[eqn_macro_maximum_arg_count];
+  char *argv[eqn_macro_maximum_arg_count]; // elements to be freed with free()
 public:
   argument_macro_input(const char *, size_t, char **, input *);
   ~argument_macro_input();
@@ -555,8 +555,8 @@ argument_macro_input::argument_macro_input(const char 
*body, size_t ac,
 argument_macro_input::~argument_macro_input()
 {
   for (size_t i = 0; i < argc; i++)
-    delete[] argv[i];
-  delete[] s;
+    free(argv[i]);
+  free(s);
 }
 
 int argument_macro_input::get()

_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to