From 0fbba5ce6654f7d0539a06ae55b0f0fa5dd6786e Mon Sep 17 00:00:00 2001 From: John Kerl Date: Tue, 14 Jul 2026 16:39:29 -0400 Subject: [PATCH] Reject --profile / -P within .mlrrc files (#358) Per maintainer feedback on the PR: profiles are selected on the mlr command line, not from within a .mlrrc file, so --profile / -P inside a .mlrrc file is now a parse error -- the same way --prepipe is rejected there -- rather than being silently ignored. Adds a unit test, a should-fail regression case, and a docs bullet. Co-Authored-By: Claude Fable 5 --- docs/src/customization.md | 3 +++ docs/src/customization.md.in | 3 +++ pkg/climain/mlrcli_mlrrc.go | 4 ++++ pkg/climain/mlrcli_mlrrc_test.go | 21 +++++++++++++++++++ test/cases/cli-mlrrc-profiles/0006/cmd | 1 + test/cases/cli-mlrrc-profiles/0006/env | 1 + test/cases/cli-mlrrc-profiles/0006/experr | 1 + test/cases/cli-mlrrc-profiles/0006/expout | 0 .../cases/cli-mlrrc-profiles/0006/should-fail | 0 test/input/mlrrc-with-profile-flag | 5 +++++ 10 files changed, 39 insertions(+) create mode 100644 test/cases/cli-mlrrc-profiles/0006/cmd create mode 100644 test/cases/cli-mlrrc-profiles/0006/env create mode 100644 test/cases/cli-mlrrc-profiles/0006/experr create mode 100644 test/cases/cli-mlrrc-profiles/0006/expout create mode 100644 test/cases/cli-mlrrc-profiles/0006/should-fail create mode 100644 test/input/mlrrc-with-profile-flag diff --git a/docs/src/customization.md b/docs/src/customization.md index e843d1bbc..c4befde21 100644 --- a/docs/src/customization.md +++ b/docs/src/customization.md @@ -128,6 +128,9 @@ Semantics: * Since `--profile` selects a section of your `.mlrrc`, it can't be combined with `--norc`, or with `MLRRC=__none__` in the environment -- that's a fatal error. +* Profiles are selected on the `mlr` command line, not from within a `.mlrrc` file: putting + `--profile` (or `-P`) inside a `.mlrrc` file is a parse error, just as `--prepipe` is. + ## Where to put your .mlrrc If the environment variable `MLRRC` is set: diff --git a/docs/src/customization.md.in b/docs/src/customization.md.in index 155a62f39..be84ad4fc 100644 --- a/docs/src/customization.md.in +++ b/docs/src/customization.md.in @@ -96,6 +96,9 @@ Semantics: * Since `--profile` selects a section of your `.mlrrc`, it can't be combined with `--norc`, or with `MLRRC=__none__` in the environment -- that's a fatal error. +* Profiles are selected on the `mlr` command line, not from within a `.mlrrc` file: putting + `--profile` (or `-P`) inside a `.mlrrc` file is a parse error, just as `--prepipe` is. + ## Where to put your .mlrrc If the environment variable `MLRRC` is set: diff --git a/pkg/climain/mlrcli_mlrrc.go b/pkg/climain/mlrcli_mlrrc.go index 25574b7ef..8d56eacd9 100644 --- a/pkg/climain/mlrcli_mlrrc.go +++ b/pkg/climain/mlrcli_mlrrc.go @@ -231,6 +231,10 @@ func handleMlrrcLine( } else if args[0] == "--load" || args[0] == "--mload" { // Don't allow code execution via .mlrrc return false + } else if args[0] == "--profile" || args[0] == "-P" { + // Profiles are selected on the mlr command line, not from within a + // .mlrrc file + return false } else if cli.FLAG_TABLE.Parse(args, argc, &argi, options) { // handled } else { diff --git a/pkg/climain/mlrcli_mlrrc_test.go b/pkg/climain/mlrcli_mlrrc_test.go index 16f5e101e..2b2efd8eb 100644 --- a/pkg/climain/mlrcli_mlrrc_test.go +++ b/pkg/climain/mlrcli_mlrrc_test.go @@ -196,3 +196,24 @@ func TestMlrrcPrepipeStillDisallowed(t *testing.T) { t.Fatal("expected error for --prepipe within a profile, got nil") } } + +func TestMlrrcProfileFlagDisallowedWithinMlrrc(t *testing.T) { + // Profiles are selected on the mlr command line, not from within a + // .mlrrc file: --profile / -P there is a parse error, like --prepipe. + for _, line := range []string{"profile j", "--profile j", "-P j"} { + writeTempMlrrc(t, line+"\n") + options := cli.DefaultOptions() + err := loadMlrrc(options, "") + if err == nil { + t.Errorf("expected parse error for %q within .mlrrc, got nil", line) + } else if !strings.Contains(err.Error(), "parse error") { + t.Errorf("expected parse error for %q within .mlrrc, got: %v", line, err) + } + } + // Inside a selected profile section, too. + writeTempMlrrc(t, "[j]\nprofile p\n") + options := cli.DefaultOptions() + if err := loadMlrrc(options, "j"); err == nil { + t.Fatal("expected parse error for --profile within a profile section, got nil") + } +} diff --git a/test/cases/cli-mlrrc-profiles/0006/cmd b/test/cases/cli-mlrrc-profiles/0006/cmd new file mode 100644 index 000000000..10c885251 --- /dev/null +++ b/test/cases/cli-mlrrc-profiles/0006/cmd @@ -0,0 +1 @@ +mlr cat test/input/a.csv diff --git a/test/cases/cli-mlrrc-profiles/0006/env b/test/cases/cli-mlrrc-profiles/0006/env new file mode 100644 index 000000000..10250cf93 --- /dev/null +++ b/test/cases/cli-mlrrc-profiles/0006/env @@ -0,0 +1 @@ +MLRRC=test/input/mlrrc-with-profile-flag diff --git a/test/cases/cli-mlrrc-profiles/0006/experr b/test/cases/cli-mlrrc-profiles/0006/experr new file mode 100644 index 000000000..fef0e1ca8 --- /dev/null +++ b/test/cases/cli-mlrrc-profiles/0006/experr @@ -0,0 +1 @@ +mlr: parse error at file "test/input/mlrrc-with-profile-flag" line 2: profile j diff --git a/test/cases/cli-mlrrc-profiles/0006/expout b/test/cases/cli-mlrrc-profiles/0006/expout new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/cli-mlrrc-profiles/0006/should-fail b/test/cases/cli-mlrrc-profiles/0006/should-fail new file mode 100644 index 000000000..e69de29bb diff --git a/test/input/mlrrc-with-profile-flag b/test/input/mlrrc-with-profile-flag new file mode 100644 index 000000000..d53948444 --- /dev/null +++ b/test/input/mlrrc-with-profile-flag @@ -0,0 +1,5 @@ +icsv +profile j + +[j] +ojson