473,406 Members | 2,894 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,406 software developers and data experts.

Problem with va_start()/vsnprintf()

Hi All,

I am facing a strange issue. if the string passed to
va_start()/vsnprintf() contains "%n", there is a segmentation fault. If
it's replaced with any other character, no issues. Any idea why? I
can't control %n as this is contained in the user input string.

Code Snip:

#include <stdio.h>
#include <stdarg.h>

void call_print(const char *fmt, ...)
{
va_list valist;
char tmp[1000];
va_start(valist, fmt);
printf("%s\n",fmt);
strncpy(tmp, fmt, 1000);
if (valist)
{
vsnprintf(tmp, 1000, fmt, valist);
} else
{
snprintf(tmp, 1000, fmt);
}
va_end(valist);
}

main()
{
const char *test = "testing0%x";

call_print(test);
}
Thanks in advance.

Manju

Jan 5 '07 #1
8 8318

Manju wrote:
Hi All,

I am facing a strange issue. if the string passed to
va_start()/vsnprintf() contains "%n", there is a segmentation fault. If
it's replaced with any other character, no issues. Any idea why? I
can't control %n as this is contained in the user input string.
It's not at all strange - have you read what "%n" means in a printf()
format string?

I suggest you do so.

Jan 5 '07 #2
On Jan 5, 12:54 pm, "Manju" <manju.myso...@gmail.comwrote:
Hi All,

I am facing a strange issue. if the string passed to
va_start()/vsnprintf() contains "%n", there is a segmentation fault. If
it's replaced with any other character, no issues. Any idea why? I
can't control %n as this is contained in the user input string.

Code Snip:

#include <stdio.h>
#include <stdarg.h>

void call_print(const char *fmt, ...)
{
va_list valist;
char tmp[1000];
va_start(valist, fmt);
printf("%s\n",fmt);
strncpy(tmp, fmt, 1000);
if (valist)
{
vsnprintf(tmp, 1000, fmt, valist);
} else
{
snprintf(tmp, 1000, fmt);
}
va_end(valist);

}main()
{
const char *test = "testing0%x";

call_print(test);

}Thanks in advance.

Manju
Because you didn't provide the argument to call_print()/printf() - %n
expects a pointer to integer into which it will store the number of
characters written so far. Note that %x expects an integer that you
also didn't provide, which means:
"If there are insufficient arguments for the format, the behavior is
undefined."
So for %n, you would do it like this:
...
int count;
printf ("hello world%n", &count);
...
man printf() or similar for more detail...
--
WYCIWYG

Jan 5 '07 #3
"Manju" <ma***********@gmail.comwrites:
Hi All,

I am facing a strange issue. if the string passed to
va_start()/vsnprintf() contains "%n", there is a segmentation fault. If
it's replaced with any other character, no issues.
I don't entirely agree. The code you posted has an "issue" in that you
give a %x format with no corresponding argument to convert. %n will
often have a more dramatic effect in that it requires a valid int *
argument, but any miss-match between the format string and the other
arguments can be equally serious.
Any idea why?
Presumably because no valid int * argument was provided.
I can't control %n as this is contained in the user input string.
Then your program is in the lap of the gods (otherwise known as
users). You will have to control either the format or the other
arguments (or both) if you want your program to have defined behaviour.
#include <stdio.h>
#include <stdarg.h>

void call_print(const char *fmt, ...)
{
va_list valist;
char tmp[1000];
va_start(valist, fmt);
printf("%s\n",fmt);
strncpy(tmp, fmt, 1000);
if (valist)
{
vsnprintf(tmp, 1000, fmt, valist);
} else
{
snprintf(tmp, 1000, fmt);
}
va_end(valist);
}

main()
{
const char *test = "testing0%x";

call_print(test);
}
--
Ben.
Jan 5 '07 #4
Thanks for all the replies.

I'd definitely go through books again to know about %n !

The string I have put is a test string to show that this is the kind of
string I get from user input or from the network. I have know way of
controlling that. All we need is to just treat it as a string and
nothing else (like vsnprintf trying to see %n within the string as a
format string).

Thanks in advance.

Manju

Jan 5 '07 #5

Thanks for all the replies.

I'd definitely go through books again to know about %n !

