git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 07/18] link_alt_odb_entry: handle normalize_path errors

From
Jeff King <peff@peff.net>
Date
Nov 8, 2016, 00:30 UTC
Message-ID
<20161108003034.apydvv3bav3s7ehq@sigill.intra.peff.net>
In-Reply-To
<CAGyf7-HWAMF8S+Bw3wcwJCS1Subc28KHjpSCc1__0qn-GSMyvA@mail.gmail.com>
On Mon, Nov 07, 2016 at 03:42:35PM -0800, Bryan Turner wrote:
Show 13 quoted lines
> > @@ -335,7 +340,9 @@ static void link_alt_odb_entries(const char *alt, int len, int sep,
> >         }
> >
> >         strbuf_add_absolute_path(&objdirbuf, get_object_directory());
> > -       normalize_path_copy(objdirbuf.buf, objdirbuf.buf);
> > +       if (strbuf_normalize_path(&objdirbuf) < 0)
> > +               die("unable to normalize object directory: %s",
> > +                   objdirbuf.buf);
> 
> This appears to break the ability to use a relative alternate via an
> environment variable, since normalize_path_copy_len is explicitly
> documented "Returns failure (non-zero) if a ".." component appears as
> first path"

That shouldn't happen, though, because the path we are normalizing has been converted to an absolute path via strbuf_add_absolute_path. IOW, if your relative path is "../../../foo", we should be feeding something like "/path/to/repo/.git/objects/../../../foo" and normalizing that to "/path/to/foo".

But in your example, you see:
  error: unable to normalize alternate object path: ../0/objects

which cannot come from the code above, which calls die(). It should be coming from the call in link_alt_odb_entry().

I think what is happening is that relative paths via environment variables have always been slightly broken, but happened to mostly work. In prepare_alt_odb(), we call link_alt_odb_entries() with a NULL relative_base. That function does two things with it:

  - it may unconditionally dereference it for an error message, which
    would cause a segfault. This is impossible to trigger in practice,
    though, because the error message is related to the depth, which we
    know will always be 0 here.
  - we pass the NULL along to the singular link_alt_odb_entry().
    That function only creates an absolute path if given a non-NULL
    relative_base; otherwise we have always fed the path to
    normalize_path_copy, which is nonsense for a relative path.
    So normalize_path_copy() was _always_ returning an error there, but
    we ignored it and used whatever happened to be left in the buffer
    anyway. And because of the way normalize_path_copy() is implemented,
    that happened to be the untouched original string in most cases. But
    that's mostly an accident. I think it would not be for something
    like "foo/../../bar", which is technically valid (if done from a
    relative base that has at least one path component).
    Moreover, it means we don't have an absolute path to our alternate
    odb. So the path is taken as relative whenever we do an object
    lookup, meaning it will behave differently between a bare repository
    (where we chdir to $GIT_DIR) and one with a working tree (where we
    are generally in the root of the working tree). It can even behave
    differently in the same process if we chdir between object lookups.

So it did happen to work, but I'm not sure it was planned (and obviously we have no test coverage for it). More on that below.

Show 5 quoted lines
> Other commits, like [1], suggest the ability to use relative paths in
> alternates is something still actively developed and enhanced. Is it
> intentional that this breaks the ability to use relative alternates?
> If this is to be the "new normal", is there any other option when
> using environment variables besides using absolute paths?

No, I had no intention of disallowing relative alternates (and as you noticed, a commit from the same series actually expands the use of relative alternates). My use has been entirely within info/alternates files, though, not via the environment.

As I said, I'm not sure this was ever meant to work, but as far as I can tell it mostly _has_ worked, modulo some quirks. So I think we should consider it a regression for it to stop working in v2.11.

The obvious solution is one of:
  1. Stop calling normalize() at all when we do not have a relative base
     and the path is not absolute. This restores the original quirky
     behavior (plus makes the "foo/../../bar" case work).
     If we want to do the minimum before releasing v2.11, it would be
     that. I'm not sure it leaves things in a very sane state, but at
     least v2.11 does no harm, and anybody who cares can build saner
     semantics for v2.12.
  2. Fix it for real. Pass a real relative_base when linking from the
     environment. The question is: what is the correct relative base? I
     suppose "getcwd() at the time we prepare the alt odb" is
     reasonable, and would behave similarly to older versions ($GIT_DIR
     for bare repos, top of the working tree otherwise).
     If we were designing from scratch, I think saner semantics would
     probably be always relative from $GIT_DIR, or even always relative
     from the object directory (i.e., behave as if the paths were given
     in objects/info/alternates). But that breaks compatibility with
     older versions. If we are treating this as a regression, it is not
     very friendly to say "you are still broken, but you might just need
     to add an extra '..' to your path".

So I dunno. I guess that inclines me towards (1), as it lets us punt on the harder question.

