{"record":{"id":"608a66116d52b1d7","repo":"kovidgoyal/kitty","slug":"passwd-line-has-d-colon-delimited-fields-instead","errorCode":null,"errorMessage":"passwd line has %d colon delimited fields instead of 7","messagePattern":"passwd line has (.+?) colon delimited fields instead of 7","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"tools/utils/passwd.go","lineNumber":29,"sourceCode":"\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"howett.net/plist\"\n)\n\nvar _ = fmt.Print\n\ntype PasswdEntry struct {\n\tUsername, Pass, Uid, Gid, Gecos, Home, Shell string\n}\n\nfunc ParsePasswdLine(line string) (PasswdEntry, error) {\n\tparts := strings.Split(line, \":\")\n\tif len(parts) == 7 {\n\t\treturn PasswdEntry{parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6]}, nil\n\t}\n\treturn PasswdEntry{}, fmt.Errorf(\"passwd line has %d colon delimited fields instead of 7\", len(parts))\n}\n\nfunc ParsePasswdDatabase(raw string) (ans map[string]PasswdEntry) {\n\tscanner := NewLineScanner(raw)\n\tans = make(map[string]PasswdEntry)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif entry, e := ParsePasswdLine(line); e == nil {\n\t\t\tans[entry.Uid] = entry\n\t\t}\n\t}\n\treturn ans\n}\n\nfunc ParsePasswdFile(path string) (ans map[string]PasswdEntry, err error) {\n\traw, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/tools/utils/passwd.go#L11-L47","documentation":"ParsePasswdLine splits a line of /etc/passwd (or DSCL output) on colons and expects exactly 7 fields: name, passwd, uid, gid, gecos, home, shell. Any other field count produces this error. It is a strict format validation of passwd-style records.","triggerScenarios":"Feeding ParsePasswdLine a malformed line: missing trailing fields, extra colons in GECOS (e.g. a comment containing ':'), empty lines with colons, or Windows-style line endings leaving stray characters.","commonSituations":"Parsing hand-edited /etc/passwd files, passwd files from exotic NSS backends, or test fixtures that abbreviate lines. Also GECOS fields containing colons, which inflate the field count.","solutions":["Inspect the reported line and its field count; fix or discard malformed entries upstream.","If GECOS may contain colons, split with strings.SplitN(line, \":\", 7) so extra colons stay in the GECOS field.","Skip blank/comment lines before calling ParsePasswdLine.","Validate input with a regexp like ^([^:]*:){6}[^:]*$ before parsing."],"exampleFix":"// before\nparts := strings.Split(line, \":\")\n// after\nparts := strings.SplitN(line, \":\", 7)\nif len(parts) == 7 { ... }","handlingStrategy":"validation","validationCode":"if !passwdLineRE.MatchString(line) {\n    return nil, fmt.Errorf(\"skipping malformed passwd line: %q\", line)\n}\n// var passwdLineRE = regexp.MustCompile(`^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*$`)","typeGuard":null,"tryCatchPattern":"entry, err := utils.ParsePasswdLine(line)\nif err != nil {\n    log.Printf(\"skipping bad passwd line %q: %v\", line, err)\n    continue\n}","preventionTips":["Use SplitN(line, \":\", 7) when GECOS may contain colons.","Skip blank and '#' comment lines before parsing.","Diff custom passwd files against vipw/pwck output."],"tags":["go","passwd","parsing","unix"],"backgroundTag":"malformed-input-record","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}