From owner-svn-src-head@FreeBSD.ORG Wed Jun 3 06:39:46 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id AC51C332; Wed, 3 Jun 2015 06:39:46 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail104.syd.optusnet.com.au (mail104.syd.optusnet.com.au [211.29.132.246]) by mx1.freebsd.org (Postfix) with ESMTP id 6EACC11F0; Wed, 3 Jun 2015 06:39:45 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c211-30-166-197.carlnfd1.nsw.optusnet.com.au (c211-30-166-197.carlnfd1.nsw.optusnet.com.au [211.30.166.197]) by mail104.syd.optusnet.com.au (Postfix) with ESMTPS id 7546542811F; Wed, 3 Jun 2015 16:39:35 +1000 (AEST) Date: Wed, 3 Jun 2015 16:39:32 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Baptiste Daroussin cc: Bruce Evans , svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r283842 - head/usr.sbin/pw In-Reply-To: <20150601180501.GA7523@ivaldir.etoilebsd.net> Message-ID: <20150603155545.E1331@besplex.bde.org> References: <201505312207.t4VM73Vh015383@svn.freebsd.org> <20150601143951.J863@besplex.bde.org> <20150601180501.GA7523@ivaldir.etoilebsd.net> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=BoBgutj5 c=1 sm=1 tr=0 a=KA6XNC2GZCFrdESI5ZmdjQ==:117 a=PO7r1zJSAAAA:8 a=kj9zAlcOel0A:10 a=JzwRw_2MAAAA:8 a=0lsTka3QrQbgM_JBd40A:9 a=EoK6N0YADXpUK65B:21 a=a6pfpDM_nVtj1rF-:21 a=CjuIK1q_8ugA:10 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jun 2015 06:39:46 -0000 On Mon, 1 Jun 2015, Baptiste Daroussin wrote: > On Mon, Jun 01, 2015 at 03:36:58PM +1000, Bruce Evans wrote: >> On Sun, 31 May 2015, Baptiste Daroussin wrote: >> >>> Log: >>> Remove useless cast in printf and printf-like functions: >>> use %u for uid_t and gid_t >> >> The cast was not useless. It was to avoid the assumption that the default >> promotion of uid_t and gid_t is anything in particular. Now it is assumed >> that the default promotion is unsigned (int works too, but this is subtler). >> >> uids and gids are only guaranteed to have non-negative values. In >> POSIX before about 2001, uid_t and gid_t can be any type that can >> represent all the values taken on, so can be floating point. Floating >> point was rarely used for POSIX types, and most programs make too many >> assumptions about types, so POSIX now requires uid_t and gid_t to be >> integer types. Then can still be signed integer types IIRC. Nornally >> it is a bug to print signed integer types with unsigned integer formats, >> but since uids and gids are guaranteed to be non-negative both formats >> work. (pids require different handling since they are overloaded to >> hold process group ids as negative values, so pid_t is signed and %u >> format is very broken for printing general pids.) > > Well uid_t is defined as an unsigned int (__uint32_t actually) if it is ever > going to be changed to something else they at least it will now raise a warning. The definition is an implementation detail. Knowing this detail defeats the point of using typedefs. > I consider using %u here is less buggy than the previous casts. The casts were almost 100% correct (only had sign mismatches) when written in ~1996 before C99 added uintmax_t and broke unsigned long. Using %u don't even attempt to preserve the 1996 level of correctness/ carefulness. pw is badly written so I'm surprised that it was this careful. chpass from 4.4BSD at least uses strtoul() to parse uids and gids, although it has many of the usual errors in such use (first it blindly assigns the result of strtoul() to a uid_t. Then it has a bogus check for ids being (uid_t)ULONG_MAX. It is isn't clear if this is one of the usual errors in the use of strto*(), or just an obfuscated way of checking that the special id (uid_t)-1 is not input...) chpass int 4.4BSD was improved from chpass in Net/2 by switching from atoi() to strtoul(). Note that unless you further switch all these strto*()s to strtoumax(), ids larger than ULONG_MAX are just unsupported, so uid_t can't be larger than uint32_t on 32-bit arches, and all the casts to u_long remained 100% correct within this limit. This shows that C99's breakage of long is much more than for printing. All input methods that were careful enough to use strtol() or strtoul() to parse values represented by typedefed integer types are now broken unless they have been changed to use strtoimax or stroumax() (or more usually, because the types are still no larger than long or u_long). It will take a few more rounds of expansion before the larger types are common. On i386, u_long must remains 32 bits and use of 64 bits for any basic type will cause much the same bugs as use of it for off_t. On amd64, u_long must remain 64 bits and it will take use of __int128_t to break things. Bruce