使用vfprintf()时出现分段错误
Segmentation fault while using vfprintf()
下面的程序出现了分段错误,我不知道是什么问题
1 #include<stdio.h>
2 #include<stdarg.h>
3 void writeformat(FILE*,char*, ...);
4 int main()
5 {
6 FILE *fp;
7 fp=fopen("file1.txt","w");
8 writeformat(fp,"/modules.php?name=Top&querylang=%20WHERE%201=2%20ALL%20SELECT%201,pwd,1,1%20FROM%20nuke_authors/*");
9 fclose(fp);
10 return(0);
11 }
12
13 void writeformat(FILE *stream,char *format, ...)
14 {
15 va_list args;
16 va_start(args,format);
17 vfprintf(stream,format,args);
18 va_end(args);
19 }
我在gdb中尝试过,它告诉我问题在vfprintf()
:
(gdb) run
Starting program: /ws/anaganes-sjc/junk
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
Program received signal SIGSEGV, Segmentation fault.
0x0000003c44c7fb30 in wcslen () from /lib64/libc.so.6
(gdb) bt
#0 0x0000003c44c7fb30 in wcslen () from /lib64/libc.so.6
#1 0x0000003c44c80b27 in wcsrtombs () from /lib64/libc.so.6
#2 0x0000003c44c464b2 in vfprintf () from /lib64/libc.so.6
#3 0x0000000000400649 in writeformat (stream=0x601010, format=0x400758 "/modules.php?name=Top&querylang=%20WHERE%201=2%20ALL%20SELECT%201,pwd,1,1%20FROM%20nuke_authors/*") at junk.c:20
#4 0x0000000000400556 in main () at junk.c:9
你能帮我找到问题吗?
格式字符串包含转义的空格字符。转义用百分号完成,HTML样式:
"querylang=%20WHERE%201=2%20ALL%20SELECT%201..."
这些百分号在printf
样式的格式字符串中有一定的含义。必须逐字呈现空格:
"querylang= WHERE 1=2 ALL SELECT 1..."
或使用printf
自己的转义来打印百分号,即%%
:
"querylang=%%20WHERE%%201=2%%20ALL%%20SELECT%%201..."
或者,正如alk在注释中指出的,使用字符串格式并打印字符串作为参数:
writeformat(fp, "%s", "/modules.php?name=");
,这是打印具有或可能具有格式化说明符的字符串的最佳方式。
你会得到一个分段冲突,因为除了%%
以外,用%
指定的每个格式都需要一个额外的参数。例如,%20A
打印宽度为20的浮点数的二进制表示。因此,它需要一个双参数,但是您没有指定任何参数,因此vprintf
尝试访问超出变量参数列表范围的内存。
对于众所周知的printf
函数,许多编译器可以警告您格式不匹配。一些编译器允许您将自己的函数的参数标记为printf
,就像格式字符串一样。Microsoft的SAL或gcc样式的属性将允许您这样做。
vfprintf
认为您正在传递一些带有数据的变参数,因为您的格式字符串包含%
。
看起来您想要逐字打印%
,所以您必须将它们转义为%%
:
"/modules.php?name=Top&querylang="
"%%20WHERE%%201=2%%20ALL%%20SELECT%%201,pwd,1,1%%20FROM%%20nuke_authors/*"
顺便说一下,/*
可能不应该在那里,查询本身似乎很奇怪。这段代码要么很奇怪,要么就是你的目的不好。
当将字符串传递给vfprintf时,%
字符被解释为转换规范的引入。为了保持%
一字不差,你必须逃避它。这是通过用转换规范%%
替换每个%
来完成的。
如果您将writeformat
标记为采用printf
样式的格式字符串,GCC将在编译时捕获格式字符串错误:
void writeformat(FILE *stream, char *format, ...)
__attribute__((format (printf, 2, 3)));
顺便说一下,我对void
的返回类型提出了质疑——你真的要忽略vprintf
的返回值吗?
相关文章:
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?