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: bad quotes in second <div> #12149

Closed
Miaonster opened this issue Aug 14, 2015 · 11 comments
Closed

html/template: bad quotes in second <div> #12149

Miaonster opened this issue Aug 14, 2015 · 11 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@Miaonster
Copy link

I asked this question on StackOverflow, but there's no answer. Someone commented this seems a framework bug, so I post it here. After asking this question, I tried in another way using pure go without gin and I got the same result.

Basic information

  • Go version: go1.4.2 darwin/amd64
  • Operating System: Mac OS X 10.10.5
  • Processor Architecture: 2.5 GHz Intel Core i7

I'm working on a small Web project written based on go and gin. Here is my golang code. After running go run test.go we have a web server, which is listening on 8089.

Golang test.go

package main

import "github.com/gin-gonic/gin"
import "net/http"

func main() {
    router := gin.Default()
    router.LoadHTMLGlob("templates/*")
    router.GET("/index", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.html", gin.H{
            "scheme": "http",
            "domain": "meican.loc",
        })
    })
    router.Run(":8089") // listen and serve on 0.0.0.0:8089
}

The html code generated in back-end should contain a template used by front-end javascript engine (Let's say Angular.js).

So the template code is in script tag, just like this:

Part of templates/index.html

<script type="text/template" charset="utf-8">
    <div data="{{.scheme}}://{{.domain}}/qr"></div>
    <div data="{{.scheme}}://{{.domain}}/qr"></div> <!-- problem here -->
</script>

When {{.domain}} is used at the second time, I got different result. I refreshed the browser and checked out the source code. Then I got this:

Browser source code result

<script type="text/template" charset="utf-8">
    <div data="http://meican.loc/qr"></div>
    <div data="http://"meican.loc"/qr"></div>  <!-- problems here -->
</script>

The second div has 2 extra double quotes.

Why this happens? And how to resolve this problem?

@ALTree
Copy link
Member

ALTree commented Aug 14, 2015

Hi Witcher,

this seems to be an issue related to the gin framework, so you should write in the gin issue tracker (https://github.com/gin-gonic/gin/issues)

@Miaonster
Copy link
Author

Hi @ALTree Thanks for the reply. But as mentioned in my first comment, I thought it's not related to gin framework.

After asking this question, I tried in another way using pure go without gin and I got the same result.

I'll post some code which bring out the same result without gin.

test.go

package main

import "net/http"
import "html/template"

type Page struct {
    Scheme string
    Domain string
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    p := &Page{
        Scheme: "http",
        Domain: "meican.loc",
    }
    t, _ := template.ParseFiles("templates/index.html")
    t.Execute(w, p)
}

func main() {
    http.HandleFunc("/index", indexHandler)
    http.ListenAndServe(":8089", nil)
}

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <script type="text/template" charset="utf-8">
    <div data="{{.Scheme}}://{{.Domain}}/qr"></div>
    <div data="{{.Scheme}}://{{.Domain}}/qr"></div>  <!-- problems here -->
  </script>
</body>
</html>

Then run command go run test.go, we will get this result when visiting http://127.0.0.1:8089/index.

browser source code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <script type="text/template" charset="utf-8">
    <div data="http://meican.loc/qr"></div>
    <div data="http://"meican.loc"/qr"></div>  <!-- problems here -->
  </script>
</body>
</html>

The result browser source code gives a different a result after rendering the second <div data="{{.Scheme}}://{{.Domain}}/qr"></div>.

@robpike
Copy link
Contributor

robpike commented Aug 17, 2015

Here is a version that does not require a web server.

package main

import (
    "html/template"
    "log"
    "os"
)

type Page struct {
    Scheme string
    Domain string
}


const text = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <script type="text/template" charset="utf-8">
    <div data="{{.Scheme}}://{{.Domain}}/qr"></div>
    <div data="{{.Scheme}}://{{.Domain}}/qr"></div>  <!-- problems here -->
  </script>
</body>
</html>
`

func main() {
    p := &Page{
        Scheme: "http",
        Domain: "meican.loc",
    }
    t, err := template.New("index").Parse(text)
    if err != nil {
        log.Fatal(err)
    }
    err = t.Execute(os.Stdout, p)
    if err != nil {
        log.Fatal(err)
    }
}

With text/template, the (core of the) output is

<div data="http://meican.loc/qr"></div>
<div data="http://meican.loc/qr"></div>  <!-- problems here -->

while with html/template, it is

<div data="http://meican.loc/qr"></div>
<div data="http://"meican.loc"/qr"></div>  <!-- problems here -->

It does indeed seem like a bug in html/template.

@robpike robpike changed the title html/template same code but different results using go-template html/template: bad quotes in second <div> Aug 17, 2015
@robpike robpike added this to the Go1.6 milestone Aug 17, 2015
@fyelles
Copy link

fyelles commented Aug 17, 2015

Interestingly enough if you removed the script tag and replace it for example by a span .
The output is as expected. (http://play.golang.org/p/Lxge_eg835)

I will take a look at it

package main

import (
    "html/template"
    "log"
    "os"
)

type Page struct {
    Scheme string
    Domain string
}


const text = `  <span type="text/template" charset="utf-8">
    <div data="{{.Scheme}}://{{.Domain}}/qr"></div>
    <div data="{{.Scheme}}://{{.Domain}}/qr"></div>
  </span>
`

func main() {
    p := &Page{
        Scheme: "http",
        Domain: "meican.loc",
    }
    t, err := template.New("index").Parse(text)
    if err != nil {
        log.Fatal(err)
    }
    err = t.Execute(os.Stdout, p)
    if err != nil {
        log.Fatal(err)
    }
}

@rsc rsc modified the milestones: Go1.6Early, Go1.6 Aug 26, 2015
@gopherbot
Copy link

CL https://golang.org/cl/14336 mentions this issue.

@gopherbot
Copy link

CL https://golang.org/cl/14335 mentions this issue.

robpike pushed a commit that referenced this issue Sep 9, 2015
Context: #12149. The problem there is that contents of
<script type="text/template"> are treated as JS, and thus // is treated
as regexp.

Preserve context.attr while we are in the attribute, in particular in
stateBeforeValue, so we have attr when reading attr value.

Next CL will actually fix the bug.

Change-Id: I99add2237b0885ecdcc08b4f7c25d0af99173e53
Reviewed-on: https://go-review.googlesource.com/14335
Reviewed-by: Rob Pike <r@golang.org>
@ianlancetaylor ianlancetaylor modified the milestones: Go1.6, Go1.6Early Dec 11, 2015
@rsc rsc modified the milestones: Go1.7, Go1.6 Dec 17, 2015
@jeffallen
Copy link
Contributor

@robpike Ping? You made a commit that prepared for a fix, but the fix didn't land? Can you pass me what you have so far, and can finish it up for ya.

@robpike
Copy link
Contributor

robpike commented Feb 2, 2016

@jeffallen I didn't make any commit regarding this. Not sure what you're referring to.

@ALTree
Copy link
Member

ALTree commented Feb 2, 2016

@jeffallen: Nodir Turakulov sent the patch, the nickname you see on the commit it's just the name of the team member that approved and cherrypicked it.

@jeffallen
Copy link
Contributor

OK, sorry to confuse. @nodirt, CL 14336 is waiting for Go 1.7, I guess?

@mdempsky mdempsky modified the milestones: Go1.8Early, Go1.7 May 19, 2016
@rsc
Copy link
Contributor

rsc commented Sep 26, 2016

There is a fix pending in CL 13446 that needs review (and in particular needs to address review comments). I will make sure this gets reviewed.

@rsc rsc added the NeedsFix The path to resolution is known, but the work has not been done. label Sep 26, 2016
@rsc rsc self-assigned this Sep 26, 2016
@golang golang locked and limited conversation to collaborators Sep 29, 2017
@rsc rsc removed their assignment Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

9 participants