1313#include "parse-options.h"
1414#include "userdiff.h"
1515#include "grep.h"
16+ #include "quote.h"
1617
1718#ifndef NO_EXTERNAL_GREP
1819#ifdef __unix__
@@ -125,35 +126,22 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, const char
125126 unsigned long size ;
126127 char * data ;
127128 enum object_type type ;
128- char * to_free = NULL ;
129129 int hit ;
130+ struct strbuf pathbuf = STRBUF_INIT ;
130131
131132 data = read_sha1_file (sha1 , & type , & size );
132133 if (!data ) {
133134 error ("'%s': unable to read %s" , name , sha1_to_hex (sha1 ));
134135 return 0 ;
135136 }
136137 if (opt -> relative && opt -> prefix_length ) {
137- static char name_buf [PATH_MAX ];
138- char * cp ;
139- int name_len = strlen (name ) - opt -> prefix_length + 1 ;
140-
141- if (!tree_name_len )
142- name += opt -> prefix_length ;
143- else {
144- if (ARRAY_SIZE (name_buf ) <= name_len )
145- cp = to_free = xmalloc (name_len );
146- else
147- cp = name_buf ;
148- memcpy (cp , name , tree_name_len );
149- strcpy (cp + tree_name_len ,
150- name + tree_name_len + opt -> prefix_length );
151- name = cp ;
152- }
138+ quote_path_relative (name + tree_name_len , -1 , & pathbuf , opt -> prefix );
139+ strbuf_insert (& pathbuf , 0 , name , tree_name_len );
140+ name = pathbuf .buf ;
153141 }
154142 hit = grep_buffer (opt , name , data , size );
143+ strbuf_release (& pathbuf );
155144 free (data );
156- free (to_free );
157145 return hit ;
158146}
159147
@@ -163,6 +151,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
163151 int i ;
164152 char * data ;
165153 size_t sz ;
154+ struct strbuf buf = STRBUF_INIT ;
166155
167156 if (lstat (filename , & st ) < 0 ) {
168157 err_ret :
@@ -187,8 +176,9 @@ static int grep_file(struct grep_opt *opt, const char *filename)
187176 }
188177 close (i );
189178 if (opt -> relative && opt -> prefix_length )
190- filename += opt -> prefix_length ;
179+ filename = quote_path_relative ( filename , -1 , & buf , opt -> prefix ) ;
191180 i = grep_buffer (opt , filename , data , sz );
181+ strbuf_release (& buf );
192182 free (data );
193183 return i ;
194184}
@@ -471,6 +461,7 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached,
471461 hit = external_grep (opt , paths , cached );
472462 if (hit >= 0 )
473463 return hit ;
464+ hit = 0 ;
474465 }
475466#endif
476467
@@ -763,6 +754,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
763754 };
764755
765756 memset (& opt , 0 , sizeof (opt ));
757+ opt .prefix = prefix ;
766758 opt .prefix_length = (prefix && * prefix ) ? strlen (prefix ) : 0 ;
767759 opt .relative = 1 ;
768760 opt .pathname = 1 ;
@@ -832,15 +824,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
832824 verify_filename (prefix , argv [j ]);
833825 }
834826
835- if (i < argc ) {
827+ if (i < argc )
836828 paths = get_pathspec (prefix , argv + i );
837- if (opt .prefix_length && opt .relative ) {
838- /* Make sure we do not get outside of paths */
839- for (i = 0 ; paths [i ]; i ++ )
840- if (strncmp (prefix , paths [i ], opt .prefix_length ))
841- die ("git grep: cannot generate relative filenames containing '..'" );
842- }
843- }
844829 else if (prefix ) {
845830 paths = xcalloc (2 , sizeof (const char * ));
846831 paths [0 ] = prefix ;
0 commit comments