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

Re: [PATCH 2/2] Restrict ref-like names immediately below $GIT_DIR

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Oct 19, 2011, 15:18 UTC
Message-ID
<4E9EEA4D.50207@alum.mit.edu>
In-Reply-To
<7vty75ec54.fsf@alter.siamese.dyndns.org>
On 10/19/2011 08:19 AM, Junio C Hamano wrote:
Show 82 quoted lines
> Junio C Hamano <gitster@pobox.com> writes:
> 
>> I was trying to summarize this topic for Release Notes.
>>
>>   Possibly incompatible changes
>>   -----------------------------
>>
>>    * Special refs such as "HEAD", "MERGE_HEAD", and "FETCH_HEAD" are now
>>      restricted to names with only uppercase letters and underscore. All
>>      other refs must live under refs/ namespace. Earlier, you could
>>      confuse git by storing an object name in $GIT_DIR/tmp/junk and say
>>      "git show tmp/junk", but this will no longer work.
>>
>> But noticed that "git update-ref tmp/junk HEAD" does create such a ref
>> that won't be recognized, and "git check-ref-format tmp/junk" is happy.
>>
>> I think we would need to restrict check_ref_format() so that these
>> commands (and possibly others, but I think that single function will cover
>> pretty much everything) also reject "tmp/junk" immediately below $GIT_DIR
>> as a bad string. Otherwise we cannot merge these fixups, which would mean
>> we would have to revert the "Clean up refname checks and normalization"
>> series, at least the part that started emitting the "warning", which is a
>> mess I would rather want to avoid.
>>
>> Opinions on how to get us out of this mess?
> 
> Addendum.
> 
> I was digging this further and see fairly large conflicts between the bulk
> of "clean up refname checks and normalization" topic and the logic to
> avoid the additional warning by tightening the dwimmery.
> 
> check_refname_format() has always assumed that it is OK to be called at
> any level of substring, and there are many code like this one (example is
> from remote.c::get_fetch_map()):
> 
>         for (rmp = &ref_map; *rmp; ) {
>                 if ((*rmp)->peer_ref) {
>                         if (check_refname_format((*rmp)->peer_ref->name + 5,
>                                 REFNAME_ALLOW_ONELEVEL)) {
>                                 struct ref *ignore = *rmp;
>                                 error("* Ignoring funny ref '%s' locally",
>                                       (*rmp)->peer_ref->name);
> 
> This code somehow _knows_ that peer_ref->name begins with "refs/" and that
> is the reason it adds 5 to skip that known part. In this particular case,
> I think we can simply drop the +5 and allow-onelevel, but there are other
> instances of the calls to the function that feeds the rest of the refname
> string, skipping leading substring (not necessarily "refs/"), assuming
> that any component string is either valid or invalid no matter where it
> appears in the full refname. I wouldn't be surprised if some callers do
> not even have enough information to tell what the leading substring would
> be in the full refname context (e.g. parsing of "master:master" refspec,
> relying on the later dwimmery to add refs/heads/ in front, could just
> verify that "master" is in good format with allow-onelevel).
> 
> The new restriction bolted on to that logic in jc/check-ref-format-fixup
> series to work around the new warning in 629cd3a (resolve_ref(): emit
> warnings for improperly-formatted references, 2011-09-15) is incompatible
> with the assumption, as we would need to check full refname, and treat the
> first refname component very differently from other components. It has to
> be either "refs" in multi-component refname, or all caps in a one-level
> one, but the callers of check_refname_format() are not designed to feed
> the full refname to begin with.
> 
> I am tempted to revert 629cd3a (resolve_ref(): emit warnings for
> improperly-formatted references, 2011-09-15) that started giving the
> warnings, and drop the jc/check-ref-format-fixup topic [*1*] altogether,
> but that is a short-sighted workaround I would rather want to avoid. It
> essentially declares that the "Clean up refname checks" topic was a
> failure and did not manage to really clean things up.
> 
> A possible alternative might be to leave check_refname_format() and its
> callers as they are, introduce check_full_refname() function that knows
> the new restriction on top of check-ref-format-fixup, and use that in
> lock_ref_sha1(), lock_any_ref_for_update() and is_refname_available()
> [*2*]. That way, we can keep the potentially useful "ill-formed contents
> in the ref" warning and avoid possible confusion caused by random files
> that are directly under $GIT_DIR, which would be far more preferable in
> the longer term.
> 
> Anybody wants to give it a try?

I think that the refs/-or-ALL_CAPS test fits most naturally in check_refname_format(), controlled by an option flag.

I'm starting by building parts of the solution, namely something like:
* Add an option REFNAME_ALLOW_DWIM which causes check_refname_format()
to accept reference names that *could* be dwimmed into a valid refname.
 Specifically, when this option is *not* specified, then the option must
start with "refs/" or be ALL_CAPS.  When it *is* specified, the behavior
will be much like the current behavior when ALLOW_ONELEVEL is specified
(in fact, the new option might make ALLOW_ONELEVEL obsolete).
* Add a new function parse_refname_prefix(str, len, flags) which tries
to read a refname from the front of str (of length len, not necessarily
NUL-terminated) and returns the length of the part that could be used.
This function will support the same flag argument as
check_refname_format() (in fact the latter would become a trivial
wrapper of the new function).  I expect that this function will be
useful for dwimmery.
Hopefully I'll have patches before the end of the (Berlin) day.
Michael
-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
Previous: Junio C HamanoNext: Junio C Hamano
Message 48 of 60 in “Clean up refname checks and normalization”
  1. 00/22 Clean up refname checks and normalizationMichael Haggerty, Sep 15, 2011
  2. 01/22 t1402: add some more testsMichael Haggerty, Sep 15, 2011
  3. 02/22 git check-ref-format: add options --allow-onelevel and --refspec-patternMichael Haggerty, Sep 15, 2011
  4. 03/22 Change bad_ref_char() to return a boolean valueMichael Haggerty, Sep 15, 2011
  5. 04/22 Change check_ref_format() to take a flags argumentMichael Haggerty, Sep 15, 2011
  6. 05/22 Refactor check_refname_format()Michael Haggerty, Sep 15, 2011
  7. 06/22 Do not allow ".lock" at the end of any refname componentMichael Haggerty, Sep 15, 2011
  8. 07/22 Make collapse_slashes() allocate memory for its resultMichael Haggerty, Sep 15, 2011
  9. 08/22 Inline function refname_format_print()Michael Haggerty, Sep 15, 2011
  10. 09/22 Change check_refname_format() to reject unnormalized refnamesMichael Haggerty, Sep 15, 2011
  11. 10/22 resolve_ref(): explicitly fail if a symlink is not readableMichael Haggerty, Sep 15, 2011
  12. 11/22 resolve_ref(): use prefixcmp()Michael Haggerty, Sep 15, 2011
  13. 12/22 resolve_ref(): only follow a symlink that contains a valid, normalized refnameMichael Haggerty, Sep 15, 2011
  14. 13/22 resolve_ref(): turn buffer into a proper string as soon as possibleMichael Haggerty, Sep 15, 2011
  15. Thomas RastSep 23, 2011
  16. Michael HaggertySep 23, 2011
  17. 1/1 get_sha1_hex(): do not read past a NUL characterMichael Haggerty, Sep 23, 2011
  18. Junio C HamanoSep 23, 2011
  19. Thomas RastOct 5, 2011
  20. Junio C HamanoOct 5, 2011
  21. 14/22 resolve_ref(): extract a function get_packed_ref()Michael Haggerty, Sep 15, 2011
  22. 15/22 resolve_ref(): do not follow incorrectly-formatted symbolic refsMichael Haggerty, Sep 15, 2011
  23. 16/22 remote: use xstrdup() instead of strdup()Michael Haggerty, Sep 15, 2011
  24. 17/22 remote: avoid passing NULL to read_ref()Michael Haggerty, Sep 15, 2011
  25. 18/22 resolve_ref(): verify that the input refname has the right formatMichael Haggerty, Sep 15, 2011
  26. 19/22 resolve_ref(): emit warnings for improperly-formatted referencesMichael Haggerty, Sep 15, 2011
  27. Jeff KingOct 11, 2011
  28. Junio C HamanoOct 11, 2011
  29. Junio C HamanoOct 11, 2011
  30. Re* [PATCH v3 19/22] resolve_ref(): emit warnings for improperly-formatted referencesJunio C Hamano, Oct 11, 2011
  31. Jeff KingOct 11, 2011
  32. Junio C HamanoOct 11, 2011
  33. Jeff KingOct 11, 2011
  34. Junio C HamanoOct 12, 2011
  35. Jeff KingOct 11, 2011
  36. Junio C HamanoOct 11, 2011
  37. Jeff KingOct 12, 2011
  38. Junio C HamanoOct 12, 2011
  39. Jeff KingOct 12, 2011
  40. 1/2 refs.c: move dwim_ref()/dwim_log() from sha1_name.cJunio C Hamano, Oct 12, 2011
  41. 2/2 Restrict ref-like names immediately below $GIT_DIRJunio C Hamano, Oct 12, 2011
  42. Michael HaggertyOct 12, 2011
  43. Junio C HamanoOct 12, 2011
  44. Michael HaggertyOct 12, 2011
  45. Junio C HamanoOct 12, 2011
  46. Junio C HamanoOct 19, 2011
  47. Junio C HamanoOct 19, 2011
  48. Michael HaggertyOct 19, 2011
  49. Junio C HamanoOct 19, 2011
  50. Junio C HamanoOct 19, 2011
  51. resolve_ref(): report breakage to the caller without warningJunio C Hamano, Oct 19, 2011
  52. Michael HaggertyOct 19, 2011
  53. Junio C HamanoOct 19, 2011
  54. Jeff KingOct 12, 2011
  55. Michael HaggertyOct 12, 2011
  56. Junio C HamanoOct 12, 2011
  57. Jeff KingOct 12, 2011
  58. 20/22 resolve_ref(): also treat a too-long SHA1 as invalidMichael Haggerty, Sep 15, 2011
  59. 21/22 resolve_ref(): expand documentationMichael Haggerty, Sep 15, 2011
  60. 22/22 add_ref(): verify that the refname is formatted correctlyMichael Haggerty, Sep 15, 2011

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.