Merge branch 'mc/netrc-service-names'

"netrc" credential helper has been improved to understand textual
service names (like smtp) in addition to the numeric port numbers
(like 25).

* mc/netrc-service-names:
  contrib: better support symbolic port names in git-credential-netrc
  contrib: warn for invalid netrc file ports in git-credential-netrc
  contrib: use a more portable shebang for git-credential-netrc
maint
Junio C Hamano 2025-07-14 11:19:25 -07:00
commit db4a912c4a
5 changed files with 46 additions and 7 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/perl #!/usr/bin/env perl


use strict; use strict;
use warnings; use warnings;
@ -267,8 +267,16 @@ sub load_netrc {
if (!defined $nentry->{machine}) { if (!defined $nentry->{machine}) {
next; next;
} }
if (defined $nentry->{port} && $nentry->{port} =~ m/^\d+$/) { if (defined $nentry->{port}) {
$num_port = $nentry->{port}; $num_port = Git::port_num($nentry->{port});
unless ($num_port) {
printf(STDERR "ignoring invalid port `%s' " .
"from netrc file\n", $nentry->{port});
}
# Since we've already validated and converted
# the port to its numerical value, do not
# capture it as the `protocol' value, as used
# to be the case for symbolic port names.
delete $nentry->{port}; delete $nentry->{port};
} }



View File

@ -45,7 +45,7 @@ chmod 0600, $netrc;
diag "Testing with invalid data\n"; diag "Testing with invalid data\n";
$cred = run_credential(['-f', $netrc, 'get'], $cred = run_credential(['-f', $netrc, 'get'],
"bad data"); "bad data");
ok(scalar keys %$cred == 4, "Got first found keys with bad data"); ok(scalar keys %$cred == 3, "Got first found keys with bad data");


diag "Testing netrc file for a missing corovamilkbar entry\n"; diag "Testing netrc file for a missing corovamilkbar entry\n";
$cred = run_credential(['-f', $netrc, 'get'], $cred = run_credential(['-f', $netrc, 'get'],
@ -64,12 +64,12 @@ is($cred->{username}, 'carol', "Got correct Github username");


diag "Testing netrc file for a username-specific entry\n"; diag "Testing netrc file for a username-specific entry\n";
$cred = run_credential(['-f', $netrc, 'get'], $cred = run_credential(['-f', $netrc, 'get'],
{ host => 'imap', username => 'bob' }); { host => 'imap:993', username => 'bob' });


ok(scalar keys %$cred == 2, "Got 2 username-specific keys"); # Only the password field gets returned.
ok(scalar keys %$cred == 1, "Got 1 username-specific keys");


is($cred->{password}, 'bobwillknow', "Got correct user-specific password"); is($cred->{password}, 'bobwillknow', "Got correct user-specific password");
is($cred->{protocol}, 'imaps', "Got correct user-specific protocol");


diag "Testing netrc file for a host:port-specific entry\n"; diag "Testing netrc file for a host:port-specific entry\n";
$cred = run_credential(['-f', $netrc, 'get'], $cred = run_credential(['-f', $netrc, 'get'],

View File

@ -2112,6 +2112,17 @@ if ($validate) {
} }
} }


# Validate the SMTP server port, if provided.
if (defined $smtp_server_port) {
my $port = Git::port_num($smtp_server_port);
if ($port) {
$smtp_server_port = $port;
} else {
die sprintf(__("error: invalid SMTP port '%s'\n"),
$smtp_server_port);
}
}

# Run the loop once again to avoid gaps in the counter due to FIFO # Run the loop once again to avoid gaps in the counter due to FIFO
# arguments provided by the user. # arguments provided by the user.
my $num = 1; my $num = 1;

View File

@ -1061,6 +1061,19 @@ sub _close_cat_blob {
delete @$self{@vars}; delete @$self{@vars};
} }


# Given PORT, a port number or service name, return its numerical
# value else undef.
sub port_num {
my ($port) = @_;

# Port can be either a positive integer within the 16-bit range...
if ($port =~ /^\d+$/ && $port > 0 && $port <= (2**16 - 1)) {
return $port;
}

# ... or a symbolic port (service name).
return scalar getservbyname($port, '');
}


=item credential_read( FILEHANDLE ) =item credential_read( FILEHANDLE )



View File

@ -201,6 +201,13 @@ test_expect_success $PREREQ 'cc trailer with get_maintainer.pl output' '
test_cmp expected-cc commandline1 test_cmp expected-cc commandline1
' '


test_expect_failure $PREREQ 'invalid smtp server port value' '
clean_fake_sendmail &&
git send-email -1 --to=recipient@example.com \
--smtp-server-port=bogus-symbolic-name \
--smtp-server="$(pwd)/fake.sendmail"
'

test_expect_success $PREREQ 'setup expect' " test_expect_success $PREREQ 'setup expect' "
cat >expected-show-all-headers <<\EOF cat >expected-show-all-headers <<\EOF
0001-Second.patch 0001-Second.patch