Skip to content

Commit f70fa53

Browse files
committed
Replace InsecureProcessPluginNames with EnableProcessPlugins
A single bool is enough — the previous allowlist by-name was overkill once we accepted the CLI is responsible for translating SQLCDEBUG into the option. EnableProcessPlugins=false (zero value) refuses any process plugin in the config; the CLI sets it to env.Debug.ProcessPlugins which defaults to true and flips off under SQLCDEBUG=processplugins=0. This drops the config pre-parse the CLI was doing to extract plugin names; loadConfig now just reads bytes and chdirs. https://claude.ai/code/session_01RCzB2JR5Y5ScFDUmwcxGVZ
1 parent ff433ad commit f70fa53

2 files changed

Lines changed: 39 additions & 64 deletions

File tree

internal/api/generate.go

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"fmt"
77
"io"
88
"path/filepath"
9-
"slices"
109
"strings"
1110
"sync"
1211

@@ -39,14 +38,14 @@ type GenerateOptions struct {
3938
// labels. When empty, BaseDir defaults to the current working directory.
4039
BaseDir string
4140

42-
// InsecureProcessPluginNames is the allowlist of process-based plugin
43-
// names that Generate is permitted to invoke. Any process plugin declared
44-
// in the configuration whose name is not in this list causes Generate to
45-
// fail before parsing or codegen runs. Process plugins execute arbitrary
46-
// local commands; the "Insecure" prefix mirrors
47-
// crypto/tls.Config.InsecureSkipVerify as a reminder that callers must
48-
// consciously trust each plugin name they pass here.
49-
InsecureProcessPluginNames []string
41+
// EnableProcessPlugins controls whether the configuration may invoke
42+
// process-based plugins. When false (the zero value), Generate fails
43+
// before parsing or codegen runs if the configuration declares any
44+
// process plugin. Process plugins execute arbitrary local commands, so
45+
// callers must opt in explicitly. The sqlc CLI populates this from
46+
// SQLCDEBUG: it defaults to true, and SQLCDEBUG=processplugins=0 turns
47+
// it off.
48+
EnableProcessPlugins bool
5049
}
5150

5251
// GenerateResult is the outcome of a Generate call.
@@ -97,15 +96,14 @@ func Generate(ctx context.Context, opts GenerateOptions) GenerateResult {
9796
return res
9897
}
9998

