URI: 
       parser: Fix handling of quoted brackets in JSON front matter - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 3183b9a29d8adac962fbc73f79b04542f4c4c55d
   DIR parent 1a282ee4325588b410531401387e4e4daa1a33c5
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Mon, 19 Jun 2017 16:45:52 +0200
       
       parser: Fix handling of quoted brackets in JSON front matter
       
       Also remove a broken JSON test.
       
       Fixes #3511
       
       Diffstat:
         M hugolib/page_test.go                |      19 ++-----------------
         M parser/page.go                      |      12 +++++++++---
         M parser/parse_frontmatter_test.go    |       9 ++++++---
       
       3 files changed, 17 insertions(+), 23 deletions(-)
       ---
   DIR diff --git a/hugolib/page_test.go b/hugolib/page_test.go
       @@ -79,21 +79,7 @@ Leading
        
        Content of the file goes Here
        `
       -        simplePageJSONLoose = `
       -{
       -"title": "spf13-vim 3.0 release and new website"
       -"description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim."
       -"tags": [ ".vimrc", "plugins", "spf13-vim", "VIm" ]
       -"date": "2012-04-06"
       -"categories": [
       -    "Development"
       -    "VIM"
       -],
       -"slug": "spf13-vim-3-0-release-and-new-website"
       -}
        
       -Content of the file goes Here
       -`
                simplePageRFC3339Date  = "---\ntitle: RFC3339 Date\ndate: \"2013-05-17T16:59:30Z\"\n---\nrfc3339 content"
                simplePageJSONMultiple = `
        {
       @@ -941,16 +927,15 @@ func TestCreatePage(t *testing.T) {
                        r string
                }{
                        {simplePageJSON},
       -                {simplePageJSONLoose},
                        {simplePageJSONMultiple},
                        //{strings.NewReader(SIMPLE_PAGE_JSON_COMPACT)},
                }
        
       -        for _, test := range tests {
       +        for i, test := range tests {
                        s := newTestSite(t)
                        p, _ := s.NewPage("page")
                        if _, err := p.ReadFrom(strings.NewReader(test.r)); err != nil {
       -                        t.Errorf("Unable to parse page: %s", err)
       +                        t.Fatalf("[%d] Unable to parse page: %s", i, err)
                        }
                }
        }
   DIR diff --git a/parser/page.go b/parser/page.go
       @@ -304,8 +304,8 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm []byte, e
                        buf       bytes.Buffer
                        level     int
                        sameDelim = bytes.Equal(left, right)
       +                inQuote   bool
                )
       -
                // Frontmatter must start with a delimiter. To check it first,
                // pre-reads beginning delimiter length - 1 bytes from Reader
                for i := 0; i < len(left)-1; i++ {
       @@ -332,6 +332,8 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm []byte, e
                        }
        
                        switch c {
       +                case '"':
       +                        inQuote = !inQuote
                        case left[len(left)-1]:
                                if sameDelim { // YAML, TOML case
                                        if bytes.HasSuffix(buf.Bytes(), left) && (buf.Len() == len(left) || buf.Bytes()[buf.Len()-len(left)-1] == '\n') {
       @@ -373,10 +375,14 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm []byte, e
                                                }
                                        }
                                } else { // JSON case
       -                                level++
       +                                if !inQuote {
       +                                        level++
       +                                }
                                }
                        case right[len(right)-1]: // JSON case only reaches here
       -                        level--
       +                        if !inQuote {
       +                                level--
       +                        }
                        }
        
                        if level == 0 {
   DIR diff --git a/parser/parse_frontmatter_test.go b/parser/parse_frontmatter_test.go
       @@ -296,18 +296,21 @@ func TestExtractFrontMatterDelim(t *testing.T) {
                        {"{\n{\n}\n}\n", "{\n{\n}\n}", noErrExpected},
                        {"{\n  \"categories\": \"d\",\n  \"tags\": [\n    \"a\", \n    \"b\", \n    \"c\"\n  ]\n}\nJSON Front Matter with tags and categories", "{\n  \"categories\": \"d\",\n  \"tags\": [\n    \"a\", \n    \"b\", \n    \"c\"\n  ]\n}", noErrExpected},
                        {"{\n  \"categories\": \"d\"\n  \"tags\": [\n    \"a\" \n    \"b\" \n    \"c\"\n  ]\n}\nJSON Front Matter with tags and categories", "{\n  \"categories\": \"d\"\n  \"tags\": [\n    \"a\" \n    \"b\" \n    \"c\"\n  ]\n}", noErrExpected},
       +                // Issue #3511
       +                {`{ "title": "{" }`, `{ "title": "{" }`, noErrExpected},
       +                {`{ "title": "{}" }`, `{ "title": "{}" }`, noErrExpected},
                }
        
       -        for _, test := range tests {
       +        for i, test := range tests {
                        fm, err := extractFrontMatterDelims(bufio.NewReader(strings.NewReader(test.frontmatter)), []byte("{"), []byte("}"))
                        if (err == nil) != test.errIsNil {
                                t.Logf("\n%q\n", string(test.frontmatter))
       -                        t.Errorf("Expected err == nil => %t, got: %t. err: %s", test.errIsNil, err == nil, err)
       +                        t.Errorf("[%d] Expected err == nil => %t, got: %t. err: %s", i, test.errIsNil, err == nil, err)
                                continue
                        }
                        if !bytes.Equal(fm, []byte(test.extracted)) {
                                t.Logf("\n%q\n", string(test.frontmatter))
       -                        t.Errorf("Frontmatter did not match:\nexp: %q\ngot: %q", string(test.extracted), fm)
       +                        t.Errorf("[%d] Frontmatter did not match:\nexp: %q\ngot: %q", i, string(test.extracted), fm)
                        }
                }
        }