0

Here is my code for the implementation of load, lookup, parse and indexes.

char* indexes(const char* path)
{
    char* full_path = malloc(strlen(path) + strlen("/index.html") + 1);

    strcpy(full_path, path);
    strcat(full_path, "/index.html");

    if (access(full_path, F_OK) != -1)
    {
        return full_path;
    }

    else 
    {
        strcpy(full_path, path);
        strcat(full_path, "/index.php");

        if (access(full_path, F_OK) != -1)
        {
            return full_path;
        }
    }

    return NULL;
}


const char* lookup(const char* path)
{
    char* extension = strchr(path, '.');
    extension++;                           //Shift pointer to beginning of extension

    if (extension != NULL)
    {
        if (strcasecmp(extension, "css") == 0)
        {
            return "text/css";
        }

        else if (strcasecmp(extension, "html") == 0)
        {
            return "text/html";
        }

        else if (strcasecmp(extension, "gif") == 0)
        {
            return "image/gif";
        }

        else if (strcasecmp(extension, "ico") == 0)
        {
            return "image/x-icon";
        }

        else if (strcasecmp(extension, "jpg") == 0)
        {
            return "image/jpeg";
        }

        else if (strcasecmp(extension, "js") == 0)
        {
            return "text/javascript";
        }

        else if (strcasecmp(extension, "php") == 0)
        {
            return "text/x-php";
        }

        else if (strcasecmp(extension, "png") == 0)
        {
            return "image/png";
        }

        else return NULL;
    }

    return NULL;
}


bool parse(const char* line, char* abs_path, char* query)
{

    int i, len = strlen(line);

    char line_cpy[len + 1];                 //make a copy of line for tokenising using strtok
    strcpy(line_cpy, line);

    char* method = strtok(line_cpy, " ");

    if (strcmp(method, "GET") != 0)
    {
        error(405);
        return false;
    }

    char* request_target = strtok(NULL, " ");

    if (request_target[0] != '/')
    {
        error(501);
        return false;
    }

    int tar_len;

    for (i = 0, tar_len = strlen(request_target); i < tar_len; i++)
    {
        if (request_target[i] == '"')
        {
            error(400);
            return false;
        }
    }

    char* version = strtok(NULL, " ");

    if (strcmp(version, "HTTP/1.1\r\n") != 0)
    {
        error(505);
        return false;
    }

    for (i = 0; request_target[i] != '?' && request_target[i] != '\0'; i++)
    {
        abs_path[i] = request_target[i];          //copy absolute path into abs_path
    }

    if (request_target[i] == '\0')
    {
        return true;
    }

     else if (request_target[i] == '?')
    {
        int j;
        i++;                                      //increment counter to first character of query
        for (j = 0; request_target[i] != '\0'; i++, j++)
        {
            query[j] = request_target[i];
        }

        query[j] = '\0';
    }

    return true;
}


bool load(FILE* file, BYTE** content, size_t* length)
{

    char* data = malloc(sizeof(BYTE));
    int i = 0;                               //count for number of bytes allocated
    int c;

    while ((c = fgetc(file)) != EOF)
    {
        data[i] = (char)c;
        i++;
        data = realloc(data, (sizeof(BYTE) * (i + 1)));
    }

    *content = data;                   //store address of memory in *content
    *length = i;                       //store length of memory in *length

    return true;
}

I'm having a lot of trouble debugging this program and running valgrind tells me there's an uninitialised use of strlen which I'm not able to find and also 48 bytes of memory definitely lost. Any help would be appreciated with regards to this.

$ valgrind ./server public
==18113== Memcheck, a memory error detector
==18113== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==18113== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==18113== Command: ./server public
==18113== 
Using /home/ubuntu/workspace/pset6/public for server's root
Listening on port 8080
GET / HTTP/1.1
HTTP/1.1 200 OK
GET /favicon.ico HTTP/1.1
HTTP/1.1 200 OK
GET /cat.jpg HTTP/1.1
HTTP/1.1 200 OK
GET /hello.php HTTP/1.1
==18113== Conditional jump or move depends on uninitialised value(s)
==18113==    at 0x4C2E0E9: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18113==    by 0x403181: interpret (server.c:486)
==18113==    by 0x401BC1: main (server.c:255)
==18113==  Uninitialised value was created by a stack allocation
==18113==    at 0x401524: main (server.c:73)
==18113== 
==18113== Conditional jump or move depends on uninitialised value(s)
==18113==    at 0x5188943: vfprintf (vfprintf.c:1661)
==18113==    by 0x51AD8FA: vsprintf (iovsprintf.c:42)
==18113==    by 0x5191506: sprintf (sprintf.c:32)
==18113==    by 0x4031B5: interpret (server.c:487)
==18113==    by 0x401BC1: main (server.c:255)
==18113==  Uninitialised value was created by a stack allocation
==18113==    at 0x401524: main (server.c:73)
1

"48 bytes of memory definitely lost could be from indexes. full_path is not freed if neither file is found. (Review the spec for the order in which the files should be returned).

If you use valgrind command valgrind -v --leak-check=full --show-leak-kinds=all --track-origins=yes ./server ./public it should help you find "an uninitialised use of strlen"

It looks like abs_path is not properly null-terminated.

It looks like if there is not query, query is not stored according to the spec.

If that substring is absent (even if a ? is present), then query should be "", thereby consuming one byte, whereby query[0] is '\0'

There are tips on using gdb/debug50 with server here.

9
  • Fixed it and it seems to be working but running valgrind tells me there is still some other uninitialised use of strlen. Any insight?
    – user34304
    Feb 17 '17 at 18:06
  • Not without seeing valgrind result. Feb 17 '17 at 18:10
  • give me 5 minutes
    – user34304
    Feb 17 '17 at 18:11
  • how to copy paste terminal output?
    – user34304
    Feb 17 '17 at 18:14
  • The usual way, select with the mouse, ctrl-c copy. Then you could edit the question and paste it in. Feb 17 '17 at 18:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .