요약

  • RFC 1556은 오른쪽에서 왼쪽 방향과 왼쪽에서 오른쪽 방향이 섞인 메일을 표현하는 세 가지 방식을 기술했다. 작성자가 준비하는 시각 순서, 알고리즘이 해석하는 암시적 순서, 그리고 본문 안의 제어 문자가 지시하는 명시적 순서가 그것이다.
  • MIME은 비(非)ASCII 콘텐츠를 보존할 수 있었지만, 수신자가 의도된 읽기 순서를 재구성할 것이라는 보장은 아니었다. 문자셋, 방향 모드, 렌더러 맥락은 수신의 서로 다른 부분이었다.
  • 이 메모는 인터넷 표준이 아니라 Informational 문서였다. 이후의 HTML, 유니코드, UTF-8 메일 작업은 이 경계가 지속됐음을 보여주지만, RFC 1556의 명칭이 직접 계승되거나 채택됐다는 것을 증명하지는 않는다.

두 명의 독자가 같은 줄을 받았다

1993년의 한 메일 메시지를 상상해 보라. 제목이나 본문이 히브리어와 영어를 번갈아 쓰고, 중간에 날짜와 제품 번호가 들어 있다. MIME 전송 인코딩은 유효하다. 수신 시스템은 모든 옥텟을 의도된 문자로 디코딩한다. 아카이브는 손상된 바이트 하나 없이 메시지를 보존한다.

한 독자는 작성자가 기대한 대로 줄을 표시한다. 다른 독자는 영어 구절과 구두점, 숫자를 전혀 다른 가시적 배치로 옮겨 놓는다. 세 번째 독자는 처음에는 정확해 보이다가, 텍스트를 새 창으로 복사하는 순간 순서가 다시 바뀐다.

이 논쟁을 가릴 수 있는 전송 체크섬은 없다. 세 시스템 모두 같은 문자를 갖고 있을 수 있다. 불일치는 전달 이후에 시작된다. 저장된 순서가 인간의 눈을 위한 한 줄이 되는 방식을 각 시스템이 결정해야 하는 바로 그 지점에서.

이것이RFC 1556, 즉Handling of Bi-directional Texts in MIME이 다룬 경계였다. Hank Nussbacher가 1993년 12월에 이 메모를 발행했다.RFC Editor 기록과IETF 기록은 이를 Informational로 분류한다. 이 문서는 인터넷 표준을 명시적으로 지정하지 않았다.

제안은 작았다. 쌍방향 MIME 텍스트를 위한direction관례를 기술하고 세 가지 표현 모드를 구분하는 것이었다. 그 작은 문법 뒤에 있던 문제는 훨씬 컸다. 네트워크는 표현(representation)을 전달할 수 있지만, 유일한 렌더링 결정까지 함께 전달하지는 않는다.

MIME은 '줄'을 해결하기 전에 '여정'을 먼저 해결했다

RFC 1521은 인터넷 메일에 단순 ASCII를 넘어서는 메시지 본문을 기술하는 방법을 제공했다. 본문 부분은 미디어 타입과 문자셋을 식별한 뒤, Base64나 Quoted-Printable을 사용해 옥텟이 구식 제약에 맞춰진 메일 인프라를 통과하도록 했다.RFC 1521 기록은 그 역사적 역할을 보존한다.

RFC 1522는 이 체계를 일부 헤더 필드로 확장했다. 작성자는 비ASCII 텍스트를 encoded-word로 변환했다. 이를 지원하는 리더는 그것을 인식하고, 전송 인코딩을 되돌리고, 지정된 문자셋으로 결과 텍스트를 표시했다.정보 페이지는 이를 헤더용 동반 사양으로 지목한다.

이 두 가지는 중요한 상호운용성 진전이었지만, 그 영수증은 한 경계에서 멈췄다. 문자셋은 인코딩된 값을 문자로 대응시킨다. 전송 인코딩은 제한된 경로를 통과하며 그 값을 보호한다. 그러나 어느 하나만으로는 아랍어-영어 또는 히브리어-영어가 섞인 줄을 왼쪽에서 오른쪽으로 표시할지, 오른쪽에서 왼쪽으로 표시할지, 아니면 삽입된 구간 주위에서 국소적으로 뒤집을지를 말해주지 않는다.

따라서 RFC 1556은 성공적인 MIME 디코더가 여전히 독자를 실패시킬 수 있는 지점에서 출발했다. 이 문서는 오른쪽에서 왼쪽 문자와 혼합 방향 자료를 담을 수 있는 문자셋으로 아랍어 ISO-8859-6과 히브리어 ISO-8859-8을 지명했다. 글자를 올바르게 맞추는 것은 필요했다. 그러나 그것이 글자들의 가시적 관계를 올바르게 맞추는 것과 같지는 않았다.

동반 히브리어 메모가 그 분리를 드러냈다

인접한RFC 1555는 Nussbacher와 Yehavi Bourvine이 집필했으며, MIME과 ISO-8859-8을 사용하는 히브리어 메일을 규정했다.RFC Editor 항목역시 이를 Informational로 표시한다.

이 메모는 기본 방향성이 시각(visual)이라고 명시했다. 히브리어 텍스트는 오른쪽에서 왼쪽으로 입력되고 읽히는 텍스트임에도 왼쪽에서 오른쪽으로 인코딩되었고, 그 후 평범한 MIME 메커니즘으로 왼쪽에서 오른쪽으로 전송됐다. 수신 디스플레이는 추상적인 논리 문장을 재구성하지 않았다. 작성자가 이미 예상 화면을 위해 저장된 문자를 배열해 놓은 것이다.

이 설계는 방향을 모르는 뷰어를 가능하게 했지만, 취약성을 상류로 옮겼다. 시각 순서의 아카이브는 이후 소프트웨어가 그것을 논리 순서 텍스트로 재해석하지 않는 한에 한해 의도된 모습을 유지한다. 같은 순서를 암시적 쌍방향 엔진에 넣으면, 그 엔진은 작성자가 이미 재배열한 것을 다시 재배열할 수 있다.

RFC 1555는 더 근본적인 손실도 기술했다. 일부 Listserv 구성은 메일을 재배포하거나 아카이브할 때 MIME 헤더를 생략했다. 그 헤더 없이는 인코딩된 콘텐츠가 그대로 남아 있으면서도, 그것을 해석하는 데 필요한 정보가 사라진다. 파일이 반드시 비어 있거나 손상된 것은 아니다. 그것을 둘러싼 계약이 벗겨져 나간 것이다.

이 메모의 예측은 특히 시사적이었다. 투명한 8비트 메일은 Base64나 Quoted-Printable을 부분적으로 쓸모없게 만들 수 있지만, Content-Type과 방향성은 여전히 필요할 것이라고 저자들은 썼다. 더 깨끗한 파이프는 전송 부담을 없앨 수 있지만, 표현의 소유자가 누구인지는 답하지 않는다.

시각 모드는 작성자에게 책임을 지웠다

RFC 1556의 첫 번째 모드는 기본값이었다. 시각 방향성이며, 새로운 접미사 레이블 대신 평범한 ISO-8859 문자셋 이름을 사용한다.

디스플레이에는 왼쪽에서 오른쪽이라는 하나의 주 방향이 있었다. 뷰잉 애플리케이션은 텍스트를 단방향으로 취급하고, 그 내용의 방향을 알지 못했다. 작성 애플리케이션은 그 고정된 순서로 출력했을 때 올바르게 보이도록 시퀀스를 준비해야 했다. 표시 시점에 방향 제어 문자도 순서화 알고리즘도 개입하지 않는다.

이 매력은 쉽게 보인다. 단순한 수신자도 메시지를 표시할 수 있다. 오래된 터미널은 언어 모델을 필요로 하지 않는다. 발신자가 보는 것을 이미 배열된 한 줄로 직렬화할 수 있다.

대가는 숨겨진 상태(hidden state)다. 의도된 순서는 작성자의 준비 과정과, 수신자가 다시 재배열하지 않을 것이라는 가정 속에 존재한다. 편집, 검색, 커서 이동, 줄 바꿈, 복사-붙여넣기는 문장의 논리 구조가 아니라 하나의 예상 디스플레이를 따르는 저장 순서를 다룬다. 폭을 바꾸거나 라틴 토큰을 삽입하면, 기존 배열은 더 이상 새 줄을 기술하지 못할 수 있다.

따라서 시각 모드는 방향성을 제거한 것이 아니었다. 결정을 전송 이전으로 옮기고, 방향을 구분하지 못하는 뷰어를 계약의 일부로 만든 것이다.

