Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
49d62e8d
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
49d62e8d
编写于
5月 13, 2019
作者:
I
Igor Matuszewski
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Prohibit bare CRs in raw byte strings
上级
cab7e7fe
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
66 addition
and
74 deletion
+66
-74
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/lexer/mod.rs
+24
-70
src/libsyntax/parse/unescape.rs
src/libsyntax/parse/unescape.rs
+24
-0
src/libsyntax/parse/unescape_error_reporting.rs
src/libsyntax/parse/unescape_error_reporting.rs
+5
-0
src/test/ui/parser/raw-byte-string-literals.rs
src/test/ui/parser/raw-byte-string-literals.rs
+3
-0
src/test/ui/parser/raw-byte-string-literals.stderr
src/test/ui/parser/raw-byte-string-literals.stderr
+10
-4
未找到文件。
src/libsyntax/parse/lexer/mod.rs
浏览文件 @
49d62e8d
...
...
@@ -292,15 +292,6 @@ fn struct_fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c:
self
.sess.span_diagnostic
.struct_span_fatal
(
self
.mk_sp
(
from_pos
,
to_pos
),
&
m
[
..
])
}
/// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
/// escaped character to the error message
fn
err_span_char
(
&
self
,
from_pos
:
BytePos
,
to_pos
:
BytePos
,
m
:
&
str
,
c
:
char
)
{
let
mut
m
=
m
.to_string
();
m
.push_str
(
": "
);
push_escaped_char
(
&
mut
m
,
c
);
self
.err_span_
(
from_pos
,
to_pos
,
&
m
[
..
]);
}
/// Advance peek_token to refer to the next token, and
/// possibly update the interner.
fn
advance_token
(
&
mut
self
)
->
Result
<
(),
()
>
{
...
...
@@ -1070,7 +1061,13 @@ fn next_token_inner(&mut self) -> Result<TokenKind, ()> {
self
.validate_byte_str_escape
(
start_with_quote
);
(
token
::
ByteStr
,
symbol
)
},
Some
(
'r'
)
=>
self
.scan_raw_byte_string
(),
Some
(
'r'
)
=>
{
let
(
start
,
end
,
hash_count
)
=
self
.scan_raw_string
();
let
symbol
=
self
.name_from_to
(
start
,
end
);
self
.validate_raw_byte_str_escape
(
start
,
end
);
(
token
::
ByteStrRaw
(
hash_count
),
symbol
)
}
_
=>
unreachable!
(),
// Should have been a token::Ident above.
};
let
suffix
=
self
.scan_optional_raw_name
();
...
...
@@ -1300,66 +1297,6 @@ fn scan_raw_string(&mut self) -> (BytePos, BytePos, u16) {
(
content_start_bpos
,
content_end_bpos
,
hash_count
)
}
fn
scan_raw_byte_string
(
&
mut
self
)
->
(
token
::
LitKind
,
Symbol
)
{
let
start_bpos
=
self
.pos
;
self
.bump
();
let
mut
hash_count
=
0
;
while
self
.ch_is
(
'#'
)
{
if
hash_count
==
65535
{
let
bpos
=
self
.next_pos
;
self
.fatal_span_
(
start_bpos
,
bpos
,
"too many `#` symbols: raw strings may be
\
delimited by up to 65535 `#` symbols"
)
.raise
();
}
self
.bump
();
hash_count
+=
1
;
}
if
self
.is_eof
()
{
self
.fail_unterminated_raw_string
(
start_bpos
,
hash_count
);
}
else
if
!
self
.ch_is
(
'"'
)
{
let
last_bpos
=
self
.pos
;
let
curr_char
=
self
.ch
.unwrap
();
self
.fatal_span_char
(
start_bpos
,
pos
,
"found invalid character; only `#` is allowed in raw
\
string delimitation"
,
ch
)
.raise
();
}
self
.bump
();
let
content_start_bpos
=
self
.pos
;
let
mut
content_end_bpos
;
'outer
:
loop
{
match
self
.ch
{
None
=>
{
self
.fail_unterminated_raw_string
(
start_bpos
,
hash_count
);
}
Some
(
'"'
)
=>
{
content_end_bpos
=
self
.pos
;
for
_
in
0
..
hash_count
{
self
.bump
();
if
!
self
.ch_is
(
'#'
)
{
continue
'outer
;
}
}
break
;
}
Some
(
c
)
=>
{
if
c
>
'\x7F'
{
let
pos
=
self
.pos
;
self
.err_span_char
(
pos
,
pos
,
"raw byte string must be ASCII"
,
c
);
}
}
}
self
.bump
();
}
self
.bump
();
(
token
::
ByteStrRaw
(
hash_count
),
self
.name_from_to
(
content_start_bpos
,
content_end_bpos
))
}
fn
validate_char_escape
(
&
self
,
start_with_quote
:
BytePos
)
{
self
.with_str_from_to
(
start_with_quote
+
BytePos
(
1
),
self
.pos
-
BytePos
(
1
),
|
lit
|
{
if
let
Err
((
off
,
err
))
=
unescape
::
unescape_char
(
lit
)
{
...
...
@@ -1424,6 +1361,23 @@ fn validate_raw_str_escape(&self, content_start: BytePos, content_end: BytePos)
});
}
fn
validate_raw_byte_str_escape
(
&
self
,
content_start
:
BytePos
,
content_end
:
BytePos
)
{
self
.with_str_from_to
(
content_start
,
content_end
,
|
lit
:
&
str
|
{
unescape
::
unescape_raw_byte_str
(
lit
,
&
mut
|
range
,
c
|
{
if
let
Err
(
err
)
=
c
{
emit_unescape_error
(
&
self
.sess.span_diagnostic
,
lit
,
self
.mk_sp
(
content_start
-
BytePos
(
1
),
content_end
+
BytePos
(
1
)),
unescape
::
Mode
::
ByteStr
,
range
,
err
,
)
}
})
});
}
fn
validate_byte_str_escape
(
&
self
,
start_with_quote
:
BytePos
)
{
self
.with_str_from_to
(
start_with_quote
+
BytePos
(
1
),
self
.pos
-
BytePos
(
1
),
|
lit
|
{
unescape
::
unescape_byte_str
(
lit
,
&
mut
|
range
,
c
|
{
...
...
src/libsyntax/parse/unescape.rs
浏览文件 @
49d62e8d
...
...
@@ -29,6 +29,7 @@ pub(crate) enum EscapeError {
UnicodeEscapeInByte
,
NonAsciiCharInByte
,
NonAsciiCharInByteString
,
}
/// Takes a contents of a char literal (without quotes), and returns an
...
...
@@ -88,6 +89,29 @@ pub(crate) fn unescape_raw_str<F>(literal_text: &str, callback: &mut F)
}
}
/// Takes a contents of a string literal (without quotes) and produces a
/// sequence of characters or errors.
/// NOTE: Raw strings do not perform any explicit character escaping, here we
/// only translate CRLF to LF and produce errors on bare CR.
pub
(
crate
)
fn
unescape_raw_byte_str
<
F
>
(
literal_text
:
&
str
,
callback
:
&
mut
F
)
where
F
:
FnMut
(
Range
<
usize
>
,
Result
<
char
,
EscapeError
>
),
{
let
mut
byte_offset
:
usize
=
0
;
let
mut
chars
=
literal_text
.chars
()
.peekable
();
while
let
Some
(
curr
)
=
chars
.next
()
{
let
result
=
match
(
curr
,
chars
.peek
())
{
(
'\r'
,
Some
(
'\n'
))
=>
Ok
(
curr
),
(
'\r'
,
_
)
=>
Err
(
EscapeError
::
BareCarriageReturn
),
(
c
,
_
)
if
c
>
'\x7F'
=>
Err
(
EscapeError
::
NonAsciiCharInByteString
),
_
=>
Ok
(
curr
),
};
callback
(
byte_offset
..
(
byte_offset
+
curr
.len_utf8
()),
result
);
byte_offset
+=
curr
.len_utf8
();
}
}
#[derive(Debug,
Clone,
Copy)]
pub
(
crate
)
enum
Mode
{
Char
,
...
...
src/libsyntax/parse/unescape_error_reporting.rs
浏览文件 @
49d62e8d
...
...
@@ -124,6 +124,11 @@ pub(crate) fn emit_unescape_error(
handler
.span_err
(
span
,
"byte constant must be ASCII.
\
Use a
\\
xHH escape for a non-ASCII byte"
)
}
EscapeError
::
NonAsciiCharInByteString
=>
{
assert
!
(
mode
.is_bytes
());
let
(
_
c
,
span
)
=
last_char
();
handler
.span_err
(
span
,
"raw byte string must be ASCII"
)
}
EscapeError
::
OutOfRangeHexEscape
=>
{
handler
.span_err
(
span
,
"this form of character escape may only be used
\
with characters in the range [
\\
x00-
\\
x7f]"
)
...
...
src/test/ui/parser/raw-byte-string-literals.rs
浏览文件 @
49d62e8d
// ignore-tidy-cr
// compile-flags: -Z continue-parse-after-error
pub
fn
main
()
{
br
"a "
;
//~ ERROR bare CR not allowed in string
br
"é"
;
//~ ERROR raw byte string must be ASCII
br
##
~
"a"
~
##
;
//~ ERROR only `#` is allowed in raw string delimitation
}
...
...
src/test/ui/parser/raw-byte-string-literals.stderr
浏览文件 @
49d62e8d
error: raw byte string must be ASCII: \u{e9}
--> $DIR/raw-byte-string-literals.rs:2:8
error: bare CR not allowed in string, use \r instead
--> $DIR/raw-byte-string-literals.rs:4:9
|
LL | br"a ";
| ^
error: raw byte string must be ASCII
--> $DIR/raw-byte-string-literals.rs:5:8
|
LL | br"é";
| ^
error: found invalid character; only `#` is allowed in raw string delimitation: ~
--> $DIR/raw-byte-string-literals.rs:
3
:6
--> $DIR/raw-byte-string-literals.rs:
6
:6
|
LL | br##~"a"~##;
| ^^^
error: aborting due to
2
previous errors
error: aborting due to
3
previous errors
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录