Program triggers assert when returning from main

0

I genuinely can't figure this out. When I run this program in the debugger, it all works until the final line, which contains return 0;. For some reason I can't figure out, it causes an exception in the Visual Studio debugger when going past a breakpoint I put on it. When running the executable from the command line without VS, a vague assertion is triggered. Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "..\sui.h"

typedef struct {
    char* data;
} string;

string GetDataFromDictionary(char* dict, char* dividor, int index) {
    char* r1 = calloc(20, 1);

    if (!r1) {
        printf("Calloc() failed!");
        exit(EXIT_FAILURE);
    }

    r1 = strstr(dict, dividor);
    for (int i = 0; i < index - 1; i++) {
        r1 = strstr(&r1[1], dividor);
    }

    char* r2 = calloc(20, 1);

    if (!r2) {
        printf("Calloc() failed!");
        exit(EXIT_FAILURE);
    }

    strcpy(r2, strstr(dict, dividor));
    for (int i = 0; i < index - 1 + 1; i++) {
        strcpy(r2, strstr(&r2[1], dividor));
    }

    int len = strlen(r1) - strlen(r2) - 1;

    string r;
    r.data = calloc(30, 1);

    if (!r.data) {
        printf("Calloc() failed!");
        exit(EXIT_FAILURE);
    }

    strncpy(r.data, &r1[1], len);

    return r;
}


int GetCountOfDictionaryValues(char* dict) {
    int charcount;

    charcount = 0;
    for (int i = 0; dict[i]; i++) {
        if (dict[i] == '~') {
            charcount++;
        }
    }

    return charcount - 1;
}

int main(int argc, char* argv[]) {
    // Read file
    char  ch;

    FILE* fp = fopen(argv[1], "r"); // Nice

    if (argc != 2) {
        printf("Invalid argument count! Expected 1 argument, got %i", argc - 1);
        exit(EXIT_FAILURE);
    }

    if (fp == NULL) {
        printf("Error while opening the file.\n");
        exit(EXIT_FAILURE);
    }

    int i = 0;
    char* buf = calloc(20000, 1);

    if (!buf) {
        printf("Calloc() failed!");
        exit(EXIT_FAILURE);
    }

    while ((ch = fgetc(fp)) != EOF) {
        buf[i] = ch;
        i++;
    }

    fclose(fp);

    // Organise data

    char* parsedata = calloc(10000, 2);

    if (parsedata == NULL) {
        printf("Calloc() failed!");
        exit(EXIT_FAILURE);
    }

    parsedata[0] = '~';

    for (int x = 1, o = 1; x < (int)strlen(buf); x++) {
        if (buf[x-o] == ' ') {
            parsedata[x] = '~';
        } else if (buf[x - o] == ';') {
            parsedata[x] = '~';
        } else if (buf[x - o] == '\n') {
            o--;
            x--;
        } else {
            if (buf[x - o] < 91 && buf[x - o] > 64) {
                parsedata[x] = buf[x - o] + ' ';
            } else {
                parsedata[x] = buf[x - o];
            }
        }
    }

    // Execute stuff :D

    SUIInit(INPUT_KEYBOARD);

    string rip;
    rip.data = calloc(30, 1);

    if (!rip.data) {
        printf("Calloc() failed!");
        exit(EXIT_FAILURE);
    }
    
    for (int i = 1; i < GetCountOfDictionaryValues(parsedata) + 1; i++) {
        strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
        
        if (!strcmp(rip.data, "movecursor")) {
            strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i + 1).data);
            int x = 0;
            int y = 0;
            char* e;
            int index = 0;

            e = strchr(rip.data, 'x');
            index = (int)(e - rip.data);


            e = calloc(30, 1);
            if (!e) {
                printf("Calloc() failed!");
                exit(EXIT_FAILURE);
            }

            strncpy(e, rip.data, index);
            e[19] = 0;

            x = atoi(e);

            free(e);

            e = calloc(30, 1);
            if (!e) {
                printf("Calloc() failed!");
                exit(EXIT_FAILURE);
            }

            for (int i = 0; i < 4; i++) {
                e[i] = 0;
            }

            strncpy(e, &rip.data[index + 1], strlen(rip.data));
            e[19] = 0;

            y = atoi(e);

            SUIInit(INPUT_MOUSE);

            SUIMoveCursor(x, y);

            SUIInit(INPUT_KEYBOARD);

            free(e);

            strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
        } else if (!strcmp(rip.data, "presskey")) {
            strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i + 1).data);

            char key = atoi(rip.data) - 32;

            if (rip.data[0] > 65) {
                key = rip.data[0];
                if (key > 96 && key < 123) {
                    key -= 32;
                }
            }

            SUIPressKey(key);
            // 200 lines D:
            strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
        } else if (!strcmp(rip.data, "click")) {
            strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i + 1).data);

            SUIInit(INPUT_MOUSE);

            if (!strcmp(rip.data, "left")) {
                SUIClickMouse(MOUSE_LEFT_CLICK);
            } else if (!strcmp(rip.data, "right")) {
                SUIClickMouse(MOUSE_RIGHT_CLICK);
            } else {
                printf("Invalid mouse button \"%s\"! Terminating program...", rip.data);
                exit(EXIT_FAILURE);
            }
            
            SUIInit(INPUT_KEYBOARD);

            strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
        }
    }

    free(rip.data);
    free(buf);
    free(parsedata);

    return 0;
}

