diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | src/roff/troff/charinfo.h | 6 | ||||
-rw-r--r-- | src/roff/troff/input.cpp | 38 |
3 files changed, 43 insertions, 10 deletions
@@ -1,3 +1,12 @@ +2010-12-19 Werner LEMBERG <wl@gnu.org> + + Protect `.class' against cyclic nesting. + + * src/roff/troff/charinfo.h (charinfo::contains): Add optional + boolean argument. + * src/roff/troff/input.cpp (define_class, charinfo::contains): Check + for cyclic nesting. + 2010-12-18 Werner LEMBERG <wl@gnu.org> Improve CJK support with new values for `.cflags'. diff --git a/src/roff/troff/charinfo.h b/src/roff/troff/charinfo.h index 544f24f2..3e07662f 100644 --- a/src/roff/troff/charinfo.h +++ b/src/roff/troff/charinfo.h @@ -105,9 +105,9 @@ public: void add_to_class(int, int); void add_to_class(charinfo *); bool is_class(); - bool contains(int); - bool contains(symbol); - bool contains(charinfo *); + bool contains(int, bool = false); + bool contains(symbol, bool = false); + bool contains(charinfo *, bool = false); }; charinfo *get_charinfo(symbol); diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 4d579f80..b6e73ed7 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -6788,8 +6788,14 @@ void define_class() child1 = child2 = 0; } else if (child1 != 0) { - if (child1->is_class()) + if (child1->is_class()) { + if (ci == child1) { + warning(WARN_SYNTAX, "invalid cyclic class nesting"); + skip_line(); + return; + } ci->add_to_class(child1); + } else { int u1 = child1->get_unicode_code(); if (u1 < 0) { @@ -6812,8 +6818,14 @@ void define_class() } } if (child1 != 0) { - if (child1->is_class()) + if (child1->is_class()) { + if (ci == child1) { + warning(WARN_SYNTAX, "invalid cyclic class nesting"); + skip_line(); + return; + } ci->add_to_class(child1); + } else { int u1 = child1->get_unicode_code(); if (u1 < 0) { @@ -8560,8 +8572,14 @@ int charinfo::get_number() return number; } -bool charinfo::contains(int c) +bool charinfo::contains(int c, bool already_called) { + if (already_called) { + warning(WARN_SYNTAX, + "cyclic nested class detected while processing character code %1", + c); + return false; + } std::vector<std::pair<int, int> >::const_iterator ranges_iter; ranges_iter = ranges.begin(); while (ranges_iter != ranges.end()) { @@ -8578,7 +8596,7 @@ bool charinfo::contains(int c) std::vector<charinfo *>::const_iterator nested_iter; nested_iter = nested_classes.begin(); while (nested_iter != nested_classes.end()) { - if ((*nested_iter)->contains(c)) + if ((*nested_iter)->contains(c, true)) return true; ++nested_iter; } @@ -8586,19 +8604,25 @@ bool charinfo::contains(int c) return false; } -bool charinfo::contains(symbol s) +bool charinfo::contains(symbol s, bool already_called) { + if (already_called) { + warning(WARN_SYNTAX, + "cyclic nested class detected while processing symbol %1", + s.contents()); + return false; + } const char *unicode = glyph_name_to_unicode(s.contents()); if (unicode != NULL && strchr(unicode, '_') == NULL) { char *ignore; int c = (int)strtol(unicode, &ignore, 16); - return contains(c); + return contains(c, true); } else return false; } -bool charinfo::contains(charinfo *) +bool charinfo::contains(charinfo *, bool) { // TODO return false; |