総視聴再生時間43万分以上(2017年5月13日現在)の動画で基本情報技術者試験の過去問&キーワード解説!スキマ時間に動画!〜これじょIT〜

PR広告

平成27年度春 基本情報技術者試験 午後 問11 ソフトウェア開発(Java) 設問1

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

次のJavaプログラムの説明及びプログラムを読んで、設問1、2に答えよ。

〔プログラムの説明〕

 D社では、利用者が入力した文字列をHTMLに埋め込むことによって、動的にWeb ページを生成するアプリケーションを開発している。

 このようなアプリケーションでは、利用者が入力した文字列をHTMLに埋め込む際の処理が不適切な場合、情報漏えいの発生などシステムの安全な運用を脅かすおそれがある。

 利用者が入力した文字列をHTMLに埋め込む前には、サニタイズすることが必要である。サニタイズとは、システムの安全な運用を脅かす文字列を、無害な文字列に変換することをいう。文字列の変換方法は、文字列を埋め込む場所によって異なる。

 当該アプリケーションでは、HTMLのタグの間(ただし、" "との間は除く)に文字列を埋め込むケースと、JavaScriptの文字列として埋め込むケースの二つのケースでサニタイズする必要がある。サニタイズは、変換前の 文字列中の各文字を、それぞれ次のように変換することによって行うことにした。

HTMLのタグの間に文字列を埋め込むケース

英数字と次に示す文字は、そのまま出力する。

 !#$%()*+、-.:;=?@[\]^_'{|}~

表1に示す文字は、実体参照に変換する。

その他の文字は、""に変換する。ここで ddd は変換対象文字の文字コードを表す、最大で5桁の10進数である。また、変換前の文字列に含まれる各文字は、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();
	  
   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("\\x%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 に関する解答群

  • ア : !=
  • イ : <
  • ウ : ==
  • エ : >

解説

【 a 】の解説

   protected void addNoConversion(char c) {
      conversionTable.【  a  】;
   }

addConversionでは、オブジェクトconversionTableに変換が必要な文字の組合わせをハッシュに登録しています。このaddNoConversionメソッドでは何をしたいかというと、変換が必要ない文字をハッシュに登録しています。"A"や"Z"、"1"や"0"は変換が必要ないのでaddNoConversionメソッドで登録します。

addNoConversionが呼ばれる箇所をみると...例えばプログラム2の

   public HtmlEncoder() {
       addNoConversion(ALPHAS.toCharArray());
       addNoConversion(ALPHAS.toLowerCase().toCharArray());
       addNoConversion(NUMERICS.toCharArray());
       addNoConversion(PUNCTUATIONS.toCharArray());
       addConversion('<', "<");
       addConversion('>', ">");
       addConversion('&', "&");
       addConversion('"', """);
   }

HtmlEncoderというメソッドでは、「addNoConversion(ALPHAS.toCharArray());」のようにaddNoConversionを記述しています。引数をみると「ALPHAS.toCharArray()」となっており、配列で渡されています。引数が配列なので、ここで呼ばれるaddNoConversionは下記です。

【注意】ALPHAS.toCharArray()は、「ABCDEFGHIJKLMNOPQRSTUVWXYZ」を1文字ずつ配列化しています。

    protected void addNoConversion(char[] collection) {
      for (char c : collection) {
	     addNoConversion(c);
      }
    }

このメソッドでは、配列をループさせ1文字ずつaddNoConversionに渡しています(addNoConversion(c);)※cには"A"とか"B"が入ります

addNoConversionは「変換の必要のない文字」を登録します。"A"や"1"はそのまま文字として登録をします。

従って【 a 】には「ウ : put(c, String.valueOf(c))」が入ります。addNoConversionは下記のようになります。

   protected void addNoConversion(char c) {
      conversionTable.put(c, String.valueOf(c));
   }
【 b 】【 c 】の解説

【 b 】【 c 】の部分はencode(String s)という記述から、文字列をエンコード(文字を変換)するメソッドと考えられます。文字列を1文字ずつに分解し、変換が必要な場合、文字を変換します。

   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;
   }

for (char c 【 b 】) { では文字列を1文字にしている箇所です。従って【 b 】には「イ : s.toCharArray()」が入ります。s.toCharArray()で、文字列sを1文字ずつの配列にして、そのままループに入れます。

【 c 】は変換が必要かどうかを判定します。

conversionTableオブジェクトのハッシュに登録されていれば、変換は不要で、登録されていなければ変換が必要です。登録されているかどうかは「ウ : conversionTable.get(c)」で値が返ってこれば変換は不要です。

【 b 】【 c 】を埋めると下記のようになります。

   public String encode(String s) {
      if (s == null) {
	     return null;
	  }
	  
	  String result = "";
	  for (char c : s.toCharArray()) {
	     String t = conversionTable.get(c);
		 if(t == null) {
		    t = encode(c);
		 }
		 result += t;
	  }
	  return result;
   }
【 d 】の解説

   protected String encode(char c) {
      return 【  d  】;
   }

encodeでは文字cをエンコードします。どのようにエンコードするかは問題文に記載されています。下記が抜粋。

その他の文字は、""に変換する。ここで ddd は変換対象文字の文字コードを表す、最大で5桁の10進数である。また、変換前の文字列に含まれる各文字は、2バイトで表すことができるものとする。

このメッド内で""を返せばよいことになります。Javaの場合文字cを整数型(int)にキャストすると文字コードを得ることができます。従って【 d 】には「ア : "&#" + (int) c + ";"」が入ります。【 d 】を埋めると

   protected String encode(char c) {
      return "&#" + (int) c + ";";
   }

となります。

【 e 】の解説

   protected String encode(char c) {
      if(c 【  e  】 256) {
	     return String.format("\\x%02X", (int) c);
	  }
	  return String.format("\\x%04X", (int) c);
   }

ここも問題文を確認します。上記はJavaScriptの場合のエンコードをしている箇所です。

文字コードが256未満の英数字以外の文字は、"\xXX"に変換する。ここで、XXは変換対象の文字の文字コードを表す、2桁の16進数である。

とあります。「文字コードが256未満の英数字以外の文字」というのを「c 【 e 】 256」で表現します。文字cを整数型にキャストすると、文字コードを求めることができますが、比較対象が256の数値なので自動的にキャストしています。「未満」を表現すればいいので「イ : <」となります。

   protected String encode(char c) {
      if(c < 256) {
	     return String.format("\\x%02X", (int) c);
	  }
	  return String.format("\\x%04X", (int) c);
   }

平成27年度春 基本情報技術者試験 午後 問11 ソフトウェア開発(Java) 目次

  1. 問題文とキーワード
  2. 設問1
  3. 設問2

一覧に戻る

タグ: ,,,,

PR広告

フェイスブックコメント

平成28年度秋 基本情報技術者試験 午後 テキスト・動画解説

平成28年度秋 基本情報技術者試験 午前 テキスト・動画解説

平成28年度春 基本情報技術者試験 午後 テキスト・動画解説

平成28年度春 基本情報技術者試験 午前 テキスト・動画解説

平成27年度秋 基本情報技術者試験 午後 テキスト・動画解説

平成27年度春 基本情報技術者試験 午後 テキスト・動画解説

平成27年度春 基本情報技術者試験 午前 テキスト・動画解説

平成26年度秋 基本情報技術者試験 午前 テキスト・動画解説

平成26年度春 基本情報技術者試験 午前 テキスト・動画解説