MySQLのJDBCでダブルクオートの中に検索ワードを入れるときはPreparedStatementが使えない件について

alkoshikawa 527views 更新:2014年3月17日

WEBから入力された検索ワードをDB検索に使う場合、
SQLインジェクション対策のため通常PreparedStatementを使用しますが、
MySQLでProcedureなどを使ったときに、ダブルクオーテーションを使用しないといけないことがあります。

こんなん

CALL somethingFunc("table={WORD}")

通常以下のようにしたいところですが、

CALL somethingFunc("table=?")

JDBCの実装で

com.mysql.jdbc.PreparedStatement

                    if ((c == '?') && !inQuotes && !inQuotedId) {
                        endpointList.add(new int[] { lastParmEnd, i });
                        lastParmEnd = i + 1;
                        
                        if (isOnDuplicateKeyUpdate && i > locationOfOnDuplicateKeyUpdate) {
                            parametersInDuplicateKeyClause = true;
                        }
                    }

というのがあり、クオートの中の?は除外するようになっています。
そのため自前でエスケープをするする必要があります。
幸いJDBCのソースにそうゆうのがあるのでそのまま使ってしまいます。

  public static String getEscapedStringForMysql(String text) {
    if (StringUtils.isEmpty(text)) {
      return text;
    }
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < text.length(); i++) {
      char c = text.charAt(i);
      switch (c) {
        case 0: /* Must be escaped for 'mysql' */
          buf.append('\\');
          buf.append('0');
          break;
        case '\n': /* Must be escaped for logs */
          buf.append('\\');
          buf.append('n');
          break;
        case '\r':
          buf.append('\\');
          buf.append('r');
          break;
        case '\\':
          buf.append('\\');
          buf.append('\\');
          break;
        case '\'':
          buf.append('\\');
          buf.append('\'');
          break;
        case '"': /* Better safe than sorry */
          buf.append('\\');
          buf.append('"');
          break;
        case '32': /* This gives problems on Win32 */
          buf.append('\\');
          buf.append('Z');
          break;
        default:
          buf.append(c);
      }
    }
    return buf.toString();
  }

 

ログイン / 新規登録してコメントする

このソースコードをストックして後で利用したり、作業に利用したソースコードをまとめることができます。

こちらもお役に立つかもしれません