Thread: upper() problem in 7.0.2

upper() problem in 7.0.2

From
"Christopher L. Cousins"
Date:
Your name               : Christopher L. Cousins
Your email address      : chris@impulse.net


System Configuration
---------------------
  Architecture (example: Intel Pentium)         : AMD K7 (Athlon) ("AuthenticAMD" 686-class) 705 MHz

  Operating System (example: Linux 2.0.26 ELF)  : OpenBSD atlantia 2.7 ATLANTIA#3 i386

  PostgreSQL version (example: PostgreSQL-7.0):   PostgreSQL-7.0.2

  Compiler used (example:  gcc 2.8.0)           : gcc version 2.95.2 19991024 (release)


Please enter a FULL description of your problem:
------------------------------------------------

Working on the following table:

tickets=# \d tbluser
          Table "tbluser"
 Attribute |    Type     | Modifier
-----------+-------------+----------
 username  | varchar(16) |
 gecos     | varchar(50) |
 expdate   | timestamp   |

There are (4523 rows) in this table.

Using PHP4 or PHP3, the following query will ~sometimes~ cause the backend to
terminate.  It depends the value of $searchstr and appears (to me anyway) to be
random.  A $searchstr that causes the backend to crash right now may work just
fine in a few hours.

The same query issued through psql will not cause the backend to crash.

For both interfaces (psql and PHP4) the query logged (debug) is the same.

SELECT * FROM tblUser WHERE
upper(tblUser.username) LIKE upper('%$searchstr%')
OR
upper(tblUser.gecos) LIKE upper('%$searchstr%');

Please describe a way to repeat the problem.   Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------
If I change my query back to it's original form, one of our employees
will find a current value that causes the backend to crash (this is
part of a trouble ticket system).  Once they find the right string, I can
make the problem happen over and over by hitting reload on my web browser.


If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------

My fix was to use the builtin strtoupper() function in PHP4 to make $searchstr
uppercase before issueing the query to postgres.  The following query has been
working for the last couple of days.

SELECT * FROM tblUser WHERE
upper(tblUser.username) LIKE '%$searchstr%'
OR
upper(tblUser.gecos) LIKE '%$searchstr%';

--

--Chris

                              ____
Impulse Internet Services    /    \
____________________________/      \_____

http://www.impulse.net <chris@impulse.net>

Re: upper() problem in 7.0.2

From
Tom Lane
Date:
"Christopher L. Cousins" <chris@impulse.net> writes:
> Using PHP4 or PHP3, the following query will ~sometimes~ cause the
> backend to terminate.  It depends the value of $searchstr and appears
> (to me anyway) to be random.  A $searchstr that causes the backend to
> crash right now may work just fine in a few hours.

> The same query issued through psql will not cause the backend to crash.

> For both interfaces (psql and PHP4) the query logged (debug) is the same.

That's really odd.  Since you don't have a reproducible example, we'll
have to ask you to do some more digging.  Would you build the backend
with -g, and then next time you see the problem get a stack backtrace
from the core file left by the crashed backend?

Notes: (a) the core file should appear in the database subdirectory,
ie ..../data/base/YOURDBNAME/core.  (b) if you see no core file there
from the prior crashes, you probably have launched the postmaster with
a ulimit setting that prevents core dumps.  You'll need to be careful
to relaunch it with a setting that does allow dumps.

            regards, tom lane

Re: upper() problem in 7.0.2

From
"Christopher L. Cousins"
Date:
On Wed, Jul 05, 2000 at 12:03:46PM -0400, Tom Lane wrote:
> "Christopher L. Cousins" <chris@impulse.net> writes:
> > Using PHP4 or PHP3, the following query will ~sometimes~ cause the
> > backend to terminate.  It depends the value of $searchstr and appears
> > (to me anyway) to be random.  A $searchstr that causes the backend to
> > crash right now may work just fine in a few hours.
>
> > The same query issued through psql will not cause the backend to crash.
>
> > For both interfaces (psql and PHP4) the query logged (debug) is the same.
>
> That's really odd.  Since you don't have a reproducible example, we'll
> have to ask you to do some more digging.  Would you build the backend
> with -g, and then next time you see the problem get a stack backtrace
> from the core file left by the crashed backend?

I have been able to make the backend crash using psql.  I also took a dump
of the database while I had some known values that would trigger the problem.
Because of this, I can now reload the dump (to a dummy database) at any time to
reproduce the problem.

I had to attach to the running process to get a backtrace (the core file was
too large to be written to the disk, took me a while to figure that out).

I then issued the following query using psql.
SELECT * FROM tblUser
WHERE upper(tblUser.username) LIKE upper('%asdf%')
OR upper(tblUser.gecos)
LIKE upper('%asdf%');

postgres@cobalt% gdb
GNU gdb 4.16.1
Copyright 1996 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-unknown-openbsd2.7".
(gdb) file postgres
Reading symbols from postgres...done.
(gdb) attach 9740
Attaching to program `/usr/local/pgsql/bin/postgres', process 9740
Reading symbols from /usr/libexec/ld.so...done.
Reading symbols from /usr/lib/libm.so.0.1...done.
Reading symbols from /usr/lib/libutil.so.4.5...done.
Reading symbols from /usr/lib/libtermcap.so.7.1...done.
Reading symbols from /usr/lib/libcurses.so.7.1...done.
Reading symbols from /usr/lib/libc.so.25.0...done.
0x40211fe3 in _thread_sys_nanosleep ()
(gdb) continue
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xdfbfd638 in ?? (): No such file or directory.
(gdb) bt
#0  0xdfbfd638 in ?? ()"/bin/": not in executable format: File truncated.
(gdb) bt
#0  0xdfbfd638 in ?? (): No such file or directory.
(gdb) up
#1  0x10000 in rtbuild (heap=0x1, index=0x1, natts=1, attnum=0x1, istrat=0x1, pcount=1, params=0x1, finfo=0x1,
    predInfo=0x1) at rtree.c:114
114                     buffer = ReadBuffer(index, P_NEW);
(gdb) up
#2  0x1 in ?? () from /usr/lib/libc.so.25.0

--

--Chris

                              ____
Impulse Internet Services    /    \
____________________________/      \_____

http://www.impulse.net <chris@impulse.net>

Re: upper() problem in 7.0.2

From
Tom Lane
Date:
"Christopher L. Cousins" <chris@impulse.net> writes:
> I have been able to make the backend crash using psql.  I also took a dump
> of the database while I had some known values that would trigger the problem.
> Because of this, I can now reload the dump (to a dummy database) at any time to
> reproduce the problem.

> I had to attach to the running process to get a backtrace (the core file was
> too large to be written to the disk, took me a while to figure that out).

I don't think I believe that backtrace.  Could you send me the dump
file?

            regards, tom lane

Re: upper() problem in 7.0.2

From
"Christopher L. Cousins"
Date:
On Thu, Jul 06, 2000 at 12:48:53AM -0400, Tom Lane wrote:
> "Christopher L. Cousins" <chris@impulse.net> writes:
> > I have been able to make the backend crash using psql.  I also took a dump
> > of the database while I had some known values that would trigger the problem.
> > Because of this, I can now reload the dump (to a dummy database) at any time to
> > reproduce the problem.
>
> > I had to attach to the running process to get a backtrace (the core file was
> > too large to be written to the disk, took me a while to figure that out).
>
> I don't think I believe that backtrace.  Could you send me the dump
> file?

The core file is never written to disk (I did verify that the environment I am running
postgres under was setup to allow core files).  I belive the reason for this is that
the core file would be too large (see the looping bt output below taken without loading
symbols).  I will try to see if I can force part of it to disk regardless of size.

Is there anything else I should try?

BTW, I tried loading the database on a Solaris 2.7 box and the problem did not occur.

postgres@cobalt% gdb
GNU gdb 4.16.1
Copyright 1996 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-unknown-openbsd2.7".
(gdb) atach 25526
Undefined command: "atach".  Try "help".
(gdb) attach 25526
Attaching to process 25526
0x40211fe3 in ?? ()
(gdb) continue
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xdfbfd654 in ?? ()
(gdb) bt
#0  0xdfbfd654 in ?? ()
#1  0x10000 in ?? ()
#2  0x1 in ?? ()
#3  0x1000000 in ?? ()
#4  0x1 in ?? ()
#5  0x1000000 in ?? ()
#6  0x1 in ?? ()
#7  0x1000000 in ?? ()
#8  0x1 in ?? ()
#9  0x1000000 in ?? ()
#10 0x1 in ?? ()
#11 0x1000000 in ?? ()
#12 0x1 in ?? ()
#13 0x1000000 in ?? ()
#14 0x1 in ?? ()
#15 0x1000000 in ?? ()
#16 0x1 in ?? ()
#17 0x1000000 in ?? ()
#18 0x1 in ?? ()
#19 0x1000000 in ?? ()
#20 0x1 in ?? ()
#21 0x1000000 in ?? ()
#22 0x1 in ?? ()
---Type <return> to continue, or q <return> to quit---

** data removed while I held down the ~return~ key **

#17963 0x1000000 in ?? ()
#17964 0x1 in ?? ()
#17965 0x1000000 in ?? ()
#17966 0x1 in ?? ()
#17967 0x1000000 in ?? ()
#17968 0x1 in ?? ()
#17969 0x1000000 in ?? ()
#17970 0x1 in ?? ()
#17971 0x1000000 in ?? ()
#17972 0x1 in ?? ()
#17973 0x1000000 in ?? ()
#17974 0x1 in ?? ()
#17975 0x1000000 in ?? ()
#17976 0x1 in ?? ()
#17977 0x1000000 in ?? ()
#17978 0x1 in ?? ()
#17979 0x1000000 in ?? ()
#17980 0x1 in ?? ()
#17981 0x1000000 in ?? ()
#17982 0x1 in ?? ()
#17983 0x1000000 in ?? ()
#17984 0x1 in ?? ()
#17985 0x1000000 in ?? ()
---Type <return> to continue, or q <return> to quit---

--

--Chris

                              ____
Impulse Internet Services    /    \
____________________________/      \_____

http://www.impulse.net <chris@impulse.net>

Re: upper() problem in 7.0.2

From
Tom Lane
Date:
"Christopher L. Cousins" <chris@impulse.net> writes:
>> I don't think I believe that backtrace.  Could you send me the dump
>> file?

> The core file is never written to disk (I did verify that the environment I am running
> postgres under was setup to allow core files).

I don't want the corefile, I want the pg_dump file you claimed could
be used to reproduce the problem.

            regards, tom lane

Re: upper() problem in 7.0.2

From
"Christopher L. Cousins"
Date:
On Thu, Jul 06, 2000 at 03:10:28AM -0400, Tom Lane wrote:
> "Christopher L. Cousins" <chris@impulse.net> writes:
> >> I don't think I believe that backtrace.  Could you send me the dump
> >> file?
>
> > The core file is never written to disk (I did verify that the environment I am running
> > postgres under was setup to allow core files).
>
> I don't want the corefile, I want the pg_dump file you claimed could
> be used to reproduce the problem.

Unfortunately no, the dump file contains customer information that I can't give out.

What I can do is create a fake dataset, find some values that cause the problem, then give
that to you.  Would that be acceptable?

--

--Chris

                              ____
Impulse Internet Services    /    \
____________________________/      \_____

http://www.impulse.net <chris@impulse.net>

Re: upper() problem in 7.0.2

From
Tom Lane
Date:
"Christopher L. Cousins" <chris@impulse.net> writes:
> What I can do is create a fake dataset, find some values that cause the problem, then give
> that to you.  Would that be acceptable?

Sure, if you can do that.  I just want to reproduce the crash here.

            regards, tom lane

Re: upper() problem in 7.0.2

From
"Christopher L. Cousins"
Date:
On Thu, Jul 06, 2000 at 03:18:59AM -0400, Tom Lane wrote:
> "Christopher L. Cousins" <chris@impulse.net> writes:
> > What I can do is create a fake dataset, find some values that cause the problem, then give
> > that to you.  Would that be acceptable?
>
> Sure, if you can do that.  I just want to reproduce the crash here.

Ok, the fake dataset, sample output, and the tools used are available here:
http://www.impulse.net/~chris/pgsql-bugs

bad.out                       psql output of the known bad strings.
data.sql                      fake dataset generated from ticket-db-dataset.pl.
dump.out                      pg_dump of the the database.
known_bad_strings             a list of strings known to cause the crash.
pgsql-bugs.tar.gz             all of the files in this directory.
runme.sh                      wrapper for select.sh
schema.sql                    schema for the database.
select.out                    query for each username in the database using psql -e
select.sh                     used to create select.out
select_known_bad_strings.sh   used to create bad.out
ticket-db-dataset.pl          used to create data.sql, fake dataset.
username.out                  list of all "usernames" in the dataset.

--

--Chris

                              ____
Impulse Internet Services    /    \
____________________________/      \_____

http://www.impulse.net <chris@impulse.net>

Re: upper() problem in 7.0.2

From
Tom Lane
Date:
"Christopher L. Cousins" <chris-pgsql-bugs@cobalt.impulse.net> writes:
> #2  0xdaa41 in fixedlen_like (
>     s=0x1eeff4 "MQZSVRSJDSFR"... <Address 0x1ef000 out of bounds>, p=0x1bdbe0,
>     charlen=12) at like.c:53
> #3  0xdab1d in textlike (s=0x1eeff0, p=0x1bdbe0) at like.c:100

Oooh, I see it ... nasty!  fixedlen_like is effectively assuming that
it can access one byte beyond the end of the data string.  You've
managed to set up a situation where one byte beyond falls off the
end of the world (or the end of the backend's allocated memory, anyway).

I was having no luck reproducing it here, probably because of different
malloc behavior on my OS.  Thanks for going the extra mile to get that
backtrace.

This bug has probably been there all along, but it'd be pretty
low-probability under most circumstances.

Will create a patch shortly.  Need to look to see what other places
may be using the same bogus coding pattern...

            regards, tom lane

Re: upper() problem in 7.0.2

From
Tom Lane
Date:
"Christopher L. Cousins" <chris-pgsql-bugs@cobalt.impulse.net> writes:
>> This bug has probably been there all along, but it'd be pretty
>> low-probability under most circumstances.

> FYI, either postgres 6.3.2 did not have this problem or what I am doing did
> not trigger it in 6.3.2 (I recently upgraded from 6.3.2 to 7.0.2).

The bug is clearly there in 6.3 sources, but it could only fail if
LIKE's input data happened to have been allocated smack up against the
end of application memory.  Probably, this has been made more likely by
unrelated changes to our memory management code --- at least, it's more
likely than before for the specific usage pattern embodied in your
example.

            regards, tom lane

Re: upper() problem in 7.0.2

From
"Christopher L. Cousins"
Date:
On Thu, Jul 06, 2000 at 03:18:59AM -0400, Tom Lane wrote:
> "Christopher L. Cousins" <chris@impulse.net> writes:
> > What I can do is create a fake dataset, find some values that cause the problem, then give
> > that to you.  Would that be acceptable?
>
> Sure, if you can do that.  I just want to reproduce the crash here.

FYI, using the fake dataset on a different box I was able to get a better backtrace.

Architecture (example: Intel Pentium)         : Intel Pentium
Operating System (example: Linux 2.0.26 ELF)  : FreeBSD 2.2.8-STABLE
PostgreSQL version (example: PostgreSQL-7.0)  : PostgreSQL-7.0.2
Compiler used (example:  gcc 2.8.0)           : gcc version 2.7.2.1

chris@indigo% gdb ./postgres ../data/base/chris/postgres.core
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i386-unknown-freebsd),
Copyright 1996 Free Software Foundation, Inc...
Core was generated by `postgres'.
Program terminated with signal 11, Segmentation fault.
Cannot access memory at address 0x20140080.
#0  0x202036b4 in ?? ()
(gdb) bt
#0  0x202036b4 in ?? ()
#1  0x1eeff4 in ?? ()
#2  0xdaa41 in fixedlen_like (
    s=0x1eeff4 "MQZSVRSJDSFR"... <Address 0x1ef000 out of bounds>, p=0x1bdbe0,
    charlen=12) at like.c:53
#3  0xdab1d in textlike (s=0x1eeff0, p=0x1bdbe0) at like.c:100
#4  0x105019 in fmgr_c (finfo=0x1d3c18, values=0xefbfc898,
    isNull=0xefbfc98f "") at fmgr.c:137
#5  0x4a5e6 in ExecMakeFunctionResult (node=0x1bd710, arguments=0x1bdd30,
    econtext=0x1d3738, isNull=0xefbfc98f "",
    isDone=0xefbfc903 "\001       004") at execQual.c:842
#6  0x4a62a in ExecEvalOper (opClause=0x1bdd48, econtext=0x1d3738,
    isNull=0xefbfc98f "") at execQual.c:902
#7  0x4a9b8 in ExecEvalExpr (expression=0x1bdd48, econtext=0x1d3738,
    isNull=0xefbfc98f "", isDone=0xefbfc94b "\001h
    at execQual.c:1249
#8  0x4a6ff in ExecEvalOr (orExpr=0x1bdf50, econtext=0x1d3738,
    isNull=0xefbfc98f "") at execQual.c:1032
#9  0x4a9d8 in ExecEvalExpr (expression=0x1bdf50, econtext=0x1d3738,
    isNull=0xefbfc98f "", isDone=0xefbfc98e "\001") at execQual.c:1256
