A few days ago, I was trying to make a little password generator in C so that I can generate passwords of any length and with any special set of characters that I need (like for example, only capital letters or only small letters). I wanted to do it as a fun little project but I encountered something weird with my code that I wrote. Here's the code:
#include "str2int.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define CAPITALS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define SMALL "abcdefghijklmonpqrstuvwxyz"
#define ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmonpqrstuvwxyz"
#define NUMBERS "1234567890"
#define SPECIALS "!#$@&"
#define ALLCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmonpqrstuvwxyz1234567890!#$@&"
int passlength, errcode;
char* characters;
int numinclude = 0, specialinclude = 0, alphainclude = 0, capitalinclude = 0, smallinclude = 0;
int main(int argc, char* argv[]) {
srand(time(NULL));
if (argc > 1) {
passlength = str2int(argv[1]);
errcode = errorCheck();
if (errcode != 0) {
printf("passgen %s\n", argv[1]);
printf(" ^ Here\n");
printf("Invalid input for integer");
return 0;
}
} else {
printf("Usage: passgen <passlength> [add-all] [include-numbers] [include-specials] [include-alphabet] [include-capitals] [include-small]");
printf("\n[] = Optional, <> = Required\n");
printf("Options:\n");
printf(" add-all: Includes all characters. Default option if no flags are provided.\n");
printf(" include-numbers: Adds numbers to the list of usable characters.\n");
printf(" include-specials: Adds special characters (!#$@&) to the list of usable characters.\n");
printf(" include-alphabet: Adds the entire alphabet (including capital and small letters) to the list of usable characters.\n");
printf(" include-capitals: Adds the capital alphabet to the list of usable characters.\n");
printf(" include-small: Adds the small alphabet to the list of usable characters.\n");
return 0;
}
if (argc > 2) {
for (int i = 2; i < argc; i ) {
if (strcmp(argv[i], "add-all") == 0) {
characters = (char*) realloc(characters, 68);
strcat(characters, ALLCHARS);
break;
}
if (strcmp(argv[i], "include-numbers") == 0) {
if (numinclude == 0) {
characters = (char*) realloc(characters, 11);
strcat(characters, NUMBERS);
numinclude = 1;
}
}
if (strcmp(argv[i], "include-specials") == 0) {
if (specialinclude == 0) {
characters = (char*) realloc(characters, 6);
strcat(characters, SPECIALS);
specialinclude = 1;
}
}
if (strcmp(argv[i], "include-alphabet") == 0) {
if (alphainclude == 0) {
characters = (char*) realloc(characters, 53);
strcat(characters, ALPHABET);
alphainclude = 1;
capitalinclude = 1;
smallinclude = 1;
}
}
if (strcmp(argv[i], "include-capitals") == 0) {
if (capitalinclude == 0) {
characters = (char*) realloc(characters, 27);
strcat(characters, CAPITALS);
capitalinclude = 1;
if (capitalinclude && smallinclude) {
alphainclude = 1;
}
}
}
if (strcmp(argv[i], "include-small") == 0) {
if (smallinclude == 0) {
characters = (char*) realloc(characters, 27);
strcat(characters, SMALL);
smallinclude = 1;
if (smallinclude && capitalinclude) {
alphainclude = 1;
}
}
}
}
goto generate;
}
characters = (char*) realloc(characters, 68);
characters = ALLCHARS;
generate:
printf("Generating password with length %d\n", passlength);
for (int x = 0; x < passlength; x ){
printf("%c", characters[rand() % ((int) strlen(characters))]);
}
}
It's a lot, but it basically just checks if you input something like 'include-numbers', and adds a list of numbers (defined at the top) to a character pointer named 'characters'. And I do that for basically every option, and for the most part I think all of that code works as intended. My only issue is, that when I go to test it it prints out something that shouldn't be printed out. For example, if I write in the console:
passgen 10
It generates a string of 10 letters back with all of the characters I defined at the top (#define ALLCHARS). That works fine, but if I try to do:
passgen 10 include-numbers
It should print out a string of 10 numbers from the NUMBERS macro I defined, but instead I get:
9l724`è470
What I think this is, is that the rand() function (which should be selecting a random address limited by the % strlen(characters) thing), is actually trying to access memory outside the stuff I allocated to characters in the for loop, even though it should've been practically filling all of the allocated memory, and only picking stuff in that list. I'm quite new to C, so I'm quite new to the mindset of working with memory addresses and stuff, and I basically have no idea why this isn't working as intended. Also, sorry I couldn't come up with a good title, I have no idea what this issue even is and I think it probably could be some kind of memory corruption? Also I'm extremely new to StackOverflow, so I'm sorry if this question is a little dumb or easy to answer, but I honestly have no clue what to do.
CodePudding user response:
The problem (or at least one of them) is that you are calling strcat
with a non null terminated char
array in all the cases:
characters = (char*) realloc(characters, 6);
strcat(characters, SPECIALS);