{"record":{"id":"c382b8cdf44c0dc7","repo":"golang/go","slug":"unterminated-quoted-string-in-pkgconf-output","errorCode":null,"errorMessage":"unterminated quoted string in pkgconf output","messagePattern":"unterminated quoted string in pkgconf output","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/exec.go","lineNumber":2041,"sourceCode":"\t\t\tdidQuote = true\n\t\t\tcontinue\n\n\t\tcase ' ', '\\t', '\\n':\n\t\t\tif len(flag) > 0 || didQuote {\n\t\t\t\tflags = append(flags, string(flag))\n\t\t\t}\n\t\t\tflag, didQuote = flag[:0], false\n\t\t\tcontinue\n\t\t}\n\n\t\tflag = append(flag, c)\n\t}\n\n\t// Prefer to report a missing quote instead of a missing escape. If the string\n\t// is something like `\"foo\\`, it's ambiguous as to whether the trailing\n\t// backslash is really an escape at all.\n\tif quote != 0 {\n\t\treturn nil, errors.New(\"unterminated quoted string in pkgconf output\")\n\t}\n\tif escaped {\n\t\treturn nil, errors.New(\"broken character escaping in pkgconf output\")\n\t}\n\n\tif len(flag) > 0 || didQuote {\n\t\tflags = append(flags, string(flag))\n\t}\n\treturn flags, nil\n}\n\n// Calls pkg-config if needed and returns the cflags/ldflags needed to build a's package.\nfunc (b *Builder) getPkgConfigFlags(a *Action, p *load.Package) (cflags, ldflags []string, err error) {\n\tsh := b.Shell(a)\n\tif pcargs := p.CgoPkgConfig; len(pcargs) > 0 {\n\t\t// pkg-config permits arguments to appear anywhere in\n\t\t// the command line. Move them all to the front, before --.\n\t\tvar pcflags []string","sourceCodeStart":2023,"sourceCodeEnd":2059,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/exec.go#L2023-L2059","documentation":"Thrown by parsePkgConfigOutput in cmd/go/internal/work after scanning the cflags/ldflags that pkg-config (pkgconf) printed, when the parser reaches end-of-input with a quote still open (a '\"' or '\\'' with no matching close). pkg-config output is parsed shell-style; an unterminated quote means the tool emitted malformed output that cannot be safely split into flags.","triggerScenarios":"A .pc file (pkg-config package metadata) containing an unbalanced double quote in Cflags or Libs, e.g. `Cflags: -DFOO=\"bar`. A pkg-config implementation that prints trailing whitespace/quotes differently. Manual edits to system .pc files in /usr/lib/pkgconfig or /usr/local/lib/pkgconfig.","commonSituations":"CGo projects using #cgo pkg-config: directives. A misbehaving or buggy pkgconf version. Hand-edited .pc files where a closing quote was deleted. Cross-compilation sysroots with broken .pc files.","solutions":["Run `pkg-config --cflags --libs <yourpkg>` directly and inspect the output for stray quotes.","Open the offending .pc file and fix the unbalanced quote in Cflags/Libs.","Reinstall or upgrade the package that owns the broken .pc file (check with `pkg-config --variable=pcfiledir <pkg>`).","As a workaround, replace the `#cgo pkg-config: foo` line with explicit `#cgo CFLAGS` / `#cgo LDFLAGS` literals."],"exampleFix":"# before — /usr/lib/pkgconfig/foo.pc\nCflags: -I${includedir}/foo -DFOO=\"bar\nLibs: -L${libdir} -lfoo\n\n# after\nCflags: -I${includedir}/foo -DFOO=\\\"bar\\\"\nLibs: -L${libdir} -lfoo","handlingStrategy":"try-catch","validationCode":"// Inspect .pc output before building:\n//   pkg-config --cflags --libs <pkg>\n// Look for any line with an unbalanced '\"' or '\\''.\nfunc balancedQuotes(s string) bool {\n    in byte\n    for i := 0; i < len(s); i++ {\n        c := s[i]\n        if in == 0 && (c == '\"' || c == '\\'') { in = c } else if c == in { in = 0 }\n    }\n    return in == 0\n}","typeGuard":null,"tryCatchPattern":"out, err := b.getPkgConfigFlags(a, p)\nif err != nil && strings.Contains(err.Error(), \"pkgconf output\") {\n    // log the raw pkg-config output, fix the offending .pc file, and retry\n    log.Printf(\"pkg-config emitted malformed flags for %v; inspect .pc file\", p.CgoPkgConfig)\n}","preventionTips":["Treat .pc files as code: review and lint them in CI.","Use forward slashes for paths in .pc Cflags/Libs to avoid quoting pitfalls.","Prefer explicit #cgo CFLAGS/LDFLAGS over pkg-config when shipping to heterogeneous systems."],"tags":["go-toolchain","cgo","pkg-config","parsing","linux"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}