Skip to main content

4. Obsolete Syntax (废弃语法)

本规范的早期版本允许使用与本版本中允许的不同 (通常更宽松) 的语法。此外,互联网上消息中使用的某些语法元素的解释从未被记录过。虽然根据第3节中的语法,禁止 (MUST NOT) 生成这些语法形式,但符合规范的接收者必须 (MUST) 接受并解析它们。本节记录了其中许多语法元素。将第3节中的语法与本节中呈现的定义相结合,将产生用于解释消息的语法。

注意: 本节标识了任何实现都必须 (MUST) 合理解释的语法形式。但是,肯定有互联网消息甚至不符合本节中给出的附加语法。特定形式未出现在本文档的任何部分这一事实不能成为计算机程序崩溃或任何实现不可挽回地丢失格式错误数据的理由。实现有责任鲁棒地处理消息。

废弃语法与当前语法的主要区别:

  1. 空白字符的使用: 在结构化头部字段体中 (即,任何结构化头部字段的冒号和CRLF之间),空白字符 (包括折叠空白) 和注释可以在任何语法标记之间自由插入。这允许许多复杂的形式,这些形式已被证明对某些实现来说难以解析。

  2. 折叠空白规则: 第3.2.2节中关于完全由注释和折叠空白中的空白组成的行的规则不适用。参见下面第4.2节中对折叠空白的讨论。

  3. 特殊字符: 消息中曾经允许出现某些字符,现在出现在本节中。NUL字符 (ASCII值0) 曾经被允许,但出于兼容性原因不再被允许。类似地,除了CR、LF、SP和HTAB之外的US-ASCII控制字符 (ASCII值1到8、11、12、14到31和127) 被允许出现在头部字段体中。CR和LF被允许在消息中出现而不作为CRLF; 这种用法也在此处显示。

关键概念

废弃语法的目的

消息生成                     消息解析
↓ ↓
第3节语法 第3节 + 第4节
(严格规则) (宽松规则)
↓ ↓
禁止生成废弃形式 必须接受废弃形式

实现要求

角色对废弃语法的要求
消息生成器MUST NOT 生成废弃语法
消息解析器MUST 接受和解析废弃语法
所有实现MUST 鲁棒处理格式错误的消息

4.1. Miscellaneous Obsolete Tokens (其他废弃标记)

这些语法元素在废弃语法或主语法中的其他地方使用。obs-qp、obs-body和obs-unstruct中添加了裸CR、裸LF和NUL。obs-qp、obs-unstruct、obs-ctext和obs-qtext中添加了US-ASCII控制字符。obs-phrase中添加了句点字符。obs-phrase-list为可能包含"null"元素的短语的 (可能为空的) 逗号分隔列表提供支持。也就是说,这样的列表中可能有两个或更多逗号之间没有任何内容,或者列表的开头或结尾有逗号。

obs-NO-WS-CTL   =   %d1-8 /            ; US-ASCII control
%d11 / ; characters that do not
%d12 / ; include the carriage
%d14-31 / ; return, line feed, and
%d127 ; white space characters

obs-ctext = obs-NO-WS-CTL

obs-qtext = obs-NO-WS-CTL

obs-utext = %d0 / obs-NO-WS-CTL / VCHAR

obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)

obs-body = *((*LF *CR *((%d0 / text) *LF *CR)) / CRLF)

obs-unstruct = *((*LF *CR *(obs-utext *LF *CR)) / FWS)

obs-phrase = word *(word / "." / CFWS)

obs-phrase-list = [phrase / CFWS] *("," [phrase / CFWS])

注意: obs-phrase中的"句点" (或"句号") 字符 (".") 不是本规范或任何其他规范的早期版本中允许的形式。句点 (或specials中的任何其他字符) 在phrase中不被允许,因为它在区分phrase和addr-spec部分时引入了解析困难 (参见第4.4节)。它出现在这里是因为句点字符目前在许多消息的地址的display-name部分中使用,特别是用于姓名中的首字母,因此必须正确解释。

裸CR和裸LF 在消息中以两种不同的含义出现:

  1. 作为行分隔符: 在许多情况下,裸CR或裸LF被不正确地用来代替CRLF以指示行分隔符
  2. 作为控制字符: 在其他情况下,裸CR和裸LF只是作为US-ASCII控制字符使用其传统ASCII含义

4.2. Obsolete Folding White Space (废弃的折叠空白)

在废弃语法中,任何数量的折叠空白可以插入到允许obs-FWS规则的地方。这创造了在一行中有两个连续"折叠"的可能性,因此有可能组成折叠头部字段的行可能完全由空白组成。

obs-FWS         =   1*WSP *(CRLF 1*WSP)

示例:

废弃的折叠 (允许但不推荐):
Subject: This

is valid
(中间行仅包含空白)

当前标准 (第3节):
禁止完全由空白组成的折叠行

4.3. Obsolete Date and Time (废弃的日期和时间)

废弃日期格式的语法允许在date字段中使用2位数年份,并允许本规范早期版本中使用的字母时区指定符列表。它还允许在许多标记之间使用注释和折叠空白。

