★★:preparestatement 到底是如何防止注入的?

lanytin 2011-10-07 11:28:11
网上说的都不是太清楚,想自己试一下,但现在正在准备面试呢。
高手求解。
...全文
104 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
小绵羊 2011-10-07
  • 打赏
  • 举报
回复


public void setString(int parameterIndex, String x)
/* */ throws SQLException
/* */ {
/* 3206 */ if (x == null) {
/* 3207 */ setNull(parameterIndex, 1);
/* */ } else {
/* 3209 */ checkClosed();
/* */
/* 3211 */ int stringLength = x.length();
/* */
/* 3213 */ if (this.connection.isNoBackslashEscapesSet())
/* */ {
/* 3216 */ boolean needsHexEscape = false;
/* */
/* 3218 */ for (int i = 0; i < stringLength; ++i) {
/* 3219 */ char c = x.charAt(i);
/* */
/* 3221 */ switch (c)
/* */ {
/* */ case '\0':
/* 3224 */ needsHexEscape = true;
/* 3225 */ break;
/* */ case '\n':
/* 3228 */ needsHexEscape = true;
/* */
/* 3230 */ break;
/* */ case '\r':
/* 3233 */ needsHexEscape = true;
/* 3234 */ break;
/* */ case '\\':
/* 3237 */ needsHexEscape = true;
/* */
/* 3239 */ break;
/* */ case '\'':
/* 3242 */ needsHexEscape = true;
/* */
/* 3244 */ break;
/* */ case '"':
/* 3247 */ needsHexEscape = true;
/* */
/* 3249 */ break;
/* */ case '\26':
/* 3252 */ needsHexEscape = true;
/* */ }
/* */
/* 3256 */ if (needsHexEscape)
/* */ {
/* */ break;
/* */ }
/* */
/* */ }
/* */
/* 3263 */ if (!(needsHexEscape)) {
/* 3264 */ byte[] parameterAsBytes = null;
/* */
/* 3266 */ StringBuffer quotedString = new StringBuffer(x.length() + 2);
/* 3267 */ quotedString.append('\'');
/* 3268 */ quotedString.append(x);
/* 3269 */ quotedString.append('\'');
/* */
/* 3271 */ if (!(this.isLoadDataQuery)) {
/* 3272 */ parameterAsBytes = StringUtils.getBytes(quotedString.toString(), this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode());
/* */ }
/* */ else
/* */ {
/* 3278 */ parameterAsBytes = quotedString.toString().getBytes();
/* */ }
/* */
/* 3281 */ setInternal(parameterIndex, parameterAsBytes);
/* */ } else {
/* 3283 */ byte[] parameterAsBytes = null;
/* */
/* 3285 */ if (!(this.isLoadDataQuery)) {
/* 3286 */ parameterAsBytes = StringUtils.getBytes(x, this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode());
/* */ }
/* */ else
/* */ {
/* 3292 */ parameterAsBytes = x.getBytes();
/* */ }
/* */
/* 3295 */ setBytes(parameterIndex, parameterAsBytes);
/* */ }
/* */
/* 3298 */ return;
/* */ }
/* */
/* 3301 */ StringBuffer buf = new StringBuffer((int)(x.length() * 1.1D));
/* 3302 */ buf.append('\'');
/* */
/* 3311 */ for (int i = 0; i < stringLength; ++i) {
/* 3312 */ char c = x.charAt(i);
/* */
/* 3314 */ switch (c)
/* */ {
/* */ case '\0':
/* 3316 */ buf.append('\\');
/* 3317 */ buf.append('0');
/* */
/* 3319 */ break;
/* */ case '\n':
/* 3322 */ buf.append('\\');
/* 3323 */ buf.append('n');
/* */
/* 3325 */ break;
/* */ case '\r':
/* 3328 */ buf.append('\\');
/* 3329 */ buf.append('r');
/* */
/* 3331 */ break;
/* */ case '\\':
/* 3334 */ buf.append('\\');
/* 3335 */ buf.append('\\');
/* */
/* 3337 */ break;
/* */ case '\'':
/* 3340 */ buf.append('\\');
/* 3341 */ buf.append('\'');
/* */
/* 3343 */ break;
/* */ case '"':
/* 3346 */ if (this.usingAnsiMode) {
/* 3347 */ buf.append('\\');
/* */ }
/* */
/* 3350 */ buf.append('"');
/* */
/* 3352 */ break;
/* */ case '\26':
/* 3355 */ buf.append('\\');
/* 3356 */ buf.append('Z');
/* */
/* 3358 */ break;
/* */ default:
/* 3361 */ buf.append(c);
/* */ }
/* */ }
/* */
/* 3365 */ buf.append('\'');
/* */
/* 3367 */ String parameterAsString = buf.toString();
/* */
/* 3369 */ byte[] parameterAsBytes = null;
/* */
/* 3371 */ if (!(this.isLoadDataQuery)) {
/* 3372 */ parameterAsBytes = StringUtils.getBytes(parameterAsString, this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), this.connection.parserKnowsUnicode());
/* */ }
/* */ else
/* */ {
/* 3378 */ parameterAsBytes = parameterAsString.getBytes();
/* */ }
/* */
/* 3381 */ setInternal(parameterIndex, parameterAsBytes);
/* */ }
/* */ }


这是mysql的实现,它会把所有的数据库关键字,连接符之类的特殊字符转义掉
niuniu20008 2011-10-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lanytin 的回复:]
你这是手动的,过滤特殊字符,和preparestatement有什么关系呢?
我的问题是,preparestatement内部如何防止参数里面的这种特殊字符呢?
会抛出什么异常呢?
[/Quote]
Sun 的Java中jdbc,只提供了接口,里面具体实现是让各个数据库厂商实现的。所以连接数据库时,才需要导入这个数据库的驱动jar包。一楼给你看得就是mysql驱动jar包里的源代码。
softroad 2011-10-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 x19881216 的回复:]

引用 2 楼 lanytin 的回复:
你这是手动的,过滤特殊字符,和preparestatement有什么关系呢?
我的问题是,preparestatement内部如何防止参数里面的这种特殊字符呢?
会抛出什么异常呢?


preparestatement是个接口,具体都是数据库厂家实现的,上面那段代码就是mysql的实现。

不手动过滤特殊字符,还能怎么样?
[/Quote]

小绵羊 2011-10-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lanytin 的回复:]
你这是手动的,过滤特殊字符,和preparestatement有什么关系呢?
我的问题是,preparestatement内部如何防止参数里面的这种特殊字符呢?
会抛出什么异常呢?
[/Quote]

preparestatement是个接口,具体都是数据库厂家实现的,上面那段代码就是mysql的实现。

不手动过滤特殊字符,还能怎么样?
lanytin 2011-10-07
  • 打赏
  • 举报
回复
你这是手动的,过滤特殊字符,和preparestatement有什么关系呢?
我的问题是,preparestatement内部如何防止参数里面的这种特殊字符呢?
会抛出什么异常呢?

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