I've been dangling with C and a bit of cryptography, anyways I try to dynamically allocate a string to input a plain text and a key which i use to get a cypher text. Program works until I decide to free the allocated memory. then produces an error stating: HEAP CORRUPTION DETECTED: after Normal block (#73) at this and this address; checked all the other posts, nothing, I'm confused, pls help. Here's the code :
int main(int argc, char *argv[])
{
int plainSize = 0;
int keySize = 0;
InputInteger(keySize,"key size");
InputInteger(plainSize,"plaintext size");
char *plaintext = (char*)malloc((plainSize + 1) * sizeof(char));
char *key = (char*)malloc((keySize + 1) * sizeof(char));
char *cypher = (char*)malloc((plainSize + 1) * sizeof(char));
InputString(plaintext, "plaintext");
InputString(key, "key");
cypher=ViginereEncrypt(plaintext, key);
printf("\n%s encypted with Viginere key %s is %s", plaintext, key, cypher);
printf("\n\n");
free(plaintext);
free(key);
free(cypher);
}
char *ViginereEncrypt(char *plaintext,char *key)
{
int i = 0;
char *cypherText = (char*)malloc((strlen(plaintext) + 1)*sizeof(char));
printf("\n%d\n", strlen(plaintext) + 1);
for (i = 0;i < strlen(plaintext);i++)
*cypherText++ =(*plaintext++ - 'A' + *key++ - 'A' -1) % ('Z' - 'A') + 'A';
cypherText[i] = '\0';
return cypherText;
}
void InputInteger(int myInteger,char name [100])
{
printf("Input a number for %s : ",name);
scanf("%d", &myInteger);
}
void InputString(char myString[],char name[100])
{
printf("Input a string for %s : ",name);
scanf("%s", myString);
}
Is the problem with the allocation inside the function? Think it shouldn't be since I "copied" the cypher to the function return and then freed it. Thanks in advance!
The function call InputInteger(keySize,"key size"); cannot put a value to keySize. Both keySize and plainSize will remain as 0. So you are allocating 1 byte of memory for each string, only enough for a terminator. Computer melts.
I suggest these changes, firstly to pass back the input value
void InputInteger(int *myInteger, char name [100]) // add the *
{
printf("Input a number for %s : ", name);
scanf("%d", myInteger); // remove the &
}
then change the way you call it.
InputInteger(&keySize, "key size"); // add the &
InputInteger(&plainSize, "plaintext size"); // add the &
so that you pass the address of the variable you wish to alter.
Edit: That is not to say there are no other vulnerabilites in the code. The string length may be a negative number, you should be doing some input validation. Also the InputString function is open to malicious attack or accidental fault, where the user can say the string length is 2 and then wreck the stack, with some curious larger input which takes over the machine because it is executable code which the perp has placed there to steal your beans.
Related
I'd like a reliable method to read the characters from a character array and put them in a string. This will happen till a \r is found. I can iterate through the array but have no good way to put that in a string. I am afraid to use malloc since, at times, puts garbage value in a string.
Here payload is the HTTP data from a TCP packet. \r\n\r\n indicates the end of the payload.
My code so far to iterate through the character array:
void print_payload(const unsigned char *payload, int len) {
int i;
const unsigned char *ch = payload;
for (i = 0; i < len; i++) {
if (strncmp((char*) ch, "\r\n\r\n", 4) == 0) {
// Indicates end of payload data.
break;
} else if (strncmp((char*) ch, "\r\n", 2) == 0) {
//Indicates EOL
printf("\r\n");
ch++;
i++;
} else if(strncmp((char*) ch, "Host:", 5) == 0){
printf("Host: ");
const unsigned char *del = ch + 6;
int i = 0;
while (del[i] != 13 ){
/*
*13 is decimal value for '\r'.
* The characters below are to be inserted
* in a string. Not sure how though.
*/
printf("%c",del[i]);
i++;
}
} else if(strncmp((char*) ch, "User-Agent: ", 11) == 0){
/*
* It has to implemented here as well.
* And in every case where my string matches.
*/
printf("UserAgent: ");
const unsigned char* del = ch + 11;
int i = 0;
while(del[i] != 13){
printf("%c")
}
}
ch++;
}
printf("\r\n\r\n");
printf("\n");
return;
}
Can somebody help me achieve this? I know this is basic but I'm still learning C Programming and am not sure how to do this. Thank in advance.
You have a few options. First, if you can limit the size of the string, and do not need it outside of the function, then a char array would work:
#define STRING_MAX_LEN 999//chux mentions this is better then just putting "1000" in the array[] - 1000 needs to make sense in terms of the program, or something you wish to enforce (and checked!)
char newString[STRING_MAX_LEN+1] = {0};//Initialize to NULL value.
There is no reason to fear malloc though - just remember to work safely and free, and you should be fine:
char *newString = malloc(sizeof(char)*(len+1)); //Better limit on needed space - +1 for a final '\0'.
if (!newString) //Oh no! hard fail.
//do Something
}
memset(newString,0,sizeof(char)*(len+1)); //No garbage in my new string anymore!
...
...
free(newString);
//Finish up with program
You will not even have to append a '\0' - you are already sure the buffer is full of them, so you a valid C string. Note sizeof(char) may be redundant but I like to keep it anyway, in case one day it will not equal 1.
Note if you have to return the new string for some reason you must use a dynamically allocated array, using malloc. Finally, if you only need to check/hold one sub-string at a time, then re-using the same string is preferable.
void print_payload(const unsigned char *payload, int len)
{
int i;
char c;
char *p;
p = (char*)payload;
for(i=0;i<len;i++) {
if(!strncmp(&p[i],"\r\n\r\n",4)) {
c = p[i+4];
p[i+4] = 0;
break;
}
}
if(i==len) {
return;
}
printf("%s\n",p);
p[i+4] = c;
}
Ive created a vector in C that holds chars. The point is to ask a user for input from keyboard and have them input one char at a time, then add it to the vector using calloc.It currently does not load anything and quits after any input. I want to be able to keep adding characters until the user inputs return in place of a character then, the program will turn the characters into a string and append to text that is preset. After it will print out the result. My issue is that my program won't load the user input into the vector array. The final result should look like HW4 Input: 123456
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//declare a new vector structure
int arraySize =1;
char *vector(char *Array){
arraySize++;
void *temp=(char*) calloc(arraySize, sizeof(char));
Array= (char*) temp;
return Array;
}
int main(void){
int i, m;
int h=0;
int index=0;
char c;
char *array = (char *) calloc(arraySize, sizeof(char));
array[0] = '\0';
char ch[]= "HW4 input: ";
printf("\nEnter a single character to add to the string\n");
printf("Enter one character at a time, when done press enter without any other input.\n");
while((c=getc(stdin))!='\n'){
array[index]=c;
index++;
if(index<arraySize){
char *temp=(char*) calloc(arraySize, sizeof(char));
memcpy(temp,array, arraySize);
array=vector(array);
memcpy(array, temp, arraySize);
}
}
arraySize++;
array=vector(array);
index++;
array[index]='\0';
char output[arraySize+14];
for (i=0; i<strlen(ch); i++){
output[i]= ch[i];
}
for(m=i; m<strlen(output); m++){
output[m]=array[h];
}
printf("\n%c\n", array[0]);
free(array);
return 0;
}
In your code you write
index++;
if (index<arraySize) {
...
however at start arraySize==1 so that condition will never be true.
Allocating memory is a costly operation therefore to allocate every byte and then copy over the contents is not effective.
Instead allocate say 100 characters and then if the user input is longer add another 100 character. The most convenient way to do this is to use realloc.
e.g.
if (index < arraySize)
{
char* tmp = realloc(array, arraySize + 100)
if (tmp != NULL)
{
array = tmp;
arraySize += 100;
}
else
{
fprintf(stderr, "out of memory");
exit(EXIT_FAILURE);
}
}
you can always reallocate again with the correct size once the user is finished with his input to get the right buffer size.
So, my goal is to create a linear search, but i have got that down pat, I am having one problem with accessing strings from the struct, that i have stored using a txt file, so in linearSearch() I tried doing this:
printf("Name: %s \n", q.name[i]);
printf("Data: %d \n", q.data[i]);
The data would be perfect but name would just print out the same name for every array which would be the last item that I put into the array.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char* name[10];
int data[10];
}Word;
//int bubblesort (Word word);
void linearSearch(char* name, Word q);
int main (int argc, const char *argv[]){
Word q;
char username[9]; /* One extra for nul char. */
int score;
int i = 0;
FILE *ifp, *ofp;
ifp = fopen("Data.txt", "r");
while (fscanf(ifp, "%s %d", &username, &score) == 2) {
q.name[i] = username;
printf ("Name: %s, I = %d \n", q.name[i], i);
q.data[i] = score;
printf ("Data: %d, I = %d \n", q.data[i], i);
i++;
}
linearSearch("Matt", q);
return EXIT_SUCCESS;
}
void linearSearch(char* name, Word q){
int i = 0;
int foundIt = 0;
int numNames = sizeof(&q.name);
while ((foundIt == 0) && (i <= numNames)){
printf("Name: %s \n", q.name[i]);
printf("Data: %d \n", q.data[i]);
if ((strcmp(name, q.name[i]) != 0)){
i = i + 1;
} else {
foundIt = 1;
}
}
if (foundIt == 1){
printf("Name found at position %d", i);
} else {
printf("Required person not found");
}
}
This happens because of the code
q.name[i] = username;
You cannot assign the value of an array using = operator. Here, you're assigning the address of username to every q.name[i]. So, the last value of username is reflected throughout the array.
What you actually need is to use malloc() to allocate memory and then strcpy() to copy the string contents.
Otherwise, you can also make use of strdup().
Either way, don't forget to free() the allocated ememory once you're done using them.
I can see that you declared char username[9], so I assume your names should be at most 8 characters long. You should :
read with : fscanf(ifp, "%8s %d",&username, &score) == 2 : the & is useless in front of an array (it decays nicely to a pointer), but you should limit size of input - ok , your problem does not come from there
use a 2D char array for Word.name instead of an array of pointers. That way your memory is already allocated and you can safely strcpy to it :
typedef struct {
char name[10][9];
int data[10];
}Word;
then :
strcpy(q.name[i], username); /* safe because qname[i] and username are both [9] */
The rule here is always control that you do not risk a buffer overrun when writing in char arrays/
An alternative way would be to do dynamic allocation through strdup but in that case you should free it.
I'm trying to make a program where a user inputs a string then if they want to enter a letter they want to replace and what with. I want to use malloc to set the array but how would I do it with scanf?
Please can someone help.
Thanks!
This is what the program looks before going to the replace method:
char *s,x,y;
printf("Please enter String \n");
scanf("%s ", malloc(s));
printf("Please enter the character you want to replace\n");
scanf("%c ", &x);
printf("Please enter replacment \n");
scanf("%c ", &y);
prinf("%s",s);
You can't know the size of the user input beforehand, so you need to dynamically allocate more memory if the user input hasn't ended yet.
An example would be:
//don't forget to free() the result when done!
char *read_with_alloc(FILE *f) {
size_t bufsize = 8;
char *buf = (char *) malloc(bufsize);
size_t pos = 0;
while (1) {
int c = fgetc(f);
//read until EOF, 0 or newline is read
if (c < 0 or c == '\0' or c == '\n') {
buf[pos] = '\0';
return buf;
}
buf[pos++] = (char) c;
//enlarge buf to hold whole string
if (pos == bufsize) {
bufsize *= 2;
buf = (char *) realloc((void *) buf, bufsize);
}
}
}
A pragmatic alternative solution would be to limit the buf size (for example, to 256 characters), and to make sure that only that number of bytes is read:
char buf[256]; //alternative: char *buf = malloc(256), make sure you understand the precise difference between these two!
if (scanf("%255s", buf) != 1) {
//something went wrong! your error handling here.
}
scanf("%s ", malloc(s));
What does this mean? s uninitialized is pointer, it can have any value, say 0x54654, it is Undefined Behavior.
Your code should be,
int size_of_intput = 100; //decide size of string
s = malloc(size_of_intput);
scanf("%s ", s);
I am converting (from javascript) a program that will take a string of variable length (but always under 100 char) and return the data contained in the string in individual variables. This is the first portion of my code, and obviously, I am new to C and programming in general. This code is for the first section of the code, but learning how to properly code this would give me the know how to code the rest.
I need:
the first 4 digits to be stored as 'stringID'
the 5th digit to be stored as 'myindicator'
the 6th through (indicator + 6) digits to be stored as 'var1'
Example input:
'12345678901234567890123'
Example output:
stringID = 1234
myindicator = 5
var1 = 67890123456
When I run the program, it returns 'String ID: H>a' and then the program crashes. Any help would be appreciated. No, this is not homework.
int main()
{
char mystring[100];
char *stringID;
int nep;
int *myindicator;
char *var1;
nep = 0;
printf("Please enter your CODE\n");
scanf("%s", &mystring);
stringID = (char *)malloc(4 * sizeof(char));
if(NULL != stringID)
{
strncpy(stringID, mystring, 4);
stringID[4] = '\0';
free(stringID);
nep = nep +4;
printf("stringID: %s\n",myindicator);
}
if(NULL != myindicator)
{
strncpy(myindicator, (mystring+nep, 1);
nep++;
myindicator = *myindicator - '0';
printf("Indicator : %d\n",myindicator);
}
var1 = (char *)malloc((nep + 6) * sizeof(char));
if(NULL != var1)
{
strncpy(var1, mystring+nep, (myindicator+nep+6));
var1[myindicator+nep+6] = '\0';
free(var1);
printf("Var 1: %s", var1);
nep = nep +myindicator+6;
}
getchar();
return 0;
}
I fixed something, find it in the comments. But you need to check a C language manual...!
int main()
{
char mystring[100];
char *stringID;
int nep;
// Changed to integer, not pointer to int.
int myindicator;
char *var1;
nep = 0;
printf("Please enter your CODE\n");
/*
This scanf is a bad idea for the same reason for which, below, we take
care to allocate memory enough for whatever we have to do.
Should someone input 250 characters in a buffer of size 100, those 150
extra characters would wreak havoc and possibly endanger the system.
*/
// scanf("%s", &mystring);
fgets(mystring, sizeof(mystring)-1, stdin);
// fgets will read at most "sizeof(mystring)-1", that is, 99 bytes,
// from "stdin" (STanDard INput), the same as scanf. But it will halt
// when reaching the limit given. It's up to us to give a "real" limit
// (nothing stops you from saying 15000 -- even if the true value is 100).
// C strings are made of characters, terminated by a zero byte.
// So you need 5 here, to store 4 characters
stringID = (char *)malloc(5 * sizeof(char));
if (NULL == stringID)
{
// Serious out of memory error: no sense going on.
// fprintf(stderr, "Out of memory\n");
abort();
}
strncpy(stringID, mystring, 4);
stringID[4] = '\0';
printf("ID: %s\n", stringID);
free(stringID);
nep = nep + 4;
printf("NEP: %d\n", nep);
// Now we want to decode the fifth digit.
// I use '0' as character. So if the fifth digit is '0', '0'-'0' will give 0
// and if it is '9', '9'-'0' will give 9 (the number).
// The trick does not work with more than one digit, of course.
myindicator = mystring[nep] - '0';
// Had I wanted to read 3 digits, I would have had to copy them into a
// temporary buffer, add a zero in the fourth position, then run atol()
// on the resulting buffer: atol("12345\0" /* A STRING */) = 12345 /* A NUMBER */;
printf("VLI : %d\n", myindicator);
// Copy "myindicator" bytes, so alloc myindicator+1 chars
var1 = (char *)malloc((myindicator + 1) * sizeof(char));
// Check that var1 is not null and abort if it is
if (NULL == var1)
abort();
strncpy(var1, mystring + 6, myindicator);
var1[myindicator+1] = '\0';
// Moved this printf before the free. See why below.
printf("Prefix : %s\n", var1);
// NEVER use a variable after you freed it!!!
// it might APPEAR to work, but will stab you in the back the first chance it gets.
// Good if paranoid habit: null a var as soon as you've freed it.
free(var1); var1 = NULL;
getchar();
return 0;
}
why are you freeing your array's ? you are referencing them after you have freed them from heap.
Your code will segfault in these places :
where did you allocated myindicator?
strncpy(myindicator, (mystring+nep, 1); // it will segfault here.
free(var1);
printf("Prefix : %s", var1); // again segfault
Again here
strncpy(var1, mystring+nep, (myindicator+nep+6)) //where is your mystring?
taking string input by scanf() is horrible horrible idea. use buffered IO like fgets().
You are exposing your mystring to buffer overflow. who is preventing the user from inputting a 120 byte string? i can write your stack with careful jump instruction to my malicious code.