2 * Copyright (c) 2018, 2019, 2020 Stefan Sperling <stsp@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <sys/types.h>
19 #include <sys/queue.h>
22 #include <sys/socket.h>
36 #include "got_compat.h"
38 #include "got_error.h"
39 #include "got_object.h"
40 #include "got_repository.h"
41 #include "got_opentemp.h"
44 #include "got_lib_sha1.h"
45 #include "got_lib_delta.h"
46 #include "got_lib_inflate.h"
47 #include "got_lib_object.h"
48 #include "got_lib_object_parse.h"
49 #include "got_lib_object_cache.h"
50 #include "got_lib_pack.h"
51 #include "got_lib_privsep.h"
52 #include "got_lib_repository.h"
55 #define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
58 struct got_object_id
*
59 got_object_id_dup(struct got_object_id
*id1
)
61 struct got_object_id
*id2
;
63 id2
= malloc(sizeof(*id2
));
66 memcpy(id2
, id1
, sizeof(*id2
));
71 got_object_id_cmp(const struct got_object_id
*id1
,
72 const struct got_object_id
*id2
)
74 return memcmp(id1
->sha1
, id2
->sha1
, SHA1_DIGEST_LENGTH
);
77 const struct got_error
*
78 got_object_qid_alloc_partial(struct got_object_qid
**qid
)
80 const struct got_error
*err
= NULL
;
82 *qid
= malloc(sizeof(**qid
));
84 return got_error_from_errno("malloc");
86 (*qid
)->id
= malloc(sizeof(*((*qid
)->id
)));
87 if ((*qid
)->id
== NULL
) {
88 err
= got_error_from_errno("malloc");
89 got_object_qid_free(*qid
);
98 const struct got_error
*
99 got_object_id_str(char **outbuf
, struct got_object_id
*id
)
101 static const size_t len
= SHA1_DIGEST_STRING_LENGTH
;
103 *outbuf
= malloc(len
);
105 return got_error_from_errno("malloc");
107 if (got_sha1_digest_to_str(id
->sha1
, *outbuf
, len
) == NULL
) {
110 return got_error(GOT_ERR_BAD_OBJ_ID_STR
);
117 got_object_close(struct got_object
*obj
)
119 if (obj
->refcnt
> 0) {
125 if (obj
->flags
& GOT_OBJ_FLAG_DELTIFIED
) {
126 struct got_delta
*delta
;
127 while (!STAILQ_EMPTY(&obj
->deltas
.entries
)) {
128 delta
= STAILQ_FIRST(&obj
->deltas
.entries
);
129 STAILQ_REMOVE_HEAD(&obj
->deltas
.entries
, entry
);
136 const struct got_error
*
137 got_object_raw_close(struct got_raw_object
*obj
)
139 const struct got_error
*err
= NULL
;
141 if (obj
->refcnt
> 0) {
147 if (obj
->f
!= NULL
&& fclose(obj
->f
) == EOF
&& err
== NULL
)
148 err
= got_error_from_errno("fclose");
155 got_object_qid_free(struct got_object_qid
*qid
)
162 got_object_id_queue_free(struct got_object_id_queue
*ids
)
164 struct got_object_qid
*qid
;
166 while (!STAILQ_EMPTY(ids
)) {
167 qid
= STAILQ_FIRST(ids
);
168 STAILQ_REMOVE_HEAD(ids
, entry
);
169 got_object_qid_free(qid
);
173 const struct got_error
*
174 got_object_parse_header(struct got_object
**obj
, char *buf
, size_t len
)
176 const char *obj_labels
[] = {
177 GOT_OBJ_LABEL_COMMIT
,
182 const int obj_types
[] = {
189 size_t size
= 0, hdrlen
= 0;
194 hdrlen
= strnlen(buf
, len
) + 1 /* '\0' */;
196 return got_error(GOT_ERR_BAD_OBJ_HDR
);
198 for (i
= 0; i
< nitems(obj_labels
); i
++) {
199 const char *label
= obj_labels
[i
];
200 size_t label_len
= strlen(label
);
203 if (strncmp(buf
, label
, label_len
) != 0)
207 if (len
<= label_len
)
208 return got_error(GOT_ERR_BAD_OBJ_HDR
);
209 size
= strtonum(buf
+ label_len
, 0, LONG_MAX
, &errstr
);
211 return got_error(GOT_ERR_BAD_OBJ_HDR
);
216 return got_error(GOT_ERR_BAD_OBJ_HDR
);
218 *obj
= calloc(1, sizeof(**obj
));
220 return got_error_from_errno("calloc");
222 (*obj
)->hdrlen
= hdrlen
;
227 const struct got_error
*
228 got_object_read_header(struct got_object
**obj
, int fd
)
230 const struct got_error
*err
;
231 struct got_inflate_buf zb
;
233 const size_t zbsize
= 64;
234 size_t outlen
, totlen
;
239 buf
= malloc(zbsize
);
241 return got_error_from_errno("malloc");
243 err
= got_inflate_init(&zb
, buf
, zbsize
, NULL
);
249 err
= got_inflate_read_fd(&zb
, fd
, &outlen
, NULL
);
255 if (memchr(zb
.outbuf
, '\0', outlen
) == NULL
) {
258 newbuf
= recallocarray(buf
, nbuf
- 1, nbuf
, zbsize
);
259 if (newbuf
== NULL
) {
260 err
= got_error_from_errno("recallocarray");
264 zb
.outbuf
= newbuf
+ totlen
;
265 zb
.outlen
= (nbuf
* zbsize
) - totlen
;
267 } while (memchr(zb
.outbuf
, '\0', outlen
) == NULL
);
269 err
= got_object_parse_header(obj
, buf
, totlen
);
272 got_inflate_end(&zb
);
276 struct got_commit_object
*
277 got_object_commit_alloc_partial(void)
279 struct got_commit_object
*commit
;
281 commit
= calloc(1, sizeof(*commit
));
284 commit
->tree_id
= malloc(sizeof(*commit
->tree_id
));
285 if (commit
->tree_id
== NULL
) {
290 STAILQ_INIT(&commit
->parent_ids
);
295 const struct got_error
*
296 got_object_commit_add_parent(struct got_commit_object
*commit
,
299 const struct got_error
*err
= NULL
;
300 struct got_object_qid
*qid
;
302 err
= got_object_qid_alloc_partial(&qid
);
306 if (!got_parse_sha1_digest(qid
->id
->sha1
, id_str
)) {
307 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
308 got_object_qid_free(qid
);
312 STAILQ_INSERT_TAIL(&commit
->parent_ids
, qid
, entry
);
318 static const struct got_error
*
319 parse_gmtoff(time_t *gmtoff
, const char *tzstr
)
322 const char *p
= tzstr
;
330 return got_error(GOT_ERR_BAD_OBJ_DATA
);
332 if (!isdigit(*p
) && !isdigit(*(p
+ 1)))
333 return got_error(GOT_ERR_BAD_OBJ_DATA
);
334 h
= (((*p
- '0') * 10) + (*(p
+ 1) - '0'));
337 if (!isdigit(*p
) && !isdigit(*(p
+ 1)))
338 return got_error(GOT_ERR_BAD_OBJ_DATA
);
339 m
= ((*p
- '0') * 10) + (*(p
+ 1) - '0');
341 *gmtoff
= (h
* 60 * 60 + m
* 60) * sign
;
345 static const struct got_error
*
346 parse_commit_time(time_t *time
, time_t *gmtoff
, char *committer
)
348 const struct got_error
*err
= NULL
;
352 /* Parse and strip off trailing timezone indicator string. */
353 space
= strrchr(committer
, ' ');
355 return got_error(GOT_ERR_BAD_OBJ_DATA
);
356 tzstr
= strdup(space
+ 1);
358 return got_error_from_errno("strdup");
359 err
= parse_gmtoff(gmtoff
, tzstr
);
362 if (err
->code
!= GOT_ERR_BAD_OBJ_DATA
)
364 /* Old versions of Git omitted the timestamp. */
371 /* Timestamp is separated from committer name + email by space. */
372 space
= strrchr(committer
, ' ');
374 return got_error(GOT_ERR_BAD_OBJ_DATA
);
376 /* Timestamp parsed here is expressed as UNIX timestamp (UTC). */
377 *time
= strtonum(space
+ 1, 0, INT64_MAX
, &errstr
);
379 return got_error(GOT_ERR_BAD_OBJ_DATA
);
381 /* Strip off parsed time information, leaving just author and email. */
388 got_object_commit_close(struct got_commit_object
*commit
)
390 if (commit
->refcnt
> 0) {
392 if (commit
->refcnt
> 0)
396 got_object_id_queue_free(&commit
->parent_ids
);
397 free(commit
->tree_id
);
398 free(commit
->author
);
399 free(commit
->committer
);
400 free(commit
->logmsg
);
404 struct got_object_id
*
405 got_object_commit_get_tree_id(struct got_commit_object
*commit
)
407 return commit
->tree_id
;
411 got_object_commit_get_nparents(struct got_commit_object
*commit
)
413 return commit
->nparents
;
416 const struct got_object_id_queue
*
417 got_object_commit_get_parent_ids(struct got_commit_object
*commit
)
419 return &commit
->parent_ids
;
423 got_object_commit_get_author(struct got_commit_object
*commit
)
425 return commit
->author
;
429 got_object_commit_get_author_time(struct got_commit_object
*commit
)
431 return commit
->author_time
;
434 time_t got_object_commit_get_author_gmtoff(struct got_commit_object
*commit
)
436 return commit
->author_gmtoff
;
440 got_object_commit_get_committer(struct got_commit_object
*commit
)
442 return commit
->committer
;
446 got_object_commit_get_committer_time(struct got_commit_object
*commit
)
448 return commit
->committer_time
;
452 got_object_commit_get_committer_gmtoff(struct got_commit_object
*commit
)
454 return commit
->committer_gmtoff
;
457 const struct got_error
*
458 got_object_commit_get_logmsg(char **logmsg
, struct got_commit_object
*commit
)
460 const struct got_error
*err
= NULL
;
465 len
= strlen(commit
->logmsg
);
466 *logmsg
= malloc(len
+ 2); /* leave room for a trailing \n and \0 */
468 return got_error_from_errno("malloc");
471 * Strip out unusual headers. Headers are separated from the commit
472 * message body by a single empty line.
474 src
= commit
->logmsg
;
476 while (*src
!= '\0' && *src
!= '\n') {
477 int copy_header
= 1, eol
= 0;
478 if (strncmp(src
, GOT_COMMIT_LABEL_TREE
,
479 strlen(GOT_COMMIT_LABEL_TREE
)) != 0 &&
480 strncmp(src
, GOT_COMMIT_LABEL_AUTHOR
,
481 strlen(GOT_COMMIT_LABEL_AUTHOR
)) != 0 &&
482 strncmp(src
, GOT_COMMIT_LABEL_PARENT
,
483 strlen(GOT_COMMIT_LABEL_PARENT
)) != 0 &&
484 strncmp(src
, GOT_COMMIT_LABEL_COMMITTER
,
485 strlen(GOT_COMMIT_LABEL_COMMITTER
)) != 0)
488 while (*src
!= '\0' && !eol
) {
500 if (strlcat(*logmsg
, src
, len
+ 1) >= len
+ 1) {
501 err
= got_error(GOT_ERR_NO_SPACE
);
505 /* Trim redundant trailing whitespace. */
506 len
= strlen(*logmsg
);
507 while (len
> 1 && isspace((unsigned char)(*logmsg
)[len
- 2]) &&
508 isspace((unsigned char)(*logmsg
)[len
- 1])) {
509 (*logmsg
)[len
- 1] = '\0';
513 /* Append a trailing newline if missing. */
514 if (len
> 0 && (*logmsg
)[len
- 1] != '\n') {
515 (*logmsg
)[len
] = '\n';
516 (*logmsg
)[len
+ 1] = '\0';
527 got_object_commit_get_logmsg_raw(struct got_commit_object
*commit
)
529 return commit
->logmsg
;
532 const struct got_error
*
533 got_object_parse_commit(struct got_commit_object
**commit
, char *buf
,
536 const struct got_error
*err
= NULL
;
539 ssize_t remain
= (ssize_t
)len
;
542 return got_error(GOT_ERR_BAD_OBJ_DATA
);
544 *commit
= got_object_commit_alloc_partial();
546 return got_error_from_errno("got_object_commit_alloc_partial");
548 label_len
= strlen(GOT_COMMIT_LABEL_TREE
);
549 if (strncmp(s
, GOT_COMMIT_LABEL_TREE
, label_len
) == 0) {
551 if (remain
< SHA1_DIGEST_STRING_LENGTH
) {
552 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
556 if (!got_parse_sha1_digest((*commit
)->tree_id
->sha1
, s
)) {
557 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
560 remain
-= SHA1_DIGEST_STRING_LENGTH
;
561 s
+= SHA1_DIGEST_STRING_LENGTH
;
563 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
567 label_len
= strlen(GOT_COMMIT_LABEL_PARENT
);
568 while (strncmp(s
, GOT_COMMIT_LABEL_PARENT
, label_len
) == 0) {
570 if (remain
< SHA1_DIGEST_STRING_LENGTH
) {
571 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
575 err
= got_object_commit_add_parent(*commit
, s
);
579 remain
-= SHA1_DIGEST_STRING_LENGTH
;
580 s
+= SHA1_DIGEST_STRING_LENGTH
;
583 label_len
= strlen(GOT_COMMIT_LABEL_AUTHOR
);
584 if (strncmp(s
, GOT_COMMIT_LABEL_AUTHOR
, label_len
) == 0) {
590 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
594 p
= memchr(s
, '\n', remain
);
596 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
601 err
= parse_commit_time(&(*commit
)->author_time
,
602 &(*commit
)->author_gmtoff
, s
);
605 (*commit
)->author
= strdup(s
);
606 if ((*commit
)->author
== NULL
) {
607 err
= got_error_from_errno("strdup");
614 label_len
= strlen(GOT_COMMIT_LABEL_COMMITTER
);
615 if (strncmp(s
, GOT_COMMIT_LABEL_COMMITTER
, label_len
) == 0) {
621 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
625 p
= memchr(s
, '\n', remain
);
627 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
632 err
= parse_commit_time(&(*commit
)->committer_time
,
633 &(*commit
)->committer_gmtoff
, s
);
636 (*commit
)->committer
= strdup(s
);
637 if ((*commit
)->committer
== NULL
) {
638 err
= got_error_from_errno("strdup");
645 (*commit
)->logmsg
= strndup(s
, remain
);
646 if ((*commit
)->logmsg
== NULL
) {
647 err
= got_error_from_errno("strndup");
652 got_object_commit_close(*commit
);
659 got_object_tree_close(struct got_tree_object
*tree
)
661 if (tree
->refcnt
> 0) {
663 if (tree
->refcnt
> 0)
671 static const struct got_error
*
672 parse_tree_entry(struct got_parsed_tree_entry
**pte
, const char **name
,
673 size_t *elen
, char *buf
,
677 const struct got_error
*err
= NULL
;
682 *pte
= malloc(sizeof(**pte
));
684 return got_error_from_errno("malloc");
686 *elen
= strnlen(buf
, maxlen
) + 1;
687 if (*elen
> maxlen
) {
690 return got_error(GOT_ERR_BAD_OBJ_DATA
);
693 space
= memchr(buf
, ' ', *elen
);
694 if (space
== NULL
|| space
<= buf
) {
695 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
703 if (*p
< '0' && *p
> '7') {
704 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
708 (*pte
)->mode
|= *p
- '0';
712 if (*elen
> maxlen
|| maxlen
- *elen
< SHA1_DIGEST_LENGTH
) {
713 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
719 *elen
+= SHA1_DIGEST_LENGTH
;
728 const struct got_error
*
729 got_object_parse_tree(struct got_pathlist_head
*entries
, int *nentries
,
730 uint8_t *buf
, size_t len
)
732 const struct got_error
*err
= NULL
;
737 return NULL
; /* tree is empty */
740 struct got_parsed_tree_entry
*pte
;
741 struct got_pathlist_entry
*new = NULL
;
745 err
= parse_tree_entry(&pte
, &name
, &elen
, buf
, remain
);
748 err
= got_pathlist_insert(&new, entries
, name
, pte
);
752 err
= got_error(GOT_ERR_TREE_DUP_ENTRY
);
761 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
766 got_object_parsed_tree_entries_free(entries
);
773 got_object_parsed_tree_entries_free(struct got_pathlist_head
*entries
)
775 struct got_pathlist_entry
*pe
;
777 TAILQ_FOREACH(pe
, entries
, entry
) {
778 struct got_parsed_tree_entry
*pte
= pe
->data
;
781 got_pathlist_free(entries
);
785 got_object_tag_close(struct got_tag_object
*tag
)
787 if (tag
->refcnt
> 0) {
799 const struct got_error
*
800 got_object_parse_tag(struct got_tag_object
**tag
, uint8_t *buf
, size_t len
)
802 const struct got_error
*err
= NULL
;
808 return got_error(GOT_ERR_BAD_OBJ_DATA
);
810 *tag
= calloc(1, sizeof(**tag
));
812 return got_error_from_errno("calloc");
814 label_len
= strlen(GOT_TAG_LABEL_OBJECT
);
815 if (strncmp(s
, GOT_TAG_LABEL_OBJECT
, label_len
) == 0) {
817 if (remain
< SHA1_DIGEST_STRING_LENGTH
) {
818 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
822 if (!got_parse_sha1_digest((*tag
)->id
.sha1
, s
)) {
823 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
826 remain
-= SHA1_DIGEST_STRING_LENGTH
;
827 s
+= SHA1_DIGEST_STRING_LENGTH
;
829 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
834 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
838 label_len
= strlen(GOT_TAG_LABEL_TYPE
);
839 if (strncmp(s
, GOT_TAG_LABEL_TYPE
, label_len
) == 0) {
842 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
846 if (strncmp(s
, GOT_OBJ_LABEL_COMMIT
,
847 strlen(GOT_OBJ_LABEL_COMMIT
)) == 0) {
848 (*tag
)->obj_type
= GOT_OBJ_TYPE_COMMIT
;
849 label_len
= strlen(GOT_OBJ_LABEL_COMMIT
);
852 } else if (strncmp(s
, GOT_OBJ_LABEL_TREE
,
853 strlen(GOT_OBJ_LABEL_TREE
)) == 0) {
854 (*tag
)->obj_type
= GOT_OBJ_TYPE_TREE
;
855 label_len
= strlen(GOT_OBJ_LABEL_TREE
);
858 } else if (strncmp(s
, GOT_OBJ_LABEL_BLOB
,
859 strlen(GOT_OBJ_LABEL_BLOB
)) == 0) {
860 (*tag
)->obj_type
= GOT_OBJ_TYPE_BLOB
;
861 label_len
= strlen(GOT_OBJ_LABEL_BLOB
);
864 } else if (strncmp(s
, GOT_OBJ_LABEL_TAG
,
865 strlen(GOT_OBJ_LABEL_TAG
)) == 0) {
866 (*tag
)->obj_type
= GOT_OBJ_TYPE_TAG
;
867 label_len
= strlen(GOT_OBJ_LABEL_TAG
);
871 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
875 if (remain
<= 0 || *s
!= '\n') {
876 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
882 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
886 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
890 label_len
= strlen(GOT_TAG_LABEL_TAG
);
891 if (strncmp(s
, GOT_TAG_LABEL_TAG
, label_len
) == 0) {
896 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
900 p
= memchr(s
, '\n', remain
);
902 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
907 (*tag
)->tag
= strndup(s
, slen
);
908 if ((*tag
)->tag
== NULL
) {
909 err
= got_error_from_errno("strndup");
915 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
919 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
923 label_len
= strlen(GOT_TAG_LABEL_TAGGER
);
924 if (strncmp(s
, GOT_TAG_LABEL_TAGGER
, label_len
) == 0) {
930 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
934 p
= memchr(s
, '\n', remain
);
936 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
941 err
= parse_commit_time(&(*tag
)->tagger_time
,
942 &(*tag
)->tagger_gmtoff
, s
);
945 (*tag
)->tagger
= strdup(s
);
946 if ((*tag
)->tagger
== NULL
) {
947 err
= got_error_from_errno("strdup");
953 err
= got_error(GOT_ERR_BAD_OBJ_DATA
);
957 /* Some old tags in the Linux git repo have no tagger. */
958 (*tag
)->tagger
= strdup("");
959 if ((*tag
)->tagger
== NULL
) {
960 err
= got_error_from_errno("strdup");
965 (*tag
)->tagmsg
= strndup(s
, remain
);
966 if ((*tag
)->tagmsg
== NULL
) {
967 err
= got_error_from_errno("strndup");
972 got_object_tag_close(*tag
);
978 const struct got_error
*
979 got_read_file_to_mem(uint8_t **outbuf
, size_t *outlen
, FILE *f
)
981 const struct got_error
*err
= NULL
;
982 static const size_t blocksize
= 512;
983 size_t n
, total
, remain
;
989 buf
= malloc(blocksize
);
991 return got_error_from_errno("malloc");
998 newbuf
= reallocarray(buf
, 1, total
+ blocksize
);
999 if (newbuf
== NULL
) {
1000 err
= got_error_from_errno("reallocarray");
1004 remain
+= blocksize
;
1006 n
= fread(buf
+ total
, 1, remain
, f
);
1009 err
= got_ferror(f
, GOT_ERR_IO
);