the program is to read back multiple bin files
there is an above-mentioned error happened at the end of "main" program. where did I code wrong? thank you for help
char* read_back(const char* filename)
{
FILE* pFile;
long lSize;
char* buffer;
pFile = fopen(filename, "rb");
if (pFile == NULL) { fputs("File error", stderr); exit(1); }
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile); // set file pos at the begining
// copy the file into the buffer:
buffer = (char*)malloc(sizeof(char)*lSize);
size_t result = fread(buffer, 1, lSize, pFile);
if (result != lSize) { fputs("Reading error", stderr); exit(3); }
fclose(pFile);
return buffer;
}
int main() {
const char *fname[2] ;
fname[0] = "C:\\0_data.bin";
fname[1] = "C:\\1_data.bin";
fname[2] = "C:\\2_data.bin";
int i;
char * readback_data;
for (i = 0; i < 3; ++i)
{
readback_data=read_back(fname[i]);
}
return 0;
}
const char *fname[2] ;
This declares an array with two values, two pointers: fname[0] and fname[1].
fname[0] = "C:\\0_data.bin";
fname[1] = "C:\\1_data.bin";
fname[2] = "C:\\2_data.bin";
This attempts to put three pointers into an array that's sized only for two. That's your stack corruption, right here.
Related
like title, here is my code:
int decompress_one_file(char *infilename, char *outfilename)
{
gzFile infile = gzopen(infilename, "rb");
FILE *outfile = fopen(outfilename, "wb");
if (!infile || !outfile) return -1;
char buffer[128] = {NULL};
int num_read = 0;
num_read = gzread(infile, buffer, sizeof(buffer)); // crash here
while (num_read > 0) {
fwrite(buffer, 1, num_read, outfile);
}
gzclose(infile);
fclose(outfile);
return 0;
}
when my console-app run to gzread(), its crash, I don't know what type of error is this?. zlib version: 1.2.11
update compress function:
int compress_one_file(char *infilename, char *outfilename)
{
FILE *infile = fopen(infilename, "rb");
gzFile outfile = gzopen(outfilename, "wb");
if (!infile || !outfile) return -1;
char inbuffer[128] = {NULL};
int num_read = 0;
unsigned long total_read = 0, total_wrote = 0;
while ((num_read = fread(inbuffer, 1, sizeof(inbuffer), infile)) > 0) {
total_read += num_read;
gzwrite(outfile, inbuffer, num_read);
}
fclose(infile);
gzclose(outfile);
return 0;
}
Error that shows up:
Anyone got an idea about this error?
I checked and it works fine at my workstation. May be here is a issue with gzipped file?
Could you show a file that give a crash?
But in any case you have a infinity loop of fwrite:
int num_read = 0;
while ((num_read = gzread(infile, buffer, sizeof(buffer))) > 0) {
while (num_read > 0) {
num_read -= fwrite(buffer, 1, num_read, outfile);
}
}
I have a simple implementation of AES (CTR Mode, which allows encrypting/decrypting more than 16bytes)
And I want to read a file to a char array and then to encrypt it.
I have tried the following, without success:
long GetFileSize(const char* filePath)
{
FILE* pFile = fopen(filePath, "rb");
if (pFile == NULL)
{
printf("error");
getchar();
}
fseek(pFile, 0, SEEK_END);
long lSize = ftell(pFile);
rewind(pFile);
fclose(pFile);
return lSize;
}
// Reads given file to buffer, and returns pointer to that buffer.
// Caller should free this memory later.
unsigned char * ReadFile(const char * filePath)
{
FILE * pFile;
long lSize;
unsigned char * buffer;
size_t result;
pFile = fopen(filePath, "rb");
if (pFile == NULL) { fputs("File error", stderr); ; }
// obtain file size:
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile);
// allocate memory to contain the whole file:
buffer = (unsigned char*)malloc(sizeof(unsigned char)*lSize);
if (buffer == NULL) { fputs("Memory error", stderr); ; }
// copy the file into the buffer:
result = fread(buffer, 1, lSize, pFile);
if (result != lSize) { fputs("Reading error", stderr); ; }
// terminate
fclose(pFile);
// the whole file is now loaded in the memory buffer. Return pointer to data.
return buffer;
}
int main(int argc, char *argv[])
{
//All char arrays are null terminated here...
uchar szkey[KEY_128] = "very strong key";
const char *filePath = "key.txt";
// Get file size which must be encrypted
long originalSize = GetFileSize(filePath);
// Make this size multiple of block size (16 bytes).
long multipleSize = (originalSize / 16 + 1) * 16;
// Store number of bytes that were needed for padding.
int nrOfPaddingBytes = (int)(multipleSize - originalSize);
// Now, read the file.
unsigned char * fileContents = ReadFile(filePath);
// Create a large buffer to store file contents (including padding bytes),
// and copy file contents to it.
unsigned char * buffer = (unsigned char*)malloc(multipleSize);
memcpy(buffer, fileContents, originalSize);
// Allocate space for ciphertext also (should also have size multiple of 8).
unsigned char * ciphertext = (unsigned char*)malloc(multipleSize);
char* cipherhex = (char*)malloc(multipleSize * 2);
char* decryptedhex = (char*)malloc(multipleSize);
unsigned char* dechex = (unsigned char*)malloc(multipleSize);
// Delete old file buffer.
free(fileContents);
fileContents = NULL;
// Pad the plaintext
for (int i = 0; i < nrOfPaddingBytes; i++)
{
buffer[originalSize + i] = nrOfPaddingBytes;
}
aes_ctx_t *ctx;
u64 nonce;
virtualAES::initialize();
ctx = virtualAES::allocatectx(szkey, sizeof(szkey));
virtualAES::rand_nonce(&nonce);
//encrypt
virtualAES::encrypt_ctr(ctx, buffer, ciphertext, sizeof(buffer), nonce);
cout << "cipherdata in ansi:\n" << ciphertext << "\n\n";
virtualAES::strtohex(ciphertext, cipherhex, originalSize);
cout << "cipherdata in hex:\n" << cipherhex << "\n\n";
return 0;
}
but it fails for some reason. Could someone provide me an algorithm to read a file for encrypting?
I will rephrase the whole question here so that it is answerable.
I am able to copy binary file perfectly in the same machine not using sockets but just making a simple copy function. Trying to implement this code for copying onto a TCP/IP connection but can't get it to work.
FILE *filehandle = fopen("imagefile.jpg", "rb");
FILE *dest =fopen("imagecopy.jpg", "wb"); // copied image file
fseek(filehandle, 0, SEEK_END);
unsigned long filesize = ftell(filehandle);
char *buffer = (char*)malloc(sizeof(char)*filesize);
rewind(filehandle);
int bytesread = fread(buffer, sizeof(char), filesize, filehandle);
for( int i=0; i<filesize; i++ )
{
fputc(buffer[i], filehandle); // copies all the contents to dest
}
The code above works perfectly for copying an image file in the computer but when implemented to copy on server, it is difficult to go about it.
I am trying to send an image file from a server to a client both which have been made manually in C. The length of the file to be sent by the server is only known to the server when it's sending the file so the buffer is dynamically generated in the server, something like this:
SERVER
fseek(filehandle, 0, SEEK_END);
long filesize = ftell(filehandle); // file could be 11000bytes
char *buffer = (char*)malloc(sizeof(char)*filesize); // char buffer with 11000 bytes to store the data from the file.
// then I call the send() function
rewind(filehandle); // go back to beginning
send(clientsocket, buffer, filesize, 0); // this is being sent perfectly, no errors because in the actual code, I am checking for errors
CLIENT
// here is where I don't understand how to dynamically allocate the 11000 bytes to store the data in a client buffer
// the filesize is not necessarily going to be 11000 so need to dynamically allocate
// I did the following:
#define BUFSIZE 10
FILE *filehandle = fopen("imagefile.jpg", "wb"); // image file created by client
char *buffer = (char*)malloc(sizeof(char)*BUFSIZE);
int bytesread = recv(buffer, 1, strlen(buffer), 0);
if( bytesread > 0 )
{
printf("Bytes read: %d\n", bytesread); // bytes read is 5
printf("Buffer: %s\n", buffer); // but buffer shows all the binary text like it normally would
// when I try to store buffer in a file, it doesn't put full buffer because only 5 characters are written
for( int i=0; i<bytesread; i++ )
{
fputc(buffer[i], filehandle); // this doesn't create full image
}
}
How can I dynamically allocate the 11000 bytes sent by the server?
You need to loop both the sending and receiving. Neither send() nor recv() are guaranteed to send/read as many bytes as you requested.
You also should send the file size before the file data so the receiver knows how many bytes to expect and when to stop reading.
Try something more like this:
SERVER
bool senddata(SOCKET sock, void *buf, int buflen)
{
unsigned char *pbuf = (unsigned char *) buf;
while (buflen > 0)
{
int num = send(sock, pbuf, buflen, 0);
if (num == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
// optional: use select() to check for timeout to fail the send
continue;
}
return false;
}
pbuf += num;
buflen -= num;
}
return true;
}
bool sendlong(SOCKET sock, long value)
{
value = htonl(value);
return senddata(sock, &value, sizeof(value));
}
bool sendfile(SOCKET sock, FILE *f)
{
fseek(f, 0, SEEK_END);
long filesize = ftell(f);
rewind(f);
if (filesize == EOF)
return false;
if (!sendlong(sock, filesize))
return false;
if (filesize > 0)
{
char buffer[1024];
do
{
size_t num = min(filesize, sizeof(buffer));
num = fread(buffer, 1, num, f);
if (num < 1)
return false;
if (!senddata(sock, buffer, num, 0))
return false;
filesize -= num;
}
while (filesize > 0);
}
return true;
}
FILE *filehandle = fopen("imagefile.jpg", "rb");
if (filehandle != NULL)
{
sendfile(clientsocket, filehandle);
fclose(filehandle);
}
CLIENT
bool readdata(SOCKET sock, void *buf, int buflen)
{
unsigned char *pbuf = (unsigned char *) buf;
while (buflen > 0)
{
int num = recv(sock, pbuf, buflen, 0);
if (num == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
// optional: use select() to check for timeout to fail the read
continue;
}
return false;
}
else if (num == 0)
return false;
pbuf += num;
buflen -= num;
}
return true;
}
bool readlong(SOCKET sock, long *value)
{
if (!readdata(sock, value, sizeof(value)))
return false;
*value = ntohl(*value);
return true;
}
bool readfile(SOCKET sock, FILE *f)
{
long filesize;
if (!readlong(sock, &filesize))
return false;
if (filesize > 0)
{
char buffer[1024];
do
{
int num = min(filesize, sizeof(buffer));
if (!readdata(sock, buffer, num))
return false;
int offset = 0;
do
{
size_t written = fwrite(&buffer[offset], 1, num-offset, f);
if (written < 1)
return false;
offset += written;
}
while (offset < num);
filesize -= num;
}
while (filesize > 0);
}
return true;
}
FILE *filehandle = fopen("imagefile.jpg", "wb");
if (filehandle != NULL)
{
bool ok = readfile(clientsocket, filehandle);
fclose(filehandle);
if (ok)
{
// use file as needed...
}
else
remove("imagefile.jpg");
}
We could avoid the header that contains the image size, but we just read to the end of the sent data. About the buffer size, we could use a fixed number such as 10 * 1024, when we received some data from the server, we just save it into a file according to the actual received data length.
// please open a file ...
FILE * fp;
// ...
const int LENGTH = 10 * 1024;
int len = 0;
char * buffer = (char *)malloc(LENGTH);
while ((len = recv(socket, buffer, LENGTH, 0)) > 0) {
fwrite(buffer, 1, len, fp);
}
free(buffer);
// close the file
#T.C: I guess we cannot allocate a buffer according to the size sent from the server in case the image is too large to save inside the client's memory. Not mention the server is fake, and intended to make any attack.
I want to open a binary file in C++.
but I have this function in C:
uint openPacket(const char* filename, unsigned char** buffer) {
FILE* fp = fopen(filename, "rb");
if (fp) {
size_t result;
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
rewind(fp);
*buffer = new unsigned char[fsize];
result = fread(*buffer, 1, fsize, fp);
if (result != fsize) {
printf("Reading error in %s, unable to send packet!\n", filename);
delete[] * buffer;
fsize = 0;
}
fclose(fp);
return fsize;
} else {
printf("Couldn't open %s for packet reading, unable to send packet!\n", filename);
return 0;
}
}
I want to make something like: string OpenPacket(string filename)
but don't work :(
May be this is a possible wrapper function:
std::string openPacket( const std::string& filename )
{
unsigned char* buff;
uint size = openPacket( filename.c_str(), &buff );
if( size )
{
std::string s( reinterpret_cast<const char*>(buff), size );
delete [] buff;
return s;
}
return std::string();
}
I think You Need this:
uint openPacket(const char* filename, unsigned char** buffer) {
ifstream file (filename, ios::in|ios::binary|ios::ate);
streampos size;
if (file.is_open())
{
size = file.tellg();
*buffer = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
cout << "the entire file content is in memory";
return size;
}
For reference Check this
hope this will help you.
i'm having a weird problem with allocating memory in c++
i'm creating a buffer and read file content into it.
problem is the allocating is incorrect and at the end of the printing there are weird chars...
the content of the file is "Hello"...
i'm sitting on it for hours... what can be the problem ? :(
void main()
{
FILE *fp;
char *buffer;
long file_size;
size_t result;
fp = fopen("input.txt","r");
if (fp == NULL) { fputs("File Error",stderr); exit(1); }
//get file size
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
rewind(fp);
//allocate memory to contain the whole file size
buffer = new char[file_size];
if (buffer == NULL) { fputs("Cannot allocate memory space",stderr); exit(2); }
//copy the file into the buffer
result = fread(buffer, 1, file_size, fp);
if (result != file_size) { fputs("Reading error",stderr); exit(3); }
cout<<buffer;
fclose(fp);
delete buffer;
}
You are not zero-terminating your buffer, so it's not a valid C/C++ string.
Try the following changes:
//allocate memory to contain the whole file size, plus one char for termination
buffer = new char[file_size + 1];
if (buffer == NULL) { fputs("Cannot allocate memory space",stderr); exit(2); }
//copy the file into the buffer
result = fread(buffer, 1, file_size, fp);
if (result != file_size) { fputs("Reading error",stderr); exit(3); }
// terminate buffer, so it becomes a valid string we can print
buffer[file_size] = '\0';
cout<<buffer;
Allocate one more place for termination character. And put it at the end of your buffer.
This will probably solve your problem.
buffer = new char[file_size + 1];
buffer[file_size] ='\0';
buffer must contain a NULL terminated string for your cout<<buffer output to make sense.
When you are in C++, what speaks against using C++?
see: http://www.cplusplus.com/doc/tutorial/files/
edit2: in response to Neil (the initial version printed an empty line 0):
int main () {
std::ifstream i ("main.cpp");
std::string str;
for (int line=0; getline (i, str); ++line) {
std::cout << line << ':' << str << '\n';
}
}