ikepyonのだめ人間日記

セキュリティに関することを書いていく予定。

MySQLのJDBC

と言う疑問がわいてきたので、ざっとソースを確認してみた。
PreparedStatement関連はcom.mysql.jdbc.PreparedStatement.javaかなぁと思ってsetStringメソッドを見てみた。

	public void setString(int parameterIndex, String x) throws SQLException {
		// if the passed string is null, then set this column to null
		if (x == null) {
			setNull(parameterIndex, Types.CHAR);
		} else {
ちょっと割愛
			String parameterAsString = x;
			boolean needsQuoted = true;
			
			if (this.isLoadDataQuery || isEscapeNeededForString(x, stringLength)) {
				needsQuoted = false; // saves an allocation later
				
				StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
				
				buf.append('\'');
	
				//
				// Note: buf.append(char) is _faster_ than
				// appending in blocks, because the block
				// append requires a System.arraycopy()....
				// go figure...
				//
	
				for (int i = 0; i < stringLength; ++i) {
					char c = x.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 */
						if (this.usingAnsiMode) {
							buf.append('\\');
						}
	
						buf.append('"');
	
						break;
	
					case '\032': /* This gives problems on Win32 */
						buf.append('\\');
						buf.append('Z');
	
						break;
	
					default:
						buf.append(c);
					}
				}
	
				buf.append('\'');
	
				parameterAsString = buf.toString();
			}

			byte[] parameterAsBytes = null;

			if (!this.isLoadDataQuery) {
				if (needsQuoted) {
					parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString,
						'\'', '\'', this.charConverter, this.charEncoding, this.connection
								.getServerCharacterEncoding(), this.connection
								.parserKnowsUnicode());
				} else {
					parameterAsBytes = StringUtils.getBytes(parameterAsString,
							this.charConverter, this.charEncoding, this.connection
									.getServerCharacterEncoding(), this.connection
									.parserKnowsUnicode());
				}
			} else {
				// Send with platform character encoding
				parameterAsBytes = parameterAsString.getBytes();
			}

			setInternal(parameterIndex, parameterAsBytes);
			
			this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.VARCHAR;
		}
	}

えーと、「'」とか「¥」をエスケープしてからコード変換かけているように見えるんですが・・・
ちなみにStringUtils.getBytesWrappedでパラメータデータの文字コード変換をやっているようだ。

やっぱり検証しないといけないかなぁ?