암시적 모드는 알고리즘에게 책임을 지웠다

암시적 방향성을 위해 RFC 1556은 접미사i가 붙은 문자셋, 즉ISO-8859-6-i와ISO-8859-8-i를 제안했다.

여기서 저장된 문자는 모든 국소 표시 동작을 직접 담지 않는다. 표현은 문자 유형, 인접 문자에 대한 상대 위치, 주 방향을 사용하는 알고리즘이 결정한다. 메모는 전체 절차가 복잡하다며 구현자에게 ECMA TR/53을 참조하도록 안내했다.

책임은 하류로 이동했다. 작성자는 더 논리적인 시퀀스를 유지할 수 있지만, 수신자는 모드를 인식하고, 호환되는 방향 속성을 부여하고, 같은 맥락을 해석해야 했다. 기본 방향이 중요했다. 구두점, 숫자, 중립 문자, 줄이 나뉘는 지점도 마찬가지였다.

암시적 모드는 보이지 않는 편집상의 가정을 실행 가능한 의존성으로 바꿔 놓았다. 두 뷰어는 같은 문자셋을 선언받고도, 서로 다른 규칙 개정판을 구현하거나, 서로 다른 단락 방향을 지정하거나, 텍스트를 서로 다르게 줄 나누면 불일치할 수 있었다. 올바른 수신에는 페이로드 해시 이상이 필요했다. 결정 환경까지 필요했다.

그렇다고 알고리즘이 자의적인 것은 아니다. 공유된 알고리즘은 상호운용성을 크게 개선할 수 있다. 다만 그 출력은 전송이 이미 증명한 속성이 아니라, 추가적인 기술적 결과라는 뜻이다.

명시적 모드는 제어 문자와 그 해석자에게 책임을 지웠다

나머지 제안 레이블은ISO-8859-6-e와ISO-8859-8-e였다. 명시적 모드에서는 방향 동작을 선언하기 위해 제어 시퀀스가 텍스트 사이에 끼워 넣어졌다.

이는 저자의 지시를 데이터 스트림 안에서 더 보이게 만들었다. 발신자는 주변 문자의 유형에만 의존하지 않고 방향 맥락을 열거나 변경할 수 있었다. 그러나 명시성은 두 가지 보존 의무를 추가했다. 제어 문자가 살아남아야 하고, 렌더러가 그 범위를 이해해야 했다.

낯선 제어 기능을 제거하는 sanitizer는 모든 보이는 글자를 유지하면서 순서 지시를 지워버릴 수 있다. 변환기는 제어 문자를 불투명한 데이터로 보존하되 그것을 무시하는 렌더러에 넣을 수 있다. 짝이 맞지 않거나 잘못 놓인 제어 문자는 의도보다 먼 곳까지 영향을 미칠 수 있다. 표시 결과는 토큰 스트림과, 그 자체로는 보이는 글리프가 없는 토큰을 해석하는 상태 기계에 달려 있었다.

RFC 1556은 그 기반이 된ECMA TR/53작업이 세 가지 제어 기능을 도입하고 기존 ECMA-48 기능 22개를 수정했다고 밝혔다. 그 규모는 명시적 모드를 단일한 '오른쪽에서 왼쪽 표시자(right-to-left marker)'로 축소 기술하는 것에 대한 경고다. 방향은 활성 위치, 이동, 그리고 저장 데이터와 표현 사이의 관계에 영향을 미쳤다.

ECMA는 데이터 표면과 표현 표면을 분리했다

ECMA TR/53의 장치 모델은 '방향'이라는 단어보다 이 구조적 문제를 더 명확하게 만든다. 쌍방향 이미징 장치는 그래픽 문자와 제어 기능의 스트림을 받는다. 이 장치는 데이터 구성요소와 표현 구성요소를 유지할 수 있고, 관련 작성 관례에 따라 인간이 읽을 수 있는 그래픽 이미지를 생성한다.

이 구성요소들은 장식적인 추상이 아니었다. 활성 데이터 위치와 활성 표현 위치는 서로 다른 규칙에 따라 움직일 수 있었다. 암시적 이동, 명시적 이동, 간접 이동이 정의되어야 했다. 백스페이스, 캐리지 리턴, 커서 보고는 어느 구성요소에, 어느 방향에 관한 것인지 알지 못하면 안전하게 해석할 수 없었다.

RFC 1556은 그 더 깊은 장치를 MIME 지향의 구분으로 압축했다. 메시지는 뷰잉 측에 어떤 가정의 계열을 받고 있는지 알려주어야 했다. 그렇지 않으면 같은 바이트 시퀀스가 잘못된 표현 기계로 들어갈 수 있었다.

이것이 쌍방향 텍스트가 결코 단순한 글꼴 선택이 아니었던 이유다. 글꼴은 글리프를 선택한다. 그러나 순서화 계약은 어떤 글리프가 어떤 글리프 옆에 나타날지, 그리고 인간이 문장을 어떻게 재구성할지를 결정한다.

네 가지 실패는 모든 보이는 문자를 보존할 수 있었다

첫 번째 실패는 메타데이터 상실이다. 게이트웨이나 아카이브는 본문은 유지하면서 Content-Type을 드롭하거나 정규화한다.ISO-8859-8-i가ISO-8859-8이 되거나, 방향 선언이 사라진다. 문자 값은 남는다. 모드 선택은 그렇지 않다.

두 번째는 이중 재배열이다. 작성자는 단순 뷰어를 위해 시각 순서를 저장한다. 현대 렌더러는 논리 순서를 가정하고 암시적 알고리즘을 적용한다. 두 구성요소는 각자 설계된 대로의 동작을 수행하고, 그 동작을 두 번 수행했기 때문에 줄이 틀어진다.

세 번째는 제어 문자 제거다. 명시적 방향 지시가 인쇄 불가능하거나 수상한 문자로 간주되어 제거된다. sanitizer 이후의 바이트 비교는 정확히 변화를 보여주지만, 보이는 글자만 비교하는 평문 비교는 동등하다고 잘못 보고할 수 있다.

네 번째는 맥락 드리프트다. 두 암시적 렌더러가 서로 다른 기본 방향, 줄 바꿈, 마크업 경계, 알고리즘 개정판을 사용한다. 디코딩된 문자 시퀀스는 동일하다. 해석된 가시 순서는 그렇지 않다.

숫자와 구두점은 이 실패들을 운영상 중요하게 만든다. 뒤집힌 구절은 눈에 띄지만, 식별자의 잘못된 쪽에 붙은 구두점은 그렇지 않을 수 있다. 사용자는 논리 순서가 화면과 다른, 겉보기에 그럴듯한 주소나 참조 번호를 복사할 수 있다. 올바름은 '모든 문자가 존재하는가'만 묻는 방식으로 감사될 수 없다.

이후의 시스템은 경계를 유지하면서 장치를 바꿨다

이후의 사양은 그 관계가 좁게 유지될 때에만 유용하다. 1997년에 발표된RFC 2070은 HTML에 국제화 기능을 추가했으며, 그중DIR속성과BDO오버라이드 요소가 있었다.기록은 웹 마크업에 속하며, MIME 문자셋 접미사 배포에는 속하지 않는다.

유니코드 쌍방향 알고리즘의 초기 버전은 유니코드 텍스트를 논리적 메모리 순서로 기술하고, 방향 서식 코드를 문자 해석이 아닌 표시 순서에 영향을 주는 것으로 다뤘다.현재 UAX #9는 상당히 진화했으며, 상위 프로토콜이 맥락을 설정하거나 방향 동작을 부과할 수 있는 방법을 정의한다.

2012년으로 시점이 확인되는정보 페이지를 가진RFC 6532는, 이후 단말 간(end-to-end) UTF-8 모델 하에서 인터넷 메시지 헤더 값에 UTF-8을 직접 사용하는 것을 허용했다. 이는 그런 메시지에서 encoded-word 우회의 필요성을 줄였다. 그러나 저장 문자 계층과 표시 순서 계층을 하나로 합치지는 않았다.

이 문서들은 RFC 1556이 HTML 방향성이 되었거나, 유니코드 알고리즘이 되었거나, SMTPUTF8이 되었다는 것을 증명하지 않는다. 이 문서들은 반복되는 하나의 경계를 보여준다. 문자 레퍼토리를 넓히고 전송 중에 보호하는 것만으로는, 인간에게 보이는 하나의 순서가 선택되지 않는다는 것.

스크린샷 하나는 적합성 기록이 아니다

유용한 조사는 세 가지 영수증을 보존한다.

