Make tag scanning code slightly cleaner.

The current code uses "length" as a proxy for "has a tag"
but the length doesn't actually match the length of the
tag when there's a %-encoded character, so use a boolean
instead.

Also fix a panic found when trying to write a test for the change.
Aside: seems that %-encoded tag handles are not allowed by
the YAML spec.
This commit is contained in:
Roger Peppe 2017-07-21 12:37:23 +01:00
Родитель 670d4cfef0
Коммит e9bfed5956
2 изменённых файлов: 8 добавлений и 7 удалений

Просмотреть файл

@ -610,7 +610,8 @@ type inlineC struct {
}
func (s *S) TestUnmarshal(c *C) {
for _, item := range unmarshalTests {
for i, item := range unmarshalTests {
c.Logf("test %d: %q", i, item.data)
t := reflect.ValueOf(item.value).Type()
var value interface{}
switch t.Kind() {
@ -654,6 +655,7 @@ var unmarshalErrorTests = []struct {
{"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
{"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
}
func (s *S) TestUnmarshalErrors(c *C) {

Просмотреть файл

@ -1944,7 +1944,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
} else {
// It's either the '!' tag or not really a tag handle. If it's a %TAG
// directive, it's an error. If it's a tag token, it must be a part of URI.
if directive && !(s[0] == '!' && s[1] == 0) {
if directive && string(s) != "!" {
yaml_parser_set_scanner_tag_error(parser, directive,
start_mark, "did not find expected '!'")
return false
@ -1959,12 +1959,12 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
//size_t length = head ? strlen((char *)head) : 0
var s []byte
length := len(head)
hasTag := len(head) > 0
// Copy the head if needed.
//
// Note that we don't copy the leading '!' character.
if length > 0 {
if len(head) > 1 {
s = append(s, head[1:]...)
}
@ -1997,15 +1997,14 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
}
} else {
s = read(parser, s)
length++
}
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
return false
}
hasTag = true
}
// Check if the tag is non-empty.
if length == 0 {
if !hasTag {
yaml_parser_set_scanner_tag_error(parser, directive,
start_mark, "did not find expected tag URI")
return false