Search code examples
htmlc++scanfcgi

sscanf ignoring "&" and scanning past where it is supposed to


I am using a .cpp file I compiled to run as a .cgi file on my website, receiving data from a web form, which it then runs sscanf() on to get the data extracted from the formatting that was sent in.

However, when the data is passed in and parsed, the first string takes all of the input past where it is supposed to.

My CPP file:

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

int main(void) {
  printf("Content-Type: text/plain;charset=us-ascii\n\n");
  printf("Hello world\n\n");
  char* data;
  data = getenv("QUERY_STRING");

  char name [50];
  int port;
  int id;
  char config[50];
  sscanf(data, "Name=%s&Port=%d&ID=%d&Config=%s", &name, &port, &id, &config);
  printf("%s", name);
  return 0;
}

The data variable is Name=ss&Port=8081&ID=0&Config=testconfig.

My expected output:

Hello world

ss

My actual output:

Hello world

ss&Port=8081&ID=0&Config=testconfig

Any ideas why it ignores the & and continues putting all the data into that variable?

So far, I have tried changing the data types of both data and name to std::string, but still had no luck.


Solution

  • %s is greedy. Since you are not telling it where to stop, it will just keep grabbing input until either a whitespace character or the null terminator is reached (which in your case is the latter).

    Use %[^&] instead. %[] is like %s except that it will only grab or ignore just the characters you specify. This way, you can tell scanf() to stop reading input when the & character is reached.

    Either way, you should always specify buffer widths to avoid overflows.

    Try this:

    sscanf(data, "Name=%49[^&]&Port=%d&ID=%d&Config=%49s", &name, &port, &id, &config);