Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

html/template: inconsistent JSON output behavior #38895

Open
xrfang opened this issue May 6, 2020 · 6 comments
Open

html/template: inconsistent JSON output behavior #38895

xrfang opened this issue May 6, 2020 · 6 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@xrfang
Copy link

xrfang commented May 6, 2020

What version of Go are you using (go version)?

$ go version

go version go1.14 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/xrfang/.cache/go-build"
GOENV="/home/xrfang/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE="git2.likeit.cn"
GONOPROXY="git2.likeit.cn"
GONOSUMDB="git2.likeit.cn"
GOOS="linux"
GOPATH="/home/xrfang/go"
GOPRIVATE="git2.likeit.cn"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build535828964=/tmp/go-build -gno-record-gcc-switches"

What did you do?

In Go:

bills := db.GetBills(&db.Bill{Type: 1})
users := db.ListUsers(1)
renderTemplate(w, "chkin.html", struct {
	Bills map[byte][]db.Bill
	Users []db.User
}{bm, users})

In "chkin.html":

<script>
function listBills(status) {
  $('#blist').append(`<p style="margin-top:1rem;margin-bottom:0.6rem;font-weight:bold"></p>`)
}
var data = {{.}}
</script>

What did you expect to see?

I expect the JS code at var data = {{.}} is valid json format data, i.e.

var data = {"Bills":{"1":[{"id":1,"type":1,"user":1,"amount":0,"markup":"","fee":0,"memo":"","status":1,"created":"2020-05-06T00:35:25Z","updated":"2020-05-06T00:35:25Z"}],"2":[{"id":2,"type":1,"user":1,"amount":0,"markup":"","fee":0,"memo":"","status":2,"created":"2020-05-06T00:35:40Z","updated":"2020-05-06T00:35:40Z"},{"id":5,"type":1,"user":1,"amount":0,"markup":"","fee":0,"memo":"","status":2,"created":"2020-05-06T00:35:50Z","updated":"2020-05-06T00:35:50Z"}],"3":null,"4":[{"id":4,"type":1,"user":1,"amount":0,"markup":"","fee":0,"memo":"","status":4,"created":"2020-05-06T00:35:44Z","updated":"2020-05-06T00:35:44Z"},{"id":7,"type":1,"user":1,"amount":0,"markup":"","fee":0,"memo":"","status":4,"created":"2020-05-06T00:35:54Z","updated":"2020-05-06T00:35:54Z"},{"id":9,"type":1,"user":1,"amount":0,"markup":"","fee":0,"memo":"","status":4,"created":"2020-05-06T00:36:05Z","updated":"2020-05-06T00:36:05Z"},{"id":10,"type":1,"user":1,"amount":0,"markup":"","fee":0,"memo":"","status":4,"created":"2020-05-06T00:36:08Z","updated":"2020-05-06T00:36:08Z"}]},"Users":[{"id":1,"name":"管理员","login":"admin","client":0,"memo":"","created":"2020-05-06T00:34:37Z","updated":"2020-05-06T00:34:37Z"}]}

What did you see instead?

The template engine generated the following:

var data = \{map\[1:\[\{1 1 1 0  0  1 2020\-05\-06 00:35:25 \x2b0000 UTC 2020\-05\-06 00:35:25 \x2b0000 UTC\}\] 2:\[\{2 1 1 0  0  2 2020\-05\-06 00:35:40 \x2b0000 UTC 2020\-05\-06 00:35:40 \x2b0000 UTC\} \{5 1 1 0  0  2 2020\-05\-06 00:35:50 \x2b0000 UTC 2020\-05\-06 00:35:50 \x2b0000 UTC\}\] 3:\[\] 4:\[\{4 1 1 0  0  4 2020\-05\-06 00:35:44 \x2b0000 UTC 2020\-05\-06 00:35:44 \x2b0000 UTC\} \{7 1 1 0  0  4 2020\-05\-06 00:35:54 \x2b0000 UTC 2020\-05\-06 00:35:54 \x2b0000 UTC\} \{9 1 1 0  0  4 2020\-05\-06 00:36:05 \x2b0000 UTC 2020\-05\-06 00:36:05 \x2b0000 UTC\} \{10 1 1 0  0  4 2020\-05\-06 00:36:08 \x2b0000 UTC 2020\-05\-06 00:36:08 \x2b0000 UTC\}\]\] \[\{1 管理员 admin  0  2020\-05\-06 00:34:37 \x2b0000 UTC 2020\-05\-06 00:34:37 \x2b0000 UTC\}\]\}

I noticed that the culprit is the following JS code in the function:

  $('#blist').append(`<p style="margin-top:1rem;margin-bottom:0.6rem;font-weight:bold">

If this line is removed, {{.}} is correctly encoded into JSON.

@xrfang
Copy link
Author

xrfang commented May 6, 2020

I further confirmed that this problem happens when backtick string is used in javascript.

i.e. if I change the above line to:

$('#blist').append("... <-- use regular double or single quote

the problem is gone. However, I need to use template string in JS. This should be fixed in Go's template engine.

@xrfang
Copy link
Author

xrfang commented May 6, 2020

ref: #29406 #9200...

final confirmation: if the declaration is before statement with backtick, this problem does not exist. i.e.

BUGGY:

<script>
function listBills(status) {
  $('#blist').append(`<p style="margin-top:1rem;margin-bottom:0.6rem;font-weight:bold"></p>`)
}
var data = {{.}}
</script>

FINE:

<script>
var data = {{.}}
function listBills(status) {
  $('#blist').append(`<p style="margin-top:1rem;margin-bottom:0.6rem;font-weight:bold"></p>`)
}
</script>

@Gregory-Ledray
Copy link

Gregory-Ledray commented May 6, 2020

From mvdan on 29406:

I've retitled the older issue to be about adding support for template strings. Now this issue is more clearly a duplicate - both issues would be fixed by adding that feature.

Shouldn't the package just copy what is written on the template as is, if it does not understand what it means?

No, that would be very complex and subtle. Right now, some of your template bytes are being discarded because they are being parsed as a comment. If you want to work around that before #9200 is fixed, somehow remove the double slash, or instead use single or double quotes.

Something we could likely do in the short term is teach html/template about tokens it doesn't yet support, like backticks. Then your template would get a parse error. I'm not sure if that's better than what we currently have, where these unknown tokens are parsed like any other character.

It might be that Go has never supported using backticks in templates and if you do use them, instead of throwing an error the behavior is undefined. If my understanding of this is correct, this issue is a duplicate of #9200 and your immediate resolution is to stop using backticks in your templates.

@xrfang
Copy link
Author

xrfang commented May 7, 2020

Please note my last comment, the problem is related to the location of {{.}} and the backtick. @Gregory-Ledray

@toothrot toothrot changed the title html/template inconsistent JSON output behavior html/template: inconsistent JSON output behavior May 11, 2020
@toothrot toothrot added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 11, 2020
@toothrot toothrot added this to the Backlog milestone May 11, 2020
@toothrot
Copy link
Contributor

/cc @mikesamuel @empijei

@empijei
Copy link
Contributor

empijei commented May 18, 2020

I confirm this is a duplicate of #9200. We should try to get that addressed but it is not a trivial change and it is quite hard to find a solution that would satisfy all current users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants