Skip to content

Commit

Permalink
Fix panics from multiple borrows of Map. (#1077)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwd36 committed Jan 19, 2021
1 parent b34bb37 commit 7b75874
Showing 1 changed file with 35 additions and 7 deletions.
42 changes: 35 additions & 7 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,20 +342,48 @@ impl Map {
let callback_arg = &args[0];
let this_arg = args.get(1).cloned().unwrap_or_else(Value::undefined);

if let Value::Object(ref object) = this {
let object = object.borrow();
if let Some(map) = object.as_map_ref().cloned() {
for (key, value) in map {
let arguments = [value, key, this.clone()];

context.call(callback_arg, &this_arg, &arguments)?;
let mut index = 0;

while index < Map::get_size(this, context)? {
let arguments = if let Value::Object(ref object) = this {
let object = object.borrow();
if let Some(map) = object.as_map_ref() {
if let Some((key, value)) = map.get_index(index) {
Some([value.clone(), key.clone(), this.clone()])
} else {
None
}
} else {
return context.throw_type_error("'this' is not a Map");
}
} else {
return context.throw_type_error("'this' is not a Map");
};

if let Some(arguments) = arguments {
context.call(callback_arg, &this_arg, &arguments)?;
}

index += 1;
}

Ok(Value::Undefined)
}

/// Helper function to get the size of the map.
fn get_size(map: &Value, context: &mut Context) -> Result<usize> {
if let Value::Object(ref object) = map {
let object = object.borrow();
if let Some(map) = object.as_map_ref() {
Ok(map.len())
} else {
Err(context.construct_type_error("'this' is not a Map"))
}
} else {
Err(context.construct_type_error("'this' is not a Map"))
}
}

/// `Map.prototype.values()`
///
/// Returns a new Iterator object that contains the values for each element in the Map object in insertion order.
Expand Down

0 comments on commit 7b75874

Please sign in to comment.