Skip to contentSkip to conversation

gpg-interface.c: use string_list_split*() instead of strbuf_split*()

PATCH In review Olamide Caleb Bello 3 participants 17 messages Oct 19, 2025 – Oct 20, 2025

lore
Share & tools
lore
#0 lore raw

v3 cover gpg-interface.c: use string_list_split*() instead of strbuf_split*()

The patch series by Junio Hamano with link below,
https://public-inbox.org/git/[email protected]/,
notices that the array of strbufs that calls to strbuf_split*() provides are merely used to store the strings gotten from the split and no edit are done on these resulting strings making the strbuf_split*() unideal for this usecase, with the string_list_split*() being a more suitable option.

Commit 2efe707054 (wt-status: avoid strbuf_split*(), 2025-07-31) for example, in the series, notes that abbrev_oid_in_line() takes one line of rebase todo list and splits tokens out of this line using strbuf_split_max(). However, no simultanous edits that take advantage of the strbuf API take place but the tokens are merely used as pieces of strings.

This series continues on this, by replacing instances of strbuf_split_max() with string_list_split_in_place() where the string from the split is merely returned as char * and no edits are done on them.

Tests have also been performed on the commits on Github CI. The link is shown below
https://github.com/git/git/pull/2074

Changes in v3:
==============
- Use string_list_split_in_place() instead of string_list_split() used in v2
- Change the test for the return value of string_list_split_in_place() in get_ssh_key_fingerprint() patch 1 to at least 2 tokens in the split list to allow a successful test where the key owner's identity is missing.
- Change the test for the return value of string_list_split_in_place() in get_default_ssh_signing_key() in patch 2 to at least 1 token to allow for a successful test.
- Modify commit messages to indicate the switch to string_list_split_in_place() from string_list_split() used in v2
- Add explanation in commit message about the test for the return value of string_list_split_in_place() in both patches
- Add Helped-by and Reported-by tags

Olamide Caleb Bello (2):
gpg-interface: replace strbuf_split*() with string_list_split*()
gpg-interface: use string_list_split*() instead of strbuf_split*()

 gpg-interface.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

Range-diff versus v2:

1: 818ca6b104 ! 1: 7da4fded53 gpg-interface: replace strbuf_split_max() with string_list_split()
@@ Metadata
Author: Olamide Caleb Bello <[email protected]>

## Commit message ##
- gpg-interface: replace strbuf_split_max() with string_list_split()
+ gpg-interface: replace strbuf_split*() with string_list_split*()

In get_ssh_finger_print(), the output of the ssh-keygen command is put into `fingerprint_stdout
@@ Commit message
The string in fingerprint_stdout is then split into 3 strbufs using strbuf_split_max(), however they are not modified after the split thereby not making use of the strbuf API as the fingerprint token is merely
- returned as a char * and not a strbuf, hence they do not need to be strbufs.
+ returned as a char * and not a strbuf, hence they do not need to be
+ strbufs.

- Use string_list_split() instead for simplicity.
+ Use string_list_split_in_place() instead for simplicity.

Note that strbuf_split_max() uses 3 to specify the number of tokens to
- extract from the string, while string_list_split() uses 2 because it specifies
- the number of times the split will be done on the string, so 2 gives 3 tokens
- as it is in the original instance.
+ extract from the string, while string_list_split_in_place() uses 2
+ because it specifies the number of times the split will be done on
+ the string, so 2 gives 3 tokens as it is in the original instance.
+
+ string_list_split_in_place() returns the number of substrings added to
+ the split.items so for a successful split of the string in
+ fingerprint_stdout, at least two items should be added to split.items
+ so we can always be certain that the substring at index 1 is the ssh
+ fingerprint even if the key owner's identity part is missing from the
+ string in fingerprint_stdout.

+ Reported-by: Junio Hamano <[email protected]>
+ Helped-by: Christian Couder <[email protected]>
+ Helped-by: Junio Hamano <[email protected]>

## gpg-interface.c ##
@@
@@ gpg-interface.c: static char *get_ssh_key_fingerprint(const char *signing_key)
int ret = -1;
struct strbuf fingerprint_stdout = STRBUF_INIT;
- struct strbuf **fingerprint;
-+ struct string_list split = STRING_LIST_INIT_DUP;
++ struct string_list split = STRING_LIST_INIT_NODUP;
char *fingerprint_ret;
const char *literal_key = NULL;

@@ gpg-interface.c: static char *get_ssh_key_fingerprint(const char *signing_key)

- fingerprint = strbuf_split_max(&fingerprint_stdout, ' ', 3);
- if (!fingerprint[1])
-+ if (string_list_split(&split, fingerprint_stdout.buf, " ", 2) != 3)
++ if (string_list_split_in_place(&split, fingerprint_stdout.buf, " ", 2) <= 1)
die_errno(_("failed to get the ssh fingerprint for key '%s'"),
signing_key);

2: 024a44a242 ! 2: 9a6eb6ff8b gpg-interface: use string_list_split() instead of strbuf_split_max()
@@ Metadata
Author: Olamide Caleb Bello <[email protected]>

## Commit message ##
- gpg-interface: use string_list_split() instead of strbuf_split_max()
+ gpg-interface: use string_list_split*() instead of strbuf_split*()

In get_default_ssh_signing_key(), the default ssh signing key is retrieved in key_stdout, which is then split using
@@ Commit message
This makes the function lack the use of strbuf API as no edits are performed on the split tokens.

- Replace strbuf_split_max() with string_list_split() for simplicity.
+ Replace strbuf_split_max() with string_list_split_in_place() for
+ simplicity

Note that strbuf_split_max() uses 2 to indicate the number of tokens
- to extract from the string, while string_list_split() uses 1 to specify
- the number of times the split will be done on the string, so 1 gives 2
- tokens as it is in the original instance.
+ to extract from the string, while string_list_split_in_place() uses 1
+ to specify the number of times the split will be done on the string,
+ so 1 gives 2 tokens as it is in the original instance.
+
+ string_list_split_in_place() returns the number of substrings added to the
+ list keys.items, so we check that at least one substring is added to the
+ list since we just want to return the first substring.

+ Reported-by: Junio Hamano <[email protected]>
+ Helped-by: Christian Couder <[email protected]>

## gpg-interface.c ##
@@ gpg-interface.c: static char *get_default_ssh_signing_key(void)
@@ gpg-interface.c: static char *get_default_ssh_signing_key(void)
int ret = -1;
struct strbuf key_stdout = STRBUF_INIT, key_stderr = STRBUF_INIT;
- struct strbuf **keys;
-+ struct string_list keys = STRING_LIST_INIT_DUP;
++ struct string_list keys = STRING_LIST_INIT_NODUP;
char *key_command = NULL;
const char **argv;
int n;
@@ gpg-interface.c: static char *get_default_ssh_signing_key(void)
if (!ret) {
- keys = strbuf_split_max(&key_stdout, '\n', 2);
- if (keys[0] && is_literal_ssh_key(keys[0]->buf, &literal_key)) {
-+ if (string_list_split(&keys, key_stdout.buf, "\n", 1) == 2 &&
++ if (string_list_split_in_place(&keys, key_stdout.buf, "\n", 1) > 0 &&
+ is_literal_ssh_key(keys.items[0].string, &literal_key)) {
/*
* We only use is_literal_ssh_key here to check validity

Signature · 1 line
2.51.0.463.g79cf913ea9
#1 lore raw

PATCH v3 1/2 gpg-interface: replace strbuf_split*() with string_list_split*()

In get_ssh_finger_print(), the output of the ssh-keygen command is put into `fingerprint_stdout

The string in fingerprint_stdout is then split into 3 strbufs using strbuf_split_max(), however they are not modified after the split thereby not making use of the strbuf API as the fingerprint token is merely returned as a char * and not a strbuf, hence they do not need to be strbufs.

Use string_list_split_in_place() instead for simplicity.

Note that strbuf_split_max() uses 3 to specify the number of tokens to extract from the string, while string_list_split_in_place() uses 2 because it specifies the number of times the split will be done on the string, so 2 gives 3 tokens as it is in the original instance.

string_list_split_in_place() returns the number of substrings added to the split.items so for a successful split of the string in fingerprint_stdout, at least two items should be added to split.items so we can always be certain that the substring at index 1 is the ssh fingerprint even if the key owner's identity part is missing from the string in fingerprint_stdout.

---
 gpg-interface.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
gpg-interface.c +5 -5
index 2f4f0e32cb..cb182f4c11 100644
@@ -14,6 +14,7 @@
 #include "sigchain.h"
 #include "tempfile.h"
 #include "alias.h"
+#include "string-list.h"
 
 static int git_gpg_config(const char *, const char *,
 			  const struct config_context *, void *);
@@ -821,7 +822,7 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
 	struct child_process ssh_keygen = CHILD_PROCESS_INIT;
 	int ret = -1;
 	struct strbuf fingerprint_stdout = STRBUF_INIT;
-	struct strbuf **fingerprint;
+	struct string_list split = STRING_LIST_INIT_NODUP;
 	char *fingerprint_ret;
 	const char *literal_key = NULL;
 
@@ -845,13 +846,12 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
 		die_errno(_("failed to get the ssh fingerprint for key '%s'"),
 			  signing_key);
 
-	fingerprint = strbuf_split_max(&fingerprint_stdout, ' ', 3);
-	if (!fingerprint[1])
+	if (string_list_split_in_place(&split, fingerprint_stdout.buf, " ", 2) <= 1)
 		die_errno(_("failed to get the ssh fingerprint for key '%s'"),
 			  signing_key);
 
-	fingerprint_ret = strbuf_detach(fingerprint[1], NULL);
-	strbuf_list_free(fingerprint);
+	fingerprint_ret = xstrdup(split.items[1].string);
+	string_list_clear(&split, 0);
 	strbuf_release(&fingerprint_stdout);
 	return fingerprint_ret;
 }
Signature · 1 line
2.51.0.463.g79cf913ea9
#2 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 2 lines · Olamide Caleb Bello

In get_ssh_finger_print(), the output of the ssh-keygen command is put into `fingerprint_stdout

Something lost at the end? I'd assume

... into fingerpritn_stdout strbuf.

and tweak the copy I received locally before applying.

Quoted 1 line

The string in fingerprint_stdout is then split into 3 strbufs using

"into up to 3 strbufs", I think. If we do not say so here, ...

Quoted 7 lines

strbuf_split_max(), however they are not modified after the split thereby not making use of the strbuf API as the fingerprint token is merely returned as a char * and not a strbuf, hence they do not need to be strbufs.

Use string_list_split_in_place() instead for simplicity.

Quoted 8 lines

Note that strbuf_split_max() uses 3 to specify the number of tokens to extract from the string, while string_list_split_in_place() uses 2 because it specifies the number of times the split will be done on the string, so 2 gives 3 tokens as it is in the original instance.

string_list_split_in_place() returns the number of substrings added to the split.items so for a successful split of the string in fingerprint_stdout, at least two items should be added to split.items

... this "at least two items" would become contradictory.

Quoted 34 lines

so we can always be certain that the substring at index 1 is the ssh fingerprint even if the key owner's identity part is missing from the string in fingerprint_stdout.

---
 gpg-interface.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
gpg-interface.c +2 -1
index 2f4f0e32cb..cb182f4c11 100644
@@ -14,6 +14,7 @@
 #include "sigchain.h"
 #include "tempfile.h"
 #include "alias.h"
+#include "string-list.h"
 
 static int git_gpg_config(const char *, const char *,
 			  const struct config_context *, void *);
@@ -821,7 +822,7 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
 	struct child_process ssh_keygen = CHILD_PROCESS_INIT;
 	int ret = -1;
 	struct strbuf fingerprint_stdout = STRBUF_INIT;
-	struct strbuf **fingerprint;
+	struct string_list split = STRING_LIST_INIT_NODUP;
 	char *fingerprint_ret;
 	const char *literal_key = NULL;
 

gpg-interface.c static char *get_ssh_key_fingerprint(const char *signing_key) · line 849

Quoted 6 lines
gpg-interface.c +1 -2
@@ -845,13 +846,12 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
 		die_errno(_("failed to get the ssh fingerprint for key '%s'"),
 			  signing_key);
 
-	fingerprint = strbuf_split_max(&fingerprint_stdout, ' ', 3);
-	if (!fingerprint[1])
+	if (string_list_split_in_place(&split, fingerprint_stdout.buf, " ", 2) <= 1)

This may be just me, but when we expect at least 2, I would find it more natural if we said "if (count < 2) then error", rather "if (count <= 1) then error". I'll let it pass, as there is nothing mathematically incorrect here ;-).

gpg-interface.c static char *get_ssh_key_fingerprint(const char *signing_key) · line 854

Quoted 7 lines
gpg-interface.c +2 -2
 		die_errno(_("failed to get the ssh fingerprint for key '%s'"),
 			  signing_key);
 
-	fingerprint_ret = strbuf_detach(fingerprint[1], NULL);
-	strbuf_list_free(fingerprint);
+	fingerprint_ret = xstrdup(split.items[1].string);
+	string_list_clear(&split, 0);

OK. This is a straight-forward rewrite that is fairly faithful to the original.

But I wonder why the original was written in such a convoluted way to just extract the first part of a string that is space delimited tokens. It is obviously not your fault that the original is written that way, bit I would have expected it to be done more like this:

    char *begin = fingerprint_stdout.buf;
    char *delim = strchr(begin, ' ');
    if (!delim)
	die_errno("Barf!");
    fingerprint_ret = xmemdupz(begin, end - begin);

Am I missing something?

That may or may not be outside the scope of this topic, which is to reduce the calls to a misdesigned strbuf_split*() API functions.

Thanks.

Quoted 3 lines
gpg-interface.c +0 -0
 	strbuf_release(&fingerprint_stdout);
 	return fingerprint_ret;
 }
#3 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 9 lines · Junio C Hamano
Quoted 2 lines · Olamide Caleb Bello

In get_ssh_finger_print(), the output of the ssh-keygen command is put into `fingerprint_stdout

Something lost at the end? I'd assume

... into fingerpritn_stdout strbuf.

Yes, thank you.

Quoted 19 lines

and tweak the copy I received locally before applying.

Quoted 1 line

The string in fingerprint_stdout is then split into 3 strbufs using

"into up to 3 strbufs", I think. If we do not say so here, ...

Quoted 12 lines

strbuf_split_max(), however they are not modified after the split thereby not making use of the strbuf API as the fingerprint token is merely returned as a char * and not a strbuf, hence they do not need to be strbufs.

Use string_list_split_in_place() instead for simplicity.

Note that strbuf_split_max() uses 3 to specify the number of tokens to extract from the string, while string_list_split_in_place() uses 2 because it specifies the number of times the split will be done on the string, so 2 gives 3 tokens as it is in the original instance.

Quoted 5 lines
Quoted 3 lines

string_list_split_in_place() returns the number of substrings added to the split.items so for a successful split of the string in fingerprint_stdout, at least two items should be added to split.items

... this "at least two items" would become contradictory.

Yes, noted.

Quoted 63 lines
Quoted 35 lines

so we can always be certain that the substring at index 1 is the ssh fingerprint even if the key owner's identity part is missing from the string in fingerprint_stdout.

---
 gpg-interface.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
gpg-interface.c +2 -1
index 2f4f0e32cb..cb182f4c11 100644
@@ -14,6 +14,7 @@
 #include "sigchain.h"
 #include "tempfile.h"
 #include "alias.h"
+#include "string-list.h"
 
 static int git_gpg_config(const char *, const char *,
                        const struct config_context *, void *);
@@ -821,7 +822,7 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
      struct child_process ssh_keygen = CHILD_PROCESS_INIT;
      int ret = -1;
      struct strbuf fingerprint_stdout = STRBUF_INIT;
-     struct strbuf **fingerprint;
+     struct string_list split = STRING_LIST_INIT_NODUP;
      char *fingerprint_ret;
      const char *literal_key = NULL;
 

gpg-interface.c static char *get_ssh_key_fingerprint(const char *signing_key) · line 849

Quoted 6 lines
gpg-interface.c +1 -2
@@ -845,13 +846,12 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
              die_errno(_("failed to get the ssh fingerprint for key '%s'"),
                        signing_key);
 
-     fingerprint = strbuf_split_max(&fingerprint_stdout, ' ', 3);
-     if (!fingerprint[1])
+     if (string_list_split_in_place(&split, fingerprint_stdout.buf, " ", 2) <= 1)

This may be just me, but when we expect at least 2, I would find it more natural if we said "if (count < 2) then error", rather "if (count <= 1) then error". I'll let it pass, as there is nothing mathematically incorrect here ;-).

gpg-interface.c static char *get_ssh_key_fingerprint(const char *signing_key) · line 854

Quoted 7 lines
gpg-interface.c +2 -2
              die_errno(_("failed to get the ssh fingerprint for key '%s'"),
                        signing_key);
 
-     fingerprint_ret = strbuf_detach(fingerprint[1], NULL);
-     strbuf_list_free(fingerprint);
+     fingerprint_ret = xstrdup(split.items[1].string);
+     string_list_clear(&split, 0);

OK. This is a straight-forward rewrite that is fairly faithful to the original.

But I wonder why the original was written in such a convoluted way to just extract the first part of a string that is space delimited tokens. It is obviously not your fault that the original is written that way, bit I would have expected it to be done more like this:

Quoted 7 lines
    char *begin = fingerprint_stdout.buf;
    char *delim = strchr(begin, ' ');
    if (!delim)
        die_errno("Barf!");
    fingerprint_ret = xmemdupz(begin, end - begin);

Am I missing something?

Okay something like this which just finds the desired token and returns a copy?

    char *begin = fingerprint_stdout.buf;
    char *end = begin + fingerprint_stdout.len;
    char *space, *start, *endtok;
   space = memchr(begin, ' ', end-begin);
    if (!space)
        die_errno(_("failed to get the ssh fingerprint for key '%s'"),
            signing_key);
    start = space + 1;
     while (start < end && (*start = ' ' || *start == '\t'))
            start++;
    if (start >=end)
        die_errno(_("failed to get the ssh fingerprint for key '%s'"),
            signing_key);

    endtok = start;
    while (endtok < end && *endtok != ' ' && *endtok != '\t' &&
             *endtok !== '\r' && *endtok != '\n')
        endtok++;

    if (endtok == start)
        die_errno(_("failed to get the ssh fingerprint for key '%s'"),
            signing_key);

    fingerprint_ret = xmemdupz(start, endtok - start);
    return fingerptint_ret
