summaryrefslogtreecommitdiff
path: root/src/libs
diff options
context:
space:
mode:
authorG. Branden Robinson <g.branden.robinson@gmail.com>2021-09-23 13:02:35 +1000
committerG. Branden Robinson <g.branden.robinson@gmail.com>2021-09-23 15:14:09 +1000
commit7800cbe9951163327a0224fa7addeea243d7585e (patch)
tree8f84649cb7abfce5bee6596715af4c6259e4b2f2 /src/libs
parent35f26ea2b71be984b5d5a20c43d2a6471c553437 (diff)
downloadgroff-git-7800cbe9951163327a0224fa7addeea243d7585e.tar.gz
[libgroff]: Validate font description files more.
[libgroff]: Perform more font description file validation. Our documentation said that the `name` directive was mandatory but we didn't actually enforce this. Also be more specific in our complaints of ill-formedness. * src/libs/libgroff/font.cpp (font::load): Add local Boolean variable `saw_name_directive`. Rename `had_charset` to `saw_charset_directive` for symmetry. Emit distinct diagnostics for `spacewidth` and `slant` directives having a missing, non-numeric, or out-of-range argument. Emit diagnostic if the file lacks a `name` directive.
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/libgroff/font.cpp55
1 files changed, 40 insertions, 15 deletions
diff --git a/src/libs/libgroff/font.cpp b/src/libs/libgroff/font.cpp
index a194457d6..b774fe7a1 100644
--- a/src/libs/libgroff/font.cpp
+++ b/src/libs/libgroff/font.cpp
@@ -771,6 +771,7 @@ bool font::load(bool load_header_only)
text_file t(fp, path);
t.silent = load_header_only;
char *p = 0;
+ bool saw_name_directive = false;
while (t.next_line()) {
p = strtok(t.buf, WS);
if (strcmp(p, "name") == 0) {
@@ -784,13 +785,21 @@ bool font::load(bool load_header_only)
" argument '%2'", name, p);
return false;
}
+ saw_name_directive = true;
}
else if (strcmp(p, "spacewidth") == 0) {
p = strtok(0, WS);
int n;
- if (0 == p || sscanf(p, "%d", &n) != 1 || n <= 0) {
- t.error("argument to 'spacewidth' directive is missing or"
- " invalid");
+ if (0 == p) {
+ t.error("missing argument to 'spacewidth' directive");
+ return false;
+ }
+ if (sscanf(p, "%d", &n) != 1) {
+ t.error("invalid argument '%1' to 'spacewidth' directive", p);
+ return false;
+ }
+ if (n <= 0) {
+ t.error("'spacewidth' argument '%1' out of range", n);
return false;
}
space_width = n;
@@ -798,8 +807,16 @@ bool font::load(bool load_header_only)
else if (strcmp(p, "slant") == 0) {
p = strtok(0, WS);
double n;
- if (0 == p || sscanf(p, "%lf", &n) != 1 || n >= 90.0 || n <= -90.0) {
- t.error("argument to 'slant' directive is missing or invalid");
+ if (0 == p) {
+ t.error("missing argument to 'slant' directive");
+ return false;
+ }
+ if (sscanf(p, "%lf", &n) != 1) {
+ t.error("invalid argument '%1' to 'slant' directive", p);
+ return false;
+ }
+ if (n >= 90.0 || n <= -90.0) {
+ t.error("'slant' directive argument '%1' out of range", n);
return false;
}
slant = n;
@@ -828,7 +845,7 @@ bool font::load(bool load_header_only)
else if (strcmp(p, "internalname") == 0) {
p = strtok(0, WS);
if (0 == p) {
- t.error("argument to 'internalname' directive is missing");
+ t.error("missing argument to 'internalname' directive");
return false;
}
internalname = new char[strlen(p) + 1];
@@ -840,12 +857,13 @@ bool font::load(bool load_header_only)
else if (strcmp(p, "kernpairs") != 0 && strcmp(p, "charset") != 0) {
char *directive = p;
p = strtok(0, "\n");
- handle_unknown_font_command(directive, trim_arg(p), t.path, t.lineno);
+ handle_unknown_font_command(directive, trim_arg(p), t.path,
+ t.lineno);
}
else
break;
}
- bool had_charset = false;
+ bool saw_charset_directive = false;
char *directive = p;
t.recognize_comments = false;
while (directive) {
@@ -883,7 +901,7 @@ bool font::load(bool load_header_only)
else if (strcmp(directive, "charset") == 0) {
if (load_header_only)
return true;
- had_charset = true;
+ saw_charset_directive = true;
glyph *last_glyph = 0;
for (;;) {
if (!t.next_line()) {
@@ -899,7 +917,8 @@ bool font::load(bool load_header_only)
}
if (p[0] == '"') {
if (last_glyph == 0) {
- t.error("first entry in 'charset' section is an alias");
+ t.error("first entry '%1' in 'charset' subsection is an"
+ " alias", nm);
return false;
}
if (strcmp(nm, "---") == 0) {
@@ -983,19 +1002,25 @@ bool font::load(bool load_header_only)
}
}
else {
- t.error("unrecognized directive '%1' after 'kernpairs' or"
- " 'charset' directive", directive);
+ t.error("unrecognized font description directive '%1' after"
+ " 'kernpairs' or 'charset'", directive);
return false;
}
}
compact();
- if (!is_unicode && !had_charset) {
- t.error("missing 'charset' directive");
+ t.lineno = 0;
+ if (!saw_name_directive) {
+ t.error("font description 'name' directive missing");
+ return false;
+ }
+ if (!is_unicode && !saw_charset_directive) {
+ t.error("font description 'charset' subsection missing");
return false;
}
if (space_width == 0) {
if (zoom)
- space_width = scale_round(unitwidth, res, 72 * 3 * sizescale, zoom);
+ space_width = scale_round(unitwidth, res, 72 * 3 * sizescale,
+ zoom);
else
space_width = scale_round(unitwidth, res, 72 * 3 * sizescale);
}