|
|
|
@ -626,17 +626,30 @@ func trace(args ...interface{}) func() {
|
|
|
|
|
func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { |
|
|
|
|
// While we need more tokens to fetch, do it.
|
|
|
|
|
for { |
|
|
|
|
if parser.tokens_head != len(parser.tokens) { |
|
|
|
|
// If queue is non-empty, check if any potential simple key may
|
|
|
|
|
// occupy the head position.
|
|
|
|
|
head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed] |
|
|
|
|
if !ok { |
|
|
|
|
break |
|
|
|
|
} else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok { |
|
|
|
|
// Check if we really need to fetch more tokens.
|
|
|
|
|
need_more_tokens := false |
|
|
|
|
|
|
|
|
|
if parser.tokens_head == len(parser.tokens) { |
|
|
|
|
// Queue is empty.
|
|
|
|
|
need_more_tokens = true |
|
|
|
|
} else { |
|
|
|
|
// Check if any potential simple key may occupy the head position.
|
|
|
|
|
if !yaml_parser_stale_simple_keys(parser) { |
|
|
|
|
return false |
|
|
|
|
} else if !valid { |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for i := range parser.simple_keys { |
|
|
|
|
simple_key := &parser.simple_keys[i] |
|
|
|
|
if simple_key.possible && simple_key.token_number == parser.tokens_parsed { |
|
|
|
|
need_more_tokens = true |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// We are finished.
|
|
|
|
|
if !need_more_tokens { |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
// Fetch the next token.
|
|
|
|
|
if !yaml_parser_fetch_next_token(parser) { |
|
|
|
@ -665,6 +678,11 @@ func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
|
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Remove obsolete potential simple keys.
|
|
|
|
|
if !yaml_parser_stale_simple_keys(parser) { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Check the indentation level against the current column.
|
|
|
|
|
if !yaml_parser_unroll_indent(parser, parser.mark.column) { |
|
|
|
|
return false |
|
|
|
@ -819,30 +837,29 @@ func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
|
|
|
|
|
"found character that cannot start any token") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) { |
|
|
|
|
if !simple_key.possible { |
|
|
|
|
return false, true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The 1.2 specification says:
|
|
|
|
|
//
|
|
|
|
|
// "If the ? indicator is omitted, parsing needs to see past the
|
|
|
|
|
// implicit key to recognize it as such. To limit the amount of
|
|
|
|
|
// lookahead required, the “:” indicator must appear at most 1024
|
|
|
|
|
// Unicode characters beyond the start of the key. In addition, the key
|
|
|
|
|
// is restricted to a single line."
|
|
|
|
|
//
|
|
|
|
|
if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index { |
|
|
|
|
// Check if the potential simple key to be removed is required.
|
|
|
|
|
if simple_key.required { |
|
|
|
|
return false, yaml_parser_set_scanner_error(parser, |
|
|
|
|
"while scanning a simple key", simple_key.mark, |
|
|
|
|
"could not find expected ':'") |
|
|
|
|
// Check the list of potential simple keys and remove the positions that
|
|
|
|
|
// cannot contain simple keys anymore.
|
|
|
|
|
func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool { |
|
|
|
|
// Check for a potential simple key for each flow level.
|
|
|
|
|
for i := range parser.simple_keys { |
|
|
|
|
simple_key := &parser.simple_keys[i] |
|
|
|
|
|
|
|
|
|
// The specification requires that a simple key
|
|
|
|
|
//
|
|
|
|
|
// - is limited to a single line,
|
|
|
|
|
// - is shorter than 1024 characters.
|
|
|
|
|
if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) { |
|
|
|
|
|
|
|
|
|
// Check if the potential simple key to be removed is required.
|
|
|
|
|
if simple_key.required { |
|
|
|
|
return yaml_parser_set_scanner_error(parser, |
|
|
|
|
"while scanning a simple key", simple_key.mark, |
|
|
|
|
"could not find expected ':'") |
|
|
|
|
} |
|
|
|
|
simple_key.possible = false |
|
|
|
|
} |
|
|
|
|
simple_key.possible = false |
|
|
|
|
return false, true |
|
|
|
|
} |
|
|
|
|
return true, true |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Check if a simple key may start at the current position and add it if
|
|
|
|
@ -862,14 +879,13 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
|
|
|
|
|
possible: true, |
|
|
|
|
required: required, |
|
|
|
|
token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), |
|
|
|
|
mark: parser.mark, |
|
|
|
|
} |
|
|
|
|
simple_key.mark = parser.mark |
|
|
|
|
|
|
|
|
|
if !yaml_parser_remove_simple_key(parser) { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
parser.simple_keys[len(parser.simple_keys)-1] = simple_key |
|
|
|
|
parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1 |
|
|
|
|
} |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
@ -884,33 +900,19 @@ func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
|
|
|
|
|
"while scanning a simple key", parser.simple_keys[i].mark, |
|
|
|
|
"could not find expected ':'") |
|
|
|
|
} |
|
|
|
|
// Remove the key from the stack.
|
|
|
|
|
parser.simple_keys[i].possible = false |
|
|
|
|
delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number) |
|
|
|
|
} |
|
|
|
|
// Remove the key from the stack.
|
|
|
|
|
parser.simple_keys[i].possible = false |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// max_flow_level limits the flow_level
|
|
|
|
|
const max_flow_level = 10000 |
|
|
|
|
|
|
|
|
|
// Increase the flow level and resize the simple key list if needed.
|
|
|
|
|
func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { |
|
|
|
|
// Reset the simple key on the next level.
|
|
|
|
|
parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{ |
|
|
|
|
possible: false, |
|
|
|
|
required: false, |
|
|
|
|
token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), |
|
|
|
|
mark: parser.mark, |
|
|
|
|
}) |
|
|
|
|
parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) |
|
|
|
|
|
|
|
|
|
// Increase the flow level.
|
|
|
|
|
parser.flow_level++ |
|
|
|
|
if parser.flow_level > max_flow_level { |
|
|
|
|
return yaml_parser_set_scanner_error(parser, |
|
|
|
|
"while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark, |
|
|
|
|
fmt.Sprintf("exceeded max depth of %d", max_flow_level)) |
|
|
|
|
} |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -918,16 +920,11 @@ func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
|
|
|
|
|
func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { |
|
|
|
|
if parser.flow_level > 0 { |
|
|
|
|
parser.flow_level-- |
|
|
|
|
last := len(parser.simple_keys) - 1 |
|
|
|
|
delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number) |
|
|
|
|
parser.simple_keys = parser.simple_keys[:last] |
|
|
|
|
parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1] |
|
|
|
|
} |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// max_indents limits the indents stack size
|
|
|
|
|
const max_indents = 10000 |
|
|
|
|
|
|
|
|
|
// Push the current indentation level to the stack and set the new level
|
|
|
|
|
// the current column is greater than the indentation level. In this case,
|
|
|
|
|
// append or insert the specified token into the token queue.
|
|
|
|
@ -942,11 +939,6 @@ func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml
|
|
|
|
|
// indentation level.
|
|
|
|
|
parser.indents = append(parser.indents, parser.indent) |
|
|
|
|
parser.indent = column |
|
|
|
|
if len(parser.indents) > max_indents { |
|
|
|
|
return yaml_parser_set_scanner_error(parser, |
|
|
|
|
"while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark, |
|
|
|
|
fmt.Sprintf("exceeded max depth of %d", max_indents)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create a token and insert it into the queue.
|
|
|
|
|
token := yaml_token_t{ |
|
|
|
@ -997,8 +989,6 @@ func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
|
|
|
|
|
// Initialize the simple key stack.
|
|
|
|
|
parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) |
|
|
|
|
|
|
|
|
|
parser.simple_keys_by_tok = make(map[int]int) |
|
|
|
|
|
|
|
|
|
// A simple key is allowed at the beginning of the stream.
|
|
|
|
|
parser.simple_key_allowed = true |
|
|
|
|
|
|
|
|
@ -1280,11 +1270,7 @@ func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
|
|
|
|
|
simple_key := &parser.simple_keys[len(parser.simple_keys)-1] |
|
|
|
|
|
|
|
|
|
// Have we found a simple key?
|
|
|
|
|
if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok { |
|
|
|
|
return false |
|
|
|
|
|
|
|
|
|
} else if valid { |
|
|
|
|
|
|
|
|
|
if simple_key.possible { |
|
|
|
|
// Create the KEY token and insert it into the queue.
|
|
|
|
|
token := yaml_token_t{ |
|
|
|
|
typ: yaml_KEY_TOKEN, |
|
|
|
@ -1302,7 +1288,6 @@ func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
|
|
|
|
|
|
|
|
|
|
// Remove the simple key.
|
|
|
|
|
simple_key.possible = false |
|
|
|
|
delete(parser.simple_keys_by_tok, simple_key.token_number) |
|
|
|
|
|
|
|
|
|
// A simple key cannot follow another simple key.
|
|
|
|
|
parser.simple_key_allowed = false |
|
|
|
|