Initializing strings in C in Visual Studio - c

I try to learn the XOR algorithm using C. I have found a great example on KyleBank's GitHub:
#include <stdio.h>
#include <string.h>
void encryptDecrypt(char *input, char *output) {
char key[] = {'K', 'C', 'Q'}; //Can be any chars, and any size array
int i;
for(i = 0; i < strlen(input); i++) {
output[i] = input[i] ^ key[i % (sizeof(key)/sizeof(char))];
}
}
int main (int argc, char *argv[]) {
char baseStr[] = "kylewbanks.com";
char encrypted[strlen(baseStr)];
encryptDecrypt(baseStr, encrypted);
printf("Encrypted:%s\n", encrypted);
char decrypted[strlen(baseStr)];
encryptDecrypt(encrypted, decrypted);
printf("Decrypted:%s\n", decrypted);
}
The above works well under Linux and gcc.
However, it does not compile in Visual Studio under Windows.
I am using build tools included in Visual Studio 2017.
What am I doing wrong?

Microsoft's compiler does not support C99 VLAs (see the note here). Array sizes must be a constant expression. The code is also broken because it fails accommodate and place a nul terminator in the output.
In this case, decrypted and encrypted might be declared thus:
char encrypted[sizeof(baseStr)] ;
...
char decrypted[sizeof(baseStr)] ;
And encryptDecrypt() modified thus:
void encryptDecrypt(char *input, char *output) {
...
output[i] = 0 ;
}
Finally the signed mismatch warning may be cleaned up by declaring i as type size_t.
On Windows of course you could always use MinGW/GCC if you want more modern C support. Or you could use C++ and std::string or std::vector containers if you want to stick with Microsoft's compiler.

Use malloc for dynamic memory allocation. Requires #include <stdlib.h>
char baseStr[] = "123";
char *encrypted = malloc(strlen(baseStr) + 1);
...
free(encrypted);
As mentioned before, you have to add 1 for the null-terminated character at the end.
The char* pointer is one piece of information, it shows where the string begins. But where does it end? strlen and other C functions have no idea where the string ends, so they go through all the characters until a '\0' character is encountered.
For efficiency, take strlen(input) out of the loop and calculate it only once:
void encryptDecrypt(char *input, char *output)
{
char key[] = { 'K', 'C', 'Q' };
int keysize = sizeof(key);
size_t i;
size_t len = strlen(input);
for(i = 0; i < len; i++)
output[i] = input[i] ^ key[i % keysize];
output[len] = 0; //will be same as output[i] = 0;
}
The function int main should return zero. Note that this method cannot be described as "encryption" by modern standards. You can call it "obfuscation".

Related

MD5Convert to hex char in C

void MD5Convert(unsigned char* BufferMD5, unsigned char* DstMD5, int size)
{
unsigned char digest[16];
char buf[32];
int tmp_i;
int counter_DstMD5 = 0;
int i = 0;
//16 +16 = 32
char tmp_c[2];
for (i; i < size; i++)
{
tmp_i = BufferMD5[i];
//itoa(tmp_i, tmp_c, 16);
sprintf_s(tmp_c, "%02X", BufferMD5[i]);
DstMD5[counter_DstMD5] = tmp_c[0];
counter_DstMD5++;
DstMD5[counter_DstMD5] = tmp_c[1];
counter_DstMD5++;
}
}
visual studio give me this following message:
"Run-Time Check Failure #2 - Stack around the variable 'tmp_c' was corrupted."
the code above doesn't work with visual studio + c, I've tried everything, but it ends up overflowing somewhere.
Sorry if the question was poorly worded, but I couldn't find a possible alternative
see the code here
sprintf_s(tmp_c, "%02X", BufferMD5[i]);
You need 3 characters to store two-character string as you need to accommodate null terminating character. tmp_c is too short and you write outside its bounds.
char tmp_c[3];

XOR-Encryption works on Code blocks not on Visual Studio 2017

