요약

  • RFC 5229는 스크립트가variables기능을 명시적으로 요구했을 때에만 Sieve에set, 문자열 확장, 매치 변수를 추가했습니다.
  • 그 결과 만들어진 메모리는 의도적으로 경계가 있었습니다: 매치 캡처는 제어 흐름에 의존했고, 값은 현재 실행 중인 스크립트에 속했으며, 구현 한도는 지나치게 큰 값을 잘라낼 수 있었습니다.

필터에는 더 큰 기계가 아니라 작은 메모리가 필요했다

2008년 1월 무렵, Sieve는 이미 최종 전달을 위한 메일 필터링 언어로서 자리 잡은 정체성을 갖고 있었습니다. 기본 사양은 유용하되 제한을 유지하는 언어를 묘사했습니다: 변수, 루프, 셸 명령 실행 능력이 없었습니다. 이러한 생략은 어떤 프로그래밍 기능이라도 기다리는 빈 공간이 아니었습니다. 그것은 서버 측 사용자 필터가 메일 시스템에 요구할 수 있는 것의 경계를 표시했습니다.

RFC 5229는 그 경계의 한 부분을 신중하게 넘었습니다. 스크립트는require "variables"를 선언할 수 있었고, 그러면set으로 이름 붙은 문자열을 할당하고, 다른 문자열 안에 그것을 삽입하고, 스크립트가 만든 문자열을 검사할 수 있었습니다. 성공한 와일드카드 매치는 전체 매치를${0}으로, 와일드카드 조각들을${1},${2등으로 노출할 수 있었습니다. 그 실용적 가치는 명확했습니다: 규칙이 헤더에서 리스트 이름을 추출해 사서함 경로로 옮기거나, 같은 조각을 반복하지 않고 이후의 텍스트를 만들 수 있었습니다.

그러나 그것은 필터에 지속적인 메모리를 준 것과는 다릅니다. 이 확장은 변수가 현재 실행 중인 스크립트에만 보인다고 명시합니다. 사서함 전체 저장소, 이전 메시지의 기록, 사용자 간 공유 상태를 정의하지 않습니다. 표준이 실제로 규정하는 대상은 '이 스크립트가 실행되는 동안 문자열 데이터에 묶인 이름'인데, 확장이 '변수'라는 단어를 쓰는 방식은 실제 대상보다 크게 들릴 수 있습니다.

선언은 안전 모델의 일부였다

기능은 사용 전에 이름이 지어져야 했습니다.variables요구가 없는 스크립트는 변경된 문자열 의미를 조용히 물려받지 않았습니다. 확장 가능한 언어에서 이 디테일은 중요합니다. 기능은 단순한 연산이 아니라, 그 연산이 존재한다고 말하는 스크립트와 인터프리터 사이의 명시적 계약이기도 합니다.

활성화된 후, 변수 참조는 제어가 그 참조를 포함한 문장에 도달할 때 평가되었습니다. 인터프리터는 한 번의 치환 패스를 수행했습니다. 정의되지 않은 이름의 변수는 빈 문자열로 확장되었고, 이름은 대소문자를 구분하지 않았습니다. 이 선택들은 조합을 간결하게 만들었지만 일부 실수를 조용하게 만들었습니다. 철자가 틀린 참조는 누락된 값으로 자신을 알리는 대신 문자열 안으로 사라질 수 있었습니다. 다른${...}참조를 담고 있는 값은 두 번째 패스에서 재귀적으로 확장되지 않았습니다.

이 확장은string검사와 함께 몇 가지 좁은 수식어—ASCII 대소문자 변환, 첫 글자 대소문자 변환, 와일드카드 인용, 문자열 길이—를 추가했습니다. 산술, 루프, 임의 코드 실행은 제공하지 않았습니다. 따라서 '더 표현력이 풍부하다'는 것은 '무제한'을 뜻하지 않았습니다. 유한한 수의 단순한 값에 이름을 붙이고, 제한된 방식으로 정규화하고, 스크립트에서 재사용할 수 있다는 뜻이었습니다.

캡처는 한 번 평가된 분기에 관한 사실이다

매치 변수는 제어 흐름을 데이터 모델의 일부로 만들었습니다. RFC 5229는 검사를 왼쪽에서 오른쪽으로 실행하고 불리언 답이 이미 알려지면 단락 평가(short-circuit)할 것을 요구합니다.anyof (true, header:matches...)를 생각해 보십시오: 헤더 검사는 실행되지 않으므로 캡처를 만들지 않습니다. 이후에 성공한:matches는 이전 매치 목록을 대체할 수 있고, 실패한 매치는 새 조각을 제공하지 않습니다. 더 복잡한 규칙에서 프로그래머는${1}을 신뢰하기 전에 실제로 어떤 검사가 실행되었는지 알아야 합니다.

이 확장은 또한 모든 이후 매치 유형에 캡처 부작용을 부과하지 않았습니다. RFC 5229의 3개월 뒤에 발표된 RFC 5173은 특히 드러나는 경계를 명시합니다: body 검사 키의 변수 참조는 확장이 활성화되었을 때 확장될 수 있지만, 그 body 검사의 와일드카드 매치는 매치 변수를 설정해서는 안 됩니다. 표준 문서는 따라서 한 기능이 다른 기능을 먹이는 것은 허용하면서도 표면적으로 유사한 모든 연산을 같게 동작하게 만드는 것은 거부합니다.

한도 표는 이 경계성을 구현 계약으로 만듭니다. 적합한 구현은 최소 128개의 변수, 최소 32자의 이름, 최소 4,000자의 값,${1}부터${9}까지의 캡처를 지원해야 했습니다. 값이 특정 구현이 담을 수 있는 크기를 넘으면, RFC는 가능하면 컴파일 시점에 그것을 잡을 것을 권장했습니다; 실행 시점에만 발견되면 잘림이 예상되었고 오류로 취급되지 않았습니다. 그 결과 보안 절은 보안상 중요한 큰 구조를 변수에 두지 말 것을 경고하고, 캡처가 발신자가 제어하는 임의의 텍스트를 담을 수 있음을 지적합니다.

하나의 확장이 긴 표준사 역사를 쌓았다

Datatracker 기록은 개별 초안 계열을 2003년 3월까지 거슬러 올라가며, 이어서 2004년 말부터의 워킹 그룹 초안과 2005년을 통한 연속 개정이 뒤따릅니다. IESG 서면은 이 사양을 Sieve Mail Filtering Language Working Group의 산출물로 식별합니다. 2006년의 승인과 2008년 1월의 RFC 발행은 서로 다른 기록된 사건입니다; 이 연대기는 작업이 왜 그렇게 오래 걸렸는지, 구현이 얼마나 널리 채택했는지를 알려주지 않습니다.

Lu Heng의 "Minimum Initial Specification"을 분석적 렌즈로 읽으면,require게이트는 지역화된 미래 결정처럼 보입니다: 작은 기반이 안정적으로 남을 수 있고, 스크립트가 정밀한 확장을 선택적으로 채택할 수 있습니다. "Running-Code Primacy"는 두 번째 구분을 제공합니다: 발표된 기능이 특정 서버가 그것을 구현하거나 활성화했음을 증명하지는 않습니다. "Reality Layers"는 스크립트가 선언한 기능, 인터프리터 상태, 서버 동작, 사용자의 최종 사서함 경험이 하나의 주장으로 붕괴되지 않게 합니다. 이들은 이후의 해석 틀이며, RFC 5229 저자들의 의도에 대한 증거가 아닙니다.

필터는 이제 한 번 평가된 매치가 캡처한 것을 기억할 수 있었고, 스크립트는 소수의 이름 붙은 문자열을 재사용할 수 있었습니다. 그러나 그것만으로 실행 간에 대화를 기억하거나, 발신자를 인증하거나, 메시지가 어디에 도착했는지 증명할 수는 없었습니다. RFC 5229의 역사적 이동은 Sieve의 경계를 지우는 것이 아니라, 신중하게 선언된 하나의 이음선을 더 유용하게 만드는 것이었습니다.

출처