在编写测试时,我正在比较字符串。测试结果为失败。我手动复制粘贴的字符串,它的工作原理... 注意mysql字符串语法;但到目前为止它永远不会触及mysql。
Console.logged copy + paste两个字符串看起来像这样:
console.log(replaced);
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE '%' AND influencer_name = ?"
console.log(sqlQuery0);
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE '%' AND influencer_name = ?"
它不应该失败,但确实如此。所以我想知道它失败的地方:
it( "submits the proper first sql query", function(){
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
for (var i = 0; i < replaced.length; i++) {
if (replaced[i] != sqlQuery0[i] ){
console.log(replaced.slice(i-10,i+10));
console.log(sqlQuery0.slice(i-10,i+10);
break
}
}
})
上面给我的SU SU ----:
me LIKE '%' AND inf
me LIKE '%' AND infl
他们的长度不一样......对。我再试一次。
it( "submits the proper first sql query", function(){
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
for (var i = 0; i < replaced.length; i++) {
if (replaced[i] != sqlQuery0[i] ){
console.log('|'+ replaced.slice(i-10,i+10)+'|',replaced.slice(i-10,i+10).length);
console.log('|'+sqlQuery0.slice(i-10,i+10)+'|',sqlQuery0.slice(i-10,i+10).length);
break
}
}
})
令我更大的惊喜:
|me LIKE '%' AND inf| 20
|me LIKE '%' AND infl| 20
但是第一个字符串只有19个长度!
我最后的挫折:
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
for (var i = 0; i < replaced.length; i++) {
console.log(replaced[i], sqlQuery0[i]);
if (replaced[i] != sqlQuery0[i] ){
console.log('|'+ replaced.slice(i-10,i+10)+'|',replaced.slice(i-10,i+10).length);
console.log('|'+sqlQuery0.slice(i-10,i+10)+'|',sqlQuery0.slice(i-10,i+10).length);
break
}
}
给了我这个:
n n
a a
m m
e e
L L
I I
K K
E E
' '
% %
% '
|me LIKE '%' AND inf| 20
|me LIKE '%' AND infl| 20
显然“%%”被解释为%和%%这是怎么回事?
更多:
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
console.log(sqlQuery0)
for (var i = 0; i < replaced.length; i++) {
console.log(replaced[i], sqlQuery0[i]);
if (replaced[i] != sqlQuery0[i] ){
console.log('|'+ JSON.stringify(replaced.slice(i-10,i+10))+'|',replaced.slice(i-10,i+10).length);
console.log('|'+ JSON.stringify(sqlQuery0.slice(i-10,i+10))+'|',sqlQuery0.slice(i-10,i+10).length);
console.log('|'+ JSON.stringify(dao.SQLquery[0].slice(i-10,i+10))+'|',sqlQuery0.slice(i-10,i+10).length);
break
}
}
|"me LIKE '%' AND inf"| 20
|"me LIKE '%' AND infl"| 20
|"ame LIKE '%' AND in"| 20
答案 0 :(得分:7)
扩展@Matt Ball和@blm所说的话,你很可能会看到一个&#39;看不见的&#39;您所替换的文字中的字符&#39;变量。要对此进行测试,请使用十六进制编辑器并粘贴“已替换”的文本。和sqlQuery0变量 - 你应该能够看到围绕&#39;%&#39;角色你有一个看不见的角色,如&#39; 00&#39; NUL或&#39; 1E&#39;记录分隔符。
您可以使用此在线Hex Viewer来测试https://hexed.it/?hl=en
查看我所指的ASCII码,查看ascii表http://www.asciitable.com/
答案 1 :(得分:2)
正如其他人所说,你可能在其中一个字符串中有某种隐藏的Unicode字符。最好的方法是使用charCodeAt()
来查看实际存在的代码点。
例如:
var a = 'foo\u200bbar';
var b = 'foobar';
console.log('a = "' + a + '"');
console.log('b = "' + b + '"');
function toCodePointArray(str) {
var result = [];
for (var i = 0; i < str.length; i++) {
result.push(str.charCodeAt(i));
}
return result;
}
console.log('toCodePointArray(a) = ', toCodePointArray(a));
console.log('toCodePointArray(b) = ', toCodePointArray(b));
当我跑步时,我得到:
a = "foobar"
b = "foobar"
toCodePointArray(a) = [ 102, 111, 111, 8203, 98, 97, 114 ]
toCodePointArray(b) = [ 102, 111, 111, 98, 97, 114 ]
这里隐藏的字符清楚地显示为8203,它是0x200b的十进制等值,即Unicode零宽度空间。
答案 2 :(得分:1)
要避免产生额外位的问题,请使用hex char val。对于%它的0x25
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE "X'250225'" AND influencer_name = ?"
甚至
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE "%X'250225'%" AND influencer_name = ?"
第二种技术包括使用Locate来实现更简单的hex val绑定,但速度稍慢。
"SELECT COUNT(*) FROM interaction WHERE LOCATE(X'25', ambassador_name) > 0 AND influencer_name = ?"
另外,正如Rob Wilson所说,为了避免在使用LIKE时在unicode中出现多余的乱码,请始终将LIO绑定到PDO :: PARAM_STR。在逃避注入的过程中,PDO也会清理那些额外的位。
SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE ? AND influencer_name = ?
bindParam(1, "X'250225'", PDO::PARAM_STR);
甚至
bindParam(1, "%X'250225'%", PDO::PARAM_STR);