平成27年春期試験午後問題 問11

午前試験免除制度対応!基本情報技術者試験のeラーニング【独習ゼミ】

問11 ソフトウェア開発(Java)

次のJavaプログラムの説明及びプログラムを読んで,設問1,2に答えよ。
(Javaプログラムで使用するAPIの説明は,こちらを参照してください。)

〔プログラムの説明〕
 D社では,利用者が入力した文字列をHTMLに埋め込むことによって,動的にWeb ページを生成するアプリケーションを開発している。
 このようなアプリケーションでは,利用者が入力した文字列をHTMLに埋め込む際の処理が不適切な場合,情報漏えいの発生などシステムの安全な運用を脅かすおそれがある。
 利用者が入力した文字列をHTMLに埋め込む前には,サニタイズすることが必要である。サニタイズとは,システムの安全な運用を脅かす文字列を,無害な文字列に変換することをいう。文字列の変換方法は,文字列を埋め込む場所によって異なる。
 当該アプリケーションでは,HTMLのタグの間(ただし,"<script>"と "</script>"との間は除く)に文字列を埋め込むケースと,JavaScriptの文字列として埋め込むケースの二つのケースでサニタイズする必要がある。サニタイズは,変換前の文字列中の各文字を,それぞれ次のように変換することによって行うことにした。
  • HTMLのタグの間に文字列を埋め込むケース
    1. 英数字と次に示す文字は,そのまま出力する。
       !#$%()*+,-.:;=?@[\]^_`{|}~
    2. 表1に示す文字は,実体参照に変換する。
      pm11_1.gif
    3. その他の文字は,"&#ddd;"に変換する。ここで ddd は変換対象文字の文字コードを表す,最大で5桁の10進数である。また,変換前の文字列に含まれる各文字は,2バイトで表すことができるものとする。
  • JavaScriptの文字列として埋め込むケース
    1. 英数字は,そのまま出力する。
    2. 文字コードが256未満の英数字以外の文字は,"\xXX"に変換する。ここで,XXは変換対象の文字の文字コードを表す,2桁の16進数である。
    3. その他の文字は,"\uXXXX"に変換する。ここで,XXXXは変換対象の文字の文字コードを表す,4桁の16進数である。また,変換前の文字列に含まれる各文字は,2バイトで表すことができるものとする。
 クラス Encoder は,サニタイズを行うクラスが継承する抽象クラスである。パブリックメソッド encode は,引数で与えられた文字列をサニタイズし,結果を返す。クラス HtmlEncoder は,HTMLのタグに埋め込む文字列をサニタイズするクラスである。クラス JavaScriptEncoder は,JavaScriptの文字列として埋め込む文字列をサニタイズするクラスである。
pm11_2.gif

設問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 に関する解答群
  • !=
  • <
  • ==
  • >
解答選択欄
  • a:
  • b:
  • c:
  • d:
  • e:
  • a=
  • b=
  • c=
  • d=
  • e=

解説

aについて〕
メソッド addConversion(c char) は、オーバーロードされた同名メソッド addConversion(char[] collection) が引数として受け取ったchar配列の1文字ずつに対して呼び出され、HashMap型変数の convertionTable に対して操作を行います。HashMapは、キーと値のペアを保持するデータ型で、本問では変換前の文字をキー、変換後の文字列を値としています。〔プログラム2〕や〔プログラム3〕で、英数字などの配列を引数として呼び出されていること、add~というメソッド名、メソッド addConvertion でメソッド put を使用している等を踏まえると、メソッド addNoConversion は"そのまま出力する文字"について convertionTable に登録する操作であることわかります。

HashMap型変数にキーと値を対応付けを登録するにはメソッド put を使います。値の方を String.valueOf(c) としているのは、convertionTable がキーをCharacter型、値をString型として定義されており、Character型をString型に変換して渡す必要があるからです。

a=ウ:put(c, String.valueOf(c))

