@@ -21,6 +21,18 @@ struct git_mailmap {
2121 git_vector entries ;
2222};
2323
24+ static void mailmap_entry_free (git_mailmap_entry * entry )
25+ {
26+ if (!entry )
27+ return ;
28+
29+ git__free (entry -> real_name );
30+ git__free (entry -> real_email );
31+ git__free (entry -> replace_name );
32+ git__free (entry -> replace_email );
33+ git__free (entry );
34+ }
35+
2436/* Check if we're at the end of line, w/ comments */
2537static bool is_eol (git_parse_ctx * ctx )
2638{
@@ -43,7 +55,8 @@ static int advance_until(
4355 return 0 ;
4456}
4557
46- /* Parse a single entry from a mailmap file.
58+ /*
59+ * Parse a single entry from a mailmap file.
4760 *
4861 * The output git_bufs will be non-owning, and should be copied before being
4962 * persisted.
@@ -61,16 +74,21 @@ static int parse_mailmap_entry(
6174 git_buf_clear (replace_name );
6275 git_buf_clear (replace_email );
6376
64- /* Parse the real name */
6577 git_parse_advance_ws (ctx );
78+ if (is_eol (ctx ))
79+ return -1 ; /* blank line */
80+
81+ /* Parse the real name */
6682 if (advance_until (& start , & len , ctx , '<' ) < 0 )
6783 return -1 ;
6884
6985 git_buf_attach_notowned (real_name , start , len );
7086 git_buf_rtrim (real_name );
7187
72- /* If this is the last email in the line, this is the email to replace,
73- * otherwise, it's the real email. */
88+ /*
89+ * If this is the last email in the line, this is the email to replace,
90+ * otherwise, it's the real email.
91+ */
7492 if (advance_until (& start , & len , ctx , '>' ) < 0 )
7593 return -1 ;
7694
@@ -131,38 +149,27 @@ int git_mailmap_from_buffer(git_mailmap **out, git_buf *buf)
131149 if (error < 0 ) {
132150 error = 0 ; /* Skip lines which don't contain a valid entry */
133151 git_parse_advance_line (& ctx );
134- continue ;
152+ continue ; /* TODO: warn */
135153 }
136154
137- GITERR_CHECK_ALLOC_ADD5 (
138- & entry_size , sizeof (git_mailmap_entry ) + 4 /* 4x'\0' */ ,
139- real_name .size , real_email .size ,
140- replace_name .size , replace_email .size );
141- entry = git__calloc (1 , entry_size );
155+ entry = git__calloc (1 , sizeof (git_mailmap_entry ));
142156 GITERR_CHECK_ALLOC (entry );
143-
144157 entry -> version = GIT_MAILMAP_ENTRY_VERSION ;
145158
146- /* Copy strings into the buffer following entry */
147- entry_data = (char * )(entry + 1 );
148159 if (real_name .size > 0 ) {
149- memcpy (entry_data , real_name .ptr , real_name .size );
150- entry -> real_name = entry_data ;
151- entry_data += real_name .size + 1 ; /* advance past null from calloc */
160+ entry -> real_name = git__substrdup (real_name .ptr , real_name .size );
161+ GITERR_CHECK_ALLOC (entry -> real_name );
152162 }
153163 if (real_email .size > 0 ) {
154- memcpy (entry_data , real_email .ptr , real_email .size );
155- entry -> real_email = entry_data ;
156- entry_data += real_email .size + 1 ;
164+ entry -> real_email = git__substrdup (real_email .ptr , real_email .size );
165+ GITERR_CHECK_ALLOC (entry -> real_email );
157166 }
158167 if (replace_name .size > 0 ) {
159- memcpy (entry_data , replace_name .ptr , replace_name .size );
160- entry -> replace_name = entry_data ;
161- entry_data += replace_name .size + 1 ;
168+ entry -> replace_name = git__substrdup (replace_name .ptr , replace_name .size );
169+ GITERR_CHECK_ALLOC (entry -> replace_name );
162170 }
163- /* replace_email is always non-null */
164- memcpy (entry_data , replace_email .ptr , replace_email .size );
165- entry -> replace_email = entry_data ;
171+ entry -> replace_email = git__substrdup (replace_email .ptr , replace_email .size );
172+ GITERR_CHECK_ALLOC (entry -> replace_email );
166173
167174 error = git_vector_insert (& mm -> entries , entry );
168175 if (error < 0 )
@@ -175,7 +182,7 @@ int git_mailmap_from_buffer(git_mailmap **out, git_buf *buf)
175182 mm = NULL ;
176183
177184cleanup :
178- git__free (entry );
185+ mailmap_entry_free (entry );
179186 git_mailmap_free (mm );
180187
181188 /* We never allocate data in these buffers, but better safe than sorry */
@@ -191,11 +198,15 @@ void git_mailmap_free(git_mailmap *mailmap)
191198 if (!mailmap )
192199 return ;
193200
194- git_vector_free_deep (& mailmap -> entries );
201+ git_vector_foreach (& mailmap -> entries , i , entry ) {
202+ mailmap_entry_free (entry );
203+ }
204+ git_vector_free (& mailmap -> entries );
205+
195206 git__free (mailmap );
196207}
197208
198- void git_mailmap_resolve (
209+ int git_mailmap_resolve (
199210 const char * * name_out , const char * * email_out ,
200211 const git_mailmap * mailmap ,
201212 const char * name , const char * email )
@@ -207,7 +218,7 @@ void git_mailmap_resolve(
207218 * email_out = email ;
208219
209220 if (!mailmap )
210- return ;
221+ return 0 ;
211222
212223 entry = git_mailmap_entry_lookup (mailmap , name , email );
213224 if (entry ) {
@@ -216,6 +227,7 @@ void git_mailmap_resolve(
216227 if (entry -> real_email )
217228 * email_out = entry -> real_email ;
218229 }
230+ return 0 ;
219231}
220232
221233const git_mailmap_entry * git_mailmap_entry_lookup (
@@ -229,10 +241,12 @@ const git_mailmap_entry *git_mailmap_entry_lookup(
229241 return NULL ;
230242
231243 git_vector_foreach (& mailmap -> entries , i , entry ) {
232- if (!git__strcmp (email , entry -> replace_email ) &&
233- (!entry -> replace_name || !git__strcmp (name , entry -> replace_name ))) {
234- return entry ;
235- }
244+ if (git__strcmp (email , entry -> replace_email ))
245+ continue ;
246+ if (entry -> replace_name && git__strcmp (name , entry -> replace_name ))
247+ continue ;
248+
249+ return entry ;
236250 }
237251
238252 return NULL ;
0 commit comments