100-
for _, plug := range conf.Plugins {
101-
if plug.Process == nil {
102-
continue
103-
}
104-
if !slices.Contains(opts.InsecureProcessPluginNames, plug.Name) {
105-
err := fmt.Errorf("process plugin %q is not in InsecureProcessPluginNames; refusing to run", plug.Name)
106-
fmt.Fprintf(stderr, "error validating config: %s\n", err)
107-
res.Errors = append(res.Errors, err)
108-
return res
99+
if !opts.EnableProcessPlugins {
100+
for _, plug := range conf.Plugins {
101+
if plug.Process != nil {
102+
err := fmt.Errorf("process plugin %q declared but EnableProcessPlugins is false", plug.Name)
103+
fmt.Fprintf(stderr, "error validating config: %s\n", err)
104+
res.Errors = append(res.Errors, err)
105+
return res
106+
}
109107
}
110108
}
111109

internal/cmd/cmd.go

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,11 @@ func getConfigPath(stderr io.Writer, f *pflag.Flag) (string, string) {
183183
}
184184
}
185185

186-
// loadConfig opens the sqlc config and reads it into memory. It also chdirs
187-
// the process to the config's directory so that relative paths declared in the
188-
// config resolve correctly when api.Generate is called. Returns the config
189-
// bytes, the absolute config directory (for api.GenerateOptions.BaseDir), and
190-
// the list of process plugin names declared in the config (used to populate
191-
// api.GenerateOptions.InsecureProcessPluginNames).
192-
func loadConfig(stderr io.Writer, dir, name string) ([]byte, string, []string) {
186+
// loadConfig reads the sqlc config into memory and chdirs the process to its
187+
// directory so relative paths in the config resolve correctly. Returns the
188+
// config bytes and the absolute config directory (for
189+
// api.GenerateOptions.BaseDir).
190+
func loadConfig(stderr io.Writer, dir, name string) ([]byte, string) {
193191
configPath, _, err := readConfig(stderr, dir, name)
194192
if err != nil {
195193
os.Exit(1)
@@ -204,33 +202,12 @@ func loadConfig(stderr io.Writer, dir, name string) ([]byte, string, []string) {
204202
fmt.Fprintf(stderr, "error reading %s: %s\n", configPath, err)
205203
os.Exit(1)
206204
}
207-
conf, err := config.ParseConfig(bytes.NewReader(data))
208-
if err != nil {
209-
fmt.Fprintf(stderr, "error parsing %s: %s\n", configPath, err)
210-
os.Exit(1)
211-
}
212205
configDir := filepath.Dir(configPath)
213206
if err := os.Chdir(configDir); err != nil {
214207
fmt.Fprintf(stderr, "error changing directory: %s\n", err)
215208
os.Exit(1)
216209
}
217-
var names []string
218-
for _, p := range conf.Plugins {
219-
if p.Process != nil {
220-
names = append(names, p.Name)
221-
}
222-
}
223-
return data, configDir, names
224-
}
225-
226-
// allowedProcessPluginNames returns the names that should populate
227-
// api.GenerateOptions.InsecureProcessPluginNames. SQLCDEBUG=processplugins=0
228-
// disables every process plugin by returning nil.
229-
func allowedProcessPluginNames(env Env, declared []string) []string {
230-
if !env.Debug.ProcessPlugins {
231-
return nil
232-
}
233-
return declared
210+
return data, configDir
234211
}
235212

236213
var genCmd = &cobra.Command{
@@ -241,13 +218,13 @@ var genCmd = &cobra.Command{
241218
stderr := cmd.ErrOrStderr()
242219
dir, name := getConfigPath(stderr, cmd.Flag("file"))
243220
env := ParseEnv(cmd)
244-
data, baseDir, declared := loadConfig(stderr, dir, name)
221+
data, baseDir := loadConfig(stderr, dir, name)
245222
res := api.Generate(cmd.Context(), api.GenerateOptions{
246-
Config: bytes.NewReader(data),
247-
Stderr: stderr,
248-
Write: true,
249-
BaseDir: baseDir,
250-
InsecureProcessPluginNames: allowedProcessPluginNames(env, declared),
223+
Config: bytes.NewReader(data),
224+
Stderr: stderr,
225+
Write: true,
226+
BaseDir: baseDir,
227+
EnableProcessPlugins: env.Debug.ProcessPlugins,
251228
})
252229
if len(res.Errors) > 0 {
253230
os.Exit(1)
@@ -264,12 +241,12 @@ var checkCmd = &cobra.Command{
264241
stderr := cmd.ErrOrStderr()
265242
dir, name := getConfigPath(stderr, cmd.Flag("file"))
266243
env := ParseEnv(cmd)
267-
data, baseDir, declared := loadConfig(stderr, dir, name)
244+
data, baseDir := loadConfig(stderr, dir, name)
268245
res := api.Generate(cmd.Context(), api.GenerateOptions{
269-
Config: bytes.NewReader(data),
270-
Stderr: stderr,
271-
BaseDir: baseDir,
272-
InsecureProcessPluginNames: allowedProcessPluginNames(env, declared),
246+
Config: bytes.NewReader(data),
247+
Stderr: stderr,
248+
BaseDir: baseDir,
249+
EnableProcessPlugins: env.Debug.ProcessPlugins,
273250
})
274251
if len(res.Errors) > 0 {
275252
os.Exit(1)
@@ -286,13 +263,13 @@ var diffCmd = &cobra.Command{
286263
stderr := cmd.ErrOrStderr()
287264
dir, name := getConfigPath(stderr, cmd.Flag("file"))
288265
env := ParseEnv(cmd)
289-
data, baseDir, declared := loadConfig(stderr, dir, name)
266+
data, baseDir := loadConfig(stderr, dir, name)
290267
res := api.Generate(cmd.Context(), api.GenerateOptions{
291-
Config: bytes.NewReader(data),
292-
Stderr: stderr,
293-
Diff: true,
294-
BaseDir: baseDir,
295-
InsecureProcessPluginNames: allowedProcessPluginNames(env, declared),
268+
Config: bytes.NewReader(data),
269+
Stderr: stderr,
270+
Diff: true,
271+
BaseDir: baseDir,
272+
EnableProcessPlugins: env.Debug.ProcessPlugins,
296273
})
297274
if len(res.Errors) > 0 {
298275
os.Exit(1)

0 commit comments

Comments
 (0)