Download raw body.
got-read-gitconfig: send key-value pairs for extensions
On Sun, Feb 05, 2023 at 04:50:51PM +0100, Omar Polo wrote:
> This depends on the diff I just sent about replacing
> got_repo_get_gitconfig_extensions with got_repo_has_extension.
> it'll make parsing of objectformat=sha256 dead-simple :)
>
> ok?
Yes, ok. This is a nice way of generalizing things.
> -----------------------------------------------
> commit 801ecd4bd7f8dd41df43a4225a5e3c41c144c595 (main)
> from: Omar Polo <op@omarpolo.com>
> date: Sun Feb 5 15:27:06 2023 UTC
>
> got-read-gitconfig: send key-value pairs for extensions
>
> Most extension allow only for a boolean value so the current behaviour
> of just sending the extension with a trueish value is fine. However,
> some extensions that we could eventually support (like "objectformat")
> have a string value. This is a preparatory step towards that.
>
> diff 7c3a2af1f17dda354dd8ae31d233458143646797 801ecd4bd7f8dd41df43a4225a5e3c41c144c595
> commit - 7c3a2af1f17dda354dd8ae31d233458143646797
> commit + 801ecd4bd7f8dd41df43a4225a5e3c41c144c595
> blob - 1b4b7bc8fc2baddfd1f3353725f35bd6ac9af0cf
> blob + 076cab5adad635b8e7ea46af68a14510dced4da4
> --- lib/got_lib_privsep.h
> +++ lib/got_lib_privsep.h
> @@ -158,6 +158,7 @@ enum got_imsg_type {
> GOT_IMSG_GITCONFIG_REMOTES_REQUEST,
> GOT_IMSG_GITCONFIG_INT_VAL,
> GOT_IMSG_GITCONFIG_STR_VAL,
> + GOT_IMSG_GITCONFIG_PAIR,
> GOT_IMSG_GITCONFIG_REMOTES,
> GOT_IMSG_GITCONFIG_REMOTE,
> GOT_IMSG_GITCONFIG_OWNER_REQUEST,
> @@ -627,6 +628,16 @@ struct got_imsg_remotes {
> };
>
> /*
> + * Structure for GOT_IMSG_GITCONFIG_PAIR.
> + */
> +struct got_imsg_gitconfig_pair {
> + size_t klen;
> + size_t vlen;
> + /* Followed by klen data bytes of key string. */
> + /* Followed by vlen data bytes of value string. */
> +};
> +
> +/*
> * Structure for GOT_IMSG_PATCH data.
> */
> struct got_imsg_patch {
> @@ -747,6 +758,8 @@ const struct got_error *got_privsep_recv_gitconfig_int
> const struct got_error *got_privsep_send_gitconfig_owner_req(struct imsgbuf *);
> const struct got_error *got_privsep_recv_gitconfig_str(char **,
> struct imsgbuf *);
> +const struct got_error *got_privsep_recv_gitconfig_pair(char **, char **,
> + struct imsgbuf *);
> const struct got_error *got_privsep_recv_gitconfig_int(int *, struct imsgbuf *);
> const struct got_error *got_privsep_recv_gitconfig_remotes(
> struct got_remote_repo **, int *, struct imsgbuf *);
> blob - b8032ffd3ffe9dab29beaf3cc57c39a6ef957859
> blob + 83d718aa029bf9afded3debb15731d617de2169c
> --- lib/got_lib_repository.h
> +++ lib/got_lib_repository.h
> @@ -124,7 +124,8 @@ struct got_repository {
> int ngitconfig_remotes;
> struct got_remote_repo *gitconfig_remotes;
> char *gitconfig_owner;
> - char **extensions;
> + char **extnames;
> + char **extvals;
> int nextensions;
>
> /* Settings read from got.conf. */
> @@ -170,7 +171,7 @@ const struct got_error *got_repo_read_gitconfig(int *,
> void got_repo_unpin_pack(struct got_repository *);
>
> const struct got_error *got_repo_read_gitconfig(int *, char **, char **,
> - struct got_remote_repo **, int *, char **, char ***, int *,
> + struct got_remote_repo **, int *, char **, char ***, char ***, int *,
> const char *);
>
> const struct got_error *got_repo_temp_fds_get(int *, int *,
> blob - a54ba7c0e2d8f3fc5ac97dacc39c1d54cb028eb7
> blob + ddb1e595d753eddc725ce0bbb056d1dc8236fc07
> --- lib/privsep.c
> +++ lib/privsep.c
> @@ -2103,6 +2103,60 @@ got_privsep_recv_gitconfig_int(int *val, struct imsgbu
> }
>
> const struct got_error *
> +got_privsep_recv_gitconfig_pair(char **key, char **val, struct imsgbuf *ibuf)
> +{
> + const struct got_error *err = NULL;
> + struct got_imsg_gitconfig_pair p;
> + struct imsg imsg;
> + size_t datalen;
> + uint8_t *data;
> +
> + *key = *val = NULL;
> +
> + err = got_privsep_recv_imsg(&imsg, ibuf, 0);
> + if (err)
> + return err;
> +
> + data = imsg.data;
> + datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
> +
> + if (imsg.hdr.type != GOT_IMSG_GITCONFIG_PAIR) {
> + err = got_error(GOT_ERR_PRIVSEP_MSG);
> + goto done;
> + }
> +
> + if (datalen < sizeof(p)) {
> + err = got_error(GOT_ERR_PRIVSEP_LEN);
> + goto done;
> + }
> +
> + memcpy(&p, data, sizeof(p));
> + data += sizeof(p);
> +
> + if (datalen != sizeof(p) + p.klen + p.vlen) {
> + err = got_error(GOT_ERR_PRIVSEP_LEN);
> + goto done;
> + }
> +
> + *key = strndup(data, p.klen);
> + if (*key == NULL) {
> + err = got_error_from_errno("strndup");
> + goto done;
> + }
> + data += p.klen;
> +
> + *val = strndup(data, p.vlen);
> + if (*val == NULL) {
> + err = got_error_from_errno("strndup");
> + goto done;
> + }
> +
> +done:
> + imsg_free(&imsg);
> + return err;
> +}
> +
> +const struct got_error *
> got_privsep_recv_gitconfig_int(int *val, struct imsgbuf *ibuf)
> {
> const struct got_error *err = NULL;
> blob - e76312afb71dc950015ded8344d412b185adb00c
> blob + db996fe3996b3c638c45e65da4fbdd6fa80f02b2
> --- lib/read_gitconfig_privsep.c
> +++ lib/read_gitconfig_privsep.c
> @@ -47,8 +47,8 @@ got_repo_read_gitconfig(int *gitconfig_repository_form
> got_repo_read_gitconfig(int *gitconfig_repository_format_version,
> char **gitconfig_author_name, char **gitconfig_author_email,
> struct got_remote_repo **remotes, int *nremotes,
> - char **gitconfig_owner, char ***extensions, int *nextensions,
> - const char *gitconfig_path)
> + char **gitconfig_owner, char ***extnames, char ***extvals,
> + int *nextensions, const char *gitconfig_path)
> {
> const struct got_error *err = NULL, *child_err = NULL;
> int fd = -1;
> @@ -57,8 +57,10 @@ got_repo_read_gitconfig(int *gitconfig_repository_form
> struct imsgbuf *ibuf;
>
> *gitconfig_repository_format_version = 0;
> - if (extensions)
> - *extensions = NULL;
> + if (extnames)
> + *extnames = NULL;
> + if (extvals)
> + *extvals = NULL;
> if (nextensions)
> *nextensions = 0;
> *gitconfig_author_name = NULL;
> @@ -119,7 +121,7 @@ got_repo_read_gitconfig(int *gitconfig_repository_form
> if (err)
> goto done;
>
> - if (extensions && nextensions) {
> + if (extnames && extvals && nextensions) {
> err = got_privsep_send_gitconfig_repository_extensions_req(
> ibuf);
> if (err)
> @@ -129,18 +131,24 @@ got_repo_read_gitconfig(int *gitconfig_repository_form
> goto done;
> if (*nextensions > 0) {
> int i;
> - *extensions = calloc(*nextensions, sizeof(char *));
> - if (*extensions == NULL) {
> + *extnames = calloc(*nextensions, sizeof(char *));
> + if (*extnames == NULL) {
> err = got_error_from_errno("calloc");
> goto done;
> }
> + *extvals = calloc(*nextensions, sizeof(char *));
> + if (*extvals == NULL) {
> + err = got_error_from_errno("calloc");
> + goto done;
> + }
> for (i = 0; i < *nextensions; i++) {
> - char *ext;
> - err = got_privsep_recv_gitconfig_str(&ext,
> - ibuf);
> + char *ext, *val;
> + err = got_privsep_recv_gitconfig_pair(&ext,
> + &val, ibuf);
> if (err)
> goto done;
> - (*extensions)[i] = ext;
> + (*extnames)[i] = ext;
> + (*extvals)[i] = val;
> }
> }
> }
> blob - 724a22a36f25053e940871eed29828527c813f87
> blob + 9b6bfeb03479b844dcb5ea253742cfce88a0b45f
> --- lib/repository.c
> +++ lib/repository.c
> @@ -74,6 +74,28 @@ const char *
> RB_PROTOTYPE(got_packidx_bloom_filter_tree, got_packidx_bloom_filter, entry,
> got_packidx_bloom_filter_cmp);
>
> +static inline int
> +is_boolean_val(const char *val)
> +{
> + return (strcasecmp(val, "true") == 0 ||
> + strcasecmp(val, "false") == 0 ||
> + strcasecmp(val, "on") == 0 ||
> + strcasecmp(val, "off") == 0 ||
> + strcasecmp(val, "yes") == 0 ||
> + strcasecmp(val, "no") == 0 ||
> + strcasecmp(val, "1") == 0 ||
> + strcasecmp(val, "0") == 0);
> +}
> +
> +static inline int
> +get_boolean_val(const char *val)
> +{
> + return (strcasecmp(val, "true") == 0 ||
> + strcasecmp(val, "on") == 0 ||
> + strcasecmp(val, "yes") == 0 ||
> + strcasecmp(val, "1") == 0);
> +}
> +
> const char *
> got_repo_get_path(struct got_repository *repo)
> {
> @@ -128,8 +150,8 @@ got_repo_has_extension(struct got_repository *repo, co
> int i;
>
> for (i = 0; i < repo->nextensions; ++i) {
> - if (!strcasecmp(ext, repo->extensions[i]))
> - return 1;
> + if (!strcasecmp(ext, repo->extnames[i]))
> + return get_boolean_val(repo->extvals[i]);
> }
>
> return 0;
> @@ -598,7 +620,8 @@ read_gitconfig(struct got_repository *repo, const char
> err = got_repo_read_gitconfig(&dummy_repo_version,
> &repo->global_gitconfig_author_name,
> &repo->global_gitconfig_author_email,
> - NULL, NULL, NULL, NULL, NULL, global_gitconfig_path);
> + NULL, NULL, NULL, NULL, NULL, NULL,
> + global_gitconfig_path);
> if (err)
> return err;
> }
> @@ -612,8 +635,8 @@ read_gitconfig(struct got_repository *repo, const char
> &repo->gitconfig_repository_format_version,
> &repo->gitconfig_author_name, &repo->gitconfig_author_email,
> &repo->gitconfig_remotes, &repo->ngitconfig_remotes,
> - &repo->gitconfig_owner, &repo->extensions, &repo->nextensions,
> - repo_gitconfig_path);
> + &repo->gitconfig_owner, &repo->extnames, &repo->extvals,
> + &repo->nextensions, repo_gitconfig_path);
> if (err)
> goto done;
>
> @@ -766,8 +789,18 @@ got_repo_open(struct got_repository **repop, const cha
> goto done;
> }
> for (i = 0; i < repo->nextensions; i++) {
> - char *ext = repo->extensions[i];
> + char *ext = repo->extnames[i];
> + char *val = repo->extvals[i];
> int j, supported = 0;
> +
> + if (!is_boolean_val(val)) {
> + err = got_error_path(ext, GOT_ERR_GIT_REPO_EXT);
> + goto done;
> + }
> +
> + if (!get_boolean_val(val))
> + continue;
> +
> for (j = 0; j < nitems(repo_extensions); j++) {
> if (strcmp(ext, repo_extensions[j]) == 0) {
> supported = 1;
> @@ -852,9 +885,12 @@ got_repo_close(struct got_repository *repo)
> for (i = 0; i < repo->ngitconfig_remotes; i++)
> got_repo_free_remote_repo_data(&repo->gitconfig_remotes[i]);
> free(repo->gitconfig_remotes);
> - for (i = 0; i < repo->nextensions; i++)
> - free(repo->extensions[i]);
> - free(repo->extensions);
> + for (i = 0; i < repo->nextensions; i++) {
> + free(repo->extnames[i]);
> + free(repo->extvals[i]);
> + }
> + free(repo->extnames);
> + free(repo->extvals);
>
> got_pathlist_free(&repo->packidx_paths, GOT_PATHLIST_FREE_PATH);
> free(repo);
> blob - eb2cb32cc344ddd544e7ee0c3ed70fb044acb212
> blob + 6a5a396aaacb6e0b82ba18447c97c739cd0377cb
> --- libexec/got-read-gitconfig/got-read-gitconfig.c
> +++ libexec/got-read-gitconfig/got-read-gitconfig.c
> @@ -83,6 +83,36 @@ gitconfig_str_request(struct imsgbuf *ibuf, struct got
> }
>
> static const struct got_error *
> +send_gitconfig_pair(struct imsgbuf *ibuf, const char *key, const char *val)
> +{
> + struct ibuf *wbuf;
> + size_t klen = key ? strlen(key) : 0;
> + size_t vlen = val ? strlen(val) : 0;
> + size_t tot = sizeof(klen) + sizeof(vlen) + klen + vlen;
> +
> + if (tot > MAX_IMSGSIZE - IMSG_HEADER_SIZE)
> + return got_error(GOT_ERR_NO_SPACE);
> +
> + wbuf = imsg_create(ibuf, GOT_IMSG_GITCONFIG_PAIR, 0, 0, tot);
> + if (wbuf == NULL)
> + return got_error_from_errno("imsg_create GITCONFIG_PAIR");
> +
> + /* Keep in sync with got_imsg_gitconfig_pair */
> + if (imsg_add(wbuf, &klen, sizeof(klen)) == -1)
> + return got_error_from_errno("imsg_add GITCONFIG_PAIR");
> + if (imsg_add(wbuf, &vlen, sizeof(vlen)) == -1)
> + return got_error_from_errno("imsg_add GITCONFIG_PAIR");
> + if (imsg_add(wbuf, key, klen) == -1)
> + return got_error_from_errno("imsg_add GITCONFIG_PAIR");
> + if (imsg_add(wbuf, val, vlen) == -1)
> + return got_error_from_errno("imsg_add GITCONFIG_PAIR");
> +
> + wbuf->fd = -1;
> + imsg_close(ibuf, wbuf);
> + return got_privsep_flush_imsg(ibuf);
> +}
> +
> +static const struct got_error *
> gitconfig_str_request(struct imsgbuf *ibuf, struct got_gitconfig *gitconfig,
> const char *section, const char *tag)
> {
> @@ -281,12 +311,8 @@ gitconfig_extensions_request(struct imsgbuf *ibuf,
> if (tags == NULL)
> return send_gitconfig_int(ibuf, 0);
>
> - TAILQ_FOREACH(node, &tags->fields, link) {
> - val = got_gitconfig_get_str(gitconfig, "extensions",
> - node->field);
> - if (get_boolean_val(val))
> - nextensions++;
> - }
> + TAILQ_FOREACH(node, &tags->fields, link)
> + nextensions++;
>
> err = send_gitconfig_int(ibuf, nextensions);
> if (err)
> @@ -295,11 +321,9 @@ gitconfig_extensions_request(struct imsgbuf *ibuf,
> TAILQ_FOREACH(node, &tags->fields, link) {
> val = got_gitconfig_get_str(gitconfig, "extensions",
> node->field);
> - if (get_boolean_val(val)) {
> - err = send_gitconfig_str(ibuf, node->field);
> - if (err)
> - goto done;
> - }
> + err = send_gitconfig_pair(ibuf, node->field, val);
> + if (err)
> + goto done;
> }
> done:
> got_gitconfig_free_list(tags);
> blob - 68e0227e67176703391ab5f32a7cd9a9d1a91bce
> blob + 9403e4715c6ed077315fb8b1bcb68bccd4247176
> --- regress/cmdline/checkout.sh
> +++ regress/cmdline/checkout.sh
> @@ -793,7 +793,7 @@ test_checkout_repo_with_unknown_extension() {
> local testroot=`test_init checkout_repo_with_unknown_extension`
>
> (cd $testroot/repo &&
> - git config --add extensions.badExtension true)
> + git config --add extensions.badExtension foobar)
> (cd $testroot/repo &&
> git config --add extensions.otherBadExtension 0)
>
>
>
>
got-read-gitconfig: send key-value pairs for extensions