624 // Ensure that the tokens queue contains at least one token which can be |
624 // Ensure that the tokens queue contains at least one token which can be |
625 // returned to the Parser. |
625 // returned to the Parser. |
626 func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { |
626 func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { |
627 // While we need more tokens to fetch, do it. |
627 // While we need more tokens to fetch, do it. |
628 for { |
628 for { |
629 // Check if we really need to fetch more tokens. |
629 if parser.tokens_head != len(parser.tokens) { |
630 need_more_tokens := false |
630 // If queue is non-empty, check if any potential simple key may |
631 |
631 // occupy the head position. |
632 if parser.tokens_head == len(parser.tokens) { |
632 head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed] |
633 // Queue is empty. |
633 if !ok { |
634 need_more_tokens = true |
634 break |
635 } else { |
635 } else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok { |
636 // Check if any potential simple key may occupy the head position. |
|
637 if !yaml_parser_stale_simple_keys(parser) { |
|
638 return false |
636 return false |
639 } |
637 } else if !valid { |
640 |
638 break |
641 for i := range parser.simple_keys { |
639 } |
642 simple_key := &parser.simple_keys[i] |
|
643 if simple_key.possible && simple_key.token_number == parser.tokens_parsed { |
|
644 need_more_tokens = true |
|
645 break |
|
646 } |
|
647 } |
|
648 } |
|
649 |
|
650 // We are finished. |
|
651 if !need_more_tokens { |
|
652 break |
|
653 } |
640 } |
654 // Fetch the next token. |
641 // Fetch the next token. |
655 if !yaml_parser_fetch_next_token(parser) { |
642 if !yaml_parser_fetch_next_token(parser) { |
656 return false |
643 return false |
657 } |
644 } |
673 return yaml_parser_fetch_stream_start(parser) |
660 return yaml_parser_fetch_stream_start(parser) |
674 } |
661 } |
675 |
662 |
676 // Eat whitespaces and comments until we reach the next token. |
663 // Eat whitespaces and comments until we reach the next token. |
677 if !yaml_parser_scan_to_next_token(parser) { |
664 if !yaml_parser_scan_to_next_token(parser) { |
678 return false |
|
679 } |
|
680 |
|
681 // Remove obsolete potential simple keys. |
|
682 if !yaml_parser_stale_simple_keys(parser) { |
|
683 return false |
665 return false |
684 } |
666 } |
685 |
667 |
686 // Check the indentation level against the current column. |
668 // Check the indentation level against the current column. |
687 if !yaml_parser_unroll_indent(parser, parser.mark.column) { |
669 if !yaml_parser_unroll_indent(parser, parser.mark.column) { |
835 return yaml_parser_set_scanner_error(parser, |
817 return yaml_parser_set_scanner_error(parser, |
836 "while scanning for the next token", parser.mark, |
818 "while scanning for the next token", parser.mark, |
837 "found character that cannot start any token") |
819 "found character that cannot start any token") |
838 } |
820 } |
839 |
821 |
840 // Check the list of potential simple keys and remove the positions that |
822 func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) { |
841 // cannot contain simple keys anymore. |
823 if !simple_key.possible { |
842 func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool { |
824 return false, true |
843 // Check for a potential simple key for each flow level. |
825 } |
844 for i := range parser.simple_keys { |
826 |
845 simple_key := &parser.simple_keys[i] |
827 // The 1.2 specification says: |
846 |
828 // |
847 // The specification requires that a simple key |
829 // "If the ? indicator is omitted, parsing needs to see past the |
848 // |
830 // implicit key to recognize it as such. To limit the amount of |
849 // - is limited to a single line, |
831 // lookahead required, the “:” indicator must appear at most 1024 |
850 // - is shorter than 1024 characters. |
832 // Unicode characters beyond the start of the key. In addition, the key |
851 if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) { |
833 // is restricted to a single line." |
852 |
834 // |
853 // Check if the potential simple key to be removed is required. |
835 if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index { |
854 if simple_key.required { |
836 // Check if the potential simple key to be removed is required. |
855 return yaml_parser_set_scanner_error(parser, |
837 if simple_key.required { |
856 "while scanning a simple key", simple_key.mark, |
838 return false, yaml_parser_set_scanner_error(parser, |
857 "could not find expected ':'") |
839 "while scanning a simple key", simple_key.mark, |
858 } |
840 "could not find expected ':'") |
859 simple_key.possible = false |
841 } |
860 } |
842 simple_key.possible = false |
861 } |
843 return false, true |
862 return true |
844 } |
|
845 return true, true |
863 } |
846 } |
864 |
847 |
865 // Check if a simple key may start at the current position and add it if |
848 // Check if a simple key may start at the current position and add it if |
866 // needed. |
849 // needed. |
867 func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { |
850 func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { |
877 if parser.simple_key_allowed { |
860 if parser.simple_key_allowed { |
878 simple_key := yaml_simple_key_t{ |
861 simple_key := yaml_simple_key_t{ |
879 possible: true, |
862 possible: true, |
880 required: required, |
863 required: required, |
881 token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), |
864 token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), |
882 } |
865 mark: parser.mark, |
883 simple_key.mark = parser.mark |
866 } |
884 |
867 |
885 if !yaml_parser_remove_simple_key(parser) { |
868 if !yaml_parser_remove_simple_key(parser) { |
886 return false |
869 return false |
887 } |
870 } |
888 parser.simple_keys[len(parser.simple_keys)-1] = simple_key |
871 parser.simple_keys[len(parser.simple_keys)-1] = simple_key |
|
872 parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1 |
889 } |
873 } |
890 return true |
874 return true |
891 } |
875 } |
892 |
876 |
893 // Remove a potential simple key at the current flow level. |
877 // Remove a potential simple key at the current flow level. |
898 if parser.simple_keys[i].required { |
882 if parser.simple_keys[i].required { |
899 return yaml_parser_set_scanner_error(parser, |
883 return yaml_parser_set_scanner_error(parser, |
900 "while scanning a simple key", parser.simple_keys[i].mark, |
884 "while scanning a simple key", parser.simple_keys[i].mark, |
901 "could not find expected ':'") |
885 "could not find expected ':'") |
902 } |
886 } |
903 } |
887 // Remove the key from the stack. |
904 // Remove the key from the stack. |
888 parser.simple_keys[i].possible = false |
905 parser.simple_keys[i].possible = false |
889 delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number) |
906 return true |
890 } |
907 } |
891 return true |
|
892 } |
|
893 |
|
894 // max_flow_level limits the flow_level |
|
895 const max_flow_level = 10000 |
908 |
896 |
909 // Increase the flow level and resize the simple key list if needed. |
897 // Increase the flow level and resize the simple key list if needed. |
910 func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { |
898 func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { |
911 // Reset the simple key on the next level. |
899 // Reset the simple key on the next level. |
912 parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) |
900 parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{ |
|
901 possible: false, |
|
902 required: false, |
|
903 token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), |
|
904 mark: parser.mark, |
|
905 }) |
913 |
906 |
914 // Increase the flow level. |
907 // Increase the flow level. |
915 parser.flow_level++ |
908 parser.flow_level++ |
|
909 if parser.flow_level > max_flow_level { |
|
910 return yaml_parser_set_scanner_error(parser, |
|
911 "while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark, |
|
912 fmt.Sprintf("exceeded max depth of %d", max_flow_level)) |
|
913 } |
916 return true |
914 return true |
917 } |
915 } |
918 |
916 |
919 // Decrease the flow level. |
917 // Decrease the flow level. |
920 func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { |
918 func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { |
921 if parser.flow_level > 0 { |
919 if parser.flow_level > 0 { |
922 parser.flow_level-- |
920 parser.flow_level-- |
923 parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1] |
921 last := len(parser.simple_keys) - 1 |
924 } |
922 delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number) |
925 return true |
923 parser.simple_keys = parser.simple_keys[:last] |
926 } |
924 } |
|
925 return true |
|
926 } |
|
927 |
|
928 // max_indents limits the indents stack size |
|
929 const max_indents = 10000 |
927 |
930 |
928 // Push the current indentation level to the stack and set the new level |
931 // Push the current indentation level to the stack and set the new level |
929 // the current column is greater than the indentation level. In this case, |
932 // the current column is greater than the indentation level. In this case, |
930 // append or insert the specified token into the token queue. |
933 // append or insert the specified token into the token queue. |
931 func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool { |
934 func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool { |
937 if parser.indent < column { |
940 if parser.indent < column { |
938 // Push the current indentation level to the stack and set the new |
941 // Push the current indentation level to the stack and set the new |
939 // indentation level. |
942 // indentation level. |
940 parser.indents = append(parser.indents, parser.indent) |
943 parser.indents = append(parser.indents, parser.indent) |
941 parser.indent = column |
944 parser.indent = column |
|
945 if len(parser.indents) > max_indents { |
|
946 return yaml_parser_set_scanner_error(parser, |
|
947 "while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark, |
|
948 fmt.Sprintf("exceeded max depth of %d", max_indents)) |
|
949 } |
942 |
950 |
943 // Create a token and insert it into the queue. |
951 // Create a token and insert it into the queue. |
944 token := yaml_token_t{ |
952 token := yaml_token_t{ |
945 typ: typ, |
953 typ: typ, |
946 start_mark: mark, |
954 start_mark: mark, |
1268 func yaml_parser_fetch_value(parser *yaml_parser_t) bool { |
1278 func yaml_parser_fetch_value(parser *yaml_parser_t) bool { |
1269 |
1279 |
1270 simple_key := &parser.simple_keys[len(parser.simple_keys)-1] |
1280 simple_key := &parser.simple_keys[len(parser.simple_keys)-1] |
1271 |
1281 |
1272 // Have we found a simple key? |
1282 // Have we found a simple key? |
1273 if simple_key.possible { |
1283 if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok { |
|
1284 return false |
|
1285 |
|
1286 } else if valid { |
|
1287 |
1274 // Create the KEY token and insert it into the queue. |
1288 // Create the KEY token and insert it into the queue. |
1275 token := yaml_token_t{ |
1289 token := yaml_token_t{ |
1276 typ: yaml_KEY_TOKEN, |
1290 typ: yaml_KEY_TOKEN, |
1277 start_mark: simple_key.mark, |
1291 start_mark: simple_key.mark, |
1278 end_mark: simple_key.mark, |
1292 end_mark: simple_key.mark, |