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

Re: [PATCH] Use FIX_UTF8_MAC to enable conversion from UTF8-MAC to UTF8

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Jan 22, 2008, 04:59 UTC
Message-ID
<alpine.LFD.1.00.0801212025050.2957@woody.linux-foundation.org>
In-Reply-To
<7vve5nzdqx.fsf@gitster.siamese.dyndns.org>
On Mon, 21 Jan 2008, Junio C Hamano wrote:
> 
> yet you can obtain a path component longer than 256 bytes.

Individual components are limited to 255 bytes by most filesystems (PATH_MAX is the whole path, not any individual component).

That said, you're right. It's not really a design requirement, and since you never get an array of "struct dirent", just a pointer to a single one, it would be perfectly normal and natural for "struct dirent" to be declared with a unsized d_name[].

It's also quite possible that some implementations might even have d_name[] not as an array, but as a pointer to somewhere else (POSIX may require it to be an array, I didn't check).

That said, I bet that Mark isn't the only one to have written code like that, so I suspect Mark's code probably works in practice pretty much everywhere, even if I don't think it's necessarily _required_ to work correctly.

I do suspect that if you really want to make this portable, and able to handle an expanding d_name[] too, I think you need to make sure you allocate a big-enough one. And if you worry about d_name perhaps being a pointer, that really does mean that you'd need to convert the system-supplied "struct dirent" into a "git_dirent_t" that you can control.

That said, I think this patch has a bigger problem, namely just fundamentally that

	char *utf8 = reencode_string(entry, "UTF8", "UTF8-MAC");
is just unbelievably slow. That's just not how it should be done.

First off, the common case is that the filename likely has everything in plain 7-bit ascii. So rather than re-encoding by default, the first thing to do is to just see if it even needs re-encoding. Even if it's as simple as saying "does it have any high bits at all", that's going to be a *huge* performance win.

So start off with something like
	int is_usascii(const char *p)
	{
		char c;
		do {
			c = *p++;
		} while (c > 0);
		return !c;
	}
and now you can do
	if (is_usascii(entry->d_name))
		return entry;

before you even *look* at re-encoding it (and this basically works for all cases - we really don't care about EBCDIC, do we? So even if this routine was meant to do Latin1<->utf8, the above "is_usascii()" test is always the right thing to do).

Anyway, even if you do that, our "reencode_string()" is really *so* expensive that you really don't want to do it on a filename by filename basis. It literally does a malloc() for each allocation. It might well be worth it to find something that is more utf-8-specific (and I could well imagine that Mac OS X comes with some UTF libraries, if only because we cannot possibly be the only people with this issue).

(Same goes for Latin1<->UTF conversion, for that matter. If somebody wants to add that, I suspect it's best done by hand, not using iconv and our rather expensive layer around it. That said, latin1->utf8 is actually much *easier* than utf-8 NFD->NFC).

			Linus
Previous: H. Peter AnvinNext: Linus Torvalds
Message 10 of 22 in “Use FIX_UTF8_MAC to enable conversion from UTF8-MAC to UTF8”
  1. Use FIX_UTF8_MAC to enable conversion from UTF8-MAC to UTF8Mark Junker, Jan 21, 2008
  2. Mark JunkerJan 21, 2008
  3. Mark JunkerJan 21, 2008
  4. Mark JunkerJan 21, 2008
  5. Junio C HamanoJan 21, 2008
  6. Mark JunkerJan 21, 2008
  7. Junio C HamanoJan 21, 2008
  8. Mark JunkerJan 21, 2008
  9. H. Peter AnvinJan 22, 2008
  10. Linus TorvaldsJan 22, 2008
  11. Linus TorvaldsJan 22, 2008
  12. Junio C HamanoJan 22, 2008
  13. Robin RosenbergJan 22, 2008
  14. Dmitry PotapovJan 22, 2008
  15. Dmitry PotapovJan 22, 2008
  16. Nicolas PitreJan 22, 2008
  17. Linus TorvaldsJan 22, 2008
  18. Johannes SchindelinJan 21, 2008
  19. Junio C HamanoJan 21, 2008
  20. Mark JunkerJan 21, 2008
  21. Johannes SchindelinJan 21, 2008
  22. Johannes SchindelinJan 21, 2008

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.