so I would like to encrypt my data when write into .txt file so I choose XOR-Encryption from this code:
Github
So when I run in code blocks it runs and shows this result:
Encrypted: :=.43*-:8m2$.a
Decrypted:kylewbanks.com0
Process returned 0 (0x0) execution time : 0.025 s
Press any key to continue.
But When I start use Visual Studio 2017 it shows this error:
Error (active) E0059 function call is not allowed in a constant expression
Which means I cant put variable when declaring an array, so is there any method for my encryption to work in VS2017.
I think the problems is when declare the variable using constant, anyway to force it or other encryption method that is easy to use, I wont need to be secure just to prevent plain text in file.
Anyway this is the only code:
#include <stdio.h>
#include <string.h>
void encryptDecrypt(char *input, char *output) {
char key[] = {'K', 'C', 'Q'}; //Can be any chars, and any size array
int i;
for(i = 0; i < strlen(input); i++) {
output[i] = input[i] ^ key[i % (sizeof(key)/sizeof(char))];
}
}
int main () {
char baseStr[] = "kylewbanks.com";
char encrypted[strlen(baseStr)];
encryptDecrypt(baseStr, encrypted);
printf("Encrypted:%s\n", encrypted);
char decrypted[strlen(baseStr)];
encryptDecrypt(encrypted, decrypted);
printf("Decrypted:%s\n", decrypted);
}
MSVC does not support Variable Length Arrays. One way round is to allocate the memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void encryptDecrypt(char *input, char *output) {
char key[] = {'K', 'C', 'Q'}; //Can be any chars, and any size array
size_t i;
for(i = 0; i < strlen(input); i++) {
output[i] = input[i] ^ key[i % (sizeof(key)/sizeof(char))];
}
output[i] = '\0'; // terminate
}
int main () {
char baseStr[] = "kylewbanks.com";
size_t len = strlen(baseStr) + 1;
char *encrypted = malloc(len);
if(encrypted == NULL) {
// error handling
}
encryptDecrypt(baseStr, encrypted);
printf("Encrypted:%s\n", encrypted);
char *decrypted = malloc(len);
if(decrypted == NULL) {
// error handling
}
encryptDecrypt(encrypted, decrypted);
printf("Decrypted:%s\n", decrypted);
free(decrypted);
free(encrypted);
}
Please note that an extra byte is needed for the string terminator - and the string should be terminated.

Producing uppercase letters without pointers

I am trying to write a function, uppercase, that converts all lowercase characters in a string into their uppercase equivalents.
However, I am getting a Bus 10 error in my code. I know that string literals cannot be modified in C; so, I am not sure if this is the right approach.
My code is below:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
int uppercase(char source[])
{
int i;
for(i=0; i<=strlen(source); ++i)
if (source[i]>= 'a' && source[i]<= 'z')
source[i]= source[i]-'a' +'A';
else
source[i]=source[i];
}
int main(){
uppercase("cold");
return 0;
}
Ideally this function should return COLD.I suppose the error lies in my whole if statement.
The reason you get a crash is that your code modifies a string literal. Characters inside string literals are placed in protected memory area, and therefore may not be changed: it us undefined behavior.
Replace this
uppercase("cold");
with this:
char cold[] = "cold";
uppercase(cold);
Now the characters of the string are placed in a modifiable area of memory, allowing you to make changes as needed.
Your absolutly working with pointers without even to know it.
In your function definition
int uppercase(char source[])
char source[] is considered by the compiler as a pointer to char (char *source)
So when passing a string literal to uppercase() your just passing it's adress. Then in your function your trying to modify it which leads to undefined behaviour.
Also you can't return a whole array so you just return a pointer to it.
char *uppercase(char source[])
{
int i;
size_t len = strlen(source);
char *tmp;
tmp = malloc(len+1);
if (tmp!=NULL){
memcpy(tmp, source, len+1);
for(i=0; i<len; ++i){
if (tmp[i]>= 'a' && tmp[i]<= 'z'){
tmp[i]= tmp[i]-'a' +'A';
}
}
}
return tmp;
}
Then:
int main(){
char *str = uppercase("cold");
printf("%s", str);
free(str);
return 0;
}
You complete code: http://ideone.com/BJHDIF

Error with mystrlen function

I was trying to write out some of the implementations of the string functions available in C. My code is:
#include <stdio.h>
#include <stdlib.h>
char *mystrcpy(char *s1, char *s2)
{
while(*s1++ = *s2++);
return s1;
}
int mystrlen(char *s)
{
int len = 0;
while(*s != '\0')
{
len++;
}
return len;
}
int main(void)
{
char arr = "Hi";
char arr1[10];
char arr2[] = "Hello";
int length;
mystrcpy(arr1, arr2);
printf("%s", arr1);
length = mystrlen(arr);
printf("%d", length);
return 0;
}
mystrcpy works fine, but the other method mystrlen does no execute. What could be the error? The following is the program termination note:
Process terminated with status -1073741510 (0 minutes, 4 seconds)
Also, there are few warnings related to casts. Is there any place in the code where I should be using any cast?
First, your mystrlen has an infinite loop.
Fixed code:
int mystrlen(const char *s)
{
int len = 0;
while (*s++ /* increment to next character every loop */ != '\0')
{
len++;
}
return len;
}
Also added const since you never change the data referred to by *s
Second, the assignment: char arr="Hi"; is not valid.
You are attempting to assign a char[] array to a char variable. The correct form would be one of the following:
char arr[]="Hi"; // array syntax
char *arr="Hi"; // pointer syntax
Given your invalid arr assignment, your runtime error is most likely caused by mystrlen attempting to incorrectly deference arr.
What compiler are you using? Most conforming compilers should have caught the second issue. If using GCC, add the -Wall flag to your makefile.
This:
char arr="Hi"; /* Should have caused compiler warning,
as is attempting to assign a char
to a char[3]. */
should be:
char arr[] ="Hi";
or:
char* arr = "Hi";

Declaring Pascal-style strings in C

