146
const int tree_entry_len = from->hexsz + 5;
147
const int parent_entry_len = from->hexsz + 7;
148
struct object_id oid, mapped_oid;
149
- const char *p;
149
+ const char *p, *eol;
150
151
tail += size;
152
- if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) ||
153
- bufptr[tree_entry_len] != '\n')
154
- return error("bogus commit object");
155
- if (parse_oid_hex_algop(bufptr + 5, &oid, &p, from) < 0)
156
- return error("bad tree pointer");
152
158
- if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
159
- return error("unable to map tree %s in commit object",
160
- oid_to_hex(&oid));
161
- strbuf_addf(out, "tree %s\n", oid_to_hex(&mapped_oid));
162
- bufptr = p + 1;
153
+ while ((bufptr < tail) && (*bufptr != '\n')) {
154
+ eol = memchr(bufptr, '\n', tail - bufptr);
155
+ if (!eol)
156
+ return error(_("bad %s in commit"), "line");
157
+
158
+ if (((bufptr + 5) < eol) && !memcmp(bufptr, "tree ", 5))
159
+ {
160
+ if (((bufptr + tree_entry_len) != eol) ||
161
+ parse_oid_hex_algop(bufptr + 5, &oid, &p, from) ||
162
+ (p != eol))
163
+ return error(_("bad %s in commit"), "tree");
164
+
165
+ if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
166
+ return error(_("unable to map %s %s in commit object"),
167
+ "tree", oid_to_hex(&oid));
168
+ strbuf_addf(out, "tree %s\n", oid_to_hex(&mapped_oid));
169
+ }
170
+ else if (((bufptr + 7) < eol) && !memcmp(bufptr, "parent ", 7))
171
+ {
172
+ if (((bufptr + parent_entry_len) != eol) ||
173
+ parse_oid_hex_algop(bufptr + 7, &oid, &p, from) ||
174
+ (p != eol))
175
+ return error(_("bad %s in commit"), "parent");
176
164
- while (bufptr + parent_entry_len < tail && !memcmp(bufptr, "parent ", 7)) {
165
- if (tail <= bufptr + parent_entry_len + 1 ||
166
- parse_oid_hex_algop(bufptr + 7, &oid, &p, from) ||
167
- *p != '\n')
168
- return error("bad parents in commit");
177
+ if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
178
+ return error(_("unable to map %s %s in commit object"),
179
+ "parent", oid_to_hex(&oid));
180
170
- if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
171
- return error("unable to map parent %s in commit object",
172
- oid_to_hex(&oid));
181
+ strbuf_addf(out, "parent %s\n", oid_to_hex(&mapped_oid));
182
+ }
183
+ else if (((bufptr + 9) < eol) && !memcmp(bufptr, "mergetag ", 9))
184
+ {
185
+ struct strbuf tag = STRBUF_INIT, new_tag = STRBUF_INIT;
186
174
- strbuf_addf(out, "parent %s\n", oid_to_hex(&mapped_oid));
175
- bufptr = p + 1;
187
+ /* Recover the tag object from the mergetag */
188
+ strbuf_add(&tag, bufptr + 9, (eol - (bufptr + 9)) + 1);
189
+
190
+ bufptr = eol + 1;
191
+ while ((bufptr < tail) && (*bufptr == ' ')) {
192
+ eol = memchr(bufptr, '\n', tail - bufptr);
193
+ if (!eol) {
194
+ strbuf_release(&tag);
195
+ return error(_("bad %s in commit"), "mergetag continuation");
196
+ }
197
+ strbuf_add(&tag, bufptr + 1, (eol - (bufptr + 1)) + 1);
198
+ bufptr = eol + 1;
199
+ }
200
+
201
+ /* Compute the new tag object */
202
+ if (convert_tag_object(&new_tag, from, to, tag.buf, tag.len)) {
203
+ strbuf_release(&tag);
204
+ strbuf_release(&new_tag);
205
+ return -1;
206
+ }
207
+
208
+ /* Write the new mergetag */
209
+ strbuf_addstr(out, "mergetag");
210
+ strbuf_add_lines(out, " ", new_tag.buf, new_tag.len);
211
+ strbuf_release(&tag);
212
+ strbuf_release(&new_tag);
213
+ }
214
+ else if (((bufptr + 7) < tail) && !memcmp(bufptr, "author ", 7))
215
+ strbuf_add(out, bufptr, (eol - bufptr) + 1);
216
+ else if (((bufptr + 10) < tail) && !memcmp(bufptr, "committer ", 10))
217
+ strbuf_add(out, bufptr, (eol - bufptr) + 1);
218
+ else if (((bufptr + 9) < tail) && !memcmp(bufptr, "encoding ", 9))
219
+ strbuf_add(out, bufptr, (eol - bufptr) + 1);
220
+ else if (((bufptr + 6) < tail) && !memcmp(bufptr, "gpgsig", 6))
221
+ strbuf_add(out, bufptr, (eol - bufptr) + 1);
222
+ else {
223
+ /* Unknown line fail it might embed an oid */
224
+ return -1;
225
+ }
226
+ /* Consume any trailing continuation lines */
227
+ bufptr = eol + 1;
228
+ while ((bufptr < tail) && (*bufptr == ' ')) {
229
+ eol = memchr(bufptr, '\n', tail - bufptr);
230
+ if (!eol)
231
+ return error(_("bad %s in commit"), "continuation");
232
+ strbuf_add(out, bufptr, (eol - bufptr) + 1);
233
+ bufptr = eol + 1;
234
+ }
235
}
177
- strbuf_add(out, bufptr, tail - bufptr);
236
+ if (bufptr < tail)
237
+ strbuf_add(out, bufptr, tail - bufptr);
238
return 0;
239
}
240