Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Text Files Date: Sun, 25 Feb 2018 15:54:56 -0800 Organization: None to speak of Lines: 100 Message-ID: References: <5a8459d1$0$707$14726298@news.sunsite.dk> <87o9kq8gh3.fsf@bsb.me.uk> <87a7wa8040.fsf@bsb.me.uk> <87y3jsz6fm.fsf@bsb.me.uk> <6flv8d9ii03eh280a1l8sia5a1eul0bsjs@4ax.com> <9990dccb-4af6-4d66-8a03-8842bd0f92a4@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="91969e26702e096475eebe657c83b391"; logging-data="17176"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/m13YO1PTDI1n62Y8Alokr" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:3F7O1oNo1911oF61kqkgxmTGHO4= sha1:Sdi/P/SOnhMo9jj7sEjCEUb33CM= Xref: csiph.com comp.lang.c:127058 supercat@casperkitty.com writes: > On Friday, February 23, 2018 at 6:46:19 PM UTC-6, Keith Thompson wrote: >> supercat@casperkitty.com writes: >> > The problem is that there are a number of useful things that scanf could >> > do in case of overflow, and none of them is sufficiently better than the >> > others to justify mandating that all scanf implementations must be changed >> > to do work that way. While the behavior should arguably be Implementation- >> > Defined rather than Undefined, the only difference between Undefined >> > Behavior and Implementation-Defined behavior in 1989 was whether >> > implementations were *required* to formally document the behavior. Unless >> > the Standard were to identify all the ways in which a scanf implementation >> > might behave in case of overflow, UB and IDB would have been the same from >> > a portability standpoint. >> >> Of course the standard would specify all the ways it might behave. >> >> Implementation-defined behavior is by definition >> unspecified behavior where each implementation documents how the >> choice is made >> and unspecified behavior is >> use of an unspecified value, or other behavior where this >> International Standard **provides two or more possibilities** >> and imposes no further requirements on which is chosen in >> any instance >> (emphasis added). > > Many C implementations make use of external libraries or platform > features. Documenting all of the factors that might affect the > behavior of an overflow that occurs within a scanf might have been > impractical for some implementations. That's not an issue. The external library is part of the C implementation, so its documentation is part of the C implementation's documentation. >> Reasonable behaviors could include setting the object to an >> unspecified or implementation-defined value, or treating overflow as >> a matching failure. If the standard were changed to require overflow >> to behave in one of those ways, it might not break any existing >> implementations, but it would make the *scanf functions much safer. > > There very likely existed some code that required each behavior, > and quite possibly code that relied upon *scanf setting errno or > some other kind of implementation-defined flag. The standard could state that the behavior of scanf("%d", ...) is implementation-defined and enumerate a finite list of permitted behaviors, consistent with what current implementations actually do. It wouldn't even have to mention setting errno, since library functions are permitted to do anyway. Or it could enumerate a smaller list of permitted behaviors, requiring some implementations to change their behavior in order to conform to C202X. It could even specify the exact required behavior, which might require *all* implementations to be updated, perhaps by borrowing code from their own strto*() implementations. As it is, since the behavior is undefined, an implementation is permitted to terminate the program on overflow. (I don't believe any implementations actually do so, but since it's permitted I have to consider the possibility if I want to write portable code.) >> As it is, `sscanf("999999999999", "%d", &n)` could crash your >> program. If overflow were implementation-defined rather than UB, >> it couldn't. > > Quality implementations that can sensibly define the behavior > should do so. An implementation that evalues some *scanf calls > by calling an external library function of that name, but > evaluates others by substituting other functions [similar to the > way gcc may replace printf("Hello\n"); with puts("Hello");] would > have a hard time describing how overflow would be handled if > those external functions might handle it differently. If the behavior is implementation-defined, then implementations would be required to document that behavior, regardless of how difficult it might be. In practice, it wouldn't be particularly difficult. > Note that from the point of view of the Standard, there is almost > never any guarantee that a scanf call won't result in a stack > overflow that could cause arbitrary behavior. Obviously that > won't usually happen in a quality implementation except during very > deeply-nested function calls, but nor should quality implementations > do anything else particularly dangerous with a scanf call. > > The notion that UB should encourage quality implementations to > behave in wackier fashion than IDB did not emerge until long after > the Committee had decided which actions to classify as UB versus > IDB. Nonsense. Nobody is talking about "encouraging" wacky behavior. The point is that UB *permits* arbitrary behavior, and IDB does not. That affects what I can safely do in code that's intended to be portable. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"