mardi 2 novembre 2021

program crash after calling random function [duplicate]

I'm currently working on a https server based on the "simple" example provided by esp idf. I want to provide a login function, in which a client sends me login data via a POST request and receives a bearer token(64 character big random generated alphanumeric value) as a answer.

To generate a alphanumeric random Number(found tons of examples online) i implemented a function which is called within the request handler. After copying a few randomgenerators(every single one caused a programcrash) i noticed that the problem might not lay on the function itself.

Important to mention would be, that both functions are not within the same .c file. For readabillity I splitt functions by usecase. Server-relevant functions are within my main.c file and the rest is in a file named functions.c

// My Main.c file

static char *bearerToken;

static esp_err_t post_login_handler(httpd_req_t *req)
{      
    
////////////////this part is used to parse the incoming username and password in JSON format////////////
    char content[150]; 

    size_t recv_size = MIN(req->content_len, sizeof(content));

    httpd_req_recv(req, content, recv_size);

    cJSON *root = cJSON_Parse(content);

    char *username = cJSON_GetObjectItem(root, "Username")->valuestring;
    char *password = cJSON_GetObjectItem(root, "Password")->valuestring;
////////////////////////////////////////////////////////////////////////////////////////

    bearerToken = tokenrandomizer(bearerToken, 64);
    
      httpd_resp_set_type(req, "text/html");
      httpd_resp_send(req, bearerToken, HTTPD_RESP_USE_STRLEN);

    return ESP_OK;
}

and here is my random generator function

//function.c file

char *tokenrandomizer();
const char charset[62] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456798";

char *tokenrandomizer(char *s, size_t len)
{
    
    for (int i = 0; i < len; ++i) {
        s[i] = charset[rand() % (sizeof(charset) - 1)]; //this is my line 32
    }

    s[len] = 0;

    return s;
}

as error i receive this message:

Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled. Core 0 register dump: PC : 0x400872c3 PS : 0x00060130 A0 : 0x80087308 A1 : 0x3ffdf230 0x400872c3: tokenrandomizer at C:\Users\Student\esp\esp-idf\components\esp_https_server\include\simple\build/../main/Funktionen.c:32 (discriminator 3) Blockquote

followed by other error messages. After receiving those messages my ESP32 reboots and if I call the same function again everything repeats.

Would be grateful for some advice! thanks!

Edit:

My 2 complete files looks like this:

/* Simple HTTP + SSL Server Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

//////////////main.c////////////////////
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include "esp_netif.h"
#include "esp_eth.h"
#include "protocol_examples_common.h"

#include <esp_https_server.h>

#include "cjson.h"

#include "Funktionen.c"

/* A simple example that demonstrates how to create GET and POST
 * handlers and start an HTTPS server.
*/

static const char *TAG = "example";
static char *username_login = "admin";
static char *password_login = "admin";
static char *bearerToken;



static esp_err_t post_login_handler(httpd_req_t *req)
{      
    

    char content[150]; 

    size_t recv_size = MIN(req->content_len, sizeof(content));

    httpd_req_recv(req, content, recv_size);

    cJSON *root = cJSON_Parse(content);

    char *username = cJSON_GetObjectItem(root, "Username")->valuestring;
    char *password = cJSON_GetObjectItem(root, "Password")->valuestring;

    bearerToken = tokenrandomizer(bearerToken, 64);

    
      httpd_resp_set_type(req, "text/html");
      httpd_resp_send(req, bearerToken, HTTPD_RESP_USE_STRLEN);

    return ESP_OK;
}

static esp_err_t root_get_handler(httpd_req_t *req)
{
    httpd_resp_set_type(req, "text/html");
    httpd_resp_send(req, "<h1>Hello Secure World!</h1>", HTTPD_RESP_USE_STRLEN);

    return ESP_OK;
}

static esp_err_t status_get_handler(httpd_req_t *req)
{
    httpd_resp_set_type(req, "text/html");
    httpd_resp_send(req, "<h1>Hello Secure World!</h1>", HTTPD_RESP_USE_STRLEN);

    return ESP_OK;

}

static esp_err_t command_on_post_handler(httpd_req_t *req)
{
    char* urlCommand = req->uri;
    int boxNumber;


    strtok(urlCommand, "/");

    for(int i = 0; i<= 1 ; i++){
        urlCommand = strtok(NULL, "/");
    }
    
    boxNumber = atoi(urlCommand);

    if(boxNumber == 0){

    httpd_resp_set_type(req, "text/html");
    httpd_resp_send(req, "Please Enter a valid URL", HTTPD_RESP_USE_STRLEN);
        return ESP_OK;
    }

    httpd_resp_set_type(req, "text/html");
    httpd_resp_send(req, urlCommand, HTTPD_RESP_USE_STRLEN);

    return ESP_OK;

}

