Skip to content

infinite loop+print in student code can cause enormous json output => check50.Missing is not truncated #388

@Jelleas

Description

@Jelleas

Ran into the following issue, a student's submission contained an infinite loop printing some values each iteration. The check uses .stdout() to check for some expected output. However, the expected output is never produced, leading to a timeout here:

check50/check50/_api.py

Lines 287 to 291 in 483e432

except TIMEOUT:
if show_timeout:
raise Missing(str_output, self.process.before,
help=_("check50 waited {} seconds for the output of the program").format(timeout))
raise Missing(str_output, self.process.before)

The entirety of self.process.before is used as collection for Missing here:

check50/check50/_api.py

Lines 407 to 435 in 483e432

class Missing(Failure):
"""
Exception signifying check failure due to an item missing from a collection.
This is typically a specific substring in a longer string, for instance the contents of stdout.
:param item: the expected item / substring
:param collection: the collection / string
:param help: optional help message to be displayed
:type help: str
Example usage::
actual = check50.run("./fibonacci 5").stdout()
if "5" not in actual and "3" in actual:
help = "Be sure to start the sequence at 1"
raise check50.Missing("5", actual, help=help)
"""
def __init__(self, missing_item, collection, help=None):
if isinstance(collection, list):
collection = _process_list(collection, _raw)
super().__init__(rationale=_("Did not find {} in {}").format(_raw(missing_item), _raw(collection)), help=help)
if missing_item == EOF:
missing_item = "EOF"
self.payload.update({"missing_item": str(missing_item), "collection": str(collection)})

check50 3.4.0's _raw will truncate the output, but not truncate the log. That means with -o json the json output is thousands of lines long.

check50 4.0.0's new _raw does not truncate so there is no truncating for Missing and check50 ends up producing thousands of lines both in its output and its log.

Steps to reproduce:

#include <stdio.h>

int main(void)
{
     while (1)
     {
          printf("0\n");
     }
}
check50.c.compile("foo.c")
check50.run("./foo").stdout("hello world\n");
check50 --dev foo/bar/baz -o json

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions