summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorwl <wl>2010-12-19 20:47:38 +0000
committerwl <wl>2010-12-19 20:47:38 +0000
commitfa1faa789de9aafcdff1575c4e3f56ed96929a22 (patch)
tree8c18cd08a8946476160606c4e3a98a3e1b922ddb /src
parent81d80a6f71cc6d6fbd3d1111498318fb22a6857a (diff)
downloadgroff-fa1faa789de9aafcdff1575c4e3f56ed96929a22.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/roff/troff/charinfo.h6
-rw-r--r--src/roff/troff/input.cpp38
2 files changed, 34 insertions, 10 deletions
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;