平成27年 春期 基本情報技術者 午後 問11(Java)
ここでは、当社の新人研修受講者に向けて、基本情報のJavaの過去問を掲載しています。
想定しているのは、NetBeansなどのIDEにコピー・ペーストしたうえで、自分の正しいと思う答えを埋めて動作を確認するという使い方です。
次の Java プログラムの説明及びプログラムを読んで,設問1,2に答えよ。
〔プログラムの説明〕
D社では,利用者が入力した文字列を HTML に埋め込むことによって, 動的に Web ページを生成するアプリケーションを開発している。
このようなアプリケーションでは,利用者が入力した文字列を HTML に埋め込む際の 処理が不適切な場合,情報漏えいの発生などシステムの安全な運用を脅かすおそれがある。
利用者が入力した文字列を HTML に埋め込む前には,サニタイズすることが必要である。 サニタイズとは,システムの安全な運用を脅かす文字列を,無害な文字列に 変換することをいう。文字列の変換方法は,文字列を埋め込む場所によって異なる。
当該アプリケーションでは,HTML のタグの間(ただし,“<script>”と “</script>”との間は除く)に文字列を埋め込むケースと,JavaScript の文字列として 埋め込むケースの二つのケースでサニタイズする必要がある。サニタイズは,変換前の 文字列中の各文字を,それぞれ次のように変換することによって行うことにした。
(1) HTML のタグの間に文字列を埋め込むケース
① 英数字と次に示す文字は,そのまま出力する。
!#$%()*+,-.:;=?@[\]^_'{|}~
② 表1に示す文字は,実体参照に変換する。
③ その他の文字は,“&#ddd;”に変換する。ここで ddd は変換対象文字の文字コードを表す, 最大で 5 桁の 10 進数である。また,変換前の文字列に含まれる各文字は, 2 バイトで表すことができるものとする。
(2) JavaScript の文字列として埋め込むケース
① 英数字は,そのまま出力する。
② 文字コードが 256 未満の英数字以外の文字は,“\xXX”に変換する。 ここで,XX は変換対象の文字の文字コードを表す,2 桁の 16 進数である。
③ その他の文字は,“\uXXXX”に変換する。ここで,XXXX は変換対象の文字の文字コードを表す, 4 桁の 16 進数である。また,変換前の文字列に含まれる各文字は, 2 バイトで表すことができるものとする。
クラス Encoder は,サニタイズを行うクラスが継承する抽象クラスである。 パブリックメソッド encode は,引数で与えられた文字列をサニタイズし,結果を返す。
クラス HtmlEncoder は,HTML のタグに埋め込む文字列をサニタイズするクラスである。 クラス JavaScriptEncoder は ,JavaScript の文字列として埋め込む文字列を サニタイズするクラスである。
[プログラム1]
import java.util.HashMap; import java.util.Map; abstract public class Encoder { private Map<Character, String> conversionTable = new HashMap<Character, String>(); protected void addConversion(char c, String s) { conversionTable.put(c, s); } protected void addNoConversion(char c) { conversionTable./* a */; } protected void addNoConversion (char[] collection) { for (char c : collection) { addNoConversion(c); } } abstract protected String encode(char c); public String encode(String s) { if (s == null) { return null; } String result = ""; for (char c /* b */ ) { String t = /* c */; if (t == null) { t = encode(c); } result += t; } return result; } }
[プログラム2]
public class HtmlEncoder extends Encoder { private static String ALPHAS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static String NUMERICS = "0123456789"; private static String PUNCTUATIONS = "!#$%()*+,-.:;=?@[\\]^_'{|}~"; public HtmlEncoder() { addNoConversion(ALPHAS.toCharArray()); addNoConversion(ALPHAS.toLowerCase().toCharArray()); addNoConversion(NUMERICS.toCharArray()); addNoConversion(PUNCTUATIONS.toCharArray()); addConversion('<', "<"); addConversion('>', ">"); addConversion('&', "&"); addConversion('"', """); } protected String encode(char c) { return /* d */; } }
[プログラム3]
public class JavaScriptEncoder extends Encoder { private static String ALPHAS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static String NUMERICS = "0123456789"; public JavaScriptEncoder() { addNoConversion(ALPHAS.toCharArray()); addNoConversion(ALPHAS.toLowerCase().toCharArray()); addNoConversion(NUMERICS.toCharArray()); } protected String encode(char c) { if (c /* e */ 256) { return String.format("\\x%02X", (int) c); } return String.format("\\u%04X", (int) c); } }
設問1 プログラム1~3中の に入れる正しい答えを, 解答群の中から選べ。
a に関する解答群
ア clear() イ get(c)
ウ put(c, String.valueOf(c)) エ remove(c)
b に関する解答群
ア : conversionTable.keySet()
イ : s.toCharArray()
ウ = 0; c < s.length(); c++
エ = 0; s.indexOf(c) > 0; c++
c に関する解答群
ア addConversion(c, t) イ addNoConversion(c)
ウ conversionTable.get(c) エ conversionTable.remove(c)
d に関する解答群
ア "&#" + (int) c + ";" イ "&#" + c + ";"
ウ "\\u" + (int) c エ "\\u" + c
e に関する解答群
ア != イ < ウ == エ >
設問2 プログラム4を実行したときに,プログラム2のメソッド encode が 呼び出される回数として正しい答えを,解答群の中から選べ。
ここで,プログラム1~3中の/* */ には正しい答えが 入っているものとする。
[プログラム4]
public class HtmlEncoderTest { static public void main(String[] args) { new HtmlEncoder().encode("<script>alert('注意!');</script>"); } }
解答群
ア 0 イ 4 ウ 5 エ 13 オ 30