Quoted 9 lines

That may or may not be outside the scope of this topic, which is to reduce the calls to a misdesigned strbuf_split*() API functions.

Thanks.

Quoted 3 lines
gpg-interface.c +0 -0
      strbuf_release(&fingerprint_stdout);
      return fingerprint_ret;
 }
#4 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 13 lines · Bello Olamide
Quoted 13 lines

gpg-interface.c static char *get_ssh_key_fingerprint(const char *signing_key) · line 854

Quoted 4 lines
gpg-interface.c +2 -2
-     fingerprint_ret = strbuf_detach(fingerprint[1], NULL);
-     strbuf_list_free(fingerprint);
+     fingerprint_ret = xstrdup(split.items[1].string);
+     string_list_clear(&split, 0);

OK. This is a straight-forward rewrite that is fairly faithful to the original.

But I wonder why the original was written in such a convoluted way to just extract the first part of a string that is space delimited tokens. It is obviously not your fault that the original is written that way, bit I would have expected it to be done more like this:

Quoted 7 lines
Quoted 7 lines
    char *begin = fingerprint_stdout.buf;
    char *delim = strchr(begin, ' ');
    if (!delim)
        die_errno("Barf!");
    fingerprint_ret = xmemdupz(begin, end - begin);

Am I missing something?

What I was missing was that we use fingerprint[1], not fingerprint[0]. So we need to do the strchr() twice, i.e.

     char *begin = fingerprint_stdout.buf;
     char *delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     begin = delim + 1
     delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     fingerprint_ret = xmemdupz(begin, end - begin);
Quoted 7 lines

Okay something like this which just finds the desired token and returns a copy?

    char *begin = fingerprint_stdout.buf;
    char *end = begin + fingerprint_stdout.len;
    char *space, *start, *endtok;
Quoted 7 lines
   space = memchr(begin, ' ', end-begin);
    if (!space)
        die_errno(_("failed to get the ssh fingerprint for key '%s'"),
            signing_key);
    start = space + 1;
     while (start < end && (*start = ' ' || *start == '\t'))
            start++;

The original does not seem to care and uses the whole fingerprint[1].buf; do we really care about tabs? The same for looking at CR or LF.

Even if we cared, we shouldn't have to open code strcspn() like this ;-)

#5 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 12 lines · Junio C Hamano

What I was missing was that we use fingerprint[1], not fingerprint[0]. So we need to do the strchr() twice, i.e.

     char *begin = fingerprint_stdout.buf;
     char *delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     begin = delim + 1
     delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     fingerprint_ret = xmemdupz(begin, end - begin);

Ouch, of course "end" is not declared anywhere and it is an obvious typo of delim. Sorry for not proofreading enough.

#6 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 16 lines · Junio C Hamano
Quoted 12 lines · Junio C Hamano

What I was missing was that we use fingerprint[1], not fingerprint[0]. So we need to do the strchr() twice, i.e.

     char *begin = fingerprint_stdout.buf;
     char *delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     begin = delim + 1
     delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     fingerprint_ret = xmemdupz(begin, end - begin);
Quoted 2 lines

Ouch, of course "end" is not declared anywhere and it is an obvious typo of delim. Sorry for not proofreading enough.

Okay thank you.

I will prepare the patch and resend it.
Thanks

Bello

#7 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

In reply to Junio C Hamano
Quoted 27 lines · Junio C Hamano
Quoted 13 lines · Bello Olamide
Quoted 13 lines

gpg-interface.c static char *get_ssh_key_fingerprint(const char *signing_key) · line 854

Quoted 4 lines
gpg-interface.c +2 -2
-     fingerprint_ret = strbuf_detach(fingerprint[1], NULL);
-     strbuf_list_free(fingerprint);
+     fingerprint_ret = xstrdup(split.items[1].string);
+     string_list_clear(&split, 0);

OK. This is a straight-forward rewrite that is fairly faithful to the original.

But I wonder why the original was written in such a convoluted way to just extract the first part of a string that is space delimited tokens. It is obviously not your fault that the original is written that way, bit I would have expected it to be done more like this:

Quoted 7 lines
Quoted 7 lines
    char *begin = fingerprint_stdout.buf;
    char *delim = strchr(begin, ' ');
    if (!delim)
        die_errno("Barf!");
    fingerprint_ret = xmemdupz(begin, end - begin);

Am I missing something?

What I was missing was that we use fingerprint[1], not fingerprint[0]. So we need to do the strchr() twice, i.e.

Quoted 9 lines
     char *begin = fingerprint_stdout.buf;
     char *delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     begin = delim + 1
     delim = strchr(begin, ' ');
     if (!delim)
         die_errno("Barf!");
     fingerprint_ret = xmemdupz(begin, end - begin);

Okay thank you

Quoted 16 lines
Quoted 8 lines

Okay something like this which just finds the desired token and returns a copy?

    char *begin = fingerprint_stdout.buf;
    char *end = begin + fingerprint_stdout.len;
    char *space, *start, *endtok;
Quoted 7 lines
   space = memchr(begin, ' ', end-begin);
    if (!space)
        die_errno(_("failed to get the ssh fingerprint for key '%s'"),
            signing_key);
    start = space + 1;
     while (start < end && (*start = ' ' || *start == '\t'))
            start++;
Quoted 6 lines

The original does not seem to care and uses the whole fingerprint[1].buf; do we really care about tabs? The same for looking at CR or LF.

Even if we cared, we shouldn't have to open code strcspn() like this ;-)

Okay thank you very much for the guidance.

Belo

#8 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

In reply to Olamide Caleb Bello
Quoted 3 lines · Olamide Caleb Bello

[snip]

Signoff should go at the end of the commit message. You’re saying that you are signing off on the changes as well as what was written in the commit message before that line. If I later add mine:

Signed-off-by ME

I would be saying that I am signing off on the changes as well as the previous lines in the commit message, including that line that you wrote.

Quoted 7 lines
---
 gpg-interface.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

[snip]

#9 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 6 lines · Kristoffer Haugsbakk
Quoted 3 lines · Olamide Caleb Bello

[snip]

Hello Kristoffer,
Thank you for your review.

Quoted 10 lines

Signoff should go at the end of the commit message. You’re saying that you are signing off on the changes as well as what was written in the commit message before that line. If I later add mine:

Signed-off-by ME

I would be saying that I am signing off on the changes as well as the previous lines in the commit message, including that line that you wrote.

Please just to make sure I get you correctly, you are saying the Signoff should be the last thing in the commit message.

Like I should put it below the other tags so that if you also want to add yours, It can easily go below mine and it would mean you are signing off on the changes including my own Signoff?

Quoted 4 lines
Quoted 4 lines

It should go below here instead?

Thank you.

Bello

#10 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 21 lines · Bello Olamide
Quoted 10 lines · Kristoffer Haugsbakk

Signoff should go at the end of the commit message. You’re saying that you are signing off on the changes as well as what was written in the commit message before that line. If I later add mine:

Signed-off-by ME

I would be saying that I am signing off on the changes as well as the previous lines in the commit message, including that line that you wrote.

Please just to make sure I get you correctly, you are saying the Signoff should be the last thing in the commit message.

Like I should put it below the other tags so that if you also want to add yours, It can easily go below mine and it would mean you are signing off on the changes including my own Signoff?

Quoted 1 line
Quoted 4 lines
Quoted 3 lines
Quoted 3 lines

It should go below here instead?

Yes, that is my understanding. :)

#11 lore raw

Re: [Outreachy PATCH v3 1/2] gpg-interface: replace strbuf_split*() with string_list_split*()

Quoted 24 lines · Kristoffer Haugsbakk
Quoted 21 lines · Bello Olamide
Quoted 10 lines · Kristoffer Haugsbakk

Signoff should go at the end of the commit message. You’re saying that you are signing off on the changes as well as what was written in the commit message before that line. If I later add mine:

Signed-off-by ME

I would be saying that I am signing off on the changes as well as the previous lines in the commit message, including that line that you wrote.

Please just to make sure I get you correctly, you are saying the Signoff should be the last thing in the commit message.

Like I should put it below the other tags so that if you also want to add yours, It can easily go below mine and it would mean you are signing off on the changes including my own Signoff?

Quoted 1 line
Quoted 6 lines
Quoted 4 lines
Quoted 3 lines
Quoted 3 lines

It should go below here instead?

Yes, that is my understanding. :)

Okay noted.
Thank you very much Kristoffer

#12 lore raw

PATCH v3 2/2 gpg-interface: use string_list_split*() instead of strbuf_split*()

In reply to Olamide Caleb Bello

In get_default_ssh_signing_key(), the default ssh signing key is retrieved in key_stdout, which is then split using strbuf_split_max() into two tokens

The string in key_stdout is then split using strbuf_split_max() into two tokens at a new line and the first token is returned as a char * and not a strbuf.
This makes the function lack the use of strbuf API as no edits are performed on the split tokens.

Replace strbuf_split_max() with string_list_split_in_place() for simplicity

Note that strbuf_split_max() uses 2 to indicate the number of tokens to extract from the string, while string_list_split_in_place() uses 1 to specify the number of times the split will be done on the string, so 1 gives 2 tokens as it is in the original instance.

string_list_split_in_place() returns the number of substrings added to the list keys.items, so we check that at least one substring is added to the list since we just want to return the first substring.

---
 gpg-interface.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
gpg-interface.c +5 -5
index cb182f4c11..3b9d85a5ef 100644
@@ -862,7 +862,7 @@ static char *get_default_ssh_signing_key(void)
 	struct child_process ssh_default_key = CHILD_PROCESS_INIT;
 	int ret = -1;
 	struct strbuf key_stdout = STRBUF_INIT, key_stderr = STRBUF_INIT;
-	struct strbuf **keys;
+	struct string_list keys = STRING_LIST_INIT_NODUP;
 	char *key_command = NULL;
 	const char **argv;
 	int n;
@@ -884,19 +884,19 @@ static char *get_default_ssh_signing_key(void)
 			   &key_stderr, 0);
 
 	if (!ret) {
-		keys = strbuf_split_max(&key_stdout, '\n', 2);
-		if (keys[0] && is_literal_ssh_key(keys[0]->buf, &literal_key)) {
+		if (string_list_split_in_place(&keys, key_stdout.buf, "\n", 1) > 0 &&
+			is_literal_ssh_key(keys.items[0].string, &literal_key)) {
 			/*
 			 * We only use `is_literal_ssh_key` here to check validity
 			 * The prefix will be stripped when the key is used.
 			 */
-			default_key = strbuf_detach(keys[0], NULL);
+			default_key = xstrdup(keys.items[0].string);
 		} else {
 			warning(_("gpg.ssh.defaultKeyCommand succeeded but returned no keys: %s %s"),
 				key_stderr.buf, key_stdout.buf);
 		}
 
-		strbuf_list_free(keys);
+		string_list_clear(&keys, 0);
 	} else {
 		warning(_("gpg.ssh.defaultKeyCommand failed: %s %s"),
 			key_stderr.buf, key_stdout.buf);
Signature · 1 line
2.51.0.463.g79cf913ea9
#13 lore raw

Re: [Outreachy PATCH v3 2/2] gpg-interface: use string_list_split*() instead of strbuf_split*()

Quoted 22 lines · Olamide Caleb Bello

In get_default_ssh_signing_key(), the default ssh signing key is retrieved in key_stdout, which is then split using strbuf_split_max() into two tokens

The string in key_stdout is then split using strbuf_split_max() into two tokens at a new line and the first token is returned as a char * and not a strbuf.
This makes the function lack the use of strbuf API as no edits are performed on the split tokens.

Replace strbuf_split_max() with string_list_split_in_place() for simplicity

Note that strbuf_split_max() uses 2 to indicate the number of tokens to extract from the string, while string_list_split_in_place() uses 1 to specify the number of times the split will be done on the string, so 1 gives 2 tokens as it is in the original instance.

string_list_split_in_place() returns the number of substrings added to the list keys.items, so we check that at least one substring is added to the list since we just want to return the first substring.

Quoted 6 lines
---
 gpg-interface.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Exactly the same comment as [1/2] (including the part about the first paragraph seemingly missing something at the end ;-).

Also, it may not be necessary to highlight the quirky way the string_list_split*() function counts numbers again, as it is done in the previous patch so readers have already been warned against it.

And the same comment applies about the round-about way the original was written in the first place. Isn't it merely the matter of finding the first line-feed and making a copy of a string up to that point?

Perhaps we would be better off if we revise the theme of the topic "use string_list_split*() to replace strbuf_split*()" to "do not use misdesigned strbuf_split*() function" and do the rewrite without using string_list_split*() after all? It may result in a much cleaner and simpler code at the end.

Thanks.

Quoted 37 lines
gpg-interface.c +5 -5
index cb182f4c11..3b9d85a5ef 100644
@@ -862,7 +862,7 @@ static char *get_default_ssh_signing_key(void)
 	struct child_process ssh_default_key = CHILD_PROCESS_INIT;
 	int ret = -1;
 	struct strbuf key_stdout = STRBUF_INIT, key_stderr = STRBUF_INIT;
-	struct strbuf **keys;
+	struct string_list keys = STRING_LIST_INIT_NODUP;
 	char *key_command = NULL;
 	const char **argv;
 	int n;
@@ -884,19 +884,19 @@ static char *get_default_ssh_signing_key(void)
 			   &key_stderr, 0);
 
 	if (!ret) {
-		keys = strbuf_split_max(&key_stdout, '\n', 2);
-		if (keys[0] && is_literal_ssh_key(keys[0]->buf, &literal_key)) {
+		if (string_list_split_in_place(&keys, key_stdout.buf, "\n", 1) > 0 &&
+			is_literal_ssh_key(keys.items[0].string, &literal_key)) {
 			/*
 			 * We only use `is_literal_ssh_key` here to check validity
 			 * The prefix will be stripped when the key is used.
 			 */
-			default_key = strbuf_detach(keys[0], NULL);
+			default_key = xstrdup(keys.items[0].string);
 		} else {
 			warning(_("gpg.ssh.defaultKeyCommand succeeded but returned no keys: %s %s"),
 				key_stderr.buf, key_stdout.buf);
 		}
 
-		strbuf_list_free(keys);
+		string_list_clear(&keys, 0);
 	} else {
 		warning(_("gpg.ssh.defaultKeyCommand failed: %s %s"),
 			key_stderr.buf, key_stdout.buf);
#14 lore raw

Re: [Outreachy PATCH v3 2/2] gpg-interface: use string_list_split*() instead of strbuf_split*()

Quoted 32 lines · Junio C Hamano
Quoted 22 lines · Olamide Caleb Bello

In get_default_ssh_signing_key(), the default ssh signing key is retrieved in key_stdout, which is then split using strbuf_split_max() into two tokens

The string in key_stdout is then split using strbuf_split_max() into two tokens at a new line and the first token is returned as a char * and not a strbuf.
This makes the function lack the use of strbuf API as no edits are performed on the split tokens.

Replace strbuf_split_max() with string_list_split_in_place() for simplicity

Note that strbuf_split_max() uses 2 to indicate the number of tokens to extract from the string, while string_list_split_in_place() uses 1 to specify the number of times the split will be done on the string, so 1 gives 2 tokens as it is in the original instance.

string_list_split_in_place() returns the number of substrings added to the list keys.items, so we check that at least one substring is added to the list since we just want to return the first substring.

Quoted 6 lines
---
 gpg-interface.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
Quoted 6 lines

Exactly the same comment as [1/2] (including the part about the first paragraph seemingly missing something at the end ;-).

Also, it may not be necessary to highlight the quirky way the string_list_split*() function counts numbers again, as it is done in the previous patch so readers have already been warned against it.

Okay noted.

Quoted 5 lines

And the same comment applies about the round-about way the original was written in the first place. Isn't it merely the matter of finding the first line-feed and making a copy of a string up to that point?

Yes that is the goal.

Quoted 6 lines

Perhaps we would be better off if we revise the theme of the topic "use string_list_split*() to replace strbuf_split*()" to "do not use misdesigned strbuf_split*() function" and do the rewrite without using string_list_split*() after all? It may result in a much cleaner and simpler code at the end.

Okay something like this?

       char *begin;
       char *end;
       char *new_line, *line_end, first_line;
       size_t line_len;

       if (!ret) {
         ...
       begin = key_stdout.buf;
       end = key_stdout.len;
       new_line = memchr(begin, '\n', key_stdout.len)
       line_end = new_line ? new_line : end;
       if (line_end > begin && *(line_end - 1) == '\r')
            line_end--;
       line_len = (size_t)(line_end - begin)
       if (line_len > 0) {
       firstline = xmemdupz(begin, line_len)
       }
       default_key = first_line
       ...
       return default_key

I am just asking to know if something like this should be done within the respective functions or I will need to write functions for each and just call here.

Thanks
Bello

#15 lore raw

Re: [Outreachy PATCH v3 2/2] gpg-interface: use string_list_split*() instead of strbuf_split*()

Quoted 3 lines · Bello Olamide

I am just asking to know if something like this should be done within the respective functions or I will need to write functions for each and just call here.

Unlike [1/2] that asked for the second string, this one just wants to discard everything after the first LF, so I am not sure if you need any new helper or hand-rolled loop. Wouldn't strchr() and xmemdupz() that were used in my response to [1/2] sufficient for the purpose of this step, too?

#16 lore raw

Re: [Outreachy PATCH v3 2/2] gpg-interface: use string_list_split*() instead of strbuf_split*()

Quoted 7 lines · Junio C Hamano
Quoted 3 lines · Bello Olamide

I am just asking to know if something like this should be done within the respective functions or I will need to write functions for each and just call here.

Quoted 6 lines

Unlike [1/2] that asked for the second string, this one just wants to discard everything after the first LF, so I am not sure if you need any new helper or hand-rolled loop. Wouldn't strchr() and xmemdupz() that were used in my response to [1/2] sufficient for the purpose of this step, too?

Yes it will,
Thank you very much Junio.
I will send the new patch

Bello