The string I have put is a test string to show that this is the kind of
string I get from user input or from the network. All we need is to
just treat it as a string ("my book" and "test%n%x" should be treated
as just strings) and
nothing else (like vsnprintf trying to see %n within the string as a
format string).

Is there a way to get around this problem (not by parsing the string)?
Thanks in advance.

Manju
On Jan 5, 5:12 pm, "matevzb" <mate...@gmail.comwrote:
On Jan 5, 12:54 pm, "Manju" <manju.myso...@gmail.comwrote:
Hi All,
I am facing a strange issue. if the string passed to
va_start()/vsnprintf() contains "%n", there is a segmentation fault. If
it's replaced with any other character, no issues. Any idea why? I
can't control %n as this is contained in the user input string.
Code Snip:
#include <stdio.h>
#include <stdarg.h>
void call_print(const char *fmt, ...)
{
va_list valist;
char tmp[1000];
va_start(valist, fmt);
printf("%s\n",fmt);
strncpy(tmp, fmt, 1000);
if (valist)
{
vsnprintf(tmp, 1000, fmt, valist);
} else
{
snprintf(tmp, 1000, fmt);
}
va_end(valist);
}main()
{
const char *test = "testing0%x";
call_print(test);
}Thanks in advance.
ManjuBecause you didn't provide the argument to call_print()/printf() - %n
expects a pointer to integer into which it will store the number of
characters written so far. Note that %x expects an integer that you
also didn't provide, which means:
"If there are insufficient arguments for the format, the behavior is
undefined."
So for %n, you would do it like this:
...
int count;
printf ("hello world%n", &count);
...
man printf() or similar for more detail...
--
WYCIWYG
Jan 5 '07 #6
Manju wrote:
>
Thanks for all the replies.

I'd definitely go through books again to know about %n !

The string I have put is a test string to show that this is the kind of
string I get from user input or from the network. All we need is to
just treat it as a string ("my book" and "test%n%x" should be treated
as just strings) and
nothing else (like vsnprintf trying to see %n within the string as a
format string).

Is there a way to get around this problem (not by parsing the string)?
So you are saying you just want to print the string itself? Thank heavens
for that! I thought we were going to have to explain the security
implications of you using a format entered by the user!

How about printf("%s", string)?
>
Thanks in advance.

Manju
On Jan 5, 5:12 pm, "matevzb" <mate...@gmail.comwrote:
>On Jan 5, 12:54 pm, "Manju" <manju.myso...@gmail.comwrote:
Hi All,
I am facing a strange issue. if the string passed to
va_start()/vsnprintf() contains "%n", there is a segmentation fault. If
it's replaced with any other character, no issues. Any idea why? I
can't control %n as this is contained in the user input string.
Code Snip:
#include <stdio.h>
#include <stdarg.h>
void call_print(const char *fmt, ...)
{
va_list valist;
char tmp[1000];
va_start(valist, fmt);
printf("%s\n",fmt);
strncpy(tmp, fmt, 1000);
if (valist)
{
vsnprintf(tmp, 1000, fmt, valist);
} else
{
snprintf(tmp, 1000, fmt);
}
va_end(valist);
}main()
{
const char *test = "testing0%x";
call_print(test);
}Thanks in advance.
ManjuBecause you didn't provide the argument to call_print()/printf() -
%n
expects a pointer to integer into which it will store the number of
characters written so far. Note that %x expects an integer that you
also didn't provide, which means:
"If there are insufficient arguments for the format, the behavior is
undefined."
So for %n, you would do it like this:
...
int count;
printf ("hello world%n", &count);
...
man printf() or similar for more detail...
--
WYCIWYG
--
Bill Medland
Jan 5 '07 #7

"Manju" <ma***********@gmail.comwrote in message
news:11**********************@51g2000cwl.googlegro ups.com...
>
Thanks for all the replies.

I'd definitely go through books again to know about %n !

The string I have put is a test string to show that this is the kind of
string I get from user input or from the network. All we need is to
just treat it as a string ("my book" and "test%n%x" should be treated
as just strings) and
nothing else (like vsnprintf trying to see %n within the string as a
format string).

Is there a way to get around this problem (not by parsing the string)?
Well, if you don't want any of the % formatting characters expanded, why not
do something like:

