特定情况下,以下的写法导致最后一个单引号没加上(display为std::string对象):
写法1:
写法2:
写法3:
以下写法不出此问题:
调试之前执行了Clean+Rebuild,VC6,操作系统是Win2003,但是另外写一个工程运行上述代码就不出错。
出错的时候display的内存情况:
strSQL的内存:
又经过试验,发现display.size() 为256 !所以想象可能还是类似上次的包含/0的问题。
追查display的来源如下:
display = CTAppeal.GetExtenNum();
按想象string不能保存包含/0的字符串,
再次测试:
a==11
string是不会被直接赋值为一个包含/0的字符串的。但是,这里有个问题,就是这样赋值的话应该是被编译器给截断的。所以内存赋值可能string实际可以支持。GetExtenNum()是输出数据库字段的值然后返回,其间也是用string保存数据的,dtl库的内部实现我并不了解,但推测应该还是字符串被赋了包含零的值。
写测试程序如下:
seclen为7,内存情况如下:
赋值成功。
我的程序因为那个字段的值包含/0,并且保存在了string中,所以在拼SQL的时候,导致单引号拼接失败,最终导致SQL执行失败。
结论:使用string的时候要格外当心/0的问题。恶意使用者可通过向数据库提交包含/0的字符串来使后台程序崩溃(斜杠零攻击)。
写法1:
string
strSQL;
strSQL = " WHERE APPEAL_DISPLAY=' " ;
strSQL.append(display);
strSQL.append( " ' " );
strSQL = " WHERE APPEAL_DISPLAY=' " ;
strSQL.append(display);
strSQL.append( " ' " );
写法2:
string
strSQL
=
"
WHERE
APPEAL_
DISPLAY='
"
+
display
+
"
'
"
;
写法3:
string
strSQL
=
"
WHERE
APPEAL_
DISPLAY='
"
+
display
+
" /
'
"
;
以下写法不出此问题:
char
szSQL[
256
]
=
{0}
;
string strSQL;
sprintf(szSQL, " WHERE APPEAL_DISPLAY='%s' " , display.c_str() );
strSQL = szSQL;
string strSQL;
sprintf(szSQL, " WHERE APPEAL_DISPLAY='%s' " , display.c_str() );
strSQL = szSQL;
调试之前执行了Clean+Rebuild,VC6,操作系统是Win2003,但是另外写一个工程运行上述代码就不出错。
出错的时候display的内存情况:
02083E31
67
7A
44
53
4C
38
37
32
35
36
35
31
31
00
00
gzDSL87256511..
strSQL的内存:
02080A61
57
48
45
52
45
20
41
50
50
45
41
4C 5F
44
49
WHERE APPEAL_DI
02080A70 53 50 4C 41 59 3D 27 67 7A 44 53 4C 38 37 32 SPLAY = ' gzDSL872
02080A7F 35 36 35 31 31 00 00 00 00 00 00 00 00 00 00 56511 ..........
02080A70 53 50 4C 41 59 3D 27 67 7A 44 53 4C 38 37 32 SPLAY = ' gzDSL872
02080A7F 35 36 35 31 31 00 00 00 00 00 00 00 00 00 00 56511 ..........
又经过试验,发现display.size() 为256 !所以想象可能还是类似上次的包含/0的问题。
追查display的来源如下:
display = CTAppeal.GetExtenNum();
按想象string不能保存包含/0的字符串,
再次测试:
经过测试:
const std:: string display = " sgsg8176216/0/0/0/0 " ;
int a = display.size();
const std:: string display = " sgsg8176216/0/0/0/0 " ;
int a = display.size();
a==11
string是不会被直接赋值为一个包含/0的字符串的。但是,这里有个问题,就是这样赋值的话应该是被编译器给截断的。所以内存赋值可能string实际可以支持。GetExtenNum()是输出数据库字段的值然后返回,其间也是用string保存数据的,dtl库的内部实现我并不了解,但推测应该还是字符串被赋了包含零的值。
写测试程序如下:
string
str
=
"
123
"
;
str.append( "/ 0/ 0/ 0 " , 3 );
str.append( " E " );
string ::size_type srclen = str.size();
str.append( "/ 0/ 0/ 0 " , 3 );
str.append( " E " );
string ::size_type srclen = str.size();
seclen为7,内存情况如下:
00E653D9
31
32
33
00
00
00
45
00
CD CD CD CD
123
...E.屯屯
赋值成功。
我的程序因为那个字段的值包含/0,并且保存在了string中,所以在拼SQL的时候,导致单引号拼接失败,最终导致SQL执行失败。
结论:使用string的时候要格外当心/0的问题。恶意使用者可通过向数据库提交包含/0的字符串来使后台程序崩溃(斜杠零攻击)。