Hoon222y

[1228] Secure Coding 본문

코딩/교육

[1228] Secure Coding

hoon222y 2018. 12. 28. 13:48

EXP00. 메서드가 반환하는 값을 무시하지 마라

EXP01. 널 포인터를 역참조 하지 않도록 하라

EXP02. 배열 내용을 비교하려면 Arrays.equals 메서드를 사용해라 

EXP03. 박싱된 기본형을 비교할 때, 동등 비교 연산자를 사용하지 마라

EXP04. 오토 박싱된 기본 타입이 의도한 타입인지를 확인하라

EXP05. assert 안에서 부작용이 있는 표현식은 사용하지 말자


NUM00. 정수 오버플로가 발생하지 않도록 하라 

NUM01. 오차 없는 정확한 계산을 할 때는 부동 소수점 타입을 사용하지 말자 

//문자나 바이트를 읽는 메소드의 반환값을 저장할 때는 int 타입을 사용하라


1의 보수의 개념 -> 현대의 모든 cpu는 2의 보수

1 + ㅌ = 1 -> 1에 대한 1의 보수 X = 0

0 + X = 1 -> 0에대한 1의 보수 X = 1


1의 보수의 단점

1의 보수는 방식을 사용하면 계산이 잘됨

1. 음의 0과 양의 0이 공존하게 된다. 

2. 절대값이 같은 두 수의 합이 0이 되지 않음 


2의 보수로 변경하는 방법

1. 1의 보수로 변경한다. 

2. 1을 더한다. 



import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.lang.reflect.Array;

import java.math.BigDecimal;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashSet;


//표현식 : EXP00 ~..


//EXP00. 메서드가 반환하는 값을 무시하지 마라

//public class main {

// public static void main(String[] args) {

// String x= "hotel";

//

// //문자열 중 특정 문자를 다른 문자로 치환

// // replace 메서드를 호출하면 문자열이 변경될 꺼 같지만 안그런다.

// // 이는 String 객체가 불변객체이기  때문이다. 따라서 replace 

// // 메서드는 수정된 문자열을 갖는 새로운 String 객체의 참조를 반환

// x = x.replace('h','m');

// System.out.println(x);

// }

//}




//

//public class main {

// //아래의 함수는 이메일 정보로부터 사용자의 이름을 얻어오는 메서드라고 가정

// public static String getNameFrom(String email) {

// //..

// //여기서 에러가 발생하여 널이 반환된다고 한다.

// return null;

// }

// //현재 코드가 널 참조로 인한 예외가 발생하지 않도록 해보아라

// //사용기 전에 널체크를 수행한다.

// public static void main(String[] args) {

// String name = getNameFrom("asd@naver.com");

// if(name != null && name.equals("asd"))

// System.out.println("same");

// else

// System.out.println("not same");

// }

//}


//EXP02. 배열 내용을 비교하려면 Arrays.equals 

// 메서드를 사용해라 

//public class main {

// public static void main(String[] args) {

// int[] arr1 = {1,2,3,4,5};

// int[] arr2 = {1,2,3,4,5};

//

// // 객체가 가진 값을 비겨 :equals

// // 동등 비교 연산자(!= , ==) 는 객체가 가진 값을 비교하는것이 아니라

// // 객체 자체를 비교하는 개념이다. 

// if(arr1 == arr2)

// System.out.println("same");

// else

// System.out.println("not same");

//

//// if(arr1.equals(arr2))

//// System.out.println("same");

//// else

//// System.out.println("not same"); 다르다고 나옴 

//

// // 배열은 Object 클래스의 equals 메서드를 오버라이딩 하지 않았다. 

// // 따라서 두 배열에 대한 내용을 비교하려면 Arrays.equals 메서드를

// // 사용하면 된다.

// if(Arrays.equals(arr1,arr2))

// System.out.println("same");

// else

// System.out.println("not same");

// }

//}



//// EXP03. 박싱된 기본형을 비교할 때, 동등 비교 연산자를 사용하지 마라

//public class main {

// public static void main(String[] args) {

// //정수를 저장하는 자료구조를 사용한다고 가정한다. 

// //ArrayLiust<int> arr = new Array<>();

// ArrayList<Integer> arr1 = new ArrayList<>();

// for(int i=0;i<10;i++) {

// arr1.add(i+200); //이렇게 하면 결과값 0

// //arr1.add(i); //이렇게 하면 결과값 10

// }

// ArrayList<Integer> arr2 = new ArrayList<>();

// for(int i=0;i<10;i++)

// arr2.add(i+200);

//

// int count = 0;

// for(int i=0;i<10;i++) {

// //if(arr1.get(i) == arr2.get(i))

// if(arr1.get(i).equals(arr2.get(i)))

// ++count;

// }

// System.out.println(count);

// Integer i1 = 1000;  //integer i1 = new Integer(1000);

// Integer i2 = 1000; //integer i2 = new Integer(1000);

//

// // 동등비교는 객체가 가진 값을 비교하는 것이 아니라 객체 자체가 같은지

// // 다른지를 비교하는 연산자 입니다.

