이벤트 훅 스크립트를 검토하는데 할당된 작업에서 핵심 용어를 추출해 검색하라는 지시가 있었다. 그 지시는 작업 내용이 입력으로 들어온다는 전제 위에 서 있었다.
Table of contents
Open Table of contents
입력을 찍어 본 이유
스크립트는 입력의 구조를 가정하고 짜여 있고 그 가정이 맞는지는 코드만 읽어서는 알 수 없다. 그래서 실제로 들어오는 입력을 파일로 떨어뜨려 봤다.
떨어진 파일을 열어 보니 들어 있는 것은 식별자와 종류 둘뿐이었다. 지시가 전제한 작업 내용에 해당하는 필드가 아예 들어 있지 않았다.
전제한 정보가 없었다
그러면 작업에서 용어를 추출하라는 그 지시는 실행될 수가 없는 것이다. 그런데 스크립트는 오류를 내지 않고 빈 문자열로 검색을 돌리고 끝난다.
전제가 틀리면 그 전제 위의 지시가 통째로 무효가 되는데 실행은 성공으로 끝난다. 없는 것 대신 있는 것으로 바꿔서 종류 이름을 검색어로 쓰게 했고 정확도는 떨어져도 실제로 돌게 됐다.
이벤트마다 다른 출력 처리
두 번째로 확인한 것은 어떤 이벤트가 스크립트의 출력을 아예 보지 않는다는 점이었다. 다른 이벤트는 출력한 구조화 데이터로 제어하는데 이쪽은 종료 코드만 본다.
일반적인 설명이 모든 이벤트에 그대로 적용되는 것처럼 읽히는 것이 이 오해의 원인이었다. 출력을 아무리 만들어도 그 이벤트에서는 제어에 쓰이지 않는다.
셸 치환이 깨지는 자리
세 번째는 따옴표를 이스케이프하려고 쓴 셸 문자열 치환이었다. 다른 특수문자가 섞이면 변수 확장이나 매치 참조로 해석돼 예상 밖의 결과가 나온다.
가공 순서도 나빠서 이스케이프 함수에 도달하기 전에 셸 치환 단계에서 이미 값이 깨졌다. 문자열을 셸 치환으로 가공하지 않고 전용 도구에 맡기는 방식으로 바꿨다.
조용한 오류의 자리
이 셋의 공통점은 전부 오류를 내지 않고 잘못 동작한다는 점이었다. 빈 검색어로 검색하고 출력이 무시되고 값이 깨진 채로 진행되는데 실행 자체는 성공한다.
본체 로직은 결과가 화면에 나오므로 틀리면 드러나지만 훅은 배경에서 돌아 안 도는 것과 잘못 도는 것을 구분하기 어렵다. 그래서 훅은 입력과 출력과 종료 코드를 직접 봐야 했다.
정리
- 이벤트 입력에 기대한 정보가 없을 수 있다
- 스크립트는 입력 구조를 가정하고 짜여 있다
- 실제 입력을 찍어 봐야 그 가정이 드러난다
- 전제가 틀리면 지시가 무효가 되는데 실행은 성공한다
- 이벤트마다 출력 처리 방식이 다를 수 있다
- 셸 치환은 특수문자에 취약하므로 전용 도구에 맡긴다
- 가공 순서 때문에 이스케이프 전에 값이 깨질 수 있다
- 훅의 오류는 조용하므로 입력과 출력과 종료 코드를 직접 본다