0
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2024-12-23 22:27:38 -05:00

Merge pull request #357 from tw4452852/my_md

markdown: fix json front matter parse issue when body content is long
This commit is contained in:
Matt Holt 2015-11-27 00:07:19 -07:00
commit ef2ca1da3d

View file

@ -1,11 +1,9 @@
package markdown package markdown
import ( import (
"bufio"
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
@ -73,23 +71,20 @@ type JSONMetadataParser struct {
// Parse the metadata // Parse the metadata
func (j *JSONMetadataParser) Parse(b []byte) ([]byte, error) { func (j *JSONMetadataParser) Parse(b []byte) ([]byte, error) {
b, markdown, err := extractMetadata(j, b)
if err != nil {
return markdown, err
}
m := make(map[string]interface{}) m := make(map[string]interface{})
// Read the preceding JSON object // Read the preceding JSON object
decoder := json.NewDecoder(bytes.NewReader(b)) decoder := json.NewDecoder(bytes.NewReader(b))
if err := decoder.Decode(&m); err != nil { if err := decoder.Decode(&m); err != nil {
return b, err return markdown, err
} }
j.metadata.load(m) j.metadata.load(m)
// Retrieve remaining bytes after decoding return markdown, nil
buf := make([]byte, len(b))
n, err := decoder.Buffered().Read(buf)
if err != nil {
return b, err
}
return buf[:n], nil
} }
// Metadata returns parsed metadata. It should be called // Metadata returns parsed metadata. It should be called
@ -183,43 +178,29 @@ func (y *YAMLMetadataParser) Closing() []byte {
// It returns the metadata, the remaining bytes (markdown), and an error, if any. // It returns the metadata, the remaining bytes (markdown), and an error, if any.
func extractMetadata(parser MetadataParser, b []byte) (metadata []byte, markdown []byte, err error) { func extractMetadata(parser MetadataParser, b []byte) (metadata []byte, markdown []byte, err error) {
b = bytes.TrimSpace(b) b = bytes.TrimSpace(b)
reader := bufio.NewReader(bytes.NewBuffer(b)) openingLine := append(parser.Opening(), '\n')
closingLine := append(parser.Closing(), '\n')
// Read first line, which should indicate metadata or not if !bytes.HasPrefix(b, openingLine) {
line, err := reader.ReadBytes('\n')
if err != nil || !bytes.Equal(bytes.TrimSpace(line), parser.Opening()) {
return nil, b, fmt.Errorf("first line missing expected metadata identifier") return nil, b, fmt.Errorf("first line missing expected metadata identifier")
} }
metaStart := len(openingLine)
// buffer for metadata contents if _, ok := parser.(*JSONMetadataParser); ok {
metaBuf := bytes.Buffer{} metaStart = 0
// Read remaining lines until closing identifier is found
for {
line, err := reader.ReadBytes('\n')
if err != nil && err != io.EOF {
return nil, nil, err
}
// if closing identifier found, the remaining bytes must be markdown content
if bytes.Equal(bytes.TrimSpace(line), parser.Closing()) {
break
}
// if file ended, by this point no closing identifier was found
if err == io.EOF {
return nil, nil, fmt.Errorf("metadata not closed ('%s' not found)", parser.Closing())
}
metaBuf.Write(line)
metaBuf.WriteString("\r\n")
} }
metaEnd := bytes.Index(b[metaStart:], closingLine)
// By now, the rest of the buffer contains markdown content if metaEnd == -1 {
contentBuf := new(bytes.Buffer) return nil, nil, fmt.Errorf("metadata not closed ('%s' not found)", parser.Closing())
io.Copy(contentBuf, reader) }
metaEnd += metaStart
return metaBuf.Bytes(), contentBuf.Bytes(), nil if _, ok := parser.(*JSONMetadataParser); ok {
metaEnd += len(closingLine)
}
metadata = b[metaStart:metaEnd]
markdown = b[metaEnd:]
if _, ok := parser.(*JSONMetadataParser); !ok {
markdown = b[metaEnd+len(closingLine):]
}
return metadata, markdown, nil
} }
// findParser finds the parser using line that contains opening identifier // findParser finds the parser using line that contains opening identifier