-Peff
Previous: Bryan TurnerNext: Bryan Turner
Message 38 of 84 in “alternate object database cleanups”
  1. 0/18 alternate object database cleanupsJeff King, Oct 3, 2016
  2. 01/18 t5613: drop reachable_via functionJeff King, Oct 3, 2016
  3. Jacob KellerOct 4, 2016
  4. Jeff KingOct 4, 2016
  5. 02/18 t5613: drop test_valid_repo functionJeff King, Oct 3, 2016
  6. Jacob KellerOct 4, 2016
  7. 03/18 t5613: use test_must_failJeff King, Oct 3, 2016
  8. Jacob KellerOct 4, 2016
  9. 05/18 t5613: do not chdir in main processJeff King, Oct 3, 2016
  10. Jacob KellerOct 4, 2016
  11. Junio C HamanoOct 4, 2016
  12. 04/18 t5613: whitespace/style cleanupsJeff King, Oct 3, 2016
  13. Jacob KellerOct 4, 2016
  14. Jeff KingOct 4, 2016
  15. Jacob KellerOct 4, 2016
  16. 06/18 t5613: clarify "too deep" recursion testsJeff King, Oct 3, 2016
  17. Jacob KellerOct 4, 2016
  18. Jeff KingOct 4, 2016
  19. Jacob KellerOct 4, 2016
  20. Jeff KingOct 4, 2016
  21. Jacob KellerOct 4, 2016
  22. Jeff KingOct 4, 2016
  23. Stefan BellerOct 4, 2016
  24. Jeff KingOct 4, 2016
  25. Jakub NarębskiOct 5, 2016
  26. Jeff KingOct 5, 2016
  27. Junio C HamanoOct 5, 2016
  28. Jacob KellerOct 5, 2016
  29. Jacob KellerOct 4, 2016
  30. Jeff KingOct 4, 2016
  31. Jacob KellerOct 4, 2016
  32. 07/18 link_alt_odb_entry: handle normalize_path errorsJeff King, Oct 3, 2016
  33. Jacob KellerOct 4, 2016
  34. Junio C HamanoOct 4, 2016
  35. René ScharfeOct 5, 2016
  36. Jeff KingOct 5, 2016
  37. Bryan TurnerNov 7, 2016
  38. Jeff KingNov 8, 2016
  39. Bryan TurnerNov 8, 2016
  40. Jeff KingNov 8, 2016
  41. Bryan TurnerNov 8, 2016
  42. 08/18 link_alt_odb_entry: refactor string handlingJeff King, Oct 3, 2016
  43. Jacob KellerOct 4, 2016
  44. Jeff KingOct 4, 2016
  45. Jacob KellerOct 4, 2016
  46. Junio C HamanoOct 4, 2016
  47. 09/18 alternates: provide helper for adding to alternates listJeff King, Oct 3, 2016
  48. Jacob KellerOct 4, 2016
  49. 10/18 alternates: provide helper for allocating alternateJeff King, Oct 3, 2016
  50. Jacob KellerOct 4, 2016
  51. 11/18 alternates: encapsulate alt->base mungingJeff King, Oct 3, 2016
  52. 12/18 alternates: use a separate scratch spaceJeff King, Oct 3, 2016
  53. Jacob KellerOct 4, 2016
  54. Junio C HamanoOct 4, 2016
  55. Jeff KingOct 4, 2016
  56. Junio C HamanoOct 4, 2016
  57. Jeff KingOct 4, 2016
  58. 13/18 fill_sha1_file: write "boring" charactersJeff King, Oct 3, 2016
  59. Jacob KellerOct 4, 2016
  60. Junio C HamanoOct 4, 2016
  61. Jeff KingOct 4, 2016
  62. Jacob KellerOct 4, 2016
  63. Junio C HamanoOct 5, 2016
  64. 14/18 alternates: store scratch buffer as strbufJeff King, Oct 3, 2016
  65. 15/18 fill_sha1_file: write into a strbufJeff King, Oct 3, 2016
  66. Jacob KellerOct 4, 2016
  67. 16/18 count-objects: report alternates via verbose modeJeff King, Oct 3, 2016
  68. Jacob KellerOct 4, 2016
  69. Jeff KingOct 4, 2016
  70. Jakub NarębskiOct 5, 2016
  71. René ScharfeOct 5, 2016
  72. 17/18 sha1_file: always allow relative paths to alternatesJeff King, Oct 3, 2016
  73. Jacob KellerOct 4, 2016
  74. Jeff KingOct 4, 2016
  75. 18/18 alternates: use fspathcmp to detect duplicatesJeff King, Oct 3, 2016
  76. Jacob KellerOct 4, 2016
  77. Jeff KingOct 4, 2016
  78. Junio C HamanoOct 4, 2016
  79. Aaron SchrabOct 5, 2016
  80. Jeff KingOct 5, 2016
  81. Jacob KellerOct 4, 2016
  82. Jeff KingOct 4, 2016
  83. Jacob KellerOct 4, 2016
  84. René ScharfeOct 5, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.