From 2aa4220a3c0dc5229b7c7231c9b442a9cc7a8f0c Mon Sep 17 00:00:00 2001 From: z3rotig4r Date: Sun, 5 Jul 2026 14:07:31 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20MessageConverterImpl=20=EB=88=84?= =?UTF-8?q?=EB=9D=BD=EB=90=9C=20List/Record=20=ED=95=84=EB=93=9C=20NullPoi?= =?UTF-8?q?nterException=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit convertToValueObject()는 ListType·RecordType 분기에서 source를 각각 ((Collection) source).toArray(), ((Map) source).entrySet()로 역참조한다. 메시지 body에서 해당 List/Record 필드가 생략되면 source가 null로 전달되고, 타입 체계는 null을 유효한 값으로 허용하므로 단순 잘못된 입력으로 볼 수 없다. 이 경우 두 분기 모두 NullPointerException이 발생한다. 두 분기에서 역참조 전에 source가 null이면 null을 그대로 반환하도록 가드를 추가한다. 타입 체계가 허용하는 null 값 의미를 보존하며, 재귀로 처리되는 중첩 필드의 null도 안전하게 반환·대입된다. 테스트: convertToValueObject(null, listType/recordType)가 NPE 없이 null 반환 확인. --- .../service/impl/MessageConverterImpl.java | 10 ++++++++++ .../service/impl/MessageConverterImplTest.java | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Integration/org.egovframe.rte.itl.webservice/src/main/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImpl.java b/Integration/org.egovframe.rte.itl.webservice/src/main/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImpl.java index 53a053d4..2731e340 100755 --- a/Integration/org.egovframe.rte.itl.webservice/src/main/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImpl.java +++ b/Integration/org.egovframe.rte.itl.webservice/src/main/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImpl.java @@ -75,6 +75,11 @@ public Object convertToValueObject(Object source, Type type) throws ClassNotFoun return source; } else if (type instanceof ListType) { LOGGER.debug("### MessageConverterImpl convertToValueObject() : Type is a List Type"); + // 메시지 body에서 List 필드가 생략되면 source가 null로 전달된다. + // 타입 체계가 null을 유효 값으로 허용하므로, 역참조 전에 null을 그대로 반환한다. + if (source == null) { + return null; + } ListType listType = (ListType) type; Object[] components = ((Collection) source).toArray(); Class arrayClass = classLoader.loadClass(listType); @@ -85,6 +90,11 @@ public Object convertToValueObject(Object source, Type type) throws ClassNotFoun return array; } else if (type instanceof RecordType) { LOGGER.debug("### MessageConverterImpl convertToValueObject() : Type is a Record(Map) Type"); + // 메시지 body에서 Record 필드가 생략되면 source가 null로 전달된다. + // 타입 체계가 null을 유효 값으로 허용하므로, 역참조 전에 null을 그대로 반환한다. + if (source == null) { + return null; + } RecordType recordType = (RecordType) type; Map map = (Map) source; Class recordClass = classLoader.loadClass(recordType); diff --git a/Integration/org.egovframe.rte.itl.webservice/src/test/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImplTest.java b/Integration/org.egovframe.rte.itl.webservice/src/test/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImplTest.java index e729208e..78dafd0b 100755 --- a/Integration/org.egovframe.rte.itl.webservice/src/test/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImplTest.java +++ b/Integration/org.egovframe.rte.itl.webservice/src/test/java/org/egovframe/rte/itl/webservice/service/impl/MessageConverterImplTest.java @@ -253,6 +253,20 @@ public void testConvertToTypedObject() throws Exception { assertEquals(person.name, personMap.get("name")); } } + + @Test + public void testConvertToValueObjectWithNullListSource() throws Exception { + // 메시지 body에서 List 필드가 생략되면 source가 null로 전달된다. + // null 역참조(NPE) 없이 null을 반환해야 한다. + assertNull(messageConverter.convertToValueObject(null, personListType)); + } + + @Test + public void testConvertToValueObjectWithNullRecordSource() throws Exception { + // 메시지 body에서 Record 필드가 생략되면 source가 null로 전달된다. + // null 역참조(NPE) 없이 null을 반환해야 한다. + assertNull(messageConverter.convertToValueObject(null, recordType)); + } } class ValueObject {