@@ -799,12 +799,12 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
799
799
*/
800
800
while ((stk = dir -> exclude_stack ) != NULL ) {
801
801
if (stk -> baselen <= baselen &&
802
- !strncmp (dir -> basebuf , base , stk -> baselen ))
802
+ !strncmp (dir -> basebuf . buf , base , stk -> baselen ))
803
803
break ;
804
804
el = & group -> el [dir -> exclude_stack -> exclude_ix ];
805
805
dir -> exclude_stack = stk -> prev ;
806
806
dir -> exclude = NULL ;
807
- free ((char * )el -> src ); /* see strdup () below */
807
+ free ((char * )el -> src ); /* see strbuf_detach () below */
808
808
clear_exclude_list (el );
809
809
free (stk );
810
810
group -> nr -- ;
@@ -814,8 +814,17 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
814
814
if (dir -> exclude )
815
815
return ;
816
816
817
+ /*
818
+ * Lazy initialization. All call sites currently just
819
+ * memset(dir, 0, sizeof(*dir)) before use. Changing all of
820
+ * them seems lots of work for little benefit.
821
+ */
822
+ if (!dir -> basebuf .buf )
823
+ strbuf_init (& dir -> basebuf , PATH_MAX );
824
+
817
825
/* Read from the parent directories and push them down. */
818
826
current = stk ? stk -> baselen : -1 ;
827
+ strbuf_setlen (& dir -> basebuf , current < 0 ? 0 : current );
819
828
while (current < baselen ) {
820
829
struct exclude_stack * stk = xcalloc (1 , sizeof (* stk ));
821
830
const char * cp ;
@@ -833,48 +842,47 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
833
842
stk -> baselen = cp - base ;
834
843
stk -> exclude_ix = group -> nr ;
835
844
el = add_exclude_list (dir , EXC_DIRS , NULL );
836
- memcpy ( dir -> basebuf + current , base + current ,
837
- stk -> baselen - current );
845
+ strbuf_add ( & dir -> basebuf , base + current , stk -> baselen - current );
846
+ assert ( stk -> baselen == dir -> basebuf . len );
838
847
839
848
/* Abort if the directory is excluded */
840
849
if (stk -> baselen ) {
841
850
int dt = DT_DIR ;
842
- dir -> basebuf [stk -> baselen - 1 ] = 0 ;
851
+ dir -> basebuf . buf [stk -> baselen - 1 ] = 0 ;
843
852
dir -> exclude = last_exclude_matching_from_lists (dir ,
844
- dir -> basebuf , stk -> baselen - 1 ,
845
- dir -> basebuf + current , & dt );
846
- dir -> basebuf [stk -> baselen - 1 ] = '/' ;
853
+ dir -> basebuf . buf , stk -> baselen - 1 ,
854
+ dir -> basebuf . buf + current , & dt );
855
+ dir -> basebuf . buf [stk -> baselen - 1 ] = '/' ;
847
856
if (dir -> exclude &&
848
857
dir -> exclude -> flags & EXC_FLAG_NEGATIVE )
849
858
dir -> exclude = NULL ;
850
859
if (dir -> exclude ) {
851
- dir -> basebuf [stk -> baselen ] = 0 ;
852
860
dir -> exclude_stack = stk ;
853
861
return ;
854
862
}
855
863
}
856
864
857
- /* Try to read per-directory file unless path is too long */
858
- if (dir -> exclude_per_dir &&
859
- stk -> baselen + strlen (dir -> exclude_per_dir ) < PATH_MAX ) {
860
- strcpy (dir -> basebuf + stk -> baselen ,
861
- dir -> exclude_per_dir );
865
+ /* Try to read per-directory file */
866
+ if (dir -> exclude_per_dir ) {
862
867
/*
863
868
* dir->basebuf gets reused by the traversal, but we
864
869
* need fname to remain unchanged to ensure the src
865
870
* member of each struct exclude correctly
866
871
* back-references its source file. Other invocations
867
872
* of add_exclude_list provide stable strings, so we
868
- * strdup () and free() here in the caller.
873
+ * strbuf_detach () and free() here in the caller.
869
874
*/
870
- el -> src = strdup (dir -> basebuf );
871
- add_excludes_from_file_to_list (dir -> basebuf ,
872
- dir -> basebuf , stk -> baselen , el , 1 );
875
+ struct strbuf sb = STRBUF_INIT ;
876
+ strbuf_addbuf (& sb , & dir -> basebuf );
877
+ strbuf_addstr (& sb , dir -> exclude_per_dir );
878
+ el -> src = strbuf_detach (& sb , NULL );
879
+ add_excludes_from_file_to_list (el -> src , el -> src ,
880
+ stk -> baselen , el , 1 );
873
881
}
874
882
dir -> exclude_stack = stk ;
875
883
current = stk -> baselen ;
876
884
}
877
- dir -> basebuf [ baselen ] = '\0' ;
885
+ strbuf_setlen ( & dir -> basebuf , baselen ) ;
878
886
}
879
887
880
888
/*
@@ -1671,4 +1679,5 @@ void clear_directory(struct dir_struct *dir)
1671
1679
free (stk );
1672
1680
stk = prev ;
1673
1681
}
1682
+ strbuf_release (& dir -> basebuf );
1674
1683
}
0 commit comments