Fix argument sinks

Fixes #886.
This commit is contained in:
Laurenz 2023-04-19 17:51:33 +02:00
parent 5a6330dbfc
commit f08ae95b9d
7 changed files with 29 additions and 12 deletions

View File

@ -1,6 +1,9 @@
name: Continuous integration
on: [push, pull_request]
env:
RUSTFLAGS: "-Dwarnings"
jobs:
ci:
runs-on: ubuntu-latest

View File

@ -541,7 +541,7 @@ pub fn gcd(
/// The second integer.
b: i64,
) -> Value {
Value::Int(calculate_gcd(a, b).into())
Value::Int(calculate_gcd(a, b))
}
/// Calculates the greatest common divisor of two integers

View File

@ -62,14 +62,23 @@ impl Args {
}
/// Consume n positional arguments if possible.
pub fn consume(&mut self, n: usize) -> SourceResult<EcoVec<Arg>> {
if n > self.items.len() {
pub fn consume(&mut self, n: usize) -> SourceResult<Vec<Arg>> {
let mut list = vec![];
let mut i = 0;
while i < self.items.len() && list.len() < n {
if self.items[i].name.is_none() {
list.push(self.items.remove(i));
} else {
i += 1;
}
}
if list.len() < n {
bail!(self.span, "not enough arguments");
}
let vec = self.items.to_vec();
let (left, right) = vec.split_at(n);
self.items = right.into();
Ok(left.into())
Ok(list)
}
/// Consume and cast the first positional argument.

View File

@ -38,20 +38,20 @@ impl<'a> Scopes<'a> {
/// Try to access a variable immutably.
pub fn get(&self, var: &str) -> StrResult<&Value> {
Ok(std::iter::once(&self.top)
std::iter::once(&self.top)
.chain(self.scopes.iter().rev())
.chain(self.base.map(|base| base.global.scope()))
.find_map(|scope| scope.get(var))
.ok_or(eco_format!("unknown variable: {}", var))?)
.ok_or_else(|| eco_format!("unknown variable: {}", var))
}
/// Try to access a variable immutably in math.
pub fn get_in_math(&self, var: &str) -> StrResult<&Value> {
Ok(std::iter::once(&self.top)
std::iter::once(&self.top)
.chain(self.scopes.iter().rev())
.chain(self.base.map(|base| base.math.scope()))
.find_map(|scope| scope.get(var))
.ok_or(eco_format!("unknown variable: {}", var))?)
.ok_or_else(|| eco_format!("unknown variable: {}", var))
}
/// Try to access a variable mutably.

View File

@ -1047,7 +1047,7 @@ fn validate_dict(p: &mut Parser, m: Marker) {
};
if !used.insert(key.clone()) {
first.convert_to_error(eco_format!("duplicate key: {}", key));
first.convert_to_error(eco_format!("duplicate key: {key}"));
child.make_erroneous();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1001 B

View File

@ -0,0 +1,5 @@
// Test bugs with argument sinks.
---
#let foo(..body) = repr(body.pos())
#foo(a: "1", b: "2", 1, 2, 3, 4, 5, 6)