#10 0x4aa8e in ExecQual (qual=0x1d3460, econtext=0x1d3738,
    resultForNull=0 '\000') at execQual.c:1377
#11 0x4afa0 in ExecScan (node=0x1bcfa0, accessMtd=0x50490 <SeqNext>)
    at execScan.c:144
#12 0x5056b in ExecSeqScan (node=0x1bcfa0) at nodeSeqscan.c:150
#13 0x490e6 in ExecProcNode (node=0x1bcfa0, parent=0x1bcfa0)
    at execProcnode.c:268
#14 0x47e50 in ExecutePlan (estate=0x1bd028, plan=0x1bcfa0,
    operation=CMD_SELECT, offsetTuples=0, numberTuples=0,
    direction=ForwardScanDirection, destfunc=0x1d3478) at execMain.c:1052
#15 0x4749b in ExecutorRun (queryDesc=0x1d34b8, estate=0x1bd028, feature=3,
    limoffset=0x0, limcount=0x0) at execMain.c:327
#16 0xc0121 in ProcessQueryDesc (queryDesc=0x1d34b8, limoffset=0x0,
    limcount=0x0) at pquery.c:310
#17 0xc019e in ProcessQuery (parsetree=0x1bc630, plan=0x1bcfa0, dest=Remote)
    at pquery.c:353
#18 0xbe12f in pg_exec_query_dest (
    query_string=0x15d3b8 "SELECT * FROM tblUser\nWHERE upper(tblUser.username) LIKE upper('%hr%')\nOR upper(tblUs
      er.gecos) LIKE upper('%hr%');", dest=Remote,  
    aclOverride=0) at postgres.c:663
#19 0xbdf54 in pg_exec_query (
    query_string=0x15d3b8 "SELECT * FROM tblUser\nWHERE upper(tblUser.username) LIKE upper('%hr%')\nOR upper(tblUs
      er.gecos) LIKE upper('%hr%');") 
    at postgres.c:562
#20 0xbf99d in PostgresMain (argc=4, argv=0xefbfd0c8, real_argc=5,
    real_argv=0xefbfd924) at postgres.c:1590
#21 0xa3b60 in DoBackend (port=0x169000) at postmaster.c:2009
#22 0xa36a6 in BackendStartup (port=0x169000) at postmaster.c:1776
#23 0xa2416 in ServerLoop () at postmaster.c:1037
#24 0xa1aec in PostmasterMain (argc=5, argv=0xefbfd924) at postmaster.c:725
#25 0x5b467 in main (argc=5, argv=0xefbfd924) at main.c:93

--

--Chris

                              ____
Impulse Internet Services    /    \
____________________________/      \_____

http://www.impulse.net <chris@impulse.net>

Re: upper() problem in 7.0.2

