C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 06-20-2008, 05:47 AM   #16
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,354
Quote:
It is (probably) guaranteed to be at least 32767.
Definitely.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 06-20-2008, 01:42 PM   #17
Registered User
 
Join Date: Jun 2008
Posts: 4
Sorry, but this doesn't seem to be working universally...

I managed to get that specific spot of code working with mkruk's solution (not making it a pointer) but it isn't working later in the code, specifically:

(ident_a is a const char* that has already been successfully allocated and initialized here-- in my tests i'm setting it to abcdefghijklmnopqrstuvwxyz0123456789 because it's a good test string)
Code:
char call[sizeof(ident_a) + strlen("security lock-keychain .keychain >& /dev/null")];
snprintf(call, sizeof(call), "security lock-keychain %s.keychain >& /dev/null", keychain);
int results=system(call);
The point is to make a system call with ident_a in the middle of it... but when I do the snprintf, I end up with the string "security lock-keychain abcdefghijklmnopqrstuvwxy" in call. I just used mkruk's solution again, why doesn't it work this time?
Lasston is offline   Reply With Quote
Old 06-20-2008, 02:03 PM   #18
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
char call[sizeof(ident_a) + strlen("security lock-keychain .keychain >& /dev/null")];

Illegal. Size is not constant.
However, you could do:

char call[sizeof(ident_a) + sizeof("security lock-keychain .keychain >& /dev/null")];

The problem is that the buffer is not large enough to hold your entire string. It is only large enough to hold "security lock-keychain %s.keychain >& /dev/null" minus the "%s".
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 06-20-2008, 02:16 PM   #19
Registered User
 
Join Date: Jun 2008
Posts: 4
OK two quickie questions about this:

1) If mkruk's idea is illegal, why does it work perfectly earlier in the code? I use
Code:
char rstring[11+strlen("dark__fun")];
snprintf(rstring, sizeof(rstring), "dark_%d_fun", (rand()*rand()));
with no problems whatsoever.

2) I replaced strlen with sizeof and I'm still not getting the full string printed, it's now giving out after "z"... is there any way I can do what I'm trying to?
Lasston is offline   Reply With Quote
Old 06-20-2008, 02:18 PM   #20
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
Quote:
Originally Posted by Lasston View Post
1) If mkruk's idea is illegal, why does it work perfectly earlier in the code? I use
Code:
char rstring[11+strlen("dark__fun")];
snprintf(rstring, sizeof(rstring), "dark_%d_fun", (rand()*rand()));
with no problems whatsoever.
It's true that it compiles, but that's because it's a compiler extension. In the standard, it's illegal.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 06-20-2008, 02:19 PM   #21
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,354
Quote:
1) If mkruk's idea is illegal, why does it work perfectly earlier in the code?
Well... it is legal in C99 as it uses the variable length array feature. I am not sure if you really want to use that though (and honestly I am not familiar with it myself).
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 06-20-2008, 02:37 PM   #22
Registered User
 
Join Date: Jun 2008
Posts: 4
I am trying to learn standard, unextended C right now, so I guess I'll be taking out the array.

So... is there just no way to do something like this in the C language? It seems like no matter what I do I get an overflow.
Lasston is offline   Reply With Quote
Old 06-20-2008, 02:43 PM   #23
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,354
Quote:
I am trying to learn standard, unextended C right now, so I guess I'll be taking out the array.
C99 is the 1999 edition of the C Standard. It so happens that the variable length array feature is a C++ extension for the g++ compiler, but that is not relevant here.

Quote:
So... is there just no way to do something like this in the C language? It seems like no matter what I do I get an overflow.
You can use dynamic memory allocation with malloc() and free() from <stdlib.h>.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 06-20-2008, 03:00 PM   #24
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Quote:
Originally Posted by Lasston View Post
So... is there just no way to do something like this in the C language? It seems like no matter what I do I get an overflow.
Aside from Laserlights suggestion, there is always the option of "oversize" - if you KNOW that your sprintf() will not produce more than a few hundred bytes, make your string 4096 or something "ridiculuously large".

Naturally, this doesn't work if you have completely and utterly arbitrary inputs - in that case, you will have to find a way to calculate how much space it takes and then use malloc/free.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 06-20-2008, 03:06 PM   #25
Registered User
 
Join Date: Oct 2001
Posts: 2,936
>1) If mkruk's idea is illegal, why does it work perfectly earlier in the code?
Code:
>char call[sizeof(ident_a) + strlen("security lock-keychain .keychain >& /dev/null")];
>snprintf(call, sizeof(call), "security lock-keychain %s.keychain >& /dev/null", keychain);
>int results=system(call);
Make this:
Code:
char call[1 + strlen(keychain) + strlen("security lock-keychain .keychain >& /dev/null")];
snprintf(call, sizeof(call), "security lock-keychain %s.keychain >& /dev/null", keychain);
int results=system(call);
__________________
http://www.freechess.org
swoopy is offline   Reply With Quote
Old 06-20-2008, 03:58 PM   #26
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
That's still C99.

strlen() is a function. Its return value can only be evaluated at runtime. Consequentally, the compiler doesn't know how big the array is going to be, and you're using variable length arrays.

To solve this problem, the first thing you need to do is figure out how many digits rand() can return. One way to do that is to look at RAND_MAX and count its digits.
Code:
int digits_in_number(int n) {
    int digits = 0;

    while(n) {
        digits ++;
        n /= 10;
    }

    return digits;
}

digits_in_number(RAND_MAX);
Of course, you might be even better off passing the actual random number to a function like that, to get the exact amount of memory that you need.

Note that I've created a function to figure out how much memory to allocate, so again, you'll either have to use VLAs (variable length arrays) or dynamic memory allocation. I suggest memory allocation. It's not too hard.

Code:
char *call = malloc(digits_in_number(ident_a)
    + strlen("security lock-keychain .keychain >& /dev/null") + 1);  /* +1 for the NULL */
int result;
sprintf(call, "security lock-keychain %s.keychain >& /dev/null", keychain);
result = system(call);
free(call);
A few notes about my version:
  • I'm using sprintf() here, instead of snprintf(). The latter is C99, so if you're using it you might as well use variable length arrays anyway.
  • I'm declaring result at the beginning of a block (right after an opening curly brace), instead of the middle of the block. The latter, as you had it, is also C99.
  • I'm adding one to the length of the string, to accomodate the NULL terminator.
I'm not sure why you're adding the size of ident_a to the string, though, because you're not using ident_a anywhere. Perhaps it should be passed to the sprintf() someplace?

Anyway . . . hopefully that helped a little bit . . . .
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort
dwks is offline   Reply With Quote
Old 06-20-2008, 04:33 PM   #27
Registered User
 
Join Date: Oct 2001
Posts: 2,936
>I'm not sure why you're adding the size of ident_a to the string, though
That's supposed to be keychain. That's the only change I made from his original code, plus adding one for the string terminator.
__________________
http://www.freechess.org
swoopy is offline   Reply With Quote
Reply

Tags
buffer, malloc, overflow, random, sprintf

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Converting a circulating mouse pointer to use a Potentionmeter phoenix23 C Programming 16 10-29-2006 05:04 AM
Question on buffer overflows maxhavoc C++ Programming 3 11-25-2004 03:48 PM
buffer contents swapping daluu C++ Programming 7 10-14-2004 02:34 PM
Avoiding Buffer Overflows Aidman C++ Programming 5 01-03-2004 12:21 PM
Console Screen Buffer GaPe Windows Programming 0 02-06-2003 05:15 AM


All times are GMT -6. The time now is 11:42 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22