I'm writing a proxy server, and I ran into a curious bug that I hoped someone would be able to explain.
I'm receiving the first line of a GET request from client. For example, the client would send the request:
GET http://en.wikipedia.org/wiki/Special:Random HTTP/1.0
Host: en.wikipedia.org
...
And I would forward this request to the server.
However, with certain web addresses, I would encounter a problem:
GET http://map.media6degrees.com/orbserv/curl=http%3A%2F%2Fwww.masteringemacs.org%2Farticles[trunc] HTTP/1.0
I read this line into char buffer[MAXLINE_LENGTH]
, which is long enough to hold the string.
When I print the received get request with
printf(buffer);
The printed string is:
GET http://map.media6degrees.com/orbserv/hbpix?pixId=2869&curl=http0X0.0000000000015P-10220.0000000.000000www.masteringemacs.org0.000000articles0.00000020100.000000110.000000010.000000running-shells-in-emacs-overview204741995430849962482228271154502456423284733956118041206315879167624419264810411254941012469231829496710329852458403099883653794777355548418601638730167027236864.000000 HTTP/1.0
It appears the %3A, %2F, etc. have been string formatted.
When I run printf("%s", buffer);
, I get the correct and expected output
EDIT: I understand why this is occurring; I'm interested in why this is occurring this way. Are the values that printf is "string formatting" coming from some arbitrary area on the stack? Are the %3A et al valid format strings?
1) If you look at the function prototype, you'll see that printf() expects a format string, and zero or more arguments. So, strictly speaking, "printf(string)" is not correct:
SYNOPSIS
#include <stdio.h>
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format,
...);
2) The first argument will be interpreted as a format string, and any "%XXX" entries it found will be interpreted as place holders. Which it sounds like is exactly what's happening :)
3) The solution, of course, is printf ("%s", string)
4) Or using puts(string)
instead :)
Never use an input string as a format parameter to printf.
To work correctly, it must have no "%..." items. These are special commands to the printf() function to access the parameters list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With