| 1176 | } |
| 1177 | |
| 1178 | static int yaml_doc_init(yaml_doc_t *doc, const char *data, size_t len) { |
| 1179 | memset(doc, 0, sizeof(*doc)); |
| 1180 | doc->data = data; |
| 1181 | doc->len = len; |
| 1182 | if (yaml_build_lines(doc) != 0) { |
| 1183 | return YAML_ERROR; |
| 1184 | } |
| 1185 | /* A UTF-8 BOM is a prologue, not content (#1656): Windows-authored |
| 1186 | * configs routinely carry one (PowerShell 5.1 Set-Content -Encoding UTF8 |
| 1187 | * writes it), and treating its bytes as the first key made every edit op |
| 1188 | * fail content-independently. Skip it for structure; edits splice ranges |
| 1189 | * at line offsets, so the BOM survives every write byte-for-byte. */ |
| 1190 | if (doc->line_count > 0U && doc->len >= YAML_DOC_MARKER_LEN && |
| 1191 | (unsigned char)data[0] == 0xEFU && (unsigned char)data[1] == 0xBBU && |
| 1192 | (unsigned char)data[2] == 0xBFU) { |
| 1193 | yaml_line_t *first = &doc->lines[0]; |
| 1194 | if (first->start == 0U && !first->blank) { |
| 1195 | first->start = YAML_DOC_MARKER_LEN; |
| 1196 | if (first->start + first->indent >= first->text_end) { |
| 1197 | first->blank = true; |
| 1198 | } |
| 1199 | } |
| 1200 | } |
| 1201 | if (yaml_mark_dquote_continuations(doc) != 0) { |
| 1202 | yaml_doc_free(doc); |
| 1203 | return YAML_ERROR; |
| 1204 | } |
| 1205 | for (size_t i = 0; i < doc->line_count; i++) { |
| 1206 | const yaml_line_t *line = &doc->lines[i]; |
| 1207 | if (line->indent == 0U && !line->blank && !line->comment && !line->dquote_cont) { |
| 1208 | size_t len_no_eol = line->text_end - line->start; |
| 1209 | if ((len_no_eol == YAML_DOC_MARKER_LEN && |
| 1210 | memcmp(doc->data + line->start, "---", YAML_DOC_MARKER_LEN) == 0) || |
| 1211 | (len_no_eol == YAML_DOC_MARKER_LEN && |
| 1212 | memcmp(doc->data + line->start, "...", YAML_DOC_MARKER_LEN) == 0)) { |
| 1213 | yaml_doc_free(doc); |
| 1214 | return YAML_ERROR; |
| 1215 | } |
| 1216 | } |
| 1217 | } |
| 1218 | if (yaml_validate_root_mapping(doc) != 0) { |
| 1219 | yaml_doc_free(doc); |
| 1220 | return YAML_ERROR; |
| 1221 | } |
| 1222 | return 0; |
| 1223 | } |
| 1224 | |
| 1225 | static size_t yaml_skip_spaces(const char *data, size_t pos, size_t end) { |
| 1226 | while (pos < end && data[pos] == ' ') { |
no test coverage detected