Blame


1 d71d75ad 2017-11-05 stsp /*
2 a1fd68d8 2018-01-12 stsp * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
3 d71d75ad 2017-11-05 stsp *
4 d71d75ad 2017-11-05 stsp * Permission to use, copy, modify, and distribute this software for any
5 d71d75ad 2017-11-05 stsp * purpose with or without fee is hereby granted, provided that the above
6 d71d75ad 2017-11-05 stsp * copyright notice and this permission notice appear in all copies.
7 d71d75ad 2017-11-05 stsp *
8 d71d75ad 2017-11-05 stsp * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 d71d75ad 2017-11-05 stsp * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 d71d75ad 2017-11-05 stsp * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 d71d75ad 2017-11-05 stsp * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 d71d75ad 2017-11-05 stsp * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 d71d75ad 2017-11-05 stsp * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 d71d75ad 2017-11-05 stsp * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 d71d75ad 2017-11-05 stsp */
16 d71d75ad 2017-11-05 stsp
17 2178c42e 2018-04-22 stsp #include <sys/types.h>
18 0ffeb3c2 2017-11-26 stsp #include <sys/stat.h>
19 d1cda826 2017-11-06 stsp #include <sys/queue.h>
20 2178c42e 2018-04-22 stsp #include <sys/uio.h>
21 2178c42e 2018-04-22 stsp #include <sys/socket.h>
22 2178c42e 2018-04-22 stsp #include <sys/wait.h>
23 d1cda826 2017-11-06 stsp
24 a1fd68d8 2018-01-12 stsp #include <errno.h>
25 2178c42e 2018-04-22 stsp #include <fcntl.h>
26 d71d75ad 2017-11-05 stsp #include <stdio.h>
27 ab9a70b2 2017-11-06 stsp #include <stdlib.h>
28 ab9a70b2 2017-11-06 stsp #include <string.h>
29 2178c42e 2018-04-22 stsp #include <stdint.h>
30 d71d75ad 2017-11-05 stsp #include <sha1.h>
31 ab9a70b2 2017-11-06 stsp #include <zlib.h>
32 ab9a70b2 2017-11-06 stsp #include <ctype.h>
33 ab9a70b2 2017-11-06 stsp #include <limits.h>
34 2178c42e 2018-04-22 stsp #include <imsg.h>
35 d71d75ad 2017-11-05 stsp
36 ab9a70b2 2017-11-06 stsp #include "got_error.h"
37 d71d75ad 2017-11-05 stsp #include "got_object.h"
38 ab9a70b2 2017-11-06 stsp #include "got_repository.h"
39 d71d75ad 2017-11-05 stsp
40 718b3ab0 2018-03-17 stsp #include "got_lib_sha1.h"
41 718b3ab0 2018-03-17 stsp #include "got_lib_delta.h"
42 718b3ab0 2018-03-17 stsp #include "got_lib_pack.h"
43 2178c42e 2018-04-22 stsp #include "got_lib_path.h"
44 718b3ab0 2018-03-17 stsp #include "got_lib_zbuf.h"
45 718b3ab0 2018-03-17 stsp #include "got_lib_object.h"
46 2178c42e 2018-04-22 stsp #include "got_lib_privsep.h"
47 1411938b 2018-02-12 stsp
48 ab9a70b2 2017-11-06 stsp #ifndef MIN
49 ab9a70b2 2017-11-06 stsp #define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
50 ab9a70b2 2017-11-06 stsp #endif
51 ab9a70b2 2017-11-06 stsp
52 ab9a70b2 2017-11-06 stsp #ifndef nitems
53 ab9a70b2 2017-11-06 stsp #define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
54 ab9a70b2 2017-11-06 stsp #endif
55 ab9a70b2 2017-11-06 stsp
56 ab9a70b2 2017-11-06 stsp #define GOT_OBJ_TAG_COMMIT "commit"
57 ab9a70b2 2017-11-06 stsp #define GOT_OBJ_TAG_TREE "tree"
58 ab9a70b2 2017-11-06 stsp #define GOT_OBJ_TAG_BLOB "blob"
59 ab9a70b2 2017-11-06 stsp
60 d1cda826 2017-11-06 stsp #define GOT_COMMIT_TAG_TREE "tree "
61 d1cda826 2017-11-06 stsp #define GOT_COMMIT_TAG_PARENT "parent "
62 d1cda826 2017-11-06 stsp #define GOT_COMMIT_TAG_AUTHOR "author "
63 d1cda826 2017-11-06 stsp #define GOT_COMMIT_TAG_COMMITTER "committer "
64 d1cda826 2017-11-06 stsp
65 ef0981d5 2018-02-12 stsp const struct got_error *
66 ef0981d5 2018-02-12 stsp got_object_id_str(char **outbuf, struct got_object_id *id)
67 d71d75ad 2017-11-05 stsp {
68 ef0981d5 2018-02-12 stsp static const size_t len = SHA1_DIGEST_STRING_LENGTH;
69 ef0981d5 2018-02-12 stsp
70 ef0981d5 2018-02-12 stsp *outbuf = calloc(1, len);
71 ef0981d5 2018-02-12 stsp if (*outbuf == NULL)
72 0a585a0d 2018-03-17 stsp return got_error_from_errno();
73 ef0981d5 2018-02-12 stsp
74 ef0981d5 2018-02-12 stsp if (got_sha1_digest_to_str(id->sha1, *outbuf, len) == NULL) {
75 ef0981d5 2018-02-12 stsp free(*outbuf);
76 ef0981d5 2018-02-12 stsp *outbuf = NULL;
77 ef0981d5 2018-02-12 stsp return got_error(GOT_ERR_BAD_OBJ_ID_STR);
78 ef0981d5 2018-02-12 stsp }
79 ef0981d5 2018-02-12 stsp
80 ef0981d5 2018-02-12 stsp return NULL;
81 59ece79d 2018-02-12 stsp }
82 59ece79d 2018-02-12 stsp
83 a1fd68d8 2018-01-12 stsp int
84 a1fd68d8 2018-01-12 stsp got_object_id_cmp(struct got_object_id *id1, struct got_object_id *id2)
85 a1fd68d8 2018-01-12 stsp {
86 a1fd68d8 2018-01-12 stsp return memcmp(id1->sha1, id2->sha1, SHA1_DIGEST_LENGTH);
87 8bf5b3c9 2018-03-17 stsp }
88 8bf5b3c9 2018-03-17 stsp
89 8bf5b3c9 2018-03-17 stsp struct got_object_id *
90 8bf5b3c9 2018-03-17 stsp got_object_id_dup(struct got_object_id *id1)
91 8bf5b3c9 2018-03-17 stsp {
92 8bf5b3c9 2018-03-17 stsp struct got_object_id *id2;
93 8bf5b3c9 2018-03-17 stsp
94 8bf5b3c9 2018-03-17 stsp id2 = malloc(sizeof(*id2));
95 8bf5b3c9 2018-03-17 stsp if (id2 == NULL)
96 8bf5b3c9 2018-03-17 stsp return NULL;
97 8bf5b3c9 2018-03-17 stsp memcpy(id2, id1, sizeof(*id2));
98 8bf5b3c9 2018-03-17 stsp return id2;
99 3235492e 2018-04-01 stsp }
100 3235492e 2018-04-01 stsp
101 3235492e 2018-04-01 stsp struct got_object_id *
102 3235492e 2018-04-01 stsp got_object_get_id(struct got_object *obj)
103 3235492e 2018-04-01 stsp {
104 3235492e 2018-04-01 stsp return got_object_id_dup(&obj->id);
105 a1fd68d8 2018-01-12 stsp }
106 d71d75ad 2017-11-05 stsp
107 b107e67f 2018-01-19 stsp int
108 b107e67f 2018-01-19 stsp got_object_get_type(struct got_object *obj)
109 a1fd68d8 2018-01-12 stsp {
110 b107e67f 2018-01-19 stsp switch (obj->type) {
111 a1fd68d8 2018-01-12 stsp case GOT_OBJ_TYPE_COMMIT:
112 a1fd68d8 2018-01-12 stsp case GOT_OBJ_TYPE_TREE:
113 a1fd68d8 2018-01-12 stsp case GOT_OBJ_TYPE_BLOB:
114 b107e67f 2018-01-19 stsp case GOT_OBJ_TYPE_TAG:
115 b107e67f 2018-01-19 stsp return obj->type;
116 96f5e8b3 2018-01-23 stsp default:
117 96f5e8b3 2018-01-23 stsp abort();
118 96f5e8b3 2018-01-23 stsp break;
119 d71d75ad 2017-11-05 stsp }
120 d71d75ad 2017-11-05 stsp
121 96f5e8b3 2018-01-23 stsp /* not reached */
122 96f5e8b3 2018-01-23 stsp return 0;
123 d71d75ad 2017-11-05 stsp }
124 ab9a70b2 2017-11-06 stsp
125 ab9a70b2 2017-11-06 stsp static const struct got_error *
126 d1cda826 2017-11-06 stsp parse_object_header(struct got_object **obj, char *buf, size_t len)
127 ab9a70b2 2017-11-06 stsp {
128 ab9a70b2 2017-11-06 stsp const char *obj_tags[] = {
129 ab9a70b2 2017-11-06 stsp GOT_OBJ_TAG_COMMIT,
130 ab9a70b2 2017-11-06 stsp GOT_OBJ_TAG_TREE,
131 ab9a70b2 2017-11-06 stsp GOT_OBJ_TAG_BLOB
132 ab9a70b2 2017-11-06 stsp };
133 ab9a70b2 2017-11-06 stsp const int obj_types[] = {
134 ab9a70b2 2017-11-06 stsp GOT_OBJ_TYPE_COMMIT,
135 ab9a70b2 2017-11-06 stsp GOT_OBJ_TYPE_TREE,
136 ab9a70b2 2017-11-06 stsp GOT_OBJ_TYPE_BLOB,
137 ab9a70b2 2017-11-06 stsp };
138 ab9a70b2 2017-11-06 stsp int type = 0;
139 d1cda826 2017-11-06 stsp size_t size = 0, hdrlen = 0;
140 ab9a70b2 2017-11-06 stsp int i;
141 ab9a70b2 2017-11-06 stsp char *p = strchr(buf, '\0');
142 ab9a70b2 2017-11-06 stsp
143 ab9a70b2 2017-11-06 stsp if (p == NULL)
144 ab9a70b2 2017-11-06 stsp return got_error(GOT_ERR_BAD_OBJ_HDR);
145 ab9a70b2 2017-11-06 stsp
146 d1cda826 2017-11-06 stsp hdrlen = strlen(buf) + 1 /* '\0' */;
147 d1cda826 2017-11-06 stsp
148 ab9a70b2 2017-11-06 stsp for (i = 0; i < nitems(obj_tags); i++) {
149 ab9a70b2 2017-11-06 stsp const char *tag = obj_tags[i];
150 63323519 2017-11-06 stsp size_t tlen = strlen(tag);
151 ab9a70b2 2017-11-06 stsp const char *errstr;
152 ab9a70b2 2017-11-06 stsp
153 63323519 2017-11-06 stsp if (strncmp(buf, tag, tlen) != 0)
154 ab9a70b2 2017-11-06 stsp continue;
155 ab9a70b2 2017-11-06 stsp
156 ab9a70b2 2017-11-06 stsp type = obj_types[i];
157 63323519 2017-11-06 stsp if (len <= tlen)
158 ab9a70b2 2017-11-06 stsp return got_error(GOT_ERR_BAD_OBJ_HDR);
159 63323519 2017-11-06 stsp size = strtonum(buf + tlen, 0, LONG_MAX, &errstr);
160 ab9a70b2 2017-11-06 stsp if (errstr != NULL)
161 ab9a70b2 2017-11-06 stsp return got_error(GOT_ERR_BAD_OBJ_HDR);
162 ab9a70b2 2017-11-06 stsp break;
163 ab9a70b2 2017-11-06 stsp }
164 ab9a70b2 2017-11-06 stsp
165 ab9a70b2 2017-11-06 stsp if (type == 0)
166 ab9a70b2 2017-11-06 stsp return got_error(GOT_ERR_BAD_OBJ_HDR);
167 ab9a70b2 2017-11-06 stsp
168 ab9a70b2 2017-11-06 stsp *obj = calloc(1, sizeof(**obj));
169 1db76ab5 2018-01-26 mpi if (*obj == NULL)
170 0a585a0d 2018-03-17 stsp return got_error_from_errno();
171 ab9a70b2 2017-11-06 stsp (*obj)->type = type;
172 d1cda826 2017-11-06 stsp (*obj)->hdrlen = hdrlen;
173 ab9a70b2 2017-11-06 stsp (*obj)->size = size;
174 ab9a70b2 2017-11-06 stsp return NULL;
175 ab9a70b2 2017-11-06 stsp }
176 ab9a70b2 2017-11-06 stsp
177 ab9a70b2 2017-11-06 stsp static const struct got_error *
178 2178c42e 2018-04-22 stsp read_object_header(struct got_object **obj, FILE *f)
179 ab9a70b2 2017-11-06 stsp {
180 ab9a70b2 2017-11-06 stsp const struct got_error *err;
181 ab9a70b2 2017-11-06 stsp struct got_zstream_buf zb;
182 a3e2cbea 2017-12-01 stsp char *buf;
183 a3e2cbea 2017-12-01 stsp const size_t zbsize = 64;
184 744d9326 2017-12-01 stsp size_t outlen, totlen;
185 25783624 2018-03-12 stsp int i;
186 ab9a70b2 2017-11-06 stsp
187 744d9326 2017-12-01 stsp buf = calloc(zbsize, sizeof(char));
188 a3e2cbea 2017-12-01 stsp if (buf == NULL)
189 0a585a0d 2018-03-17 stsp return got_error_from_errno();
190 a3e2cbea 2017-12-01 stsp
191 19d747f7 2018-03-16 stsp err = got_inflate_init(&zb, NULL, zbsize);
192 a1fd68d8 2018-01-12 stsp if (err)
193 ab9a70b2 2017-11-06 stsp return err;
194 ab9a70b2 2017-11-06 stsp
195 a3e2cbea 2017-12-01 stsp i = 0;
196 744d9326 2017-12-01 stsp totlen = 0;
197 a3e2cbea 2017-12-01 stsp do {
198 126ee060 2018-02-11 stsp err = got_inflate_read(&zb, f, &outlen);
199 a3e2cbea 2017-12-01 stsp if (err)
200 a3e2cbea 2017-12-01 stsp goto done;
201 e302c59e 2017-12-01 stsp if (strchr(zb.outbuf, '\0') == NULL) {
202 a3e2cbea 2017-12-01 stsp buf = recallocarray(buf, 1 + i, 2 + i, zbsize);
203 e302c59e 2017-12-01 stsp if (buf == NULL) {
204 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
205 e302c59e 2017-12-01 stsp goto done;
206 e302c59e 2017-12-01 stsp }
207 e302c59e 2017-12-01 stsp }
208 c56976de 2017-12-01 stsp memcpy(buf + totlen, zb.outbuf, outlen);
209 744d9326 2017-12-01 stsp totlen += outlen;
210 a3e2cbea 2017-12-01 stsp i++;
211 a3e2cbea 2017-12-01 stsp } while (strchr(zb.outbuf, '\0') == NULL);
212 ab9a70b2 2017-11-06 stsp
213 744d9326 2017-12-01 stsp err = parse_object_header(obj, buf, totlen);
214 ab9a70b2 2017-11-06 stsp done:
215 4ca7b755 2018-01-26 stsp got_inflate_end(&zb);
216 2178c42e 2018-04-22 stsp return err;
217 2178c42e 2018-04-22 stsp }
218 2178c42e 2018-04-22 stsp
219 2178c42e 2018-04-22 stsp static const struct got_error *
220 2178c42e 2018-04-22 stsp read_object_header_privsep(struct got_object **obj, int fd)
221 2178c42e 2018-04-22 stsp {
222 2178c42e 2018-04-22 stsp struct imsgbuf parent_ibuf;
223 2178c42e 2018-04-22 stsp int imsg_fds[2];
224 2178c42e 2018-04-22 stsp const struct got_error *err = NULL;
225 2178c42e 2018-04-22 stsp pid_t pid;
226 2178c42e 2018-04-22 stsp int child_status;
227 2178c42e 2018-04-22 stsp
228 2178c42e 2018-04-22 stsp if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
229 2178c42e 2018-04-22 stsp return got_error_from_errno();
230 2178c42e 2018-04-22 stsp
231 2178c42e 2018-04-22 stsp pid = fork();
232 2178c42e 2018-04-22 stsp if (pid == -1)
233 2178c42e 2018-04-22 stsp return got_error_from_errno();
234 2178c42e 2018-04-22 stsp else if (pid == 0) {
235 2178c42e 2018-04-22 stsp struct got_object *child_obj = NULL;
236 2178c42e 2018-04-22 stsp struct imsgbuf child_ibuf;
237 2178c42e 2018-04-22 stsp FILE *f = NULL;
238 2178c42e 2018-04-22 stsp int status = 0;
239 2178c42e 2018-04-22 stsp
240 2178c42e 2018-04-22 stsp setproctitle("got: read object header");
241 2178c42e 2018-04-22 stsp close(imsg_fds[0]);
242 2178c42e 2018-04-22 stsp imsg_init(&child_ibuf, imsg_fds[1]);
243 2178c42e 2018-04-22 stsp if (err)
244 2178c42e 2018-04-22 stsp goto done;
245 2178c42e 2018-04-22 stsp
246 2178c42e 2018-04-22 stsp /* revoke access to most system calls */
247 2178c42e 2018-04-22 stsp if (pledge("stdio", NULL) == -1) {
248 2178c42e 2018-04-22 stsp err = got_error_from_errno();
249 2178c42e 2018-04-22 stsp goto done;
250 2178c42e 2018-04-22 stsp }
251 2178c42e 2018-04-22 stsp
252 2178c42e 2018-04-22 stsp f = fdopen(fd, "rb");
253 2178c42e 2018-04-22 stsp if (f == NULL) {
254 2178c42e 2018-04-22 stsp err = got_error_from_errno();
255 6cd97fcc 2018-04-22 stsp close(fd);
256 2178c42e 2018-04-22 stsp goto done;
257 2178c42e 2018-04-22 stsp }
258 2178c42e 2018-04-22 stsp
259 2178c42e 2018-04-22 stsp err = read_object_header(&child_obj, f);
260 2178c42e 2018-04-22 stsp if (err)
261 2178c42e 2018-04-22 stsp goto done;
262 2178c42e 2018-04-22 stsp
263 2178c42e 2018-04-22 stsp err = got_privsep_send_obj(&child_ibuf, child_obj, 0);
264 2178c42e 2018-04-22 stsp done:
265 2178c42e 2018-04-22 stsp if (child_obj)
266 2178c42e 2018-04-22 stsp got_object_close(child_obj);
267 2178c42e 2018-04-22 stsp if (err) {
268 2178c42e 2018-04-22 stsp got_privsep_send_error(&child_ibuf, err);
269 2178c42e 2018-04-22 stsp status = 1;
270 2178c42e 2018-04-22 stsp }
271 2178c42e 2018-04-22 stsp if (f)
272 2178c42e 2018-04-22 stsp fclose(f);
273 2178c42e 2018-04-22 stsp imsg_clear(&child_ibuf);
274 15d3ea56 2018-04-22 stsp close(imsg_fds[1]);
275 2178c42e 2018-04-22 stsp _exit(status);
276 2178c42e 2018-04-22 stsp }
277 2178c42e 2018-04-22 stsp
278 2178c42e 2018-04-22 stsp close(imsg_fds[1]);
279 2178c42e 2018-04-22 stsp imsg_init(&parent_ibuf, imsg_fds[0]);
280 2178c42e 2018-04-22 stsp err = got_privsep_recv_obj(obj, &parent_ibuf);
281 2178c42e 2018-04-22 stsp imsg_clear(&parent_ibuf);
282 2178c42e 2018-04-22 stsp waitpid(pid, &child_status, 0);
283 2178c42e 2018-04-22 stsp close(imsg_fds[0]);
284 ab9a70b2 2017-11-06 stsp return err;
285 ab9a70b2 2017-11-06 stsp }
286 ab9a70b2 2017-11-06 stsp
287 d1cda826 2017-11-06 stsp static const struct got_error *
288 4558fcd4 2018-01-14 stsp object_path(char **path, struct got_object_id *id, struct got_repository *repo)
289 ab9a70b2 2017-11-06 stsp {
290 ab9a70b2 2017-11-06 stsp const struct got_error *err = NULL;
291 ef0981d5 2018-02-12 stsp char *hex;
292 d1cda826 2017-11-06 stsp char *path_objects = got_repo_get_path_objects(repo);
293 e6b1056e 2018-04-22 stsp
294 e6b1056e 2018-04-22 stsp *path = NULL;
295 ab9a70b2 2017-11-06 stsp
296 ab9a70b2 2017-11-06 stsp if (path_objects == NULL)
297 0a585a0d 2018-03-17 stsp return got_error_from_errno();
298 ab9a70b2 2017-11-06 stsp
299 ef0981d5 2018-02-12 stsp err = got_object_id_str(&hex, id);
300 ef0981d5 2018-02-12 stsp if (err)
301 ef0981d5 2018-02-12 stsp return err;
302 ab9a70b2 2017-11-06 stsp
303 d1cda826 2017-11-06 stsp if (asprintf(path, "%s/%.2x/%s", path_objects,
304 d1cda826 2017-11-06 stsp id->sha1[0], hex + 2) == -1)
305 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
306 ab9a70b2 2017-11-06 stsp
307 ef0981d5 2018-02-12 stsp free(hex);
308 d1cda826 2017-11-06 stsp free(path_objects);
309 d1cda826 2017-11-06 stsp return err;
310 d1cda826 2017-11-06 stsp }
311 d1cda826 2017-11-06 stsp
312 4ee4114f 2018-01-23 stsp static const struct got_error *
313 d5003b79 2018-04-22 stsp open_loose_object(int *fd, struct got_object *obj, struct got_repository *repo)
314 d1cda826 2017-11-06 stsp {
315 d1cda826 2017-11-06 stsp const struct got_error *err = NULL;
316 a1fd68d8 2018-01-12 stsp char *path;
317 6c00b545 2018-01-17 stsp
318 6c00b545 2018-01-17 stsp err = object_path(&path, &obj->id, repo);
319 d1cda826 2017-11-06 stsp if (err)
320 d1cda826 2017-11-06 stsp return err;
321 d5003b79 2018-04-22 stsp *fd = open(path, O_RDONLY | O_NOFOLLOW, GOT_DEFAULT_FILE_MODE);
322 d5003b79 2018-04-22 stsp if (*fd == -1) {
323 6c00b545 2018-01-17 stsp err = got_error_from_errno();
324 6c00b545 2018-01-17 stsp goto done;
325 a1fd68d8 2018-01-12 stsp }
326 4558fcd4 2018-01-14 stsp done:
327 4558fcd4 2018-01-14 stsp free(path);
328 4558fcd4 2018-01-14 stsp return err;
329 4558fcd4 2018-01-14 stsp }
330 a1fd68d8 2018-01-12 stsp
331 4558fcd4 2018-01-14 stsp const struct got_error *
332 4558fcd4 2018-01-14 stsp got_object_open(struct got_object **obj, struct got_repository *repo,
333 4558fcd4 2018-01-14 stsp struct got_object_id *id)
334 4558fcd4 2018-01-14 stsp {
335 6c00b545 2018-01-17 stsp const struct got_error *err = NULL;
336 6c00b545 2018-01-17 stsp char *path;
337 2178c42e 2018-04-22 stsp int fd;
338 4558fcd4 2018-01-14 stsp
339 6c00b545 2018-01-17 stsp err = object_path(&path, id, repo);
340 4558fcd4 2018-01-14 stsp if (err)
341 4558fcd4 2018-01-14 stsp return err;
342 4558fcd4 2018-01-14 stsp
343 2178c42e 2018-04-22 stsp fd = open(path, O_RDONLY | O_NOFOLLOW, GOT_DEFAULT_FILE_MODE);
344 2178c42e 2018-04-22 stsp if (fd == -1) {
345 6c00b545 2018-01-17 stsp if (errno != ENOENT) {
346 6c00b545 2018-01-17 stsp err = got_error_from_errno();
347 6c00b545 2018-01-17 stsp goto done;
348 6c00b545 2018-01-17 stsp }
349 6c00b545 2018-01-17 stsp err = got_packfile_open_object(obj, id, repo);
350 6c00b545 2018-01-17 stsp if (err)
351 6c00b545 2018-01-17 stsp goto done;
352 6c00b545 2018-01-17 stsp if (*obj == NULL)
353 6c00b545 2018-01-17 stsp err = got_error(GOT_ERR_NO_OBJ);
354 6c00b545 2018-01-17 stsp } else {
355 2178c42e 2018-04-22 stsp err = read_object_header_privsep(obj, fd);
356 6c00b545 2018-01-17 stsp if (err)
357 6c00b545 2018-01-17 stsp goto done;
358 ab9a70b2 2017-11-06 stsp memcpy((*obj)->id.sha1, id->sha1, SHA1_DIGEST_LENGTH);
359 6c00b545 2018-01-17 stsp }
360 6c00b545 2018-01-17 stsp done:
361 6c00b545 2018-01-17 stsp free(path);
362 2178c42e 2018-04-22 stsp if (fd != -1)
363 2178c42e 2018-04-22 stsp close(fd);
364 ab9a70b2 2017-11-06 stsp return err;
365 6c00b545 2018-01-17 stsp
366 ab9a70b2 2017-11-06 stsp }
367 ab9a70b2 2017-11-06 stsp
368 6dfa2fd3 2018-02-12 stsp const struct got_error *
369 6dfa2fd3 2018-02-12 stsp got_object_open_by_id_str(struct got_object **obj, struct got_repository *repo,
370 6dfa2fd3 2018-02-12 stsp const char *id_str)
371 6dfa2fd3 2018-02-12 stsp {
372 6dfa2fd3 2018-02-12 stsp struct got_object_id id;
373 6dfa2fd3 2018-02-12 stsp
374 6dfa2fd3 2018-02-12 stsp if (!got_parse_sha1_digest(id.sha1, id_str))
375 6dfa2fd3 2018-02-12 stsp return got_error(GOT_ERR_BAD_OBJ_ID_STR);
376 6dfa2fd3 2018-02-12 stsp
377 6dfa2fd3 2018-02-12 stsp return got_object_open(obj, repo, &id);
378 6dfa2fd3 2018-02-12 stsp }
379 6dfa2fd3 2018-02-12 stsp
380 ab9a70b2 2017-11-06 stsp void
381 ab9a70b2 2017-11-06 stsp got_object_close(struct got_object *obj)
382 ab9a70b2 2017-11-06 stsp {
383 96f5e8b3 2018-01-23 stsp if (obj->flags & GOT_OBJ_FLAG_DELTIFIED) {
384 c3703302 2018-01-23 stsp struct got_delta *delta;
385 96f5e8b3 2018-01-23 stsp while (!SIMPLEQ_EMPTY(&obj->deltas.entries)) {
386 c3703302 2018-01-23 stsp delta = SIMPLEQ_FIRST(&obj->deltas.entries);
387 96f5e8b3 2018-01-23 stsp SIMPLEQ_REMOVE_HEAD(&obj->deltas.entries, entry);
388 c3703302 2018-01-23 stsp got_delta_close(delta);
389 96f5e8b3 2018-01-23 stsp }
390 96f5e8b3 2018-01-23 stsp }
391 96f5e8b3 2018-01-23 stsp if (obj->flags & GOT_OBJ_FLAG_PACKED)
392 96f5e8b3 2018-01-23 stsp free(obj->path_packfile);
393 ab9a70b2 2017-11-06 stsp free(obj);
394 d1cda826 2017-11-06 stsp }
395 d1cda826 2017-11-06 stsp
396 d1cda826 2017-11-06 stsp static const struct got_error *
397 d1cda826 2017-11-06 stsp parse_commit_object(struct got_commit_object **commit, char *buf, size_t len)
398 d1cda826 2017-11-06 stsp {
399 d1cda826 2017-11-06 stsp const struct got_error *err = NULL;
400 d1cda826 2017-11-06 stsp char *s = buf;
401 d1cda826 2017-11-06 stsp size_t tlen;
402 d1cda826 2017-11-06 stsp ssize_t remain = (ssize_t)len;
403 d1cda826 2017-11-06 stsp
404 d1cda826 2017-11-06 stsp *commit = calloc(1, sizeof(**commit));
405 d1cda826 2017-11-06 stsp if (*commit == NULL)
406 0a585a0d 2018-03-17 stsp return got_error_from_errno();
407 59ece79d 2018-02-12 stsp (*commit)->tree_id = calloc(1, sizeof(*(*commit)->tree_id));
408 59ece79d 2018-02-12 stsp if ((*commit)->tree_id == NULL) {
409 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
410 59ece79d 2018-02-12 stsp free(*commit);
411 59ece79d 2018-02-12 stsp *commit = NULL;
412 0a585a0d 2018-03-17 stsp return err;
413 59ece79d 2018-02-12 stsp }
414 d1cda826 2017-11-06 stsp
415 d1cda826 2017-11-06 stsp SIMPLEQ_INIT(&(*commit)->parent_ids);
416 d1cda826 2017-11-06 stsp
417 d1cda826 2017-11-06 stsp tlen = strlen(GOT_COMMIT_TAG_TREE);
418 d1cda826 2017-11-06 stsp if (strncmp(s, GOT_COMMIT_TAG_TREE, tlen) == 0) {
419 d1cda826 2017-11-06 stsp remain -= tlen;
420 d1cda826 2017-11-06 stsp if (remain < SHA1_DIGEST_STRING_LENGTH) {
421 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
422 d1cda826 2017-11-06 stsp goto done;
423 d1cda826 2017-11-06 stsp }
424 d1cda826 2017-11-06 stsp s += tlen;
425 59ece79d 2018-02-12 stsp if (!got_parse_sha1_digest((*commit)->tree_id->sha1, s)) {
426 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
427 d1cda826 2017-11-06 stsp goto done;
428 d1cda826 2017-11-06 stsp }
429 d1cda826 2017-11-06 stsp remain -= SHA1_DIGEST_STRING_LENGTH;
430 d1cda826 2017-11-06 stsp s += SHA1_DIGEST_STRING_LENGTH;
431 d1cda826 2017-11-06 stsp } else {
432 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
433 d1cda826 2017-11-06 stsp goto done;
434 d1cda826 2017-11-06 stsp }
435 d1cda826 2017-11-06 stsp
436 d1cda826 2017-11-06 stsp tlen = strlen(GOT_COMMIT_TAG_PARENT);
437 d1cda826 2017-11-06 stsp while (strncmp(s, GOT_COMMIT_TAG_PARENT, tlen) == 0) {
438 d1cda826 2017-11-06 stsp struct got_parent_id *pid;
439 d1cda826 2017-11-06 stsp
440 d1cda826 2017-11-06 stsp remain -= tlen;
441 d1cda826 2017-11-06 stsp if (remain < SHA1_DIGEST_STRING_LENGTH) {
442 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
443 d1cda826 2017-11-06 stsp goto done;
444 ef0981d5 2018-02-12 stsp }
445 d1cda826 2017-11-06 stsp
446 d1cda826 2017-11-06 stsp pid = calloc(1, sizeof(*pid));
447 d1cda826 2017-11-06 stsp if (pid == NULL) {
448 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
449 d1cda826 2017-11-06 stsp goto done;
450 d1cda826 2017-11-06 stsp }
451 59ece79d 2018-02-12 stsp pid->id = calloc(1, sizeof(*pid->id));
452 59ece79d 2018-02-12 stsp if (pid->id == NULL) {
453 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
454 59ece79d 2018-02-12 stsp free(pid);
455 59ece79d 2018-02-12 stsp goto done;
456 59ece79d 2018-02-12 stsp }
457 59ece79d 2018-02-12 stsp s += tlen;
458 59ece79d 2018-02-12 stsp if (!got_parse_sha1_digest(pid->id->sha1, s)) {
459 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
460 59ece79d 2018-02-12 stsp free(pid->id);
461 59ece79d 2018-02-12 stsp free(pid);
462 d1cda826 2017-11-06 stsp goto done;
463 d1cda826 2017-11-06 stsp }
464 d1cda826 2017-11-06 stsp SIMPLEQ_INSERT_TAIL(&(*commit)->parent_ids, pid, entry);
465 d1cda826 2017-11-06 stsp (*commit)->nparents++;
466 d1cda826 2017-11-06 stsp
467 eb651edf 2018-02-11 stsp remain -= SHA1_DIGEST_STRING_LENGTH;
468 d1cda826 2017-11-06 stsp s += SHA1_DIGEST_STRING_LENGTH;
469 d1cda826 2017-11-06 stsp }
470 d1cda826 2017-11-06 stsp
471 d1cda826 2017-11-06 stsp tlen = strlen(GOT_COMMIT_TAG_AUTHOR);
472 d1cda826 2017-11-06 stsp if (strncmp(s, GOT_COMMIT_TAG_AUTHOR, tlen) == 0) {
473 d1cda826 2017-11-06 stsp char *p;
474 d1cda826 2017-11-06 stsp
475 d1cda826 2017-11-06 stsp remain -= tlen;
476 d1cda826 2017-11-06 stsp if (remain <= 0) {
477 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
478 d1cda826 2017-11-06 stsp goto done;
479 d1cda826 2017-11-06 stsp }
480 d1cda826 2017-11-06 stsp s += tlen;
481 d1cda826 2017-11-06 stsp p = strchr(s, '\n');
482 d1cda826 2017-11-06 stsp if (p == NULL) {
483 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
484 d1cda826 2017-11-06 stsp goto done;
485 d1cda826 2017-11-06 stsp }
486 d1cda826 2017-11-06 stsp *p = '\0';
487 d1cda826 2017-11-06 stsp (*commit)->author = strdup(s);
488 d1cda826 2017-11-06 stsp if ((*commit)->author == NULL) {
489 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
490 d1cda826 2017-11-06 stsp goto done;
491 d1cda826 2017-11-06 stsp }
492 d1cda826 2017-11-06 stsp s += strlen((*commit)->author) + 1;
493 eb651edf 2018-02-11 stsp remain -= strlen((*commit)->author) + 1;
494 d1cda826 2017-11-06 stsp }
495 d1cda826 2017-11-06 stsp
496 d1cda826 2017-11-06 stsp tlen = strlen(GOT_COMMIT_TAG_COMMITTER);
497 d1cda826 2017-11-06 stsp if (strncmp(s, GOT_COMMIT_TAG_COMMITTER, tlen) == 0) {
498 d1cda826 2017-11-06 stsp char *p;
499 d1cda826 2017-11-06 stsp
500 d1cda826 2017-11-06 stsp remain -= tlen;
501 d1cda826 2017-11-06 stsp if (remain <= 0) {
502 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
503 d1cda826 2017-11-06 stsp goto done;
504 d1cda826 2017-11-06 stsp }
505 d1cda826 2017-11-06 stsp s += tlen;
506 d1cda826 2017-11-06 stsp p = strchr(s, '\n');
507 d1cda826 2017-11-06 stsp if (p == NULL) {
508 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
509 d1cda826 2017-11-06 stsp goto done;
510 d1cda826 2017-11-06 stsp }
511 d1cda826 2017-11-06 stsp *p = '\0';
512 d1cda826 2017-11-06 stsp (*commit)->committer = strdup(s);
513 d1cda826 2017-11-06 stsp if ((*commit)->committer == NULL) {
514 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
515 d1cda826 2017-11-06 stsp goto done;
516 d1cda826 2017-11-06 stsp }
517 d1cda826 2017-11-06 stsp s += strlen((*commit)->committer) + 1;
518 eb651edf 2018-02-11 stsp remain -= strlen((*commit)->committer) + 1;
519 d1cda826 2017-11-06 stsp }
520 d1cda826 2017-11-06 stsp
521 eb651edf 2018-02-11 stsp (*commit)->logmsg = strndup(s, remain);
522 eb651edf 2018-02-11 stsp if ((*commit)->logmsg == NULL) {
523 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
524 eb651edf 2018-02-11 stsp goto done;
525 eb651edf 2018-02-11 stsp }
526 d1cda826 2017-11-06 stsp done:
527 59ece79d 2018-02-12 stsp if (err) {
528 d1cda826 2017-11-06 stsp got_object_commit_close(*commit);
529 59ece79d 2018-02-12 stsp *commit = NULL;
530 59ece79d 2018-02-12 stsp }
531 0ffeb3c2 2017-11-26 stsp return err;
532 0ffeb3c2 2017-11-26 stsp }
533 0ffeb3c2 2017-11-26 stsp
534 0ffeb3c2 2017-11-26 stsp static void
535 0ffeb3c2 2017-11-26 stsp tree_entry_close(struct got_tree_entry *te)
536 0ffeb3c2 2017-11-26 stsp {
537 59ece79d 2018-02-12 stsp free(te->id);
538 0ffeb3c2 2017-11-26 stsp free(te->name);
539 0ffeb3c2 2017-11-26 stsp free(te);
540 0ffeb3c2 2017-11-26 stsp }
541 0ffeb3c2 2017-11-26 stsp
542 0ffeb3c2 2017-11-26 stsp static const struct got_error *
543 0ffeb3c2 2017-11-26 stsp parse_tree_entry(struct got_tree_entry **te, size_t *elen, char *buf,
544 0ffeb3c2 2017-11-26 stsp size_t maxlen)
545 0ffeb3c2 2017-11-26 stsp {
546 0ffeb3c2 2017-11-26 stsp char *p = buf, *space;
547 0ffeb3c2 2017-11-26 stsp const struct got_error *err = NULL;
548 0ffeb3c2 2017-11-26 stsp
549 0ffeb3c2 2017-11-26 stsp *te = calloc(1, sizeof(**te));
550 0ffeb3c2 2017-11-26 stsp if (*te == NULL)
551 0a585a0d 2018-03-17 stsp return got_error_from_errno();
552 59ece79d 2018-02-12 stsp
553 59ece79d 2018-02-12 stsp (*te)->id = calloc(1, sizeof(*(*te)->id));
554 59ece79d 2018-02-12 stsp if ((*te)->id == NULL) {
555 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
556 59ece79d 2018-02-12 stsp free(*te);
557 59ece79d 2018-02-12 stsp *te = NULL;
558 0a585a0d 2018-03-17 stsp return err;
559 59ece79d 2018-02-12 stsp }
560 0ffeb3c2 2017-11-26 stsp
561 0ffeb3c2 2017-11-26 stsp *elen = strlen(buf) + 1;
562 0ffeb3c2 2017-11-26 stsp if (*elen > maxlen) {
563 0ffeb3c2 2017-11-26 stsp free(*te);
564 59ece79d 2018-02-12 stsp *te = NULL;
565 0ffeb3c2 2017-11-26 stsp return got_error(GOT_ERR_BAD_OBJ_DATA);
566 0ffeb3c2 2017-11-26 stsp }
567 0ffeb3c2 2017-11-26 stsp
568 0ffeb3c2 2017-11-26 stsp space = strchr(buf, ' ');
569 0ffeb3c2 2017-11-26 stsp if (space == NULL) {
570 0a585a0d 2018-03-17 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
571 0ffeb3c2 2017-11-26 stsp free(*te);
572 59ece79d 2018-02-12 stsp *te = NULL;
573 0a585a0d 2018-03-17 stsp return err;
574 0ffeb3c2 2017-11-26 stsp }
575 0ffeb3c2 2017-11-26 stsp while (*p != ' ') {
576 0ffeb3c2 2017-11-26 stsp if (*p < '0' && *p > '7') {
577 0ffeb3c2 2017-11-26 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
578 0ffeb3c2 2017-11-26 stsp goto done;
579 0ffeb3c2 2017-11-26 stsp }
580 0ffeb3c2 2017-11-26 stsp (*te)->mode <<= 3;
581 0ffeb3c2 2017-11-26 stsp (*te)->mode |= *p - '0';
582 0ffeb3c2 2017-11-26 stsp p++;
583 0ffeb3c2 2017-11-26 stsp }
584 0ffeb3c2 2017-11-26 stsp
585 0ffeb3c2 2017-11-26 stsp (*te)->name = strdup(space + 1);
586 0ffeb3c2 2017-11-26 stsp if (*elen > maxlen || maxlen - *elen < SHA1_DIGEST_LENGTH) {
587 0ffeb3c2 2017-11-26 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
588 0ffeb3c2 2017-11-26 stsp goto done;
589 0ffeb3c2 2017-11-26 stsp }
590 0ffeb3c2 2017-11-26 stsp buf += strlen(buf) + 1;
591 59ece79d 2018-02-12 stsp memcpy((*te)->id->sha1, buf, SHA1_DIGEST_LENGTH);
592 0ffeb3c2 2017-11-26 stsp *elen += SHA1_DIGEST_LENGTH;
593 0ffeb3c2 2017-11-26 stsp done:
594 59ece79d 2018-02-12 stsp if (err) {
595 0ffeb3c2 2017-11-26 stsp tree_entry_close(*te);
596 59ece79d 2018-02-12 stsp *te = NULL;
597 59ece79d 2018-02-12 stsp }
598 d1cda826 2017-11-06 stsp return err;
599 d1cda826 2017-11-06 stsp }
600 d1cda826 2017-11-06 stsp
601 d1cda826 2017-11-06 stsp static const struct got_error *
602 0ffeb3c2 2017-11-26 stsp parse_tree_object(struct got_tree_object **tree, struct got_repository *repo,
603 e0ab43e7 2018-03-16 stsp uint8_t *buf, size_t len)
604 0ffeb3c2 2017-11-26 stsp {
605 90356acc 2018-01-27 stsp const struct got_error *err;
606 0ffeb3c2 2017-11-26 stsp size_t remain = len;
607 0ffeb3c2 2017-11-26 stsp
608 0ffeb3c2 2017-11-26 stsp *tree = calloc(1, sizeof(**tree));
609 0ffeb3c2 2017-11-26 stsp if (*tree == NULL)
610 0a585a0d 2018-03-17 stsp return got_error_from_errno();
611 0ffeb3c2 2017-11-26 stsp
612 0ffeb3c2 2017-11-26 stsp SIMPLEQ_INIT(&(*tree)->entries);
613 0ffeb3c2 2017-11-26 stsp
614 0ffeb3c2 2017-11-26 stsp while (remain > 0) {
615 0ffeb3c2 2017-11-26 stsp struct got_tree_entry *te;
616 0ffeb3c2 2017-11-26 stsp size_t elen;
617 0ffeb3c2 2017-11-26 stsp
618 90356acc 2018-01-27 stsp err = parse_tree_entry(&te, &elen, buf, remain);
619 90356acc 2018-01-27 stsp if (err)
620 90356acc 2018-01-27 stsp return err;
621 0ffeb3c2 2017-11-26 stsp (*tree)->nentries++;
622 0ffeb3c2 2017-11-26 stsp SIMPLEQ_INSERT_TAIL(&(*tree)->entries, te, entry);
623 0ffeb3c2 2017-11-26 stsp buf += elen;
624 0ffeb3c2 2017-11-26 stsp remain -= elen;
625 0ffeb3c2 2017-11-26 stsp }
626 0ffeb3c2 2017-11-26 stsp
627 0ffeb3c2 2017-11-26 stsp if (remain != 0) {
628 0ffeb3c2 2017-11-26 stsp got_object_tree_close(*tree);
629 0ffeb3c2 2017-11-26 stsp return got_error(GOT_ERR_BAD_OBJ_DATA);
630 0ffeb3c2 2017-11-26 stsp }
631 0ffeb3c2 2017-11-26 stsp
632 0ffeb3c2 2017-11-26 stsp return NULL;
633 0ffeb3c2 2017-11-26 stsp }
634 0ffeb3c2 2017-11-26 stsp
635 0ffeb3c2 2017-11-26 stsp static const struct got_error *
636 eb651edf 2018-02-11 stsp read_to_mem(uint8_t **outbuf, size_t *outlen, FILE *f)
637 eb651edf 2018-02-11 stsp {
638 eb651edf 2018-02-11 stsp const struct got_error *err = NULL;
639 eb651edf 2018-02-11 stsp static const size_t blocksize = 512;
640 eb651edf 2018-02-11 stsp size_t n, total, remain;
641 eb651edf 2018-02-11 stsp uint8_t *buf;
642 eb651edf 2018-02-11 stsp
643 eb651edf 2018-02-11 stsp *outbuf = NULL;
644 eb651edf 2018-02-11 stsp *outlen = 0;
645 eb651edf 2018-02-11 stsp
646 eb651edf 2018-02-11 stsp buf = calloc(1, blocksize);
647 eb651edf 2018-02-11 stsp if (buf == NULL)
648 0a585a0d 2018-03-17 stsp return got_error_from_errno();
649 eb651edf 2018-02-11 stsp
650 eb651edf 2018-02-11 stsp remain = blocksize;
651 eb651edf 2018-02-11 stsp total = 0;
652 eb651edf 2018-02-11 stsp while (1) {
653 eb651edf 2018-02-11 stsp if (remain == 0) {
654 eb651edf 2018-02-11 stsp uint8_t *newbuf;
655 eb651edf 2018-02-11 stsp newbuf = reallocarray(buf, 1, total + blocksize);
656 eb651edf 2018-02-11 stsp if (newbuf == NULL) {
657 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
658 eb651edf 2018-02-11 stsp goto done;
659 eb651edf 2018-02-11 stsp }
660 eb651edf 2018-02-11 stsp buf = newbuf;
661 eb651edf 2018-02-11 stsp remain += blocksize;
662 eb651edf 2018-02-11 stsp }
663 be89e2b1 2018-03-03 stsp n = fread(buf + total, 1, remain, f);
664 eb651edf 2018-02-11 stsp if (n == 0) {
665 eb651edf 2018-02-11 stsp if (ferror(f)) {
666 eb651edf 2018-02-11 stsp err = got_ferror(f, GOT_ERR_IO);
667 eb651edf 2018-02-11 stsp goto done;
668 eb651edf 2018-02-11 stsp }
669 eb651edf 2018-02-11 stsp break; /* EOF */
670 eb651edf 2018-02-11 stsp }
671 eb651edf 2018-02-11 stsp remain -= n;
672 eb651edf 2018-02-11 stsp total += n;
673 eb651edf 2018-02-11 stsp };
674 eb651edf 2018-02-11 stsp
675 eb651edf 2018-02-11 stsp done:
676 eb651edf 2018-02-11 stsp if (err == NULL) {
677 eb651edf 2018-02-11 stsp *outbuf = buf;
678 eb651edf 2018-02-11 stsp *outlen = total;
679 eb651edf 2018-02-11 stsp } else
680 eb651edf 2018-02-11 stsp free(buf);
681 eb651edf 2018-02-11 stsp return err;
682 eb651edf 2018-02-11 stsp }
683 eb651edf 2018-02-11 stsp
684 eb651edf 2018-02-11 stsp static const struct got_error *
685 d1cda826 2017-11-06 stsp read_commit_object(struct got_commit_object **commit,
686 4558fcd4 2018-01-14 stsp struct got_repository *repo, struct got_object *obj, FILE *f)
687 d1cda826 2017-11-06 stsp {
688 d1cda826 2017-11-06 stsp const struct got_error *err = NULL;
689 d1cda826 2017-11-06 stsp size_t len;
690 eb651edf 2018-02-11 stsp uint8_t *p;
691 d1cda826 2017-11-06 stsp
692 eb651edf 2018-02-11 stsp if (obj->flags & GOT_OBJ_FLAG_PACKED)
693 eb651edf 2018-02-11 stsp err = read_to_mem(&p, &len, f);
694 eb651edf 2018-02-11 stsp else
695 eb651edf 2018-02-11 stsp err = got_inflate_to_mem(&p, &len, f);
696 4558fcd4 2018-01-14 stsp if (err)
697 d1cda826 2017-11-06 stsp return err;
698 d1cda826 2017-11-06 stsp
699 d1cda826 2017-11-06 stsp if (len < obj->hdrlen + obj->size) {
700 d1cda826 2017-11-06 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
701 d1cda826 2017-11-06 stsp goto done;
702 d1cda826 2017-11-06 stsp }
703 d1cda826 2017-11-06 stsp
704 d1cda826 2017-11-06 stsp /* Skip object header. */
705 d1cda826 2017-11-06 stsp len -= obj->hdrlen;
706 eb651edf 2018-02-11 stsp err = parse_commit_object(commit, p + obj->hdrlen, len);
707 eb651edf 2018-02-11 stsp free(p);
708 d1cda826 2017-11-06 stsp done:
709 d1cda826 2017-11-06 stsp return err;
710 d1cda826 2017-11-06 stsp }
711 d1cda826 2017-11-06 stsp
712 d1cda826 2017-11-06 stsp const struct got_error *
713 d1cda826 2017-11-06 stsp got_object_commit_open(struct got_commit_object **commit,
714 d1cda826 2017-11-06 stsp struct got_repository *repo, struct got_object *obj)
715 d1cda826 2017-11-06 stsp {
716 d1cda826 2017-11-06 stsp const struct got_error *err = NULL;
717 d1cda826 2017-11-06 stsp
718 d1cda826 2017-11-06 stsp if (obj->type != GOT_OBJ_TYPE_COMMIT)
719 d1cda826 2017-11-06 stsp return got_error(GOT_ERR_OBJ_TYPE);
720 d1cda826 2017-11-06 stsp
721 ea35256b 2018-03-16 stsp if (obj->flags & GOT_OBJ_FLAG_PACKED) {
722 ea35256b 2018-03-16 stsp uint8_t *buf;
723 ea35256b 2018-03-16 stsp size_t len;
724 ea35256b 2018-03-16 stsp err = got_packfile_extract_object_to_mem(&buf, &len, obj, repo);
725 ea35256b 2018-03-16 stsp if (err)
726 ea35256b 2018-03-16 stsp return err;
727 b29656e2 2018-03-16 stsp obj->size = len;
728 b29656e2 2018-03-16 stsp err = parse_commit_object(commit, buf, len);
729 ea35256b 2018-03-16 stsp free(buf);
730 ea35256b 2018-03-16 stsp } else {
731 ea35256b 2018-03-16 stsp FILE *f;
732 d5003b79 2018-04-22 stsp int fd;
733 d5003b79 2018-04-22 stsp err = open_loose_object(&fd, obj, repo);
734 ea35256b 2018-03-16 stsp if (err)
735 ea35256b 2018-03-16 stsp return err;
736 d5003b79 2018-04-22 stsp f = fdopen(fd, "rb");
737 d5003b79 2018-04-22 stsp if (f == NULL) {
738 d5003b79 2018-04-22 stsp err = got_error_from_errno();
739 d5003b79 2018-04-22 stsp close(fd);
740 d5003b79 2018-04-22 stsp return err;
741 d5003b79 2018-04-22 stsp }
742 ea35256b 2018-03-16 stsp err = read_commit_object(commit, repo, obj, f);
743 ea35256b 2018-03-16 stsp fclose(f);
744 ea35256b 2018-03-16 stsp }
745 d1cda826 2017-11-06 stsp return err;
746 d1cda826 2017-11-06 stsp }
747 d1cda826 2017-11-06 stsp
748 d1cda826 2017-11-06 stsp void
749 d1cda826 2017-11-06 stsp got_object_commit_close(struct got_commit_object *commit)
750 d1cda826 2017-11-06 stsp {
751 d1cda826 2017-11-06 stsp struct got_parent_id *pid;
752 d1cda826 2017-11-06 stsp
753 d1cda826 2017-11-06 stsp while (!SIMPLEQ_EMPTY(&commit->parent_ids)) {
754 d1cda826 2017-11-06 stsp pid = SIMPLEQ_FIRST(&commit->parent_ids);
755 d1cda826 2017-11-06 stsp SIMPLEQ_REMOVE_HEAD(&commit->parent_ids, entry);
756 59ece79d 2018-02-12 stsp free(pid->id);
757 d1cda826 2017-11-06 stsp free(pid);
758 d1cda826 2017-11-06 stsp }
759 d1cda826 2017-11-06 stsp
760 59ece79d 2018-02-12 stsp free(commit->tree_id);
761 d1cda826 2017-11-06 stsp free(commit->author);
762 d1cda826 2017-11-06 stsp free(commit->committer);
763 d1cda826 2017-11-06 stsp free(commit->logmsg);
764 d1cda826 2017-11-06 stsp free(commit);
765 d1cda826 2017-11-06 stsp }
766 0ffeb3c2 2017-11-26 stsp
767 0ffeb3c2 2017-11-26 stsp static const struct got_error *
768 0ffeb3c2 2017-11-26 stsp read_tree_object(struct got_tree_object **tree,
769 4558fcd4 2018-01-14 stsp struct got_repository *repo, struct got_object *obj, FILE *f)
770 0ffeb3c2 2017-11-26 stsp {
771 0ffeb3c2 2017-11-26 stsp const struct got_error *err = NULL;
772 0ffeb3c2 2017-11-26 stsp size_t len;
773 eb651edf 2018-02-11 stsp uint8_t *p;
774 0ffeb3c2 2017-11-26 stsp
775 eb651edf 2018-02-11 stsp if (obj->flags & GOT_OBJ_FLAG_PACKED)
776 eb651edf 2018-02-11 stsp err = read_to_mem(&p, &len, f);
777 eb651edf 2018-02-11 stsp else
778 eb651edf 2018-02-11 stsp err = got_inflate_to_mem(&p, &len, f);
779 4558fcd4 2018-01-14 stsp if (err)
780 0ffeb3c2 2017-11-26 stsp return err;
781 0ffeb3c2 2017-11-26 stsp
782 0ffeb3c2 2017-11-26 stsp if (len < obj->hdrlen + obj->size) {
783 0ffeb3c2 2017-11-26 stsp err = got_error(GOT_ERR_BAD_OBJ_DATA);
784 0ffeb3c2 2017-11-26 stsp goto done;
785 0ffeb3c2 2017-11-26 stsp }
786 0ffeb3c2 2017-11-26 stsp
787 0ffeb3c2 2017-11-26 stsp /* Skip object header. */
788 0ffeb3c2 2017-11-26 stsp len -= obj->hdrlen;
789 eb651edf 2018-02-11 stsp err = parse_tree_object(tree, repo, p + obj->hdrlen, len);
790 eb651edf 2018-02-11 stsp free(p);
791 0ffeb3c2 2017-11-26 stsp done:
792 0ffeb3c2 2017-11-26 stsp return err;
793 0ffeb3c2 2017-11-26 stsp }
794 0ffeb3c2 2017-11-26 stsp
795 0ffeb3c2 2017-11-26 stsp const struct got_error *
796 0ffeb3c2 2017-11-26 stsp got_object_tree_open(struct got_tree_object **tree,
797 0ffeb3c2 2017-11-26 stsp struct got_repository *repo, struct got_object *obj)
798 0ffeb3c2 2017-11-26 stsp {
799 0ffeb3c2 2017-11-26 stsp const struct got_error *err = NULL;
800 0ffeb3c2 2017-11-26 stsp
801 0ffeb3c2 2017-11-26 stsp if (obj->type != GOT_OBJ_TYPE_TREE)
802 0ffeb3c2 2017-11-26 stsp return got_error(GOT_ERR_OBJ_TYPE);
803 0ffeb3c2 2017-11-26 stsp
804 e0ab43e7 2018-03-16 stsp if (obj->flags & GOT_OBJ_FLAG_PACKED) {
805 e0ab43e7 2018-03-16 stsp uint8_t *buf;
806 e0ab43e7 2018-03-16 stsp size_t len;
807 e0ab43e7 2018-03-16 stsp err = got_packfile_extract_object_to_mem(&buf, &len, obj, repo);
808 e0ab43e7 2018-03-16 stsp if (err)
809 e0ab43e7 2018-03-16 stsp return err;
810 b29656e2 2018-03-16 stsp obj->size = len;
811 b29656e2 2018-03-16 stsp err = parse_tree_object(tree, repo, buf, len);
812 e0ab43e7 2018-03-16 stsp free(buf);
813 e0ab43e7 2018-03-16 stsp } else {
814 e0ab43e7 2018-03-16 stsp FILE *f;
815 d5003b79 2018-04-22 stsp int fd;
816 d5003b79 2018-04-22 stsp err = open_loose_object(&fd, obj, repo);
817 e0ab43e7 2018-03-16 stsp if (err)
818 e0ab43e7 2018-03-16 stsp return err;
819 d5003b79 2018-04-22 stsp f = fdopen(fd, "rb");
820 d5003b79 2018-04-22 stsp if (f == NULL) {
821 d5003b79 2018-04-22 stsp close(fd);
822 d5003b79 2018-04-22 stsp return got_error_from_errno();
823 d5003b79 2018-04-22 stsp }
824 e0ab43e7 2018-03-16 stsp err = read_tree_object(tree, repo, obj, f);
825 e0ab43e7 2018-03-16 stsp fclose(f);
826 d5003b79 2018-04-22 stsp close(fd);
827 e0ab43e7 2018-03-16 stsp }
828 0ffeb3c2 2017-11-26 stsp return err;
829 0ffeb3c2 2017-11-26 stsp }
830 0ffeb3c2 2017-11-26 stsp
831 0ffeb3c2 2017-11-26 stsp void
832 0ffeb3c2 2017-11-26 stsp got_object_tree_close(struct got_tree_object *tree)
833 0ffeb3c2 2017-11-26 stsp {
834 f715ca7f 2017-11-27 stsp struct got_tree_entry *te;
835 f715ca7f 2017-11-27 stsp
836 f715ca7f 2017-11-27 stsp while (!SIMPLEQ_EMPTY(&tree->entries)) {
837 f715ca7f 2017-11-27 stsp te = SIMPLEQ_FIRST(&tree->entries);
838 f715ca7f 2017-11-27 stsp SIMPLEQ_REMOVE_HEAD(&tree->entries, entry);
839 f715ca7f 2017-11-27 stsp tree_entry_close(te);
840 f715ca7f 2017-11-27 stsp }
841 f715ca7f 2017-11-27 stsp
842 f715ca7f 2017-11-27 stsp free(tree);
843 68482ea3 2017-11-27 stsp }
844 68482ea3 2017-11-27 stsp
845 68482ea3 2017-11-27 stsp const struct got_error *
846 68482ea3 2017-11-27 stsp got_object_blob_open(struct got_blob_object **blob,
847 68482ea3 2017-11-27 stsp struct got_repository *repo, struct got_object *obj, size_t blocksize)
848 68482ea3 2017-11-27 stsp {
849 68482ea3 2017-11-27 stsp const struct got_error *err = NULL;
850 68482ea3 2017-11-27 stsp
851 68482ea3 2017-11-27 stsp if (obj->type != GOT_OBJ_TYPE_BLOB)
852 68482ea3 2017-11-27 stsp return got_error(GOT_ERR_OBJ_TYPE);
853 68482ea3 2017-11-27 stsp
854 7d283eee 2017-11-29 stsp if (blocksize < obj->hdrlen)
855 7d283eee 2017-11-29 stsp return got_error(GOT_ERR_NO_SPACE);
856 7d283eee 2017-11-29 stsp
857 68482ea3 2017-11-27 stsp *blob = calloc(1, sizeof(**blob));
858 4558fcd4 2018-01-14 stsp if (*blob == NULL)
859 0a585a0d 2018-03-17 stsp return got_error_from_errno();
860 68482ea3 2017-11-27 stsp
861 eb651edf 2018-02-11 stsp if (obj->flags & GOT_OBJ_FLAG_PACKED) {
862 eb651edf 2018-02-11 stsp (*blob)->read_buf = calloc(1, blocksize);
863 56866f4a 2018-03-17 stsp if ((*blob)->read_buf == NULL) {
864 0a585a0d 2018-03-17 stsp err = got_error_from_errno();
865 56866f4a 2018-03-17 stsp free(*blob);
866 56866f4a 2018-03-17 stsp *blob = NULL;
867 0a585a0d 2018-03-17 stsp return err;
868 56866f4a 2018-03-17 stsp }
869 eb651edf 2018-02-11 stsp err = got_packfile_extract_object(&((*blob)->f), obj, repo);
870 56866f4a 2018-03-17 stsp if (err) {
871 56866f4a 2018-03-17 stsp free((*blob)->read_buf);
872 56866f4a 2018-03-17 stsp free(*blob);
873 56866f4a 2018-03-17 stsp *blob = NULL;
874 eb651edf 2018-02-11 stsp return err;
875 56866f4a 2018-03-17 stsp }
876 eb651edf 2018-02-11 stsp } else {
877 d5003b79 2018-04-22 stsp int fd;
878 d5003b79 2018-04-22 stsp err = open_loose_object(&fd, obj, repo);
879 eb651edf 2018-02-11 stsp if (err) {
880 eb651edf 2018-02-11 stsp free(*blob);
881 d0f3be7c 2018-03-17 stsp *blob = NULL;
882 eb651edf 2018-02-11 stsp return err;
883 eb651edf 2018-02-11 stsp }
884 d5003b79 2018-04-22 stsp (*blob)->f = fdopen(fd, "rb");
885 d5003b79 2018-04-22 stsp if ((*blob)->f == NULL) {
886 d5003b79 2018-04-22 stsp free(*blob);
887 d5003b79 2018-04-22 stsp *blob = NULL;
888 d5003b79 2018-04-22 stsp close(fd);
889 d5003b79 2018-04-22 stsp return err;
890 d5003b79 2018-04-22 stsp }
891 68482ea3 2017-11-27 stsp
892 19d747f7 2018-03-16 stsp err = got_inflate_init(&(*blob)->zb, NULL, blocksize);
893 eb651edf 2018-02-11 stsp if (err != NULL) {
894 eb651edf 2018-02-11 stsp fclose((*blob)->f);
895 eb651edf 2018-02-11 stsp free(*blob);
896 56866f4a 2018-03-17 stsp *blob = NULL;
897 eb651edf 2018-02-11 stsp return err;
898 eb651edf 2018-02-11 stsp }
899 eb651edf 2018-02-11 stsp
900 eb651edf 2018-02-11 stsp (*blob)->read_buf = (*blob)->zb.outbuf;
901 eb651edf 2018-02-11 stsp (*blob)->flags |= GOT_BLOB_F_COMPRESSED;
902 68482ea3 2017-11-27 stsp }
903 68482ea3 2017-11-27 stsp
904 7d283eee 2017-11-29 stsp (*blob)->hdrlen = obj->hdrlen;
905 eb651edf 2018-02-11 stsp (*blob)->blocksize = blocksize;
906 f78b0693 2017-11-29 stsp memcpy(&(*blob)->id.sha1, obj->id.sha1, SHA1_DIGEST_LENGTH);
907 7d283eee 2017-11-29 stsp
908 68482ea3 2017-11-27 stsp return err;
909 0ffeb3c2 2017-11-26 stsp }
910 68482ea3 2017-11-27 stsp
911 68482ea3 2017-11-27 stsp void
912 68482ea3 2017-11-27 stsp got_object_blob_close(struct got_blob_object *blob)
913 68482ea3 2017-11-27 stsp {
914 eb651edf 2018-02-11 stsp if (blob->flags & GOT_BLOB_F_COMPRESSED)
915 eb651edf 2018-02-11 stsp got_inflate_end(&blob->zb);
916 eb651edf 2018-02-11 stsp else
917 eb651edf 2018-02-11 stsp free(blob->read_buf);
918 68482ea3 2017-11-27 stsp fclose(blob->f);
919 68482ea3 2017-11-27 stsp free(blob);
920 f934cf2c 2018-02-12 stsp }
921 f934cf2c 2018-02-12 stsp
922 f934cf2c 2018-02-12 stsp char *
923 f934cf2c 2018-02-12 stsp got_object_blob_id_str(struct got_blob_object *blob, char *buf, size_t size)
924 f934cf2c 2018-02-12 stsp {
925 f934cf2c 2018-02-12 stsp return got_sha1_digest_to_str(blob->id.sha1, buf, size);
926 f934cf2c 2018-02-12 stsp }
927 f934cf2c 2018-02-12 stsp
928 f934cf2c 2018-02-12 stsp size_t
929 f934cf2c 2018-02-12 stsp got_object_blob_get_hdrlen(struct got_blob_object *blob)
930 f934cf2c 2018-02-12 stsp {
931 f934cf2c 2018-02-12 stsp return blob->hdrlen;
932 68482ea3 2017-11-27 stsp }
933 68482ea3 2017-11-27 stsp
934 f934cf2c 2018-02-12 stsp const uint8_t *
935 f934cf2c 2018-02-12 stsp got_object_blob_get_read_buf(struct got_blob_object *blob)
936 f934cf2c 2018-02-12 stsp {
937 f934cf2c 2018-02-12 stsp return blob->read_buf;
938 f934cf2c 2018-02-12 stsp }
939 f934cf2c 2018-02-12 stsp
940 68482ea3 2017-11-27 stsp const struct got_error *
941 eb651edf 2018-02-11 stsp got_object_blob_read_block(size_t *outlenp, struct got_blob_object *blob)
942 68482ea3 2017-11-27 stsp {
943 eb651edf 2018-02-11 stsp size_t n;
944 eb651edf 2018-02-11 stsp
945 eb651edf 2018-02-11 stsp if (blob->flags & GOT_BLOB_F_COMPRESSED)
946 eb651edf 2018-02-11 stsp return got_inflate_read(&blob->zb, blob->f, outlenp);
947 eb651edf 2018-02-11 stsp
948 eb651edf 2018-02-11 stsp n = fread(blob->read_buf, 1, blob->blocksize, blob->f);
949 eb651edf 2018-02-11 stsp if (n == 0 && ferror(blob->f))
950 eb651edf 2018-02-11 stsp return got_ferror(blob->f, GOT_ERR_IO);
951 eb651edf 2018-02-11 stsp *outlenp = n;
952 eb651edf 2018-02-11 stsp return NULL;
953 68482ea3 2017-11-27 stsp }