aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2025-01-30 14:36:04 -0500
committerDavid Robillard <d@drobilla.net>2025-01-30 15:51:01 -0500
commitc6cb174e7085cd2a41ed0ab74bbcbd7963e68d9d (patch)
treed8c7ae3f1de156f95bbc5c2fc06d527f3dc446b3
parente7a120cddc8a72cfcc264c4cd83a0911d352e0a2 (diff)
downloadserd-c6cb174e7085cd2a41ed0ab74bbcbd7963e68d9d.tar.gz
serd-c6cb174e7085cd2a41ed0ab74bbcbd7963e68d9d.tar.bz2
serd-c6cb174e7085cd2a41ed0ab74bbcbd7963e68d9d.zip
Fix handling of some invalid EOF cases in lax mode
The return status of these tests unfortunately isn't consistent, so instead of testing for an exact exit status, instead check that the return status doesn't seem to be an abort() or other signal code (which are negative on Linux, while serdi itself never exits with a negative status).
-rw-r--r--NEWS3
-rw-r--r--src/n3.c12
-rw-r--r--test/meson.build7
-rwxr-xr-xtest/run_suite.py11
4 files changed, 23 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 0957f469..fa649066 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,9 @@
serd (0.32.5) unstable; urgency=medium
+ * Fix handling of some invalid EOF cases in lax mode
* Remove project and version number from man page OS field
- -- David Robillard <d@drobilla.net> Thu, 30 Jan 2025 19:32:12 +0000
+ -- David Robillard <d@drobilla.net> Thu, 30 Jan 2025 19:35:32 +0000
serd (0.32.4) stable; urgency=medium
diff --git a/src/n3.c b/src/n3.c
index 31dc5d45..3d4de079 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -354,11 +354,11 @@ read_STRING_LITERAL_LONG(SerdReader* const reader,
push_byte(reader, ref, c);
st = read_character(reader, ref, flags, (uint8_t)q2);
}
- } else if (c == EOF) {
- st = r_err(reader, SERD_ERR_BAD_SYNTAX, "end of file in long string\n");
- } else {
+ } else if (c > 0) {
st =
read_character(reader, ref, flags, (uint8_t)eat_byte_safe(reader, c));
+ } else {
+ return r_err(reader, SERD_ERR_BAD_SYNTAX, "end of file in long string\n");
}
}
@@ -735,7 +735,9 @@ read_IRIREF(SerdReader* const reader, Ref* const dest)
reader, SERD_ERR_BAD_SYNTAX, "invalid IRI character '%c'\n", c);
default:
- if (c <= 0x20) {
+ if (c <= 0) {
+ st = r_err(reader, SERD_ERR_BAD_SYNTAX, "unexpected end of file\n");
+ } else if (c <= 0x20) {
st = r_err(reader,
SERD_ERR_BAD_SYNTAX,
"invalid IRI character (escape %%%02X)\n",
@@ -743,8 +745,6 @@ read_IRIREF(SerdReader* const reader, Ref* const dest)
if (!reader->strict) {
st = SERD_FAILURE;
push_byte(reader, *dest, c);
- } else {
- break;
}
} else if (!(c & 0x80)) {
push_byte(reader, *dest, c);
diff --git a/test/meson.build b/test/meson.build
index 913afe35..db88fa61 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -216,6 +216,13 @@ test_suites = {
files('extra/eof/manifest.ttl'),
ns_serdtest + 'eof/',
],
+ 'eof_lax': [
+ '--ignore',
+ files('extra/eof/manifest.ttl'),
+ ns_serdtest + 'eof/',
+ '--',
+ '-l'
+ ],
'fast': [
files('extra/good/manifest.ttl'),
ns_serdtest + 'good/',
diff --git a/test/run_suite.py b/test/run_suite.py
index 2e93502f..3811a74e 100755
--- a/test/run_suite.py
+++ b/test/run_suite.py
@@ -58,7 +58,7 @@ def run_positive_test(base_uri, command, in_path):
return True
-def run_negative_test(base_uri, command, in_path):
+def run_negative_test(base_uri, command, in_path, ignore):
"""Run a negative syntax test and return whether the error was detected."""
if not os.path.exists(in_path):
@@ -67,10 +67,14 @@ def run_negative_test(base_uri, command, in_path):
command = command + [in_path, base_uri]
proc = subprocess.run(command, check=False, stderr=PIPE, stdout=DEVNULL)
- if proc.returncode == 0:
+ if not ignore and proc.returncode == 0:
util.error("Unexpected successful return: " + in_path)
return False
+ if proc.returncode < 0:
+ util.error("Command seems to have crashed: " + in_path)
+ return False
+
if len(proc.stderr) == 0:
util.error("Command failed with no error output: " + in_path)
return False
@@ -86,7 +90,7 @@ def run_entry(args, entry, command, out_dir, suite_dir):
negative = "Negative" in entry[NS_RDF + "type"][0]
if negative and not args.lax:
- return run_negative_test(base, command, in_path)
+ return run_negative_test(base, command, in_path, args.ignore)
if NS_MF + "result" not in entry:
return run_positive_test(base, command, in_path)
@@ -151,6 +155,7 @@ def main():
)
parser.add_argument("--asserter", help="asserter URI for test report")
+ parser.add_argument("--ignore", action="store_true", help="ignore status")
parser.add_argument("--lax", action="store_true", help="tolerate errors")
parser.add_argument("--report", help="path to write result report to")
parser.add_argument("--reverse", action="store_true", help="reverse test")