mirror of
https://github.com/janet-lang/janet
synced 2025-01-13 09:00:26 +00:00
Fix write after free with printing to files.
This commit is contained in:
parent
7663b1e703
commit
55af6ce834
@ -243,6 +243,13 @@ JANET_CORE_FN(cfun_io_fwrite,
|
|||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void io_assert_writeable(JanetFile *iof) {
|
||||||
|
if (iof->flags & JANET_FILE_CLOSED)
|
||||||
|
janet_panic("file is closed");
|
||||||
|
if (!(iof->flags & (JANET_FILE_WRITE | JANET_FILE_APPEND | JANET_FILE_UPDATE)))
|
||||||
|
janet_panic("file is not writeable");
|
||||||
|
}
|
||||||
|
|
||||||
/* Flush the bytes in the file */
|
/* Flush the bytes in the file */
|
||||||
JANET_CORE_FN(cfun_io_fflush,
|
JANET_CORE_FN(cfun_io_fflush,
|
||||||
"(file/flush f)",
|
"(file/flush f)",
|
||||||
@ -250,10 +257,7 @@ JANET_CORE_FN(cfun_io_fflush,
|
|||||||
"buffered for efficiency reasons. Returns the file handle.") {
|
"buffered for efficiency reasons. Returns the file handle.") {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
JanetFile *iof = janet_getabstract(argv, 0, &janet_file_type);
|
JanetFile *iof = janet_getabstract(argv, 0, &janet_file_type);
|
||||||
if (iof->flags & JANET_FILE_CLOSED)
|
io_assert_writeable(iof);
|
||||||
janet_panic("file is closed");
|
|
||||||
if (!(iof->flags & (JANET_FILE_WRITE | JANET_FILE_APPEND | JANET_FILE_UPDATE)))
|
|
||||||
janet_panic("file is not writeable");
|
|
||||||
if (fflush(iof->file))
|
if (fflush(iof->file))
|
||||||
janet_panic("could not flush file");
|
janet_panic("could not flush file");
|
||||||
return argv[0];
|
return argv[0];
|
||||||
@ -269,6 +273,7 @@ int janet_file_close(JanetFile *file) {
|
|||||||
if (!(file->flags & (JANET_FILE_NOT_CLOSEABLE | JANET_FILE_CLOSED))) {
|
if (!(file->flags & (JANET_FILE_NOT_CLOSEABLE | JANET_FILE_CLOSED))) {
|
||||||
ret = fclose(file->file);
|
ret = fclose(file->file);
|
||||||
file->flags |= JANET_FILE_CLOSED;
|
file->flags |= JANET_FILE_CLOSED;
|
||||||
|
file->file = NULL; /* NULL derefence is easier to debug then other problems */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -449,6 +454,7 @@ static Janet cfun_io_print_impl_x(int32_t argc, Janet *argv, int newline,
|
|||||||
if (janet_abstract_type(abstract) != &janet_file_type)
|
if (janet_abstract_type(abstract) != &janet_file_type)
|
||||||
return janet_wrap_nil();
|
return janet_wrap_nil();
|
||||||
JanetFile *iofile = abstract;
|
JanetFile *iofile = abstract;
|
||||||
|
io_assert_writeable(iofile);
|
||||||
f = iofile->file;
|
f = iofile->file;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -564,6 +570,10 @@ static Janet cfun_io_printf_impl_x(int32_t argc, Janet *argv, int newline,
|
|||||||
if (janet_abstract_type(abstract) != &janet_file_type)
|
if (janet_abstract_type(abstract) != &janet_file_type)
|
||||||
return janet_wrap_nil();
|
return janet_wrap_nil();
|
||||||
JanetFile *iofile = abstract;
|
JanetFile *iofile = abstract;
|
||||||
|
if (iofile->flags & JANET_FILE_CLOSED) {
|
||||||
|
janet_panic("cannot print to closed file");
|
||||||
|
}
|
||||||
|
io_assert_writeable(iofile);
|
||||||
f = iofile->file;
|
f = iofile->file;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -688,6 +698,7 @@ void janet_dynprintf(const char *name, FILE *dflt_file, const char *format, ...)
|
|||||||
if (janet_abstract_type(abstract) != &janet_file_type)
|
if (janet_abstract_type(abstract) != &janet_file_type)
|
||||||
break;
|
break;
|
||||||
JanetFile *iofile = abstract;
|
JanetFile *iofile = abstract;
|
||||||
|
io_assert_writeable(iofile);
|
||||||
f = iofile->file;
|
f = iofile->file;
|
||||||
}
|
}
|
||||||
fwrite(buffer.data, buffer.count, 1, f);
|
fwrite(buffer.data, buffer.count, 1, f);
|
||||||
|
Loading…
Reference in New Issue
Block a user