@@ -1086,15 +1086,23 @@ static int gitdiff_unrecognized(const char *line, struct patch *patch)
1086
1086
return -1 ;
1087
1087
}
1088
1088
1089
- static const char * stop_at_slash (const char * line , int llen )
1089
+ /*
1090
+ * Skip p_value leading components from "line"; as we do not accept
1091
+ * absolute paths, return NULL in that case.
1092
+ */
1093
+ static const char * skip_tree_prefix (const char * line , int llen )
1090
1094
{
1091
- int nslash = p_value ;
1095
+ int nslash ;
1092
1096
int i ;
1093
1097
1098
+ if (!p_value )
1099
+ return (llen && line [0 ] == '/' ) ? NULL : line ;
1100
+
1101
+ nslash = p_value ;
1094
1102
for (i = 0 ; i < llen ; i ++ ) {
1095
1103
int ch = line [i ];
1096
1104
if (ch == '/' && -- nslash <= 0 )
1097
- return & line [i ];
1105
+ return ( i == 0 ) ? NULL : & line [i + 1 ];
1098
1106
}
1099
1107
return NULL ;
1100
1108
}
@@ -1124,12 +1132,11 @@ static char *git_header_name(const char *line, int llen)
1124
1132
if (unquote_c_style (& first , line , & second ))
1125
1133
goto free_and_fail1 ;
1126
1134
1127
- /* advance to the first slash */
1128
- cp = stop_at_slash (first .buf , first .len );
1129
- /* we do not accept absolute paths */
1130
- if (!cp || cp == first .buf )
1135
+ /* strip the a/b prefix including trailing slash */
1136
+ cp = skip_tree_prefix (first .buf , first .len );
1137
+ if (!cp )
1131
1138
goto free_and_fail1 ;
1132
- strbuf_remove (& first , 0 , cp + 1 - first .buf );
1139
+ strbuf_remove (& first , 0 , cp - first .buf );
1133
1140
1134
1141
/*
1135
1142
* second points at one past closing dq of name.
@@ -1143,22 +1150,21 @@ static char *git_header_name(const char *line, int llen)
1143
1150
if (* second == '"' ) {
1144
1151
if (unquote_c_style (& sp , second , NULL ))
1145
1152
goto free_and_fail1 ;
1146
- cp = stop_at_slash (sp .buf , sp .len );
1147
- if (!cp || cp == sp . buf )
1153
+ cp = skip_tree_prefix (sp .buf , sp .len );
1154
+ if (!cp )
1148
1155
goto free_and_fail1 ;
1149
1156
/* They must match, otherwise ignore */
1150
- if (strcmp (cp + 1 , first .buf ))
1157
+ if (strcmp (cp , first .buf ))
1151
1158
goto free_and_fail1 ;
1152
1159
strbuf_release (& sp );
1153
1160
return strbuf_detach (& first , NULL );
1154
1161
}
1155
1162
1156
1163
/* unquoted second */
1157
- cp = stop_at_slash (second , line + llen - second );
1158
- if (!cp || cp == second )
1164
+ cp = skip_tree_prefix (second , line + llen - second );
1165
+ if (!cp )
1159
1166
goto free_and_fail1 ;
1160
- cp ++ ;
1161
- if (line + llen - cp != first .len + 1 ||
1167
+ if (line + llen - cp != first .len ||
1162
1168
memcmp (first .buf , cp , first .len ))
1163
1169
goto free_and_fail1 ;
1164
1170
return strbuf_detach (& first , NULL );
@@ -1170,10 +1176,9 @@ static char *git_header_name(const char *line, int llen)
1170
1176
}
1171
1177
1172
1178
/* unquoted first name */
1173
- name = stop_at_slash (line , llen );
1174
- if (!name || name == line )
1179
+ name = skip_tree_prefix (line , llen );
1180
+ if (!name )
1175
1181
return NULL ;
1176
- name ++ ;
1177
1182
1178
1183
/*
1179
1184
* since the first name is unquoted, a dq if exists must be
@@ -1187,10 +1192,9 @@ static char *git_header_name(const char *line, int llen)
1187
1192
if (unquote_c_style (& sp , second , NULL ))
1188
1193
goto free_and_fail2 ;
1189
1194
1190
- np = stop_at_slash (sp .buf , sp .len );
1191
- if (!np || np == sp . buf )
1195
+ np = skip_tree_prefix (sp .buf , sp .len );
1196
+ if (!np )
1192
1197
goto free_and_fail2 ;
1193
- np ++ ;
1194
1198
1195
1199
len = sp .buf + sp .len - np ;
1196
1200
if (len < second - name &&
@@ -1222,13 +1226,27 @@ static char *git_header_name(const char *line, int llen)
1222
1226
case '\n' :
1223
1227
return NULL ;
1224
1228
case '\t' : case ' ' :
1225
- second = stop_at_slash (name + len , line_len - len );
1229
+ /*
1230
+ * Is this the separator between the preimage
1231
+ * and the postimage pathname? Again, we are
1232
+ * only interested in the case where there is
1233
+ * no rename, as this is only to set def_name
1234
+ * and a rename patch has the names elsewhere
1235
+ * in an unambiguous form.
1236
+ */
1237
+ if (!name [len + 1 ])
1238
+ return NULL ; /* no postimage name */
1239
+ second = skip_tree_prefix (name + len + 1 ,
1240
+ line_len - (len + 1 ));
1226
1241
if (!second )
1227
1242
return NULL ;
1228
- second ++ ;
1229
- if (second [len ] == '\n' && !strncmp (name , second , len )) {
1243
+ /*
1244
+ * Does len bytes starting at "name" and "second"
1245
+ * (that are separated by one HT or SP we just
1246
+ * found) exactly match?
1247
+ */
1248
+ if (second [len ] == '\n' && !strncmp (name , second , len ))
1230
1249
return xmemdupz (name , len );
1231
- }
1232
1250
}
1233
1251
}
1234
1252
}
0 commit comments