我正在编写一个代理服务器,我遇到了一个奇怪的错误,我希望有人可以解释。
我收到了客户端GET请求的第一行。例如,客户端将发送请求:
GET http://en.wikipedia.org/wiki/Special:Random HTTP/1.0
Host: en.wikipedia.org
...
我会将此请求转发给服务器。
但是,对于某些网址,我会遇到一个问题:
GET http://map.media6degrees.com/orbserv/curl=http%3A%2F%2Fwww.masteringemacs.org%2Farticles[trunc] HTTP/1.0
我将此行读入char buffer[MAXLINE_LENGTH]
,该行足以容纳字符串。
当我用
打印收到的获取请求时printf(buffer);
打印的字符串是:
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
看来%3A,%2F等已经过字符串格式化。
当我运行printf("%s", buffer);
时,我得到了正确的预期输出
答案 0 :(得分:7)
1)如果你看一下函数原型,你会看到printf()需要一个格式字符串,以及零个或多个参数。因此,严格来说,“printf(string)”不正确:
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)第一个参数将解释为格式字符串,它找到的任何“%XXX”条目将被解释为占位符。这听起来正是发生了什么:)
3)解决方案当然是printf ("%s", string)
4)或者使用puts(string)
代替:)
答案 1 :(得分:5)
切勿将输入字符串用作printf的格式参数。
要正常工作,它必须没有“%...”项。这些是printf()函数访问参数列表的特殊命令。
答案 2 :(得分:1)
在format
和printf
系列函数scanf
的{{1}}参数中,%
被视为转义字符。您的原始输入包含其中一些,而printf
正试图解释它们。
答案 3 :(得分:0)
如果使用printf(string),则打印的字符串可能为NULL 这是我看到的唯一问题.printf函数根据提供的格式读取所有va_list参数,因此如果传递NULL指针它可能会崩溃。 使用LLVM 4.1,我收到此警告:
Format string is not a literal string (potentially insecure)
这是我个人的观点:如果你确定该字符串不是NULL(可能通过断言验证它,然后在发布中删除该断言),那么你可以使用printf(string)。如果你不完全确定字符串可能为NULL或无效,然后使用文字字符串。