0

I'm working on parse for pset6 and for some reason I can't correctly check the HTTP version. Check50 gives me "\ expected output, not an exit code of 0" which I understand stands for segmentation fault. My code:

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

//check for more than 2 spaces in line
int spaces = 0;
for (int i = 0, lenght = strlen(line); i < lenght; i++)
{
    if (line[i] == ' ')
    spaces++;

    if (spaces > 2)
    {
        error(400);
        return false;
    }
}

//check for method
if (strncmp (line, "GET ", 4) != 0)
{
    error(405);
    return false;
}

//check for '/' at the start request target
char* SP = strchr(line, ' ');
if (SP[1] != '/')
{
    error(501);
    return false;
}

//check for " in the request target
//otherwise copy to abs_path
int iter = 1;
while (SP[iter] != ' ' || SP[iter] != '?')
{
    if (SP[iter] == '"')
    {
        error(400);
        return false;
    }
    strncpy(&abs_path[iter - 1], &SP[iter], 1);
    iter++;

}

//if query exists, copy to query
if (SP[iter] == '?' && SP[iter+1] == '=')
{
    int query_iter = 0;
    while (SP[iter] != ' ')
    {
        strncpy(&query[query_iter], &SP[iter], 1);
        iter++;
        query_iter++;
    }
}

//check for http version
SP = strrchr(line, ' ');
if (strncmp(SP, "HTTP/1.1", 8) != 0)
{
    error(505);
    return false;
}



error(501);
return false;
}

From check50:

:) server.c exists
:) server compiles
:( HTTP/1.0 returns error code 505
\ expected output, not an exit code of 0
:) Method of 'abcGET' returns error code 405
:) Method of 'GETabc' returns error code 405
:) request-target without starting '/' returns error code 501
:) request-target of abc/hello.php returns error code 501
:( Requesting cat.exe returns error code 501
\ expected output, not an exit code of 0
:( Requesting non-existant file returns error code 404
\ expected output, not an exit code of 0
:) Requesting request-target with " returns error code 400
:) Two spaces after GET returns error code
:) A space within the request target returns error code
:) Two spaces before HTTP/1.1 returns error code

I know there are two more errors, yet I chose to adress the HTTP first. Any help will be appreciated.

1

When will it stop? The while loop that is. When this (SP[iter] != ' ' || SP[iter] != '?') is false. When is this (SP[iter] != ' ' || SP[iter] != '?') false? Never. If SP[iter] is space then SP[iter] != ' ' is false and SP[iter] != '?' is true. false || true is true. And versa vice. Your segfault eventually occurs here strncpy(&abs_path[iter - 1], &SP[iter], 1);. Take it for a spin through gdb to see for yourself.

Speaking of strncpy(&abs_path[iter - 1], &SP[iter], 1);, it is much more complicate than it need be. Consider that abs_path[iter - 1] = SP[iter]; would accomplish the same thing. And don't forget to null-terminate abs_path.

Spoiler alert: this will not pass the query tests coming up in check50/server2 because of this
if (SP[iter] == '?' && SP[iter+1] == '='). A properly formed query will look like this ?name=Alice. And don't forget to null-terminate query.

5
  • Thanks, I never thought to check the while function itself. I have now passed all of check50 tests exept the one for non-existing file and 404 error (I get 501 not implemented), which is strange for me, since there is no error 404 in the parse function. Does it depend on the load or indexes implementation?
    – Kuba
    Jul 21 '16 at 11:49
  • That's a common problem when abs_path is not properly null-terminated. Jul 21 '16 at 12:46
  • I used abs_path[iter - 1] = '\0'; after the while loop to NUL-terminate the abs_path, which doesn't seem to be working. Is there some special way to nul-terminating strings that I should be looking for?
    – Kuba
    Jul 21 '16 at 13:55
  • No special way. Must be in the right place. Your eyes are much better debug tools than mine. If you find gdb too challenging, time to add printfs. I like to use "%s<-\n" as the format string, to make sure there are not non-printing characters that would make abs_path look right on the terminal, but still fail checks. Jul 21 '16 at 15:20
  • Well, looks like the nul byte is placed correctly. I checked with various printfs (including your suggestion, and value of iter indicates \0 will be in the right place. It also 'cuts off' anything from previous requests, so I think it works just right and error must be somewhere else.
    – Kuba
    Jul 21 '16 at 22:45

You must log in to answer this question.

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