Re: [PATCH/RFD] fix connection via git protocol

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 17, 2023 at 12:38 AM Jeff King <peff@xxxxxxxx> wrote:
>
> On Sat, Apr 15, 2023 at 10:47:35PM -0700, Elijah Newren wrote:
>
> > On Sat, Apr 15, 2023 at 4:06 AM Michael J Gruber <git@xxxxxxxxx> wrote:
> > >
> > > 5579f44d2f ("treewide: remove unnecessary cache.h inclusion", 2023-04-11)
> > > broke connections via git protocol because it removed the inclusion of
> > > the default port macro. While some may consider this transport to be
> > > deprecated, it still serves some purpose.
> >
> > In particular the problem is that
> >
> >       const char *port = STR(DEFAULT_GIT_PORT);
> >
> > translates now to
> >
> >       const char *port = "DEFAULT_GIT_PORT";
> >
> > instead of
> >
> >       const char *port = "9418";
> >
> > Since both compile and nothing in the testsuite tests this, I just
> > missed this problem when making the other changes.
>
> Your fix looks obviously correct, but the much more interesting thing to
> me is how surprising it is that neither the compiler nor tests caught
> it.  The tests don't catch it because we never use the default port for
> our daemon tests, since we don't want two scripts running in parallel to
> conflict. And your example above shows what the compiler sees, but root
> issue is this funky string-ification macro:
>
>   #define STR_(s) # s
>   #define STR(s) STR_(s)
>
> The preprocessor doesn't know that we'll be confused if "s" isn't
> resolved, and by the time the compiler sees it, it's a string already.
>
> Obviously we could add a test that catches this at run-time, but we
> should be able to do better (catch it earlier, and with less code).
>
> My first thought was: why can't we just treat the port as an "int" in
> the first place? The answer is mostly that getaddrinfo() expects it as a
> string. It could even be a non-numeric service like "http" in theory
> (and looked up in /etc/services; Debian's even has "git" in it!), but
> our get_host_and_port() refuses to allow that. But even if we didn't
> want to ever support non-numeric service names, it makes the code more
> awkward (we have to format the port into an extra buffer).
>
> This would work:
>
> diff --git a/connect.c b/connect.c
> index fd3179e545..1eba71e34c 100644
> --- a/connect.c
> +++ b/connect.c
> @@ -753,7 +753,7 @@ static char *host_end(char **hoststart, int removebrackets)
>  }
>
>  #define STR_(s)        # s
> -#define STR(s) STR_(s)
> +#define STR(s) (STR_(s) + BUILD_ASSERT_OR_ZERO(s))
>
>  static void get_host_and_port(char **host, const char **port)
>  {
>
> The error message is a bit verbose, but it starts with:
>
>   connect.c: In function ‘git_tcp_connect_sock’:
>   connect.c:801:32: error: ‘DEFAULT_GIT_PORT’ undeclared (first use in this function)
>   801 |         const char *port = STR(DEFAULT_GIT_PORT);
>       |                                ^~~~~~~~~~~~~~~~
>
> which seems OK in practice.

Seems pretty good to me.

> Another alternative is to just declare this STR() thing too clever, and
> put:
>
>   #define DEFAULT_GIT_PORT_STR "9418"
>
> next to the int declaration. It's not like its going to change. But the
> BUILD_ASSERT doesn't seem too bad to me.

Yeah, I like the BUILD_ASSERT.




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux