1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-24 15:19:26 -05:00

fix(cli): Don't strip shebangs from modules (#13220)

Deno's module loader currently strips a shebang if a module file
starts with one. However, this is no longer necessary, since there is
a stage-3 TC39 that adds support for shebangs (or "hashbangs") to the
language (https://github.com/tc39/proposal-hashbang), and V8, `tsc`
and `swc` all support it.

Furthermore, stripping shebangs causes a correctness bug with JSON
modules, since a JSON file with a shebang should not parse as a JSON
module, yet it does with this stripping. This change fixes this.
This commit is contained in:
Andreu Botella 2022-01-16 16:48:32 +01:00 committed by GitHub
parent ad224f53c7
commit 9def44979a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 27 deletions

View file

@ -27,6 +27,7 @@
"cli/tests/testdata/badly_formatted.json",
"cli/tests/testdata/byte_order_mark.ts",
"cli/tests/testdata/fmt/*",
"cli/tests/testdata/import_assertions/json_with_shebang.json",
"cli/tests/testdata/test/markdown_windows.md",
"cli/tsc/*typescript.js",
"test_util/std",

View file

@ -148,7 +148,7 @@ fn fetch_local(specifier: &ModuleSpecifier) -> Result<File, AnyError> {
})?;
let bytes = fs::read(local.clone())?;
let charset = text_encoding::detect_charset(&bytes).to_string();
let source = strip_shebang(get_source_from_bytes(bytes, Some(charset))?);
let source = get_source_from_bytes(bytes, Some(charset))?;
let media_type = MediaType::from(specifier);
Ok(File {
@ -173,10 +173,7 @@ pub fn get_source_from_data_url(
let (bytes, _) = data_url
.decode_to_vec()
.map_err(|e| uri_error(format!("{:?}", e)))?;
Ok((
strip_shebang(get_source_from_bytes(bytes, charset)?),
format!("{}", mime),
))
Ok((get_source_from_bytes(bytes, charset)?, format!("{}", mime)))
}
/// Given a vector of bytes and optionally a charset, decode the bytes to a
@ -230,19 +227,6 @@ pub fn map_content_type(
}
}
/// Remove shebangs from the start of source code strings
fn strip_shebang(mut value: String) -> String {
if value.starts_with("#!") {
if let Some(mid) = value.find('\n') {
let (_, rest) = value.split_at(mid);
value = rest.to_string()
} else {
value.clear()
}
}
value
}
/// A structure for resolving, fetching and caching source files.
#[derive(Debug, Clone)]
pub struct FileFetcher {
@ -306,7 +290,7 @@ impl FileFetcher {
let maybe_content_type = headers.get("content-type").cloned();
let (media_type, maybe_charset) =
map_content_type(specifier, maybe_content_type);
let source = strip_shebang(get_source_from_bytes(bytes, maybe_charset)?);
let source = get_source_from_bytes(bytes, maybe_charset)?;
let maybe_types = match media_type {
MediaType::JavaScript
| MediaType::Cjs
@ -450,7 +434,7 @@ impl FileFetcher {
let (media_type, maybe_charset) =
map_content_type(specifier, Some(content_type.clone()));
let source = strip_shebang(get_source_from_bytes(bytes, maybe_charset)?);
let source = get_source_from_bytes(bytes, maybe_charset)?;
let local =
self
@ -786,13 +770,6 @@ mod tests {
}
}
#[test]
fn test_strip_shebang() {
let value =
"#!/usr/bin/env deno\n\nconsole.log(\"hello deno!\");\n".to_string();
assert_eq!(strip_shebang(value), "\n\nconsole.log(\"hello deno!\");\n");
}
#[test]
fn test_map_content_type() {
let fixtures = vec![

View file

@ -1600,6 +1600,28 @@ itest!(jsx_import_source_error {
exit_code: 1,
});
itest!(shebang_tsc {
args: "run --quiet shebang.ts",
output: "shebang.ts.out",
});
itest!(shebang_swc {
args: "run --quiet --no-check shebang.ts",
output: "shebang.ts.out",
});
itest!(shebang_with_json_imports_tsc {
args: "run --quiet import_assertions/json_with_shebang.ts",
output: "import_assertions/json_with_shebang.ts.out",
exit_code: 1,
});
itest!(shebang_with_json_imports_swc {
args: "run --quiet --no-check import_assertions/json_with_shebang.ts",
output: "import_assertions/json_with_shebang.ts.out",
exit_code: 1,
});
#[test]
fn no_validate_asm() {
let output = util::deno_cmd()

View file

@ -0,0 +1,4 @@
#!/usr/env -S deno run
{
"test": null
}

View file

@ -0,0 +1,3 @@
import json from "./json_with_shebang.json" assert { type: "json" };
console.log(json);

View file

@ -0,0 +1 @@
error: Uncaught SyntaxError: Unexpected token # in JSON at position 0

5
cli/tests/testdata/shebang.ts vendored Normal file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env -S deno run
import test from "./shebang2.ts";
console.log(test as number);

1
cli/tests/testdata/shebang.ts.out vendored Normal file
View file

@ -0,0 +1 @@
42

3
cli/tests/testdata/shebang2.ts vendored Normal file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env -S deno run
export default 42;