From a8696c7336ef978aa25d28910a865600afe8ff93 Mon Sep 17 00:00:00 2001 From: "duncan.macgregor" Date: Wed, 4 Dec 2024 19:23:58 +0000 Subject: [PATCH] Ensure `next` and `orderedNext` are null for slots in `HashSlotMap`. --- .../java/org/mozilla/javascript/AccessorSlot.java | 11 +++++++++++ .../java/org/mozilla/javascript/HashSlotMap.java | 13 ++++++++++++- .../org/mozilla/javascript/LambdaAccessorSlot.java | 13 +++++++++++++ .../java/org/mozilla/javascript/LambdaSlot.java | 11 +++++++++++ .../java/org/mozilla/javascript/LazyLoadSlot.java | 9 +++++++++ .../src/main/java/org/mozilla/javascript/Slot.java | 7 +++++++ .../org/mozilla/javascript/SlotMapContainer.java | 5 +---- 7 files changed, 64 insertions(+), 5 deletions(-) diff --git a/rhino/src/main/java/org/mozilla/javascript/AccessorSlot.java b/rhino/src/main/java/org/mozilla/javascript/AccessorSlot.java index a12841b8f6..a9a3800bf0 100644 --- a/rhino/src/main/java/org/mozilla/javascript/AccessorSlot.java +++ b/rhino/src/main/java/org/mozilla/javascript/AccessorSlot.java @@ -16,6 +16,17 @@ public class AccessorSlot extends Slot { super(oldSlot); } + @Override + AccessorSlot copySlot() { + var newSlot = new AccessorSlot(this); + newSlot.value = value; + newSlot.getter = getter; + newSlot.setter = setter; + newSlot.next = null; + newSlot.orderedNext = null; + return newSlot; + } + // The Getter and Setter may each be of a different type (JavaScript function, Java // function, or neither). So, use an abstraction to distinguish them. transient Getter getter; diff --git a/rhino/src/main/java/org/mozilla/javascript/HashSlotMap.java b/rhino/src/main/java/org/mozilla/javascript/HashSlotMap.java index 5a65a6787b..542cf8e386 100644 --- a/rhino/src/main/java/org/mozilla/javascript/HashSlotMap.java +++ b/rhino/src/main/java/org/mozilla/javascript/HashSlotMap.java @@ -17,7 +17,18 @@ */ public class HashSlotMap implements SlotMap { - private final LinkedHashMap map = new LinkedHashMap<>(); + private final LinkedHashMap map; + + public HashSlotMap() { + map = new LinkedHashMap<>(); + } + + public HashSlotMap(SlotMap oldMap) { + map = new LinkedHashMap<>(oldMap.size()); + for (Slot n : oldMap) { + add(n.copySlot()); + } + } @Override public int size() { diff --git a/rhino/src/main/java/org/mozilla/javascript/LambdaAccessorSlot.java b/rhino/src/main/java/org/mozilla/javascript/LambdaAccessorSlot.java index 18538473c5..f9209fffa2 100644 --- a/rhino/src/main/java/org/mozilla/javascript/LambdaAccessorSlot.java +++ b/rhino/src/main/java/org/mozilla/javascript/LambdaAccessorSlot.java @@ -28,6 +28,19 @@ public class LambdaAccessorSlot extends Slot { super(oldSlot); } + @Override + LambdaAccessorSlot copySlot() { + var newSlot = new LambdaAccessorSlot(this); + newSlot.value = value; + newSlot.getter = getter; + newSlot.setter = setter; + newSlot.getterFunction = getterFunction; + newSlot.setterFunction = setterFunction; + newSlot.next = null; + newSlot.orderedNext = null; + return newSlot; + } + @Override boolean isValueSlot() { return false; diff --git a/rhino/src/main/java/org/mozilla/javascript/LambdaSlot.java b/rhino/src/main/java/org/mozilla/javascript/LambdaSlot.java index dbfe108e36..d5fe6e11f1 100644 --- a/rhino/src/main/java/org/mozilla/javascript/LambdaSlot.java +++ b/rhino/src/main/java/org/mozilla/javascript/LambdaSlot.java @@ -22,6 +22,17 @@ public class LambdaSlot extends Slot { super(oldSlot); } + @Override + LambdaSlot copySlot() { + var newSlot = new LambdaSlot(this); + newSlot.value = value; + newSlot.getter = getter; + newSlot.setter = setter; + newSlot.next = null; + newSlot.orderedNext = null; + return newSlot; + } + transient Supplier getter; transient Consumer setter; diff --git a/rhino/src/main/java/org/mozilla/javascript/LazyLoadSlot.java b/rhino/src/main/java/org/mozilla/javascript/LazyLoadSlot.java index e55f5aac8d..3c693189cf 100644 --- a/rhino/src/main/java/org/mozilla/javascript/LazyLoadSlot.java +++ b/rhino/src/main/java/org/mozilla/javascript/LazyLoadSlot.java @@ -13,6 +13,15 @@ public class LazyLoadSlot extends Slot { super(oldSlot); } + @Override + LazyLoadSlot copySlot() { + var newSlot = new LazyLoadSlot(this); + newSlot.value = value; + newSlot.next = null; + newSlot.orderedNext = null; + return newSlot; + } + @Override public Object getValue(Scriptable start) { Object val = this.value; diff --git a/rhino/src/main/java/org/mozilla/javascript/Slot.java b/rhino/src/main/java/org/mozilla/javascript/Slot.java index 5f29c04146..feab49eac8 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Slot.java +++ b/rhino/src/main/java/org/mozilla/javascript/Slot.java @@ -25,6 +25,13 @@ public class Slot implements Serializable { this.attributes = (short) attributes; } + Slot copySlot() { + var newSlot = new Slot(this); + newSlot.next = null; + newSlot.orderedNext = null; + return newSlot; + } + /** * Return true if this is a base-class "Slot". Sadly too much code breaks if we try to do this * any other way. diff --git a/rhino/src/main/java/org/mozilla/javascript/SlotMapContainer.java b/rhino/src/main/java/org/mozilla/javascript/SlotMapContainer.java index 63a53cb20b..ef57146426 100644 --- a/rhino/src/main/java/org/mozilla/javascript/SlotMapContainer.java +++ b/rhino/src/main/java/org/mozilla/javascript/SlotMapContainer.java @@ -93,10 +93,7 @@ public void unlockRead(long stamp) { */ protected void checkMapSize() { if ((map instanceof EmbeddedSlotMap) && map.size() >= LARGE_HASH_SIZE) { - SlotMap newMap = new HashSlotMap(); - for (Slot s : map) { - newMap.add(s); - } + SlotMap newMap = new HashSlotMap(map); map = newMap; } }