Subject: pkg/25439: mtools creates malformed long file name directory entries
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <mer@klockrike.net>
List: pkgsrc-bugs
Date: 05/02/2004 23:05:41
>Number:         25439
>Category:       pkg
>Synopsis:       mtools creates malformed long file name directory entries
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun May 02 22:45:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Michael Eriksson
>Release:        NetBSD 1.6ZK
>Organization:
>Environment:
System: NetBSD kurtz 1.6ZK NetBSD 1.6ZK (KURTZ) #0: Sun Feb 22 12:53:04 CET 2004 mer@killy:/usr/src/sys/arch/i386/compile/KURTZ i386
Architecture: i386
Machine: i386
>Description:

There is a fencepost error in mtools's handling of long file names.
When the file name is 13 characters, or an even multiple thereof, an
extra (empty) directory entry is created. This isn't necessarily
completely incorrect (I haven't read the specification), but at least
it's unnecessary and it also confuses my iRiver iFP-390T flash-based
MP3 player enough that it won't find the file.

>How-To-Repeat:

Copy a music file to an iRiver iFP-390T, using a 13 character file
name:

datan$ mcopy foo.mp3 f:abcdefghi.mp3

Then watch the MP3 player fail to play the file. For closer
examination, hex dump the root directory and see that the long file
name looks strange, with an extra empty 32-byte directory entry.

>Fix:

Here's a patch that corrects the computation of the number of
directory entries needed:

--- vfat.c.orig	2002-11-05 00:02:00.000000000 +0100
+++ vfat.c	2004-04-30 15:58:30.000000000 +0200
@@ -238,7 +238,7 @@
 		printf("Wrote checksum=%d for shortname %s.\n", 
 		       vse->sum,shortname);
 #endif
-		num_vses = strlen(longname)/VSE_NAMELEN + 1;
+		num_vses = (strlen(longname) + VSE_NAMELEN - 1)/VSE_NAMELEN;
 		for (vse_id = num_vses; vse_id; --vse_id) {
 			int end = 0;
 			
--- mk_direntry.c.orig	2002-05-01 12:17:50.000000000 +0200
+++ mk_direntry.c	2004-04-30 16:09:55.000000000 +0200
@@ -227,7 +227,8 @@
 	s->free_end = s->got_slots = s->free_start = 0;
 
 	if (use_longname & 1)
-                s->size_needed = 2 + (strlen(longname)/VSE_NAMELEN);
+                s->size_needed = 1 +
+		    (strlen(longname) + VSE_NAMELEN - 1)/VSE_NAMELEN;
 	else
                 s->size_needed = 1;
 }
>Release-Note:
>Audit-Trail:
>Unformatted: