473,399 Members | 2,774 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

strncpy() and null terminated strings

Hi all! I support a rather large production EDI application with a
number of C programs, and I ran across a very interesting problem. I
have some code that used to work just fine for years, and now all of a
sudden it doesn't work any more. The input to the program did not
change at all (even ran it through a binary browser to make certain
there were no hidden chars or something strange) and the program has
not been recompiled in years.

In general, I know how to fix the problem but management here wants an
explanation as to why it ever worked to begin with. So I guess what
I'm looking for is some theories regarding what may have changed (OS,
memory configuration, etc.)

Here's the situation...

The program is reading a buffer that contains a string value. There
are no nulls in the string contained in the buffer (if that matters).
A strncpy() is being used to move substrings from the buffer into
variables, and then the variables are written to a report using
fprintf(). THE PROBLEM IS THAT THE STRINGS ARE NOT NULL TERMINATED
(and also not initialized with any values if that makes a difference
to you). Like I said earlier, this worked for years but all of a
sudden garbage is being outputted to the report unless I change the
program to null terminate the strings.

So I'm looking for theories as to why this ever worked to begin with
(actually that is what management here wants to know, and I'm having
trouble providing them with an explanation). Somehow these variables
must have been initialized with null values (or something like that)
and now they are not - so what could have changed to cause a
difference?

Here are some snippets of code from the program if it helps (I didn't
write this, I only keep it working):

....
<some code>
....

/* Global declaration */
struct FA_Table {
char CUST_ID[5];
char CUST_NAME[37];
char GS03[16];
char ISA05[3];
char GS02[16];
char newline;
};

....
<some code>
....

int Process_msga( fa, in, out)
register struct FuncAck *fa;
FILE **in, **out;
{
char TERM[3];
struct FuncAck tbl;

while ( fgets(buf, 256, *in ) != (char *)NULL )
{

if ( strncmp(buf, "ISA", 3)==0 ) {
TERM[0] = buf[3],
TERM[1] = '\n';
TERM[2] = '\0';

/* Below is the problem */
strncpy(fa->isa.ISA05,&buf[32],2);
/*Adding fa->isa.ISA05[2]=0; here makes everything work ok*/
printf("found ISA05|%s|\n",fa->isa.ISA05);

....
<more code>
....
}
The printf above outputs the string + garbage unless I null terminate
the string. So any ideas why it ever worked to begin with???

Barry
Nov 14 '05 #1
4 4439
On 8 Apr 2004 06:39:05 -0700, ba*****@bellsouth.net (Barry) wrote:
Hi all! I support a rather large production EDI application with a
number of C programs, and I ran across a very interesting problem. I
have some code that used to work just fine for years, and now all of a
sudden it doesn't work any more. The input to the program did not
change at all (even ran it through a binary browser to make certain
there were no hidden chars or something strange) and the program has
not been recompiled in years.
<snip>
The program is reading a buffer that contains a string value. There
are no nulls in the string contained in the buffer (if that matters).
A strncpy() is being used to move substrings from the buffer into
variables, and then the variables are written to a report using
fprintf(). THE PROBLEM IS THAT THE STRINGS ARE NOT NULL TERMINATED
(and also not initialized with any values if that makes a difference
to you). Like I said earlier, this worked for years but all of a
sudden garbage is being outputted to the report unless I change the
program to null terminate the strings.


Some change in the execution environment, or a change in activity of
the program prior to the call, has made the memory used for automatic
allocation of your structure contain something other than zeros. (This
would be the stack on most common desktop and server platforms.)

It was luck that it ever worked.

--
Sev
Nov 14 '05 #2
Severian <se******@chlamydia-is-not-a-flower.com> wrote:
Some change in the execution environment, or a change in activity of
the program prior to the call, has made the memory used for automatic
allocation of your structure contain something other than zeros. (This
would be the stack on most common desktop and server platforms.)


And just one example of how this _could_ come to pass: maybe your
application has been collecting data all these years, and this data has
finally grown so large that, in the course of the calculations, that
part of memory, which previously used to be newly allocated, now needs
to come from used and reclaimed memory blocks.

Richard
Nov 14 '05 #3
In <25*************************@posting.google.com> ba*****@bellsouth.net (Barry) writes:
The printf above outputs the string + garbage unless I null terminate
the string. So any ideas why it ever worked to begin with???


Yes: the structure was initialised, by default and by accident with all
zeros. These zeros acted as string terminators. At some point, the
structure was no longer initialised with zeros, but with garbage. Now,
your "strings" were no longer null terminated and printf had no good
reason to stop at the intended place. The reason of the change is
external to the program (e.g. the new libraries coming with a new version
of the OS) and code that accidentally worked before no longer worked
after.

The easiest fix is to explicitly nullify all your data containers
(arrays, buffers, structures) before starting to fill them with
input data. Code that worked previously by accident will work now by
design, if you leave at least one byte untouched when storing the data
in your containers.

If the code wasn't supposed to handle strings, it should have used memcpy
instead of strncpy and *all* the %s conversion specifications should have
contained an explicit precision specification, i.e. %.2s for a data field
that is no longer than 2 characters.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #4

"Severian" <se******@chlamydia-is-not-a-flower.com> wrote in

It was luck that it ever worked.

Bad luck. Seemingly correct behaviour is the most dangerous type of
undefined behaviour, as the Op's experience shows.
Nov 14 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Simon | last post by:
Hi, I am a bit confused with zero based items and strncpy(...) assuming I have char str1 = "Hello world"; char str2; I now have str2 that should look something like
12
by: ­m˝Z | last post by:
I am a C programming beginner... I wonder, why strncpy(s, t, n) does not put '\0' at the end of the string. Because when I output the copied string, it output more than what I want, until I put...
4
by: Barry | last post by:
Hi all! I support a rather large production EDI application with a number of C programs, and I ran across a very interesting problem. I have some code that used to work just fine for years, and...
15
by: ehabaziz2001 | last post by:
Hi, Till now I do not understand how the null character automatically added to the end of the string and it is not an element of the string array . All books said the null character (\0) added...
12
by: semut | last post by:
Given that the string is of null terminated type. What could be the possible causes (by experience) the string to have no null terminated and cause buffer overflow later. I know it is quite broad,...
43
by: Frodo Baggins | last post by:
Hi all, We are using strcpy to copy strings in our app. This gave us problems when the destination buffer is not large enough. As a workaround, we wanted to replace calls to strcpy with strncpy....
9
by: Ron | last post by:
#define MAX_SIZE 512 char mybuffer; void myfunction( const char* src ) { if( src == null ) { return; } /* A core dump is occuring here */ strncpy( mybuffer, src, MAX_SIZE );
4
by: lurch132002 | last post by:
i am trying to create an array of structs to hold some information but whenever i get to the second element and try to strncpy it i get a segmenation fault. ive searched around for similar...
5
by: davidcollins001 | last post by:
Hi, I am writing a small program to basically copy ls. I would like to copy a string so I thought I would use strncpy but I am getting the following error: I thought I would be able to debug...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.