전송 영수증은 원시 옥텟, 콘텐츠 해시, 전송 인코딩, 디코딩된 문자 시퀀스를 담는다. 이것은 표현이 여정 동안 변경되었는지에 답한다.

해석 영수증은 Content-Type, 문자셋, 방향 모드, 명시적 방향 제어, 단락 또는 기본 방향, 상위 마크업과 스타일, 렌더러와 알고리즘 버전을 보존한다. 이것은 수신자가 어떤 규칙을 적용해야 한다고 믿었는지에 답한다.

표현 영수증은 줄 분할, 해석된 가시 순서, 스크린샷, 복사/붙여넣기 또는 왕복 동작을 기록한다. 이것은 무엇이 나타났는지, 그리고 겉보기 순서가 재사용에서 살아남았는지에 답한다.

입력 없이 남은 스크린샷은 하나의 화면이 어느 시점에 하나의 배열을 보여주었다는 것만 증명할 수 있다. 저장된 시퀀스가 올바른지, 다른 폭에서 같게 동작할지, 텍스트를 복사해도 의미가 유지될지는 증명하지 못한다. 렌더 기록 없는 페이로드 해시는 보완적인 반쪽을 증명할 뿐이다.

짝지은 픽스처는 아랍어나 히브리어에 라틴 구간, 숫자, 구두점, 중립 문자, 중첩 맥락, 서로 다른 줄 폭을 섞어야 한다. 저장된 시퀀스와 해석된 표시를 따로 비교해야 한다. 마이그레이션이 렌더러를 바꾸면, 차이가 설명될 때까지 이전 결과와 새 결과를 모두 보존해야 한다. 아카이브를 조용히 재작성하면 잘못된 선택을 되돌리는 데 필요한 증거가 사라진다.

발행이 곧 운영 현실은 아니었다

Lu Heng의Running-Code Primacy는 오늘날의 유용한 규율을 제공한다. 문서는 조정을 위한 산물이며, 그 주장은 구현, 운영, 사용에서 살아남아야 한다는 것이다. RFC 1556의 발행은 방향성 관례가 문서화되었다는 것을 증명한다. 어떤 메일 시스템이 그것을 구현했는지, 독자들이 무엇을 보았는지는 증명하지 않는다.

Minimum Initial Specification, Localized Future Decision and Voluntary Adoption은 어떤 공통 규칙이 진정으로 필요하며 국소적으로 검증 가능한지를 묻는다. RFC 1556은 전송된 문자의 동일성이 읽을 수 있는 쌍방향 메일에 너무 약한 불변식이었음을 드러낸다. 모드, 보존된 맥락, 호환되는 표현 절차도 필요했다.

현실 계층(reality-layer)의 관점은 한 영수증이 다른 영수증을 사칭하는 것을 막는다. 표현, 운반, 해석, 가시적 결과는 별개의 계층에 속한다. 이후의 교리는 Nussbacher나 ECMA의 의도에 대한 증거가 아니라, 우리 자신의 역사적 주장을 자료가 증명하는 범위 안에 유지하는 방법이다.

사라진 질문은 누가 이미 행동했는가였다

시각, 암시적, 명시적 방향성은 단순한 세 가지 렌더링 취향이 아니었다. 그것들은 책임의 문제에 대한 세 가지 답이었다.

시각 모드에서는 작성자가 이미 행동했다. 암시적 모드에서는 수신자의 알고리즘이 행동할 것이었다. 명시적 모드에서는 발신자가 명령을 공급하고 수신자가 그것을 실행했다. 어느 답이 적용되는지 모르는 시스템은 자신의 가정에 완벽하게 충실하면서도 그 메시지에 대해서는 틀릴 수 있었다.

따라서 RFC 1556의 역사는 MIME이 히브리어나 아랍어를 전달하지 못한 이야기가 아니다. MIME은 여정을 가능하게 했다. 이 메모는 여정이 인증할 수 없는 것을 지목했다.

온전한 메시지는 순서 보존에 대한 영수증이다. 선언된 모드와 남아 있는 제어 문자는 해석 맥락에 대한 영수증이다. 시험된 렌더러는 하나의 가시적 결과에 대한 영수증이다. 세 가지가 모두 보존될 때만, '정확히 도착했다'는 말이 '바이트가 여기 도착했다'보다 더 많은 것을 의미할 수 있다.

출처