tc39 / proposal-hashbang

#! for JS

Home Page:https://tc39.github.io/proposal-hashbang/out.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow whitespace before hashbang?

hax opened this issue · comments

Though shells not allow whitespaces before hashbang, it would be a little weird that we allow

<script>#! ...
console.log('ok')</script>

but not

<script>
#! ...
console.log('ok')
</script>

Consider there may be many SSI code like

<script>
<?php include 'foo.js' ?>
</script>

I wonder if we can relax the rule to allow whitespace before hashbang?

Why would that SSI code have a hashbang at all?

<script>
#! ...
console.log('ok')
</script>

It seems like a pretty bad practice and therefore I strongly object to relaxing the production specs to allow anything like it.

Also, it would be weird for ECMAScript to allow it in SSI and not in other files, and it's valuable that in files we assure there is nothing before hashbang productions, not even whitespace. We need a better motivation to relax it.

Point of concordance: the @charset declaration in a CSS file also does not allow preceding whitespace; it must be the very first bytes in the file.

Also, it's a minor security risk. Any sort of pre-scan thing needs to specify a maximum length that it'll scan for, and allowing a prefix potentially allows attackers to push the pre-scan out of that window, thus changing the meaning of the resource.

(HTML's charset prescanner obviously does allow arbitrary garbage before it, since it's specified in a meta element, and yes, it can cause security issues if you're not careful.)

Why would that SSI code have a hashbang at all?

@ljharb Maybe they just want to insert a script which happened both apply to node and browser... Anyway, <script>#! ...</script> is much impossible but we still allow this now.

It seems like a pretty bad practice

@leobalter I agree it's not a good practice, so maybe we should disallow <script>#! ...</script> at all?

@charset declaration in a CSS file also does not allow preceding whitespace

@tabatkins Preceding whitespace only make charset declaration invalid, but in most time it won't cause syntax error and the stylesheet still works. Normally, preceding/trailing whitespace never make html/css/js syntax error in our history. There may be some components (preprocessor, proxy, etc.) implicitly rely on such behavior.


Anyway, my point is potential issues of hashbang in the engineering.

Consider a script both apply to node.js and browser env, and the author decide to add hashbang, and there is already a test case <script><? include 'dist.js' ?></script> for ssi. Everything is ok so he release it online. But unfortunately someone use <script>[NEWLINE]<? include 'dist.js' ?></script> in production.

This is why I suggest allow whitespace before hashbang, or we could just make #! behave like <!-- consider there are also cases which prepend comments.

There is also another option, just don't allow #! in inline script at all. Though it will cause <script><? include 'dist.js' ?></script> stop working, at least the developers would know that in the first place and be warned. Especially the ssi instruction could be introduced by 3rd party components and out of their control.

Currently, that script wouldn’t parse - so if the newline-prefixed version never started working, I’m not sure i see the problem.

I don't think introducing such a strange inconsistency would be good just to help people who have spurious newlines inserted in production and not in their staging environment.

@domenic It's not about the difference between production/staging. What I described is the script/module could be used by others with intentional or unintentional prepend newlines/spaces/comments and the author may not know that and just add hashbang.

I was referring to the "consider a script" paragraph in #16 (comment)

Preceding whitespace only make charset declaration invalid, but in most time it won't cause syntax error and the stylesheet still works.

Not really. If your stylesheet is actually using characters outside of ASCII, having the @charset be ignored is gonna cause some problems. Likely, there won't be any syntax errors, but you'll have selectors not matching, etc.

The main purpose of this proposal is to allow shell compatible comments. I think inline script tags in HTML are outside the scope of that intent and several concerns have been raised. If you write inline script tags, don't use a HashbangComment, don't use preceding whitespace, or use a src attribute instead to allow the readability concern to be a non-issue.

@bmeck If hashbang is node-only feature I would agree your opinion but this proposal put hashbang into the standard so I can't agree this is out of scope.

We (Web frontend TC of 360) have some discussion about this proposal and I will create a new issue later as our formal feedback.

@hax even if this was in scope, allowing preceding whitespace has problems mentioned above and the proposal would not work for the purpose of interpreter directives if prefixed with whitespace. This is not only node affected but a general swath of command lines like deno, xs, the hosts that jsvu can download, hermes, etc. . I do not think the problems of whitespace can be fixed across the security concern and lack of ability to properly keep the directive for shells. However, in your code above you could do:

<script><?php include 'foo.js' ?></script>

and it would work.

You could also do:

<script
>#!/usr/bin/env node

</script>

Which is weird, but hey, so is sending an interpreter directive to a browser…