Skip to content

Commit

Permalink
kernel: close streams after internal exception
Browse files Browse the repository at this point in the history
... then rethrow.

Otherwise we may end up with references to input/output stream
objects on the stack that are invalid.
  • Loading branch information
fingolfin committed Jan 6, 2025
1 parent 60536bc commit 1f45bc7
Showing 1 changed file with 85 additions and 39 deletions.
124 changes: 85 additions & 39 deletions src/streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,17 @@ static Obj FuncREAD_COMMAND_REAL(Obj self, Obj stream, Obj echo)
if (!OpenInputStream(&input, stream, echo == True)) {
return result;
}
ExecStatus status = ReadEvalCommand(0, &input, &evalResult, 0);
ExecStatus status;

GAP_TRY
{
status = ReadEvalCommand(0, &input, &evalResult, 0);
}
GAP_CATCH

Check warning on line 254 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L254

Added line #L254 was not covered by tests
{
CloseInput(&input);
GAP_THROW();

Check warning on line 257 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L256-L257

Added lines #L256 - L257 were not covered by tests
}
CloseInput(&input);

if (status == STATUS_EOF || status == STATUS_QQUIT)
Expand Down Expand Up @@ -404,7 +414,11 @@ Int READ_GAP_ROOT ( const Char * filename )
}

TypInputFile input;
if (OpenInput(&input, path)) {
if (!OpenInput(&input, path))
return 0;

Check warning on line 418 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L418

Added line #L418 was not covered by tests

GAP_TRY
{
while (1) {
ExecStatus status = ReadEvalCommand(0, &input, 0, 0);
if (STATE(UserHasQuit) || STATE(UserHasQUIT))
Expand All @@ -416,11 +430,14 @@ Int READ_GAP_ROOT ( const Char * filename )
break;
}
}
}
GAP_CATCH

Check warning on line 434 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L434

Added line #L434 was not covered by tests
{
CloseInput(&input);
return 1;
GAP_THROW();

Check warning on line 437 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L437

Added line #L437 was not covered by tests
}

return 0;
CloseInput(&input);
return 1;
}


Expand Down Expand Up @@ -806,8 +823,17 @@ static Obj FuncREAD(Obj self, Obj inputObj)
if (!OpenInputFileOrStream(SELF_NAME, &input, inputObj))
return False;

// read the file
READ_INNER(&input);
GAP_TRY
{
// read the file
READ_INNER(&input);
}
GAP_CATCH

Check warning on line 831 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L831

Added line #L831 was not covered by tests
{
CloseInput(&input);
GAP_THROW();

Check warning on line 834 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L833-L834

Added lines #L833 - L834 were not covered by tests
}

if (!CloseInput(&input)) {
ErrorQuit("Panic: READ cannot close input", 0, 0);
}
Expand Down Expand Up @@ -856,49 +882,58 @@ static Obj FuncREAD_STREAM_LOOP(Obj self,
// get the starting time
UInt oldPrintObjState = SetPrintObjState(0);

// now do the reading
while (1) {
Obj evalResult;
BOOL dualSemicolon;
UInt oldtime = SyTime();

// read and evaluate the command
SetPrintObjState(0);
ExecStatus status =
ReadEvalCommand(context, &input, &evalResult, &dualSemicolon);

// stop the stopwatch
UpdateTime(oldtime);

// handle ordinary command
if (status == STATUS_END && evalResult != 0) {
UpdateLast(evalResult);
if (!dualSemicolon) {
ViewObjHandler(evalResult);
BOOL rethrow = FALSE;

GAP_TRY
{
// now do the reading
while (1) {
Obj evalResult;
BOOL dualSemicolon;
UInt oldtime = SyTime();

// read and evaluate the command
SetPrintObjState(0);
ExecStatus status =
ReadEvalCommand(context, &input, &evalResult, &dualSemicolon);

// stop the stopwatch
UpdateTime(oldtime);

// handle ordinary command
if (status == STATUS_END && evalResult != 0) {
UpdateLast(evalResult);
if (!dualSemicolon) {
ViewObjHandler(evalResult);
}
}
}

// handle return-value or return-void command
else if (status == STATUS_RETURN) {
Pr("'return' must not be used in file read-eval loop\n", 0, 0);
}
// handle return-value or return-void command
else if (status == STATUS_RETURN) {
Pr("'return' must not be used in file read-eval loop\n", 0, 0);
}

// handle quit command or <end-of-file>
else if (status == STATUS_EOF || status == STATUS_QUIT ||
status == STATUS_QQUIT) {
break;
// handle quit command or <end-of-file>
else if (status == STATUS_EOF || status == STATUS_QUIT ||
status == STATUS_QQUIT) {
break;
}
}
}
GAP_CATCH

Check warning on line 923 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L923

Added line #L923 was not covered by tests
{
rethrow = TRUE;

Check warning on line 925 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L925

Added line #L925 was not covered by tests
}

SetPrintObjState(oldPrintObjState);

LockCurrentOutput(FALSE);

res = CloseInput(&input);
GAP_ASSERT(res);

res &= CloseOutput(&output);
GAP_ASSERT(res);

if (rethrow)
GAP_THROW();

Check warning on line 936 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L936

Added line #L936 was not covered by tests

return res ? True : False;
}
Expand All @@ -914,7 +949,18 @@ static Obj FuncREAD_AS_FUNC(Obj self, Obj inputObj)
if (!OpenInputFileOrStream(SELF_NAME, &input, inputObj))
return False;

Obj func = READ_AS_FUNC(&input);
Obj func;

GAP_TRY
{
func = READ_AS_FUNC(&input);
}
GAP_CATCH

Check warning on line 958 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L958

Added line #L958 was not covered by tests
{
CloseInput(&input);
GAP_THROW();

Check warning on line 961 in src/streams.c

View check run for this annotation

Codecov / codecov/patch

src/streams.c#L960-L961

Added lines #L960 - L961 were not covered by tests
}

if (!CloseInput(&input)) {
ErrorQuit("Panic: READ_AS_FUNC cannot close input", 0, 0);
}
Expand Down

0 comments on commit 1f45bc7

Please sign in to comment.