Skip site navigation (1) Skip section navigation (2)

Re: [HACKERS] Open 6.4 items

From: Tom Ivar Helbekkmo <tih(at)nhh(dot)no>
To: "Thomas G(dot) Lockhart" <lockhart(at)alumni(dot)caltech(dot)edu>
Cc: Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us>, Tom Ivar Helbekkmo <tih(at)nhh(dot)no>, hackers(at)postgreSQL(dot)org
Subject: Re: [HACKERS] Open 6.4 items
Date: 1998-10-09 08:50:00
Message-ID: 863e8y5dc7.fsf@athene.nhh.no (view raw or flat)
Thread:
Lists: pgsql-hackers
"Thomas G. Lockhart" <lockhart(at)alumni(dot)caltech(dot)edu> writes:

(Oh, and "::ipaddr" is now "::inet", of course...)

> postgres=> select 'x12345678'::ipaddr;
> ERROR:  could not parse "x12345678"

This is as it should be -- it demands the leading 0 to work, as in:

> postgres=> select '0x12345678'::ipaddr;

...which should return:

?column?       
---------------
18.52.86.120/32
(1 row)

but in your case gives:

> pqReadData() -- backend closed the channel unexpectedly.

...or a number of other, weird errors, with or without crashes, but
mostly with.  It also changes with time, so it looks very much like
a memory corruption.  Now, I've read and re-read my code, and I'm
pretty damn sure that I don't write outside the palloc()ed area at
all, and I do palloc() the sum of VARHDRSZ and the size of the data
structure I'm storing.  I also set VARSIZE(dst) to the right number
(the same as the number of bytes I palloc()).

Looking at debug output from the backend, it is obvious that inet_in()
does the right thing: the expected 12 byte data structure looks the
way it ought to, and since all written data ends up inside it (that
is, it's filled with what I expect to see there), it's hard to imagine
what might end up outside.  It's also very strange that this happens
only when the '0x12345678'::inet format is used.  It would be natural
from this to suspect that inet_net_pton() is at fault, but my tests of
that function don't show up any problems.

Weirdly, this patch fixes the problem:

Index: inet.c
===================================================================
RCS file: /usr/local/cvsroot/pgsql/src/backend/utils/adt/inet.c,v
retrieving revision 1.2
diff -r1.2 inet.c
52c52
< 	dst = palloc(VARHDRSZ + sizeof(inet_struct));
---
> 	dst = palloc(VARHDRSZ + sizeof(inet_struct) + 1);

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?

-tih
-- 
Popularity is the hallmark of mediocrity.  --Niles Crane, "Frasier"

In response to

pgsql-hackers by date

Next:From: Jan WieckDate: 1998-10-09 09:00:21
Subject: PL patches (one more)
Previous:From: Bruce MomjianDate: 1998-10-09 05:00:45
Subject: Re: [HACKERS] CIDR type and functions

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group