@@ -157,7 +157,7 @@ func ParseGroup(group io.Reader) ([]Group, error) {
157157}
158158
159159func ParseGroupFileFilter (path string , filter func (Group ) bool ) ([]Group , error ) {
160- group , err := os . Open (path )
160+ group , err := openUserFile (path )
161161 if err != nil {
162162 return nil , err
163163 }
@@ -169,52 +169,22 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {
169169 if r == nil {
170170 return nil , errors .New ("nil source for group-formatted data" )
171171 }
172- rd := bufio .NewReader (r )
173- out := []Group {}
174-
175- // Read the file line-by-line.
176- for {
177- var (
178- isPrefix bool
179- wholeLine []byte
180- err error
181- )
182-
183- // Read the next line. We do so in chunks (as much as reader's
184- // buffer is able to keep), check if we read enough columns
185- // already on each step and store final result in wholeLine.
186- for {
187- var line []byte
188- line , isPrefix , err = rd .ReadLine ()
189- if err != nil {
190- // We should return no error if EOF is reached
191- // without a match.
192- if err == io .EOF {
193- err = nil
194- }
195- return out , err
196- }
197172
198- // Simple common case: line is short enough to fit in a
199- // single reader's buffer.
200- if ! isPrefix && len (wholeLine ) == 0 {
201- wholeLine = line
202- break
203- }
173+ var (
174+ s = bufio .NewScanner (r )
175+ out = []Group {}
176+ )
204177
205- wholeLine = append (wholeLine , line ... )
206-
207- // Check if we read the whole line already.
208- if ! isPrefix {
209- break
210- }
211- }
178+ // A group's user_list may be arbitrarily long, so allow lines that are
179+ // much larger than bufio.Scanner's default maximum token size (64 KiB).
180+ s .Buffer (nil , 1024 * 1024 )
212181
182+ for s .Scan () {
213183 // There's no spec for /etc/passwd or /etc/group, but we try to follow
214184 // the same rules as the glibc parser, which allows comments and blank
215185 // space at the beginning of a line.
216- wholeLine = bytes .TrimSpace (wholeLine )
217- if len (wholeLine ) == 0 || wholeLine [0 ] == '#' {
186+ line : = bytes .TrimSpace (s . Bytes () )
187+ if len (line ) == 0 || line [0 ] == '#' {
218188 continue
219189 }
220190
@@ -224,12 +194,17 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {
224194 // root:x:0:root
225195 // adm:x:4:root,adm,daemon
226196 p := Group {}
227- parseLine (wholeLine , & p .Name , & p .Pass , & p .Gid , & p .List )
197+ parseLine (line , & p .Name , & p .Pass , & p .Gid , & p .List )
228198
229199 if filter == nil || filter (p ) {
230200 out = append (out , p )
231201 }
232202 }
203+ if err := s .Err (); err != nil {
204+ return nil , err
205+ }
206+
207+ return out , nil
233208}
234209
235210type ExecUser struct {
@@ -246,12 +221,12 @@ type ExecUser struct {
246221func GetExecUserPath (userSpec string , defaults * ExecUser , passwdPath , groupPath string ) (* ExecUser , error ) {
247222 var passwd , group io.Reader
248223
249- if passwdFile , err := os . Open (passwdPath ); err == nil {
224+ if passwdFile , err := openUserFile (passwdPath ); err == nil {
250225 passwd = passwdFile
251226 defer passwdFile .Close ()
252227 }
253228
254- if groupFile , err := os . Open (groupPath ); err == nil {
229+ if groupFile , err := openUserFile (groupPath ); err == nil {
255230 group = groupFile
256231 defer groupFile .Close ()
257232 }
0 commit comments