Merge pull request #341 from schungx/master
Fix panic in property access parsing error.
This commit is contained in:
commit
17f1bf6014
@ -15,6 +15,7 @@ Bug fixes
|
|||||||
* Fixes compilation errors in `metadata` feature build.
|
* Fixes compilation errors in `metadata` feature build.
|
||||||
* Stacking `!` operators now work properly.
|
* Stacking `!` operators now work properly.
|
||||||
* Off-by-one error in `insert` method for arrays is fixed.
|
* Off-by-one error in `insert` method for arrays is fixed.
|
||||||
|
* Invalid property access now throws the appropriate error instead of panics.
|
||||||
|
|
||||||
Breaking changes
|
Breaking changes
|
||||||
----------------
|
----------------
|
||||||
|
@ -1083,9 +1083,7 @@ fn parse_primary(
|
|||||||
match input.peek().unwrap().0 {
|
match input.peek().unwrap().0 {
|
||||||
// Function call is allowed to have reserved keyword
|
// Function call is allowed to have reserved keyword
|
||||||
Token::LeftParen | Token::Bang => {
|
Token::LeftParen | Token::Bang => {
|
||||||
if s == KEYWORD_THIS {
|
if is_keyword_function(&s) {
|
||||||
return Err(PERR::Reserved(s).into_err(settings.pos));
|
|
||||||
} else if is_keyword_function(&s) {
|
|
||||||
let var_name_def = Ident {
|
let var_name_def = Ident {
|
||||||
name: state.get_interned_string(s),
|
name: state.get_interned_string(s),
|
||||||
pos: settings.pos,
|
pos: settings.pos,
|
||||||
@ -1213,13 +1211,21 @@ fn parse_primary(
|
|||||||
// Property access
|
// Property access
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
(expr, Token::Period) => {
|
(expr, Token::Period) => {
|
||||||
// prevents capturing of the object properties as vars: xxx.<var>
|
// Expression after dot must start with an identifier
|
||||||
#[cfg(not(feature = "no_closure"))]
|
match input.peek().unwrap() {
|
||||||
if let (Token::Identifier(_), _) = input.peek().unwrap() {
|
(Token::Identifier(_), _) => {
|
||||||
state.allow_capture = false;
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
{
|
||||||
|
// Prevents capturing of the object properties as vars: xxx.<var>
|
||||||
|
state.allow_capture = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Token::Reserved(s), _) if is_keyword_function(s) => (),
|
||||||
|
(_, pos) => return Err(PERR::PropertyExpected.into_err(*pos)),
|
||||||
}
|
}
|
||||||
|
|
||||||
let rhs = parse_primary(input, state, lib, settings.level_up())?;
|
let rhs = parse_primary(input, state, lib, settings.level_up())?;
|
||||||
|
|
||||||
make_dot_expr(state, expr, rhs, tail_pos)?
|
make_dot_expr(state, expr, rhs, tail_pos)?
|
||||||
}
|
}
|
||||||
// Unknown postfix operator
|
// Unknown postfix operator
|
||||||
@ -1514,23 +1520,26 @@ fn make_dot_expr(
|
|||||||
}
|
}
|
||||||
// lhs.module::id - syntax error
|
// lhs.module::id - syntax error
|
||||||
(_, Expr::Variable(x)) if x.1.is_some() => {
|
(_, Expr::Variable(x)) if x.1.is_some() => {
|
||||||
return Err(PERR::PropertyExpected.into_err(x.1.unwrap().1[0].pos));
|
return Err(PERR::PropertyExpected.into_err(x.1.unwrap().1[0].pos))
|
||||||
}
|
}
|
||||||
// lhs.prop
|
// lhs.prop
|
||||||
(lhs, prop @ Expr::Property(_)) => {
|
(lhs, prop @ Expr::Property(_)) => {
|
||||||
Expr::Dot(Box::new(BinaryExpr { lhs, rhs: prop }), op_pos)
|
Expr::Dot(Box::new(BinaryExpr { lhs, rhs: prop }), op_pos)
|
||||||
}
|
}
|
||||||
// lhs.dot_lhs.dot_rhs
|
// lhs.dot_lhs.dot_rhs
|
||||||
(lhs, Expr::Dot(x, pos)) => {
|
(lhs, Expr::Dot(x, pos)) => match x.lhs {
|
||||||
let rhs = Expr::Dot(
|
Expr::Variable(_) | Expr::Property(_) | Expr::FnCall(_, _) => {
|
||||||
Box::new(BinaryExpr {
|
let rhs = Expr::Dot(
|
||||||
lhs: x.lhs.into_property(state),
|
Box::new(BinaryExpr {
|
||||||
rhs: x.rhs,
|
lhs: x.lhs.into_property(state),
|
||||||
}),
|
rhs: x.rhs,
|
||||||
pos,
|
}),
|
||||||
);
|
pos,
|
||||||
Expr::Dot(Box::new(BinaryExpr { lhs, rhs }), op_pos)
|
);
|
||||||
}
|
Expr::Dot(Box::new(BinaryExpr { lhs, rhs }), op_pos)
|
||||||
|
}
|
||||||
|
_ => unreachable!("invalid dot expression: {:?}", x.lhs),
|
||||||
|
},
|
||||||
// lhs.idx_lhs[idx_rhs]
|
// lhs.idx_lhs[idx_rhs]
|
||||||
(lhs, Expr::Index(x, pos)) => {
|
(lhs, Expr::Index(x, pos)) => {
|
||||||
let rhs = Expr::Index(
|
let rhs = Expr::Index(
|
||||||
@ -1555,14 +1564,14 @@ fn make_dot_expr(
|
|||||||
x.name, x.name
|
x.name, x.name
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.into_err(pos));
|
.into_err(pos))
|
||||||
}
|
}
|
||||||
// lhs.func!(...)
|
// lhs.func!(...)
|
||||||
(_, Expr::FnCall(x, pos)) if x.capture => {
|
(_, Expr::FnCall(x, pos)) if x.capture => {
|
||||||
return Err(PERR::MalformedCapture(
|
return Err(PERR::MalformedCapture(
|
||||||
"method-call style does not support capturing".into(),
|
"method-call style does not support capturing".into(),
|
||||||
)
|
)
|
||||||
.into_err(pos));
|
.into_err(pos))
|
||||||
}
|
}
|
||||||
// lhs.func(...)
|
// lhs.func(...)
|
||||||
(lhs, func @ Expr::FnCall(_, _)) => {
|
(lhs, func @ Expr::FnCall(_, _)) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user