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

No one assigned

    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