obs-day-of-week =   [CFWS] day-name [CFWS]

obs-day = [CFWS] 1*2DIGIT [CFWS]

obs-year = [CFWS] 2*DIGIT [CFWS]

obs-hour = [CFWS] 2DIGIT [CFWS]

obs-minute = [CFWS] 2DIGIT [CFWS]

obs-second = [CFWS] 2DIGIT [CFWS]

obs-zone = "UT" / "GMT" / ; Universal Time
; North American UT
; offsets
"EST" / "EDT" / ; Eastern: - 5/ - 4
"CST" / "CDT" / ; Central: - 6/ - 5
"MST" / "MDT" / ; Mountain: - 7/ - 6
"PST" / "PDT" / ; Pacific: - 8/ - 7
;
%d65-73 / ; Military zones - "A"
%d75-90 / ; through "I" and "K"
%d97-105 / ; through "Z", both
%d107-122 ; upper and lower case

2位数或3位数年份的解释:

  • 00-49: 加上2000,得到2000-2049
  • 50-99: 加上1900,得到1950-1999
  • 3位数: 加上1900

时区缩写解释:

缩写含义等效
UT, GMT世界时+0000
EST东部标准时间-0500
EDT东部夏令时间-0400
CST中部标准时间-0600
CDT中部夏令时间-0500
MST山地标准时间-0700
MDT山地夏令时间-0600
PST太平洋标准时间-0800
PDT太平洋夏令时间-0700
军事时区 (A-Z)不可预测应视为-0000

注意: 1字符军事时区在 [RFC0822] 中以非标准方式定义,因此其含义是不可预测的。除非有带外信息确认其含义,否则它们都应该 (SHOULD) 被视为等同于"-0000"。

4.4. Obsolete Addressing (废弃的地址)

地址方面有四个主要区别:

  1. 路由: 邮箱地址允许在用<>括起来时在addr-spec之前有路由部分。路由只是以逗号分隔的域名列表,每个前面都有"@",列表以冒号终止。

  2. CFWS插入: local-part和domain的句点分隔元素之间允许使用CFWS (即,不使用dot-atom)。此外,local-part除了atom之外还允许包含quoted-string。

  3. 空成员: mailbox-list和address-list允许有"null"成员。也就是说,这样的列表中可能有两个或更多逗号之间没有任何内容,或者列表的开头或结尾有逗号。

  4. 域字面值: 在域字面值中允许使用US-ASCII控制字符和quoted-pairs,并在此处添加。

obs-angle-addr  =   [CFWS] "<" obs-route addr-spec ">" [CFWS]

obs-route = obs-domain-list ":"

obs-domain-list = *(CFWS / ",") "@" domain
*("," [CFWS] ["@" domain])

obs-mbox-list = *([CFWS] ",") mailbox *("," [mailbox / CFWS])

obs-addr-list = *([CFWS] ",") address *("," [address / CFWS])

obs-group-list = 1*([CFWS] ",") [CFWS]

obs-local-part = word *("." word)

obs-domain = atom *("." atom)

obs-dtext = obs-NO-WS-CTL / quoted-pair

解释消息时,路由部分应该 (SHOULD) 被忽略。

路由地址示例:

废弃的路由格式:
<@node1.example,@node2.example:[email protected]>
↑ ↑
└── 路由 ──────────────┘

解释时应忽略路由,仅使用:
[email protected]

4.5. Obsolete Header Fields (废弃的头部字段)

在语法上,废弃字段语法的主要区别是它允许任何字段的多次出现,并且它们可以以任何顺序出现。此外,在字段名末尾的":"之前允许任意数量的空白。

除非在以下各节中另有说明,否则其他字段的解释与其在第3节中的非废弃对应项的解释相同。

废弃字段特点:

  • 允许多次出现
  • 允许以任何顺序出现
  • 字段名后、冒号前允许空白

示例:

废弃格式 (不推荐):
From : [email protected]
Date:Mon, 21 Nov 1997 09:55:06 GMT

当前标准:
From: [email protected]
Date: Mon, 21 Nov 1997 09:55:06 -0600

第4章总结

关键要点

  1. 废弃语法的双重角色:

    • 禁止生成
    • 必须解析
  2. 主要差异:

    • 更宽松的空白规则
    • 允许特殊字符 (NUL, 控制字符)
    • 2位数年份
    • 字母时区
    • 地址路由
    • 字段重复
  3. 实现责任:

    • 鲁棒处理格式错误的消息
    • 不崩溃
    • 不丢失数据

兼容性策略

严格生成                    宽松解析
↓ ↓
仅使用第3节 接受第3+4节
新标准格式 新旧两种格式

测试检查清单

解析器实现应测试以下废弃格式:

  • 2位数年份 (如"21 Nov 97")
  • 字母时区 (如"EST", "PST")
  • 裸CR或裸LF
  • 包含路由的地址
  • 字段名后有空白
  • 完全由空白组成的折叠行
  • 包含句点的phrase

下一节: 5. Security Considerations (安全考虑)

上一节: 3. Syntax (语法)