1010#include "strbuf.h"
1111#include "quote.h"
1212
13- #define MAXNAME (256)
14-
1513typedef struct config_file {
1614 struct config_file * prev ;
1715 FILE * f ;
1816 const char * name ;
1917 int linenr ;
2018 int eof ;
2119 struct strbuf value ;
22- char var [ MAXNAME ] ;
20+ struct strbuf var ;
2321} config_file ;
2422
2523static config_file * cf ;
@@ -260,7 +258,7 @@ static inline int iskeychar(int c)
260258 return isalnum (c ) || c == '-' ;
261259}
262260
263- static int get_value (config_fn_t fn , void * data , char * name , unsigned int len )
261+ static int get_value (config_fn_t fn , void * data , struct strbuf * name )
264262{
265263 int c ;
266264 char * value ;
@@ -272,11 +270,9 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
272270 break ;
273271 if (!iskeychar (c ))
274272 break ;
275- name [len ++ ] = tolower (c );
276- if (len >= MAXNAME )
277- return -1 ;
273+ strbuf_addch (name , tolower (c ));
278274 }
279- name [ len ] = 0 ;
275+
280276 while (c == ' ' || c == '\t' )
281277 c = get_next_char ();
282278
@@ -288,10 +284,10 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
288284 if (!value )
289285 return -1 ;
290286 }
291- return fn (name , value , data );
287+ return fn (name -> buf , value , data );
292288}
293289
294- static int get_extended_base_var (char * name , int baselen , int c )
290+ static int get_extended_base_var (struct strbuf * name , int c )
295291{
296292 do {
297293 if (c == '\n' )
@@ -302,7 +298,7 @@ static int get_extended_base_var(char *name, int baselen, int c)
302298 /* We require the format to be '[base "extension"]' */
303299 if (c != '"' )
304300 return -1 ;
305- name [ baselen ++ ] = '.' ;
301+ strbuf_addch ( name , '.' ) ;
306302
307303 for (;;) {
308304 int c = get_next_char ();
@@ -315,45 +311,39 @@ static int get_extended_base_var(char *name, int baselen, int c)
315311 if (c == '\n' )
316312 goto error_incomplete_line ;
317313 }
318- name [baselen ++ ] = c ;
319- if (baselen > MAXNAME / 2 )
320- return -1 ;
314+ strbuf_addch (name , c );
321315 }
322316
323317 /* Final ']' */
324318 if (get_next_char () != ']' )
325319 return -1 ;
326- return baselen ;
320+ return 0 ;
327321error_incomplete_line :
328322 cf -> linenr -- ;
329323 return -1 ;
330324}
331325
332- static int get_base_var (char * name )
326+ static int get_base_var (struct strbuf * name )
333327{
334- int baselen = 0 ;
335-
336328 for (;;) {
337329 int c = get_next_char ();
338330 if (cf -> eof )
339331 return -1 ;
340332 if (c == ']' )
341- return baselen ;
333+ return 0 ;
342334 if (isspace (c ))
343- return get_extended_base_var (name , baselen , c );
335+ return get_extended_base_var (name , c );
344336 if (!iskeychar (c ) && c != '.' )
345337 return -1 ;
346- if (baselen > MAXNAME / 2 )
347- return -1 ;
348- name [baselen ++ ] = tolower (c );
338+ strbuf_addch (name , tolower (c ));
349339 }
350340}
351341
352342static int git_parse_file (config_fn_t fn , void * data )
353343{
354344 int comment = 0 ;
355345 int baselen = 0 ;
356- char * var = cf -> var ;
346+ struct strbuf * var = & cf -> var ;
357347
358348 /* U+FEFF Byte Order Mark in UTF8 */
359349 static const unsigned char * utf8_bom = (unsigned char * ) "\xef\xbb\xbf" ;
@@ -389,17 +379,24 @@ static int git_parse_file(config_fn_t fn, void *data)
389379 continue ;
390380 }
391381 if (c == '[' ) {
392- baselen = get_base_var (var );
393- if (baselen <= 0 )
382+ /* Reset prior to determining a new stem */
383+ strbuf_reset (var );
384+ if (get_base_var (var ) < 0 || var -> len < 1 )
394385 break ;
395- var [ baselen ++ ] = '.' ;
396- var [ baselen ] = 0 ;
386+ strbuf_addch ( var , '.' ) ;
387+ baselen = var -> len ;
397388 continue ;
398389 }
399390 if (!isalpha (c ))
400391 break ;
401- var [baselen ] = tolower (c );
402- if (get_value (fn , data , var , baselen + 1 ) < 0 )
392+ /*
393+ * Truncate the var name back to the section header
394+ * stem prior to grabbing the suffix part of the name
395+ * and the value.
396+ */
397+ strbuf_setlen (var , baselen );
398+ strbuf_addch (var , tolower (c ));
399+ if (get_value (fn , data , var ) < 0 )
403400 break ;
404401 }
405402 die ("bad config file line %d in %s" , cf -> linenr , cf -> name );
@@ -899,12 +896,14 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
899896 top .linenr = 1 ;
900897 top .eof = 0 ;
901898 strbuf_init (& top .value , 1024 );
899+ strbuf_init (& top .var , 1024 );
902900 cf = & top ;
903901
904902 ret = git_parse_file (fn , data );
905903
906904 /* pop config-file parsing state stack */
907905 strbuf_release (& top .value );
906+ strbuf_release (& top .var );
908907 cf = top .prev ;
909908
910909 fclose (f );
0 commit comments