{"record":{"id":"0e2c2f847eb471ac","repo":"golang/go","slug":"parsing-cgo-s-allow-v","errorCode":null,"errorMessage":"parsing $CGO_%s_ALLOW: %v","messagePattern":"parsing \\$CGO_(.+?)_ALLOW: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/security.go","lineNumber":377,"sourceCode":"\t\t\tfl == \"-Wl,-static\" || fl == \"-Wl,--static\" ||\n\t\t\tfl == \"-Wl,-Bstatic\" {\n\t\t\treturn fmt.Errorf(\"flag %q triggers external linking\", fl)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc checkFlags(name, source string, list []string, invalid, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {\n\t// Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc.\n\tvar (\n\t\tallow    *regexp.Regexp\n\t\tdisallow *regexp.Regexp\n\t)\n\tif checkOverrides {\n\t\tif env := cfg.Getenv(\"CGO_\" + name + \"_ALLOW\"); env != \"\" {\n\t\t\tr, err := regexp.Compile(env)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"parsing $CGO_%s_ALLOW: %v\", name, err)\n\t\t\t}\n\t\t\tallow = r\n\t\t}\n\t\tif env := cfg.Getenv(\"CGO_\" + name + \"_DISALLOW\"); env != \"\" {\n\t\t\tr, err := regexp.Compile(env)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"parsing $CGO_%s_DISALLOW: %v\", name, err)\n\t\t\t}\n\t\t\tdisallow = r\n\t\t}\n\t}\n\nArgs:\n\tfor i := 0; i < len(list); i++ {\n\t\targ := list[i]\n\t\tif disallow != nil && disallow.FindString(arg) == arg {\n\t\t\tgoto Bad\n\t\t}","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/security.go#L359-L395","documentation":"Thrown by checkFlags when the CGO_<NAME>_ALLOW environment variable (e.g. CGO_CFLAGS_ALLOW, CGO_LDFLAGS_ALLOW) is set to a string that is not a valid Go regexp. The value is compiled with regexp.Compile; a parse failure surfaces as this wrapped error. ALLOW/DISALLOW are user escape-hatches to permit or block specific cgo flags.","triggerScenarios":"Set `CGO_CFLAGS_ALLOW=[invalid` (or any malformed regexp) in the environment and run a cgo build. checkFlags enters the checkOverrides branch (note: for the internal-link variants checkOverrides is false, so this fires from the general compiler/linker flag checkers), compiles the env value, and regexp.Compile returns an error.","commonSituations":"A shell-quoting bug turns a glob into an unbalanced bracket; copy-pasting a PCRE-only construct (e.g. lookahead `(?=...)`) Go's RE2 rejects; a CI secret-injection mangles the variable.","solutions":["Fix the regexp syntax to be RE2-compatible (no lookbehind/lookahead, balanced brackets/parens).","Test locally: `go run` a tiny program calling `regexp.Compile(os.Getenv(\"CGO_CFLAGS_ALLOW\"))`.","Unset the variable if you no longer need the override: `unset CGO_CFLAGS_ALLOW`.","Prefer simpler character classes and escape literal regex metacharacters."],"exampleFix":"// before\n// export CGO_CFLAGS_ALLOW=[-O\n\n// after\n// export CGO_CFLAGS_ALLOW=-O[0-9]","handlingStrategy":"validation","validationCode":"// Validate CGO_CFLAGS_ALLOW regexp before building\nif v := os.Getenv(\"CGO_CFLAGS_ALLOW\"); v != \"\" {\n    if _, err := regexp.Compile(v); err != nil {\n        log.Fatalf(\"fix CGO_CFLAGS_ALLOW: %v\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Test RE2 regexps with regexp.Compile in isolation first.","Avoid PCRE-only features (lookahead, backreferences).","Unset unused CGO_*_ALLOW variables."],"tags":["go-toolchain","cgo","flags","regex","environment"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}