SUI.h:

// Single-Header Library for Simulating user input
// Putting it on GitHub so i can always download 
// it if I get a new computer

#pragma once

// Defines so you dont have to remember left and right click are 1 and 2
#define MOUSE_LEFT_CLICK 1
#define MOUSE_RIGHT_CLICK 2

// Include Windows.h, wont work on unix systems ¯\_(ツ)_/¯
#ifndef _WINDOWS_
#include <Windows.h>
#endif

#ifdef __cplusplus
class SUI {
private:
    // Input variable, private so nobody changes it without Init().
    INPUT _input;
public:
    // Function for initializing SUI
    void Init(int mode) {
        if (mode > 1) {
            return;
        }
        _input.type = mode;
        if (mode == 0) {
            _input.mi.time = 0;
            _input.mi.mouseData = 0;
            _input.mi.dwExtraInfo = 0;
        }

        if (mode == 1) {
            _input.ki.wScan = 0;
            _input.ki.time = 0;
            _input.ki.dwExtraInfo = 0;
        }
    }

    // Moving cursor pos. its just SetCursorPos, but it would have been weird if we didnt have something for this ¯\_(ツ)_/¯
    void MoveCursor(int x, int y) {
        SetCursorPos(x, y);
    }

    // Click mouse button
    void ClickMouse(int button) {
        if (button == 1) {
            _input.mi.dwFlags = 2;
            SendInput(1, &_input, sizeof(INPUT));
            _input.mi.dwFlags = 4;
            SendInput(1, &_input, sizeof(INPUT));
        } else
            if (button == 2) {
                _input.mi.dwFlags = 8;
                SendInput(1, &_input, sizeof(INPUT));
                _input.mi.dwFlags = 10;
                SendInput(1, &_input, sizeof(INPUT));
            } else {
                return;
            }
    }

    // Keyboard input
    void PressKey(int keycode) {
        if (_input.type == 0) {
            return;
        }
        _input.ki.wVk = keycode;
        _input.ki.dwFlags = 0;
        SendInput(1, &_input, sizeof(INPUT));

        _input.ki.dwFlags = KEYEVENTF_KEYUP;
        SendInput(1, &_input, sizeof(INPUT));
    }
};
#else

// Input variable
INPUT _input;

// Function for initializing SUI
void SUIInit(int mode) {
    if (mode > 1) {
        return;
    }
    _input.type = mode;
    if (mode == 0) {
        _input.mi.time = 0;
        _input.mi.mouseData = 0;
        _input.mi.dwExtraInfo = 0;
    }

    if (mode == 1) {
        _input.ki.wScan = 0;
        _input.ki.time = 0;
        _input.ki.dwExtraInfo = 0;
    }
}

// Moving cursor pos. its just SetCursorPos, but it would have been weird if we didnt have something for this ¯\_(ツ)_/¯
void SUIMoveCursor(int x, int y) {
    SetCursorPos(x, y);
}

// Click mouse button
void SUIClickMouse(int button) {
    if (button == 1) {
        _input.mi.dwFlags = 2;
        SendInput(1, &_input, sizeof(INPUT));
        _input.mi.dwFlags = 4;
        SendInput(1, &_input, sizeof(INPUT));
    } else
        if (button == 2) {
            _input.mi.dwFlags = 8;
            SendInput(1, &_input, sizeof(INPUT));
            _input.mi.dwFlags = 10;
            SendInput(1, &_input, sizeof(INPUT));
        } else {
            return;
        }
}

// Keyboard input
void SUIPressKey(int keycode) {
    if (_input.type == 0) {
        return;
    }
    _input.ki.wVk = keycode;
    _input.ki.dwFlags = 0;
    SendInput(1, &_input, sizeof(INPUT));

    _input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1, &_input, sizeof(INPUT));
}

#endif

And here is the exception caused:

Exception thrown at 0x779C8215 (ntdll.dll) in Macrotool32.exe: 0xC0000005: Access violation reading location 0x66656C7E.

And a screenshot of the assert triggered: Assertion

c
windows
asked on Stack Overflow May 22, 2021 by Finxx • edited May 22, 2021 by Finxx

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0