[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[groff] 03/03: Fix SEGV arising from recursing destructor.
From: |
G. Branden Robinson |
Subject: |
[groff] 03/03: Fix SEGV arising from recursing destructor. |
Date: |
Tue, 29 Sep 2020 04:40:02 -0400 (EDT) |
gbranden pushed a commit to branch master
in repository groff.
commit c788cf8c6bbe939fa11f7ec032e525a7e33f41b6
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Tue Sep 29 07:02:25 2020 +1000
Fix SEGV arising from recursing destructor.
* src/roff/troff/node.h (output_file): Add class member `is_dying` to
track whether destructor has already been entered; initialize false.
* src/roff/troff/node.cpp (real_output_file::~real_output_file): Set
`is_dying` true when destructor entered.
* src/roff/troff/div.cpp (cleanup_and_exit): Only delete
`the_output` object if it is not already being destroyed.
Thanks to "hackerb9" for reporting the problem. Problem appears to date
back to groff 1.02 (June 1991) or earlier.
Fixes <https://savannah.gnu.org/bugs/index.php?59202>.
---
ChangeLog | 14 ++++++++++++++
src/roff/troff/div.cpp | 5 ++++-
src/roff/troff/node.cpp | 2 ++
src/roff/troff/node.h | 1 +
4 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index ec58216..f27a875 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,22 @@
2020-09-29 G. Branden Robinson <g.branden.robinson@gmail.com>
+ Fix SEGV arising from recursing destructor.
+
+ * src/roff/troff/node.h (output_file): Add class member
+ `is_dying` to track whether destructor has already been entered;
+ initialize false.
+ * src/roff/troff/node.cpp (real_output_file::~real_output_file):
+ Set `is_dying` true when destructor entered.
+ * src/roff/troff/div.cpp (cleanup_and_exit): Only delete
+ `the_output` object if it is not already being destroyed.
* src/roff/groff/tests/regression_savannah_59202.sh: Add test.
* src/roff/groff/groff.am (groff_TESTS): Run test.
+ Thanks to "hackerb9" for reporting the problem. Problem appears
+ to date back to groff 1.02 (June 1991) or earlier.
+
+ Fixes <https://savannah.gnu.org/bugs/index.php?59202>.
+
2020-09-28 G. Branden Robinson <g.branden.robinson@gmail.com>
* tmac/an-old.tmac (register setup): Condition decisions on
diff --git a/src/roff/troff/div.cpp b/src/roff/troff/div.cpp
index 920a38c..2bb0dc4 100644
--- a/src/roff/troff/div.cpp
+++ b/src/roff/troff/div.cpp
@@ -559,7 +559,10 @@ void cleanup_and_exit(int exit_code)
{
if (the_output) {
the_output->trailer(topdiv->get_page_length());
- delete the_output;
+ // If we're already dying, don't call the_output's destructor. See
+ // node.cpp:real_output_file::~real_output_file().
+ if (!the_output->is_dying)
+ delete the_output;
}
FLUSH_INPUT_PIPE(STDIN_FILENO);
exit(exit_code);
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index d696865..37260bd 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -1656,6 +1656,8 @@ real_output_file::~real_output_file()
{
if (!fp)
return;
+ // Prevent destructor from recursing; see div.cpp:cleanup_and_exit().
+ is_dying = true;
// To avoid looping, set fp to 0 before calling fatal().
if (ferror(fp) || fflush(fp) < 0) {
fp = 0;
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 15b654d..e1c1960 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -626,6 +626,7 @@ class output_file {
char make_g_plus_plus_shut_up;
public:
output_file();
+ bool is_dying = false;
virtual ~output_file();
virtual void trailer(vunits);
virtual void flush() = 0;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [groff] 03/03: Fix SEGV arising from recursing destructor.,
G. Branden Robinson <=