Subject: pkg/32128: pkg_add may match incorrectly if dewey wildcard is followed by suffix
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <nbgnats@anastigmatix.net>
List: pkgsrc-bugs
Date: 11/20/2005 01:17:00
>Number:         32128
>Category:       pkg
>Synopsis:       pkg_add may match incorrectly if dewey wildcard is followed by suffix
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Nov 20 01:17:00 +0000 2005
>Originator:     Chapman Flack
>Release:        2.0
>Organization:
>Environment:
NetBSD lundestad.anastigmatix.net 2.0 NetBSD 2.0 (lundestad) #11: Sat Mar  5 14:01:49 EST 2005  xxx@xxx:/usr/src/sys/arch/i386/compile/lundestad i386
>Description:
pkg_add given a package name with only a dewey wildcard (say php<5)
works as expected, but given a dewey wildcard plus a suffix
(say php<5.tgz) does it can misbehave and match a package that does
not satisfy the dewey condition.

The C code in pkgtools/pkg_install/files/lib/str.c and ftpio.c
is clearly intended to correctly handle the combination of a dewey
condition and a suffix. The function strip_txz is provided in str.c
to isolate the suffix, and findmatchingname explicitly uses it to
set the suffix aside temporarily, then match the dewey condition and
the wildcard separately:

	/* chop any possible suffix off of 'pattern' and
	 * store it in pat_sfx
	 */
	strip_txz(tmp_pattern, pat_sfx, pattern);
	
	while ((dp = readdir(dirp)) != (struct dirent *) NULL) {
		char    tmp_file[MaxPathSize];
		
		if (strcmp(dp->d_name, ".") == 0 ||
		    strcmp(dp->d_name, "..") == 0)
			continue;

		/* chop any possible suffix off of 'tmp_file' and
		 * store it in file_sfx
		 */
		strip_txz(tmp_file, file_sfx, dp->d_name);
		
		/* we need to match pattern and suffix separately, in case
		 * each is a different pattern class (e.g. dewey and
		 * character class (.t[bg]z)) */
		if (pmatch(tmp_pattern, tmp_file)
		    && (pat_sfx[0] == '\0' || pmatch(pat_sfx, file_sfx))) {
			if (match) {
				match(dp->d_name, data);
				/* return value ignored for now */
			}
			found = 1;
		}
	}


For ftp urls, the analogous code is around line 724 of ftpio.c.

Although clearly intended to handle the combination of a dewey
condition followed by a suffix, the code is failing somewhere.

If this proved very difficult to fix, it could be turned into a doc
bug and package wildcards could be documented as not supporting a
following suffix. But as the code appears to be mostly there and was
intended to work, it is probably worth fixing.
>How-To-Repeat:
PKG_PATH=ftp://ftp.netbsd.org/pub/NetBSD/packages/2.0/i386/All \
pkg_add 'php<5'

correctly installs php-4.4.1nb2, but

PKG_PATH=ftp://ftp.netbsd.org/pub/NetBSD/packages/2.0/i386/All \
pkg_add 'php<5.tgz'

installs php-5.0.5 (contrary to the dewey wildcard).
>Fix: