[PATCH 5/7] pxe_utils: optionally ignore unknown keys in parse_label_keys()
Alexey Charkov
alchark at flipper.net
Thu Jun 4 17:31:10 CEST 2026
The parser currently treats any keyword it does not recognise inside a
label body as the end of that label, pushing the token back so the
caller can dispatch it as menu-level input. That is correct for
extlinux/pxelinux, where the only thing legitimately following a label
body is another 'label' (or a top-level 'menu ...') line.
Other formats that share enough syntax to reuse this parser have
different rules. The Boot Loader Specification, in particular, lists a
number of entry-level keys (title, version, sort-key, machine-id,
architecture, ...) that this parser knows nothing about, and the spec
explicitly requires implementations to silently ignore unrecognised
keys rather than treat them as a structural boundary.
Add an ignore_unknown flag to parse_label_keys(): when set, the default
switch case consumes the rest of the offending line via eol_or_eof()
and continues parsing instead of returning. The existing extlinux
caller passes false and so is unaffected.
Signed-off-by: Alexey Charkov <alchark at flipper.net>
---
boot/pxe_utils.c | 29 +++++++++++++++++++++++++++--
include/pxe_utils.h | 8 +++++++-
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 6dad3045f9d4..7ecee86a9ada 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -1266,7 +1266,8 @@ static int parse_label_kernel(char **c, struct pxe_label *label)
return 1;
}
-int parse_label_keys(char **c, struct pxe_menu *cfg, struct pxe_label *label)
+int parse_label_keys(char **c, struct pxe_menu *cfg, struct pxe_label *label,
+ bool ignore_unknown)
{
struct token t;
char *s;
@@ -1339,7 +1340,31 @@ int parse_label_keys(char **c, struct pxe_menu *cfg, struct pxe_label *label)
case T_EOL:
break;
+ case T_EOF:
+ if (ignore_unknown) {
+ /*
+ * BLS-style callers parse a standalone label
+ * body, so there is no outer context to push
+ * T_EOF back into — stop cleanly here.
+ */
+ return 1;
+ }
+ /*
+ * For pxelinux/extlinux, fall through so the default
+ * case pushes T_EOF back for the top-level parser.
+ */
+ fallthrough;
default:
+ if (ignore_unknown) {
+ /*
+ * Skip the rest of the line and keep going.
+ * Used for formats like the Boot Loader
+ * Specification, where the spec mandates that
+ * unknown keys must be silently ignored.
+ */
+ eol_or_eof(c);
+ break;
+ }
/*
* put the token back! we don't want it - it's the end
* of a label and whatever token this is, it's
@@ -1381,7 +1406,7 @@ static int parse_label(char **c, struct pxe_menu *cfg)
list_add_tail(&label->list, &cfg->labels);
- return parse_label_keys(c, cfg, label);
+ return parse_label_keys(c, cfg, label, false);
}
/*
diff --git a/include/pxe_utils.h b/include/pxe_utils.h
index e639e59e5dc8..653e1a7d866e 100644
--- a/include/pxe_utils.h
+++ b/include/pxe_utils.h
@@ -237,9 +237,15 @@ void label_destroy(struct pxe_label *label);
* @cfg: Menu the label belongs to (used for 'menu default' bookkeeping)
* @label: Label to populate; must already be allocated and (when called for
* a file that has a 'label' header) attached to @cfg->labels
+ * @ignore_unknown: If true, silently skip unknown keys (and consume the
+ * rest of their lines) instead of stopping. This matches the Boot
+ * Loader Specification's requirement that unknown keys be ignored.
+ * If false (extlinux/pxelinux behaviour), an unknown token is pushed
+ * back so the caller can treat it as the start of the next label.
* Return: 1 on success, < 0 on error
*/
-int parse_label_keys(char **c, struct pxe_menu *cfg, struct pxe_label *label);
+int parse_label_keys(char **c, struct pxe_menu *cfg, struct pxe_label *label,
+ bool ignore_unknown);
/**
* label_boot() - Boot according to the contents of a single pxe_label
--
2.53.0
More information about the U-Boot
mailing list