void call_printf(const char *fmt, ...)
{
char temp[1000];
snprintf( temp, 1000, "%s", fmt );
}

and not bother with the va_list. If you want some formatting characters
expanded, and others not, well, you're pretty much stuck with parsing the
format string (at the very least).

BTW: the statement "if (valist)" isn't portable -- a C compiler can make
va_list a type that can't be compared to 0 (and, in any case, it's not clear
what that if statement is supposed to do even if the compiler accepts it).
>

Thanks in advance.

Manju
On Jan 5, 5:12 pm, "matevzb" <mate...@gmail.comwrote:
>On Jan 5, 12:54 pm, "Manju" <manju.myso...@gmail.comwrote:
Hi All,
I am facing a strange issue. if the string passed to
va_start()/vsnprintf() contains "%n", there is a segmentation fault. If
it's replaced with any other character, no issues. Any idea why? I
can't control %n as this is contained in the user input string.
Code Snip:
#include <stdio.h>
#include <stdarg.h>
void call_print(const char *fmt, ...)
{
va_list valist;
char tmp[1000];
va_start(valist, fmt);
printf("%s\n",fmt);
strncpy(tmp, fmt, 1000);
if (valist)
{
vsnprintf(tmp, 1000, fmt, valist);
} else
{
snprintf(tmp, 1000, fmt);
}
va_end(valist);
}main()
{
const char *test = "testing0%x";
call_print(test);
}Thanks in advance.
ManjuBecause you didn't provide the argument to call_print()/printf() -
%n
expects a pointer to integer into which it will store the number of
characters written so far. Note that %x expects an integer that you
also didn't provide, which means:
"If there are insufficient arguments for the format, the behavior is
undefined."
So for %n, you would do it like this:
...
int count;
printf ("hello world%n", &count);
...
man printf() or similar for more detail...
--
WYCIWYG

Jan 5 '07 #8
On Fri, 5 Jan 2007 10:21:07 -0600, Bill Medland wrote
(in article <TVunh.556386$5R2.290450@pd7urf3no>):
>
So you are saying you just want to print the string itself? Thank heavens
for that! I thought we were going to have to explain the security
implications of you using a format entered by the user!
There's a surprising number of programs that can be broken (induce evil
behavior) simply by entering format specifiers when prompted for input.
Your post reminds me that I've been meaning to implement a generic
"strip_all_potential_bs_from_string()" function for a while now.

--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw

Jan 10 '07 #9

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

Similar topics

6
by: John Harrison | last post by:
Is the following code OK? #include <stdarg.h> void func(const X& x) { va_list args; va_start(args, x); funcv(x, args); va_end(args);
12
by: jois.de.vivre | last post by:
Hi, I have the following piece of code that is designed to help me add debug traces to my program (I wanted to use purely C++ code, but the only way I know how to do something like this is with...
17
by: gyan | last post by:
Why it is that following program behaving like this: 1 #include <stdlib.h> 2 #include <stdarg.h> 3 #include <stdio.h> 4 5 void comd(char *p,int a, ...); 6 void f(void); 7 8 main(){
11
by: j23 | last post by:
I have library (static) testlib.cpp: #include <stdarg.h> void xxx(...) { char buf; va_list args; va_start(args, buf); va_end(args); }
2
by: ajikoe | last post by:
Hi, I tried to follow the example in swig homepage. I found error which I don't understand. I use bcc32, I already include directory where my python.h exist in bcc32.cfg. /* File : example.c...
4
by: Sekhar | last post by:
While using variable arguments we have to initialize variable argument like va_start( arg_ptr, prevParam ); Can any body explain what is the significance of second parameter(prevParam) while...
4
by: saumya.agarwal | last post by:
Hi, I am executing a piece of code which continually tries to do the sprintf into the allocated buffer on a 64-bit RedHat linux machine. Here are the details of the system and the gcc version...
5
by: Joakim Hove | last post by:
Hello, I have written the following (stripped down) code: /********************************/ #include <stdio.h> #include <stdlib.h> #include <stdarg.h>
1
by: Chuck Chopp | last post by:
I have some code that is being built on the following: Windows Server 2003, both 32-bit & 64-bit editions Windows Vista, both 32-bit & 64-bit editions Windows Server 2008, both 32-bit & 64-bit...
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
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.