In C, is there a good way to define length first, Pascal-style strings as constants, so they can be placed in ROM? (I'm working with a small embedded system with a non-GCC ANSI C compiler).
A C-string is 0 terminated, eg. {'f','o','o',0}.
A Pascal-string has the length in the first byte, eg. {3,'f','o','o'}.
I can declare a C-string to be placed in ROM with:
const char *s = "foo";
For a Pascal-string, I could manually specify the length:
const char s[] = {3, 'f', 'o', 'o'};
But, this is awkward. Is there a better way? Perhaps in the preprocessor?
I think the following is a good solution, but don't forget to enable packed structs:
#include <stdio.h>
#define DEFINE_PSTRING(var,str) const struct {unsigned char len; char content[sizeof(str)];} (var) = {sizeof(str)-1, (str)}
DEFINE_PSTRING(x, "foo");
/* Expands to following:
const struct {unsigned char len; char content[sizeof("foo")];} x = {sizeof("foo")-1, "foo"};
*/
int main(void)
{
printf("%d %s\n", x.len, x.content);
return 0;
}
One catch is, it adds an extra NUL byte after your string, but it can be desirable because then you can use it as a normal c string too. You also need to cast it to whatever type your external library is expecting.
GCC and clang (and possibly others) accept the -fpascal-strings option which allows you to declare pascal-style string literals by having the first thing that appears in the string be a \p, e.g. "\pfoo". Not exactly portable, but certainly nicer than funky macros or the runtime construction of them.
See here for more info.
You can still use a const char * literal and an escape sequence as its first character that indicates the length:
const char *pascal_string = "\x03foo";
It will still be null-terminated, but that probably doesn't matter.
It may sound a little extreme but if you have many strings of this kind that need frequent updating you may consider writing your own small tool (a perl script maybe?) that runs on the host system, parses an input file with a custom format that you can design to your own taste and outputs a .c file. You can integrate it to your makefile or whatever and live happily ever after :)
I'm talking about a program that will convert this input (or another syntax that you prefer):
s = "foo";
x = "My string";
To this output, which is a .c file:
const char s[] = {3, 'f', 'o', 'o'};
const char x[] = {9, 'M', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g'};
My approach would be to create functions for dealing with Pascal strings:
void cstr2pstr(const char *cstr, char *pstr) {
int i;
for (i = 0; cstr[i]; i++) {
pstr[i+1] = cstr[i];
}
pstr[0] = i;
}
void pstr2cstr(const char *pstr, char *cstr) {
int i;
for (i = 0; i < pstr[0]; i++) {
cstr[i] = pstr[i+1];
}
cstr[i] = 0;
}
Then I could use it this way:
int main(int arg, char *argv[]) {
char cstr[] = "ABCD", pstr[5], back[5];
cstr2pstr(cstr, pstr);
pstr2cstr(pstr, back);
printf("%s\n", back);
return 0;
}
This seems to be simple, straightforward, less error prone and not specially awkward. It may be not the solution to your problem, but I would recommend you to at least think about using it.
You can apply sizeof to string literals as well. This allows a little less awkward
const char s[] = {sizeof "foo" - 1u, 'f', 'o', 'o'};
Note that the sizeof a string literal includes the terminating NUL character, which is why you have to subtract 1. But still, it's a lot of typing and obfuscated :-)
One option might be to abuse the preprocessor. By declaring a struct of the right size and populating it on initialization, it can be const.
#define DECLARE_PSTR(id,X) \
struct pstr_##id { char len; char data[sizeof(X)]; }; \
static const struct pstr_##id id = {sizeof(X)-1, X};
#define GET_PSTR(id) (const char *)&(id)
#pragma pack(push)
#pragma pack(1)
DECLARE_PSTR(bob, "foo");
#pragma pack(pop)
int main(int argc, char *argv[])
{
const char *s = GET_PSTR(bob);
int len;
len = *s++;
printf("len=%d\n", len);
while(len--)
putchar(*s++);
return 0;
}
This is why Variable Length Arrays were introduced in c99 (and to avoid the use of the "struct hack") IIRC, Pascal-strings were limited to a maximal length of 255.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h> // For CHAR_BIT
struct pstring {
unsigned char len;
char dat[];
};
struct pstring *pstring_new(char *src, size_t len)
{
struct pstring *this;
if (!len) len = strlen(src);
/* if the size does not fit in the ->len field: just truncate ... */
if (len >=(1u << (CHAR_BIT * sizeof this->len))) len = (1u << (CHAR_BIT * sizeof this->len))-1;
this = malloc(sizeof *this + len);
if (!this) return NULL;
this->len = len;
memcpy (this->dat, src, len);
return this;
}
int main(void)
{
struct pstring *pp;
pp = pstring_new("Hello, world!", 0);
printf("%p:[%u], %*.*s\n", (void*) pp
, (unsigned int) pp->len
, (unsigned int) pp->len
, (unsigned int) pp->len
, pp->dat
);
return 0;
}
You can define an array in the way you like, but note that this syntax is not adequate:
const char *s = {3, 'f', 'o', 'o'};
You need an array instead of a pointer:
const char s[] = {3, 'f', 'o', 'o'};
Note that a char will only store numbers up to 255 (considering it's not signed) and this will be your maximum string length.
Don't expect this to work where other strings would, however. A C string is expected to terminate with a null character not only by the compiler, but by everything else.
Here's my answer, complete with an append operation that uses alloca() for automatic storage.
#include <stdio.h>
#include <string.h>
#include <alloca.h>
struct pstr {
unsigned length;
char *cstr;
};
#define PSTR(x) ((struct pstr){sizeof x - 1, x})
struct pstr pstr_append (struct pstr out,
const struct pstr a,
const struct pstr b)
{
memcpy(out.cstr, a.cstr, a.length);
memcpy(out.cstr + a.length, b.cstr, b.length + 1);
out.length = a.length + b.length;
return out;
}
#define PSTR_APPEND(a,b) \
pstr_append((struct pstr){0, alloca(a.length + b.length + 1)}, a, b)
int main()
{
struct pstr a = PSTR("Hello, Pascal!");
struct pstr b = PSTR("I didn't C you there.");
struct pstr result = PSTR_APPEND(PSTR_APPEND(a, PSTR(" ")), b);
printf("\"%s\" is %d chars long.\n", result.cstr, result.length);
return 0;
}
You could accomplish the same thing using c strings and strlen. Because both alloca and strlen prefer short strings I think that would make more sense.

Resources