From
"Christopher L. Cousins"
Date:
On Thu, Jul 06, 2000 at 05:03:21PM -0400, Tom Lane wrote:
> "Christopher L. Cousins" <chris-pgsql-bugs@cobalt.impulse.net> writes:
> > #2  0xdaa41 in fixedlen_like (
> >     s=0x1eeff4 "MQZSVRSJDSFR"... <Address 0x1ef000 out of bounds>, p=0x1bdbe0,
> >     charlen=12) at like.c:53
> > #3  0xdab1d in textlike (s=0x1eeff0, p=0x1bdbe0) at like.c:100
>
> Oooh, I see it ... nasty!  fixedlen_like is effectively assuming that
> it can access one byte beyond the end of the data string.  You've
> managed to set up a situation where one byte beyond falls off the
> end of the world (or the end of the backend's allocated memory, anyway).
>
> I was having no luck reproducing it here, probably because of different
> malloc behavior on my OS.  Thanks for going the extra mile to get that
> backtrace.

No problem, I'm just glad I was able to reproduce it on a box I could get a
clean backtrace from.

> This bug has probably been there all along, but it'd be pretty
> low-probability under most circumstances.

FYI, either postgres 6.3.2 did not have this problem or what I am doing did
not trigger it in 6.3.2 (I recently upgraded from 6.3.2 to 7.0.2).

> Will create a patch shortly.  Need to look to see what other places
> may be using the same bogus coding pattern...

Ok, thanks!

--

--Chris

                              ____
Impulse Internet Services    /    \
____________________________/      \_____

http://www.impulse.net <chris@impulse.net>

Re: upper() problem in 7.0.2

From
Tom Lane
Date:
I wrote:
> Oooh, I see it ... nasty!  fixedlen_like is effectively assuming that
> it can access one byte beyond the end of the data string.  You've
> managed to set up a situation where one byte beyond falls off the
> end of the world (or the end of the backend's allocated memory, anyway).

Turns out there were several places with this problem.  Attached is a
patch against 7.0.* sources.

            regards, tom lane

*** src/backend/utils/adt/like.c.orig    Wed Apr 12 13:15:50 2000
--- src/backend/utils/adt/like.c    Fri Jul  7 17:29:57 2000
***************
*** 50,56 ****
      (void) pg_mb2wchar_with_len((unsigned char *) s, sterm, charlen);
  #else
      sterm = (char *) palloc(charlen + 1);
!     StrNCpy(sterm, s, charlen + 1);
  #endif

      /*
--- 50,57 ----
      (void) pg_mb2wchar_with_len((unsigned char *) s, sterm, charlen);
  #else
      sterm = (char *) palloc(charlen + 1);
!     memcpy(sterm, s, charlen);
!     sterm[charlen] = '\0';
  #endif

      /*
*** src/backend/utils/adt/regexp.c.orig    Wed Jan 26 00:57:14 2000
--- src/backend/utils/adt/regexp.c    Fri Jul  7 17:29:57 2000
***************
*** 182,188 ****

      /* be sure sterm is null-terminated */
      sterm = (char *) palloc(charlen + 1);
!     StrNCpy(sterm, s, charlen + 1);

      result = RE_compile_and_execute(p, sterm, cflags);

--- 182,189 ----

      /* be sure sterm is null-terminated */
      sterm = (char *) palloc(charlen + 1);
!     memcpy(sterm, s, charlen);
!     sterm[charlen] = '\0';

      result = RE_compile_and_execute(p, sterm, cflags);

*** src/backend/utils/adt/varchar.c.orig    Wed Apr 12 13:15:52 2000
--- src/backend/utils/adt/varchar.c    Fri Jul  7 17:29:57 2000
***************
*** 117,123 ****
      {
          len = VARSIZE(s) - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         StrNCpy(result, VARDATA(s), len + 1);    /* these are blank-padded */
      }

  #ifdef CYR_RECODE
--- 117,124 ----
      {
          len = VARSIZE(s) - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         memcpy(result, VARDATA(s), len);
!         result[len] = '\0';
      }

  #ifdef CYR_RECODE
***************
*** 249,256 ****
          return NULL;

      len = VARSIZE(s) - VARHDRSZ;
!     if (len > NAMEDATALEN)
!         len = NAMEDATALEN;

      while (len > 0)
      {
--- 250,257 ----
          return NULL;

      len = VARSIZE(s) - VARHDRSZ;
!     if (len >= NAMEDATALEN)
!         len = NAMEDATALEN-1;

      while (len > 0)
      {
***************
*** 265,271 ****
  #endif

      result = (NameData *) palloc(NAMEDATALEN);
!     StrNCpy(NameStr(*result), VARDATA(s), NAMEDATALEN);

      /* now null pad to full length... */
      while (len < NAMEDATALEN)
--- 266,272 ----
  #endif

      result = (NameData *) palloc(NAMEDATALEN);
!     memcpy(NameStr(*result), VARDATA(s), len);

      /* now null pad to full length... */
      while (len < NAMEDATALEN)
***************
*** 297,303 ****
  #endif

      result = (char *) palloc(VARHDRSZ + len);
!     strncpy(VARDATA(result), NameStr(*s), len);
      VARSIZE(result) = len + VARHDRSZ;

      return result;
--- 298,304 ----
  #endif

      result = (char *) palloc(VARHDRSZ + len);
!     memcpy(VARDATA(result), NameStr(*s), len);
      VARSIZE(result) = len + VARHDRSZ;

      return result;
***************
*** 354,360 ****
      {
          len = VARSIZE(s) - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         StrNCpy(result, VARDATA(s), len + 1);
      }

  #ifdef CYR_RECODE
--- 355,362 ----
      {
          len = VARSIZE(s) - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         memcpy(result, VARDATA(s), len);
!         result[len] = '\0';
      }

  #ifdef CYR_RECODE