Skip to content

fix: DOM 검증기가 스키마 등록 여부를 XML 파일 유무로 판단하는 문제 수정 - #371

Open
wantaekchoi wants to merge 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/xml-domvalidator-schema-check
Open

fix: DOM 검증기가 스키마 등록 여부를 XML 파일 유무로 판단하는 문제 수정#371
wantaekchoi wants to merge 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/xml-domvalidator-schema-check

Conversation

@wantaekchoi

Copy link
Copy Markdown
Contributor

수정 사유 Reason for modification

  • 버그수정 Bug fixes
  • 기능개선 Enhancements
  • 기능추가 Adding features
  • 기타 Others

수정된 소스 내용 Modified source

EgovDOMValidatorService.parse() 가 JAXP 스키마 검증을 켜는 조건과 그때 넘기는 값이 서로 다른 프로퍼티입니다.

// EgovDOMValidatorService.java:88
if (!ObjectUtils.isEmpty(getXMLFile())) {
    factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
    factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", getSCHEMAFile());
}

형제인 EgovSAXValidatorService 는 같은 자리에서 스키마 파일이 있는지만 봅니다.

// EgovSAXValidatorService.java:91
if (getSCHEMAFile() != null) {
    parser.setFeature("http://apache.org/xml/features/validation/schema", true);
    parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
    parser.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", getSCHEMAFile());
}

XML 을 파일로 주는지 문자열로 주는지는 스키마 검증 여부를 정하는 조건이 아니라서, DOM 쪽은 두 방향으로 어긋납니다.

스키마를 준 적이 없는데 스키마 검증이 켜집니다. XML 을 setXMLFile() 로 주고 parse(true) 를 부르면 cvc-elt.1.a: 'person' 요소의 선언을 찾을 수 없습니다 가 나옵니다. cvc- 는 XML Schema 검증 오류 코드입니다. 조건이 getXMLFile() 이라, 같은 XML 을 setXML() 로 주면 이 검증은 켜지지 않습니다.

반대로 스키마를 줘도 무시됩니다. XML 을 setXML() 로 주고 setSCHEMAFile() 을 부른 뒤 parse(true) 를 부르면 스키마가 등록되지 않아 문서가 부적합함: 문법을 찾을 수 없습니다 가 나옵니다. 같은 입력에서 SAX 쪽은 스키마 등록을 시도합니다.

AS-IS / TO-BE

값으로 이미 쓰고 있는 프로퍼티를 조건에도 씁니다. 형제 SAX 쪽과 같은 조건입니다.

-            if (!ObjectUtils.isEmpty(getXMLFile())) {
+            if (!ObjectUtils.isEmpty(getSCHEMAFile())) {

영향 범위

저장소 안에서 setSCHEMAFile() 을 부르는 코드는 이 PR 이 추가한 테스트뿐입니다.

스키마를 주지 않고 XML 을 파일로 주던 호출자는 parse(true) 에서 cvc- 계열 스키마 오류 대신, 같은 XML 을 문자열로 줬을 때와 같은 결과를 받습니다. 둘 다 검증에 실패하는 입력이라 성공·실패 판정은 달라지지 않습니다.

스키마를 주면서 XML 을 문자열로 주던 호출자는 지금까지 스키마가 무시됐으므로, 앞으로는 XML 을 파일로 줬을 때와 같은 결과가 됩니다. 다만 이 클래스는 XXE 방지로 외부 개체 해석을 막고 있어(:94-95, :147-148), 스키마 등록을 시도하면 스키마 로딩 단계에서 SAXException: External entity resolution is disabled for security (XXE prevention) 로 끝납니다. 이 호출자가 받는 예외가 ValidatorException 에서 SAXException 으로 바뀌고, 스키마 검증이 실제로 동작하게 되는 것은 아닙니다. XXE 설정과 스키마 등록이 부딪히는 것은 SAX 쪽도 같아 이 수정 밖의 일로 두었습니다.

JUnit 테스트 JUnit tests

  • JUnit 테스트 JUnit tests
  • 수동 테스트 Manual testing

XML 을 파일로 준 결과와 문자열로 준 결과가 같은지 비교하는 테스트를 더했습니다. 로케일에 따라 메시지가 달라지므로 문자열을 그대로 단정하지 않고 두 실행 결과를 서로 비교했고, 스키마를 주지 않은 경우는 cvc- 코드가 나오는지로 봅니다.

수정을 되돌리면 두 건 모두 실패합니다.

$ mvn -o test -pl Foundation/org.egovframe.rte.fdl.xml -Dtest=EgovDOMValidatorSchemaSourceTest
[ERROR] EgovDOMValidatorSchemaSourceTest.schemaModeStaysOffWithoutSchemaFile:66 스키마 없이 스키마 검증이 수행되었다: org.egovframe.rte.fdl.xml.exception.ValidatorException: Parsing error:  cvc-elt.1.a: 'person' 요소의 선언을 찾을 수 없습니다.<br/> ==> expected: <false> but was: <true>
[ERROR] Tests run: 2, Failures: 2, Errors: 0, Skipped: 0

수정 후 모듈 전체입니다. 기존 3건은 그대로 통과합니다.

$ mvn -o test -pl Foundation/org.egovframe.rte.fdl.xml
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS

테스트 브라우저 Test Browser

  • Chrome
  • Firefox
  • Edge
  • Safari
  • Opera
  • Internet Explorer
  • 기타 Others

테스트 스크린샷 또는 캡처 영상 Test screenshots or captured video

화면이 없는 실행환경 모듈이라 첨부하지 않았습니다.

EgovDOMValidatorService.parse() 는 getXMLFile() 이 비어 있지 않으면 JAXP 의
schemaLanguage 를 XML Schema 로 바꾸고 schemaSource 에 getSCHEMAFile() 을
넣는다. 조건을 거는 프로퍼티와 값으로 쓰는 프로퍼티가 서로 다르다.

그래서 두 방향으로 어긋난다. 스키마 없이 XML 만 파일로 넘기면 schemaSource
가 null 인 채 스키마 모드가 켜져, parse(true) 가 "cvc-elt.1.a: 'person'
요소의 선언을 찾을 수 없습니다" 로 실패한다. 같은 XML 을 문자열로 넘기면
스키마 모드가 꺼져 있어 문법을 찾을 수 없다는 다른 결과가 나온다. 반대로
스키마를 줘도 XML 을 문자열로 넘기면 스키마가 등록되지 않아 setSCHEMAFile()
이 무시된다. XML 을 파일로 주는지 문자열로 주는지는 검증 방식을 정하는
조건이 아니다.

형제인 EgovSAXValidatorService 는 같은 자리에서 getSCHEMAFile() 이 null 인지
만 보고 스키마 검증 기능을 켠다. 그 조건에 맞췄다.

XML 을 파일로 준 결과와 문자열로 준 결과가 같은지 확인하는 테스트를 더했다.
수정을 되돌리면 두 건 모두 실패한다. 모듈 테스트 5건 통과.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant