Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) by hub.org (8.8.8/8.8.8) with ESMTP id LAA14820 for ; Fri, 9 Oct 1998 11:09:02 -0400 (EDT) (envelope-from tgl@sss.pgh.pa.us) Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.sss.pgh.pa.us (8.9.1/8.9.1) with ESMTP id LAA22956; Fri, 9 Oct 1998 11:01:30 -0400 (EDT) To: Tom Ivar Helbekkmo cc: hackers@postgreSQL.org Subject: Re: [HACKERS] Open 6.4 items In-reply-to: Your message of 09 Oct 1998 10:50:00 +0200 <863e8y5dc7.fsf@athene.nhh.no> Date: Fri, 09 Oct 1998 11:01:29 -0400 Message-ID: <22954.907945289@sss.pgh.pa.us> From: Tom Lane Tom Ivar Helbekkmo writes: > Now I'm explicitly asking for at least one byte more than I need, and > I'm pretty damn sure that I never touch that extra byte, but something > seems to, since the problem goes away. It's arrogant of me, I know, > but barring a complete misunderstanding on my part of how variable > size records work (or a stupid bug that I've been staring at for hours > without seeing, of course), I'd say that something outside my code is > at fault. Any ideas as to how to try to find out? Well, I hate to ruin your day, but coming pre-armed with the knowledge that the code is writing one byte too many, it's pretty obvious that the first loop in inet_net_pton_ipv4 does indeed do that. Specifically at else if (size-- > 0) *++dst = 0, dirty = 0; where, when size (the number of remaining destination bytes) is reduced to 0, the code nonetheless advances dst and clears the next byte. The loop logic is fundamentally faulty: you can't check for emsgsize overflow until you get a digit that is supposed to go into another byte. I'd try something like tmp = 0; ndigits = 0; // ndigits is # of hex digits seen for cur byte while (ch = next hex digit) { n = numeric equivalent of ch; assert(n >= 0 && n <= 15); tmp = (tmp << 4) | n; if (++ndigits == 2) { if (size-- <= 0) goto emsgsize; *dst++ = (u_char) tmp; tmp = 0, ndigits = 0; } } if (ndigits) goto enoent; // odd number of hex digits is bogus BTW, shouldn't this routine clear out all "size" bytes of the destination, even if the given data doesn't fill it all? A memset at the top might be worthwhile. regards, tom lane