bについて〕
メソッド encode は、引数で与えられた文字列をサニタイズし、結果を返すものです。
ここでは引数 s の構成文字を1文字ずつ確認していくことになります。「ア」「イ」の2つは拡張for文(for-each文)と呼ばれるもので、配列やコレクションから値を1つずつ取り出しながら繰り返す処理で使用されます。[b]の直前のデータ型がcharになっているので、[b]にはchar型の配列を渡せば文字列の1文字ずつに対して処理ができます。
クラス String のメソッド toCharArray は、文字列を文字配列に変換する関数ですから、引数 s を toCharArray で変換することでfor文に文字配列を渡せます。

b=イ:s.toCharArray()
  • convertionTable に登録されているキーの集合が返るので誤りです。
  • 正しい。
  • char を数値として扱い、1ずつ増加するループ変数とすることもできますが、この場合 s.charAt(c) で s から該当位置の文字を取り出すことが必要となります。プログラム中では charAt を使っておらず、c には文字が格納されていなければならないので誤りです。
  • 「ウ」と同じ理由で誤りです。
cについて〕
選択肢を見ると、addConversion と addNoConversion が含まれています。この2つは何の値も返さないメソッドなので、返却値を t に代入していることから考えると不適切とわかります。

[b]の行に続く処理では次の操作を行っています。
  • [b]の返却値がnullならばその文字を引数に encode を呼び出して t に文字列を格納する
  • 文字列 t を結果文字列 result に連結する。
つまり、convertionTable に文字 c が登録されていれば、それに対応する文字列を、登録されていなれば"その他の文字"として変換した文字列を、サニタイズ後の文字列に連結することを行っています。HashMap型で指定されたキーに関連付けられた値を取得するにはメソッド get を使います(指定されたキーペアがなければnullを返します)。remove も削除したキーに関連付けられていた値を返しますが、当該キーペアが convertionTable から削除されてしまうので不適切です。

c=ウ:conversionTable.get(c)

dについて〕
クラス HtmlEncoder 内のメソッド encode は、親クラスである Encoder の抽象メソッドを実装したものです。char型を引数とするメソッド encode は、convertionTable にキーと値のペアがなかったときに呼び出されるメソッドで、〔プログラムの説明〕(1)の③"その他の文字"を処理するためのものです。

HTMLのタグの間の文字については、「その他の文字は,"&#ddd;"に変換する。ここで ddd は変換対象文字の文字コードを表す,最大で5桁の10進数である。」とあります。つまり、引数の文字を文字コードに変換して"&#"と";"で囲めばよいので、引数 c をint型にキャストして、"&#"と";"を付ける「ア」が適切です。

d=ア:"&#" + (int) c + ";"

eについて〕
〔プログラムの説明〕(2)には以下の説明があります。
  • ②文字コードが256未満の英数字以外の文字は,"\xXX"に変換する。ここで,XXは変換対象の文字の文字コードを表す,2桁の16進数である。
  • ③その他の文字は,"\uXXXX"に変換する。ここで,XXXXは変換対象の文字の文字コードを表す,4桁の16進数である。
if文内では、char型をint型にキャストし、それを書式指示子"%02X"で16進数2桁に変換しているので、②の処理に当たることがわかります。②の処理を行うのは文字コードが256未満の場合なので、[e]には「<」が入ります。

e=イ:<

設問2

プログラム4を実行したときに,プログラム2のメソッド encode が呼び出される回数として正しい答えを,解答群の中から選べ。
 ここで,プログラム1~3中の には正しい答えが入っているものとする。
pm11_3.gif
解答群
  • 0
  • 4
  • 5
  • 13
  • 30
解答選択欄
  •  
  •  

解説

クラス HtmlEncoder の内部でメソッド encode が呼ばれるのは、convertionTable.get(c) の結果がnull、すなわち convertionTable に登録されていない文字に遭遇した場合です。クラス HtmlEncoder で登録対象となっているのは以下の文字です。
  • 英数字 0-9a-zA-Z
  • 記号 !#$%()*+,-.:;=?@[\]^_`{|}~
  • <>&"
したがって〔プログラム4〕でサニタイズの対象となっている文字列のうち、上記に含まれない以下の5文字についてメソッド encode が呼ばれることになります。
pm11_4.gif
よって、呼び出される回数は5回です。

∴ウ:5

Pagetop