Reputation: 14750
I've been using this tutorial to make C++ CGI script. However, it's not compiling when I try to read the form POST data:
char* lpszContentLength = getenv("CONTENT_LENGTH");
char* lpszBuffer;
int nContentLength = atoi(lpszContentLength);
lpszBuffer = malloc(lpszContentLength+1); // allocate a buffer
memset(lpszBuffer, 0, lpszContentLength+1); // zero it out
fread(lpszBuffer,1,lpszContentLength,stdin); // get data
Here's the compiler's complaint:
cgi.cpp: In function ‘int main()’:
cgi.cpp:12: error: invalid conversion from ‘char*’ to ‘size_t’
cgi.cpp:12: error: initializing argument 1 of ‘void* malloc(size_t)’
cgi.cpp:12: error: invalid conversion from ‘void*’ to ‘char*’
cgi.cpp:13: error: ‘memset’ was not declared in this scope
cgi.cpp:15: error: invalid conversion from ‘char*’ to ‘size_t’
cgi.cpp:15: error: initializing argument 3 of ‘size_t fread(void*, size_t, size_t, FILE*)’
Where ln 12 is the one starting with "lpszBuffer".
I'm new to C++ so I'm unsure how to fix this, or why this might be happening. Maybe it's just outdated code... I would happily accept some other solution to read the data from a POST request.
Edit: I've updated the code according to your guys' fixes.
char* lpszContentLength = getenv("CONTENT_LENGTH");
char* lpszBuffer;
int nContentLength = atoi(lpszContentLength);
lpszBuffer = (char*)malloc(nContentLength+1); // allocate a buffer
memset(lpszBuffer, 0, nContentLength+1); // zero it out
fread(lpszBuffer,1,nContentLength,stdin); // get data
However, I still get a Segmentation fault from atoi:
==23419== Invalid read of size 1
==23419== at 0x498DA8C: ____strtol_l_internal (strtol_l.c:298)
==23419== by 0x498D7EF: strtol (strtol.c:110)
==23419== by 0x498AB60: atoi (atoi.c:28)
==23419== by 0x8048899: main (in .../cgi.cpp.cgi)
==23419== Address 0x0 is not stack'd, malloc'd or (recently) free'd
What's the problem here? I'm assuming it has something to do with POST form submission if the POST is blank...
Upvotes: 1
Views: 1303
Reputation: 6823
This is a type-cast issue with C++
. lpszBuffer
is a char*
, however, malloc
returns a void*
. So you need to cast it to char*
. Also note that you are trying to use a char*
(lpszContentLength) as an integer value which is not true. This must be updated in your other functions as well - you have converted it earlier using the atoi
function; so use that value.
So the line should read
lpszBuffer = (char*)malloc(nContentLength+1);
Finally, to use memset
, you must #include <string.h>
in the beginning of the source file.
Also, as good practice (especially if the script runs for any significant amount of time), do not forget to free
your memory when you are done with it. That is, anything allocated with malloc
should have free
called on it when you are no longer going to use it. So if you use lpszBuffer
through the entire function, at the end of the function simply do free(lpszBuffer);
Upvotes: 1
Reputation: 22165
error: invalid conversion from ‘char*’ to ‘size_t’
This is caused by trying to use lpszContentLength
(which is a char*
, in this case a string of characters presumably representing a number), as a size_t
(usually a long integer). To solve this, you will first need to convert lpszContentLength
to an integer value. I'd recommend strtol()
for this, since it will detect errors - which you will need to handle.
Looking at the tutorial, they've already converted it using atoi()
. You could also fix this error by using nContentLength
everywhere they've tried to use lpszContentLength
by mistake. Their code must have never been tested.
Note that atoi()
doesn't detect errors - so once you're done with the tutorial, it would be a good learning exercise to change to strtol()
with appropriate error checking.
error: invalid conversion from ‘void*’ to ‘char*’
This is caused by missing the cast to (char*)
on the return value of malloc. In C++, the cast is required:
lpszBuffer = (char*)malloc(convertedNumber+1);
error: ‘memset’ was not declared in this scope
This is caused by not including the header for memset. The man page for memset tells you you'll need to add:
#include <string.h>
error: invalid conversion from ‘char*’ to ‘size_t’
error: initializing argument 3 of ‘size_t fread(void*, size_t, size_t, FILE*)’
These are both caused by lpszContentLength being a string of chars, when it needs to be an integer type. See the first error above.
Upvotes: 0