summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatya Rohith <me@satyarohith.com>2021-04-08 20:06:52 +0530
committerGitHub <noreply@github.com>2021-04-08 16:36:52 +0200
commit543080de559d997d5ff911e8a8a1625d51f2e0bd (patch)
treede2389edd09925dd55911d2eb90ca2fdae24cc0e
parentc867c1aa476b3f00933be08cbc5f528973e37857 (diff)
fix(runtime/readFile*): close resources on error during read (#10059)
This commit ensures readFile, readFileSync, readTextFile, and readTextFileSync does not leak resources on error.
-rw-r--r--cli/tests/unit/read_file_test.ts18
-rw-r--r--cli/tests/unit/read_text_file_test.ts18
-rw-r--r--runtime/js/40_read_file.js40
3 files changed, 62 insertions, 14 deletions
diff --git a/cli/tests/unit/read_file_test.ts b/cli/tests/unit/read_file_test.ts
index 5594eb4ae..5f8ee2c11 100644
--- a/cli/tests/unit/read_file_test.ts
+++ b/cli/tests/unit/read_file_test.ts
@@ -77,3 +77,21 @@ unitTest({ perms: { read: true } }, function readFileSyncLoop(): void {
Deno.readFileSync("cli/tests/fixture.json");
}
});
+
+unitTest(
+ { perms: { read: true } },
+ async function readFileDoesNotLeakResources(): Promise<void> {
+ const resourcesBefore = Deno.resources();
+ await assertThrowsAsync(async () => await Deno.readFile("cli"));
+ assertEquals(resourcesBefore, Deno.resources());
+ },
+);
+
+unitTest(
+ { perms: { read: true } },
+ function readFileSyncDoesNotLeakResources(): void {
+ const resourcesBefore = Deno.resources();
+ assertThrows(() => Deno.readFileSync("cli"));
+ assertEquals(resourcesBefore, Deno.resources());
+ },
+);
diff --git a/cli/tests/unit/read_text_file_test.ts b/cli/tests/unit/read_text_file_test.ts
index dc6a901bb..2223d9c18 100644
--- a/cli/tests/unit/read_text_file_test.ts
+++ b/cli/tests/unit/read_text_file_test.ts
@@ -69,3 +69,21 @@ unitTest({ perms: { read: true } }, function readTextFileSyncLoop(): void {
Deno.readTextFileSync("cli/tests/fixture.json");
}
});
+
+unitTest(
+ { perms: { read: true } },
+ async function readTextFileDoesNotLeakResources(): Promise<void> {
+ const resourcesBefore = Deno.resources();
+ await assertThrowsAsync(async () => await Deno.readTextFile("cli"));
+ assertEquals(resourcesBefore, Deno.resources());
+ },
+);
+
+unitTest(
+ { perms: { read: true } },
+ function readTextFileSyncDoesNotLeakResources(): void {
+ const resourcesBefore = Deno.resources();
+ assertThrows(() => Deno.readTextFileSync("cli"));
+ assertEquals(resourcesBefore, Deno.resources());
+ },
+);
diff --git a/runtime/js/40_read_file.js b/runtime/js/40_read_file.js
index 0ca8f56e9..1efd5338d 100644
--- a/runtime/js/40_read_file.js
+++ b/runtime/js/40_read_file.js
@@ -7,32 +7,44 @@
function readFileSync(path) {
const file = openSync(path);
- const contents = readAllSync(file);
- file.close();
- return contents;
+ try {
+ const contents = readAllSync(file);
+ return contents;
+ } finally {
+ file.close();
+ }
}
async function readFile(path) {
const file = await open(path);
- const contents = await readAll(file);
- file.close();
- return contents;
+ try {
+ const contents = await readAll(file);
+ return contents;
+ } finally {
+ file.close();
+ }
}
function readTextFileSync(path) {
const file = openSync(path);
- const contents = readAllSync(file);
- file.close();
- const decoder = new TextDecoder();
- return decoder.decode(contents);
+ try {
+ const contents = readAllSync(file);
+ const decoder = new TextDecoder();
+ return decoder.decode(contents);
+ } finally {
+ file.close();
+ }
}
async function readTextFile(path) {
const file = await open(path);
- const contents = await readAll(file);
- file.close();
- const decoder = new TextDecoder();
- return decoder.decode(contents);
+ try {
+ const contents = await readAll(file);
+ const decoder = new TextDecoder();
+ return decoder.decode(contents);
+ } finally {
+ file.close();
+ }
}
window.__bootstrap.readFile = {