// if(i1 == i2)

// System.out.println("same");

// else

// System.out.println("not same");

//

// //자바의  래퍼 클래스들은 자주 사용되는 값에대하여 미리 객체를 생성하고 

// // 사용한다. 정수 래퍼 클래스의 경우, -128 ~ 127 사이의 값에 대하여

// // 미리 객체를 생성하고 사용한다. 따라서 이 범위 사이에서 동등 비교를 할 경우

// // 같은 객체인지가 아닌 객체가 가진 값을 비교하는 착각을 일으킨다.

// // 따라서 모든 객체에 대하여 객체가 가진 값을 비교하려면 동등비교 연산자가 아니라

// // equals 메서드를 사용해야한다. 

//

// Integer i3 = 100; 

// Integer i4 = 100;

//

// if(i3 == i4) //same 출력 

// System.out.println("same");

// else

// System.out.println("not same");

// }

//}


//// EXP04. 오토 박싱된 기본 타입이 의도한 타입인지를 확인하라

//public class main {

// public static void main(String[] args) {

// HashSet<Short> set = new HashSet<>();

// for(Short i=0; i<100;i++) {

// set.add(i);

// //set.remove(i-1);

// set.remove((short)(i-1));

// }

// System.out.println(set.size());

// }

//}




////EXP05. assert 안에서 부작용이 있는 표현식은 사용하지 말자

//public class main {

// public static void main(String[] args) {

// ArrayList<String> names = new ArrayList<>();

// names.add("life");

// names.add("hell");

//

// //assert 는 실행 시의 옵션 값에 따라 활성 또는 비활성입니다.

// // 이 때, assert가 비활성화되어 있다면 assert 다음의 표현식은 평가되지

// // 않습니다. 따라서 이는 사용자가 의도하지 않게 동작하므로 이러한 효과를

// // 부수효과(side effect)라고 한다.

// //assert names.remove("life");

//

// // 때문에 이러한 부수 효과를 피하려면 assert가 활성 또는 비활성에 상관없이

// // 의도한대로 실행되도록 하려면 assert 다음에 표현식을 넣기보다는

// // 표현식의 결과를 사용하는 것이 좋습니다. 

//

// boolean result = names.remove("life");

// assert result;

// System.out.println(names.size());

// }

//}


////NUM00. 정수 오버플로가 발생하지 않도록 하라 

//public class main {

//// public static int safeAdd(int left,int right) {

//// if((left> Integer.MAX_VALUE - right)||

//// (left < Integer.MAX_VALUE - right))

//// throw new ArithmeticException("integer overflow");

//// return left +right;

//// }

// public static int safeAdd(int left,int right) {

// if(right > 0? left > Integer.MAX_VALUE- right 

// : left < Integer.MAX_VALUE - right)

// throw new ArithmeticException("integer overflow");

// return left +right;

// }

// public static void main(String[] args) {

// int num1 = Integer.MAX_VALUE;

// int num2 = 1; //1 이면 오류 -1이면 정상 출력 가능 

//

// //int result = num1 + num2;

// int result = safeAdd(num1,num2);

// System.out.println(result);

// }

//}


////NUM01. 오차 없는 정확한 계산을 할 때는 부동 소수점 타입을 사용하지 말자 

//public class main {

// public static void main(String[] args) {

//// float f = 0.1f;

//// float sum = 0.0f;

//// double f = 0.1f;

//// double sum = 0.0f;

////

////

//// for(int i= 0;i<1000;i++) {

//// sum += f;

//// }

//// System.out.println(sum);

//

// // 해결 방법 : long 타입보다 더 큰 범위의 연산을 하고 싶다면

// // BinIngeger 클래스를 사용하면 되고, 

// // double 보다 더 큼 범위의 연산을 하고 싶다면 

// // BigDecimal클래스를 사용하면 된다. 

//

// BigDecimal d = new BigDecimal("0.1");

// BigDecimal sum = new BigDecimal("0.0");

//

// for(int i= 0;i<1000;i++) {

// //sum += d;\

// sum = sum.add(d);

// }

// System.out.println(sum);

// }

//}




//public class main {

// public static void main(String[] args) {

// int count = 0;

// //for(float i=0.1F;i<=1.0F;i+=0.1F)

// for(int i=0;i<10;i++)

// ++count;

//

// System.out.println(count);

// }

//}



//문자나 바이트를 읽는 메소드의 반환값을 저장할 때는 int 타입을 사용하라 

public class main {

public static void main(String[] args) {

FileInputStream is = null;

try {

is = new FileInputStream(new File("d:\\a.txt"));

int size=0;

//데이터의 타입이바이트인 경우 -1과 0xFF의 값을 구분하지 못한다 

// 이를 해결하기 위해 read의 리턴타입인 int를 사용하면

//0xFF는 255로 0xFFFFFFF는 -1로 구분이 가능하다. 

int data = 0;

while((data = is.read()) != -1)

++size;

System.out.println("size = " + size);

}

catch(IOException e) {

e.printStackTrace();

}finally {

try {is.close();}catch(IOException e) {}

}

}

}


Comments