LibWeb: Avoid stale DataTransferItem access after clearing data
Previously, clearing a DataTransfer's data removed entries from the drag data store without updating the associated `DataTransferItem` objects. An item obtained beforehand kept an index that no longer referenced a valid entry, so reading its kind or type accessed an out of bounds element of the now-empty list and crashed. We now keep the item objects in sync when clearing data, placing any stale ones into the disabled mode.
This commit is contained in:
parent
3c4076597e
commit
525ce459fc
3 changed files with 25 additions and 7 deletions
|
|
@ -319,16 +319,11 @@ void DataTransfer::clear_data(Optional<String> maybe_format)
|
|||
return;
|
||||
|
||||
auto remove_items_from_drag_data_store = [&](Optional<String> const& format = {}) {
|
||||
auto did_remove_item = false;
|
||||
for (size_t i = m_associated_drag_data_store->item_list().size(); i > 0; --i) {
|
||||
auto const& item = m_associated_drag_data_store->item_list().at(i - 1);
|
||||
if (item.kind == DragDataStoreItem::Kind::Text && (!format.has_value() || item.type_string == *format)) {
|
||||
m_associated_drag_data_store->remove_item_at(i - 1);
|
||||
did_remove_item = true;
|
||||
}
|
||||
if (item.kind == DragDataStoreItem::Kind::Text && (!format.has_value() || item.type_string == *format))
|
||||
remove_item(i - 1);
|
||||
}
|
||||
if (did_remove_item)
|
||||
update_data_transfer_types_list();
|
||||
};
|
||||
|
||||
// 3. If the method was called with no arguments, remove each item in the drag data store item list whose kind is
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
items.length after clearData = 0
|
||||
stale item kind = ""
|
||||
stale item type = ""
|
||||
stale item getAsFile() = null
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const dataTransfer = new DataTransfer();
|
||||
const item = dataTransfer.items.add("payload", "text/plain");
|
||||
|
||||
dataTransfer.clearData();
|
||||
|
||||
println(`items.length after clearData = ${dataTransfer.items.length}`);
|
||||
|
||||
// The item is now in the disabled mode, because it is not associated with a drag data store.
|
||||
// DataTransferItem's kind and type should be empty string because we are in disabled mode, but other engines
|
||||
// don't seem to follow the spec here.
|
||||
println(`stale item kind = "${item.kind}"`);
|
||||
println(`stale item type = "${item.type}"`);
|
||||
println(`stale item getAsFile() = ${item.getAsFile()}`);
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in a new issue