chttphttpserverstrncpy

Using sizeof(pointer) with strncpy


I have this parser, I want to use the size of the pointer (that is 8 bytes) in the function strncpy, I was able do it with the "method" part, why does it crash the "path" part ?

It tells me Segmentation fault (core dumped) in the path part, so it does not have the authorization?

Am I missing something ?

int http_parser(char *request) {

    char tmp_request[BUFFER_SIZE];
   
    char *method;
    char *path;
       
    strncpy(tmp_request, request, sizeof(tmp_request));

    char *token = strtok(tmp_request, " ");

    if (token == NULL) {
        printf("\nInvalid Request Format!");
        return 0;
    }

    //METODO
    strncpy(method, token, sizeof(method));
  
    token = strtok(NULL, " ");
    //printf("METODO!\n");
    if (token == NULL) {
        printf("Invalid Request Method!\n"); 
        return 0;
    } else {
        printf("Metodo : %s\n",method);
    }

    //path
    strncpy(path, token, sizeof(path));
    token = strtok(NULL, " ");

    printf("PATH\n");
    if (token == NULL) {
        printf("Invalid Request Path\n");
        return 0;
    } else {
        printf("Path : %s\n",path);
    }
}

I tried using sizeof(8) and it works, but I want to know why it doesn't work when I do it this way.


Solution

  • There are several errors here.

    First, method and path are uninitialized and therefore don't point to a valid buffer. Using strncpy to write into them triggers undefined behavior in your code. In the first case it appears to work properly while in the second case it causes a crash.

    Second, sizeof(method) and sizeof(path) give you the size of a pointer (most likely 8), while you probably want the size of the buffer.

    If you were to fix this by making them arrays:

    char method[BUFFER_SIZE];
    char path[BUFFER_SIZE];
    

    This would give you space to write to, and the above sizeof expressions would give you a proper value.

    This still isn't entirely proper however, as strncpy doesn't null-terminate the destination string in all cases, meaning you'd have to manually add one in the array's last element. In this particular case though it isn't required because the source string is known to be smaller than the destination so the null termination will in fact happen.

    All that being said, you don't actually have to copy anything at all. Since strtok inserts null bytes into the source string to tokenize it, you can simply use pointers instead of arrays and just point them to the proper places in the source.

    int http_parser(char *request) {
    
        char tmp_request[BUFFER_SIZE];
    
        char *method;
        char *path;
    
        strncpy(tmp_request, request, sizeof(tmp_request));
    
        char *token = strtok(tmp_request, " ");
    
        if (token == NULL) {
            printf("\nInvalid Request Format!");
            return 0;
        }
    
        method = token;
        printf("Method : %s\n",method);
    
        token = strtok(NULL, " ");
        if (token == NULL) {
            printf("Invalid Request Path\n");
            return 0;
        }
    
        path = token;
        printf("Path : %s\n",path);
    }