static esp_err_t command_off_post_handler(httpd_req_t *req)
{
    char* urlCommand = req->uri;
    int boxNumber;


    strtok(urlCommand, "/");

    for(int i = 0; i<= 1 ; i++){
        urlCommand = strtok(NULL, "/");
    }
    
    boxNumber = atoi(urlCommand);

    if(boxNumber == 0){

    httpd_resp_set_type(req, "text/html");
    httpd_resp_send(req, "Please Enter a valid URL", HTTPD_RESP_USE_STRLEN);
        return ESP_OK;
    }

    httpd_resp_set_type(req, "text/html");
    httpd_resp_send(req, urlCommand, HTTPD_RESP_USE_STRLEN);

    return ESP_OK;
}

static const httpd_uri_t postLogin = {
    .uri       = "/login",
    .method    = HTTP_POST,
    .handler   = post_login_handler
};

static const httpd_uri_t getStatus = {
    .uri       = "/status",
    .method    = HTTP_GET,
    .handler   = status_get_handler
};

static const httpd_uri_t postCommandOn = {
    .uri       = "/command/on/*",
    .method    = HTTP_POST,
    .handler   = command_on_post_handler
};

static const httpd_uri_t postCommandOff = {
    .uri       = "/command/off/*",
    .method    = HTTP_POST,
    .handler   = command_off_post_handler
};

static const httpd_uri_t root = {
    .uri       = "/",
    .method    = HTTP_GET,
    .handler   = root_get_handler
};


static httpd_handle_t start_webserver(void)
{
    httpd_handle_t server = NULL;

    // Start the httpd server
    ESP_LOGI(TAG, "Starting server");

    httpd_ssl_config_t conf = HTTPD_SSL_CONFIG_DEFAULT();


    extern const unsigned char cacert_pem_start[] asm("_binary_cacert_pem_start");
    extern const unsigned char cacert_pem_end[]   asm("_binary_cacert_pem_end");
    conf.cacert_pem = cacert_pem_start;
    conf.cacert_len = cacert_pem_end - cacert_pem_start;

    extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
    extern const unsigned char prvtkey_pem_end[]   asm("_binary_prvtkey_pem_end");
    conf.prvtkey_pem = prvtkey_pem_start;
    conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;


    esp_err_t ret = httpd_ssl_start(&server, &conf);
    if (ESP_OK != ret) {
        ESP_LOGI(TAG, "Error starting server!");
        return NULL;
    }

    // Set URI handlers
    ESP_LOGI(TAG, "Registering URI handlers");
    httpd_register_uri_handler(server, &root);
    httpd_register_uri_handler(server, &getStatus);
    httpd_register_uri_handler(server, &postCommandOff);
    httpd_register_uri_handler(server, &postCommandOn);
    httpd_register_uri_handler(server, &postLogin);
    return server;
}

static void stop_webserver(httpd_handle_t server)
{
    // Stop the httpd server
    httpd_ssl_stop(server);
}

static void disconnect_handler(void* arg, esp_event_base_t event_base,
                               int32_t event_id, void* event_data)
{
    httpd_handle_t* server = (httpd_handle_t*) arg;
    if (*server) {
        stop_webserver(*server);
        *server = NULL;
    }
}

static void connect_handler(void* arg, esp_event_base_t event_base,
                            int32_t event_id, void* event_data)
{
    httpd_handle_t* server = (httpd_handle_t*) arg;
    if (*server == NULL) {
        *server = start_webserver();
    }
}

void app_main(void)
{
    static httpd_handle_t server = NULL;

    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    /* Register event handlers to start server when Wi-Fi or Ethernet is connected,
     * and stop server when disconnection happens.
     */

#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
    ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET

    /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
     * Read "Establishing Wi-Fi or Ethernet Connection" section in
     * examples/protocols/README.md for more information about this function.
     */
    ESP_ERROR_CHECK(example_connect());
}

//////////////function.c////////////////////
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include "esp_netif.h"
#include "esp_eth.h"
#include "protocol_examples_common.h"

#include <esp_https_server.h>

bool is_authorized();
char *tokenrandomizer();
const char charset[62] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456798";
// char letters[65]= {"a","b","c","d","e","f","g","h","i","j","k","l","m",
// "n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E",
// "F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W",
// "X","Y","Z","1","2","3","4","5","6","7","8","9","0"};



bool is_authorized(){

    return true;
}

char *tokenrandomizer(char *s, size_t len)
{
    
    for (int i = 0; i < len; ++i) {
        s[i] = charset[rand() % (sizeof(charset) - 1)];
    }

    s[len] = 0;

    return s;
}



Aucun commentaire:

Enregistrer un commentaire