[Webkit-unassigned] [Bug 216667] New: BigInt Duplicate keys in Maps and items in Sets

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Thu Sep 17 15:14:35 PDT 2020


https://bugs.webkit.org/show_bug.cgi?id=216667

            Bug ID: 216667
           Summary: BigInt Duplicate keys in Maps and items in Sets
           Product: WebKit
           Version: Safari Technology Preview
          Hardware: Macintosh
                OS: macOS 10.15
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: JavaScriptCore
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: dwighthouse at gmail.com

Created attachment 409070

  --> https://bugs.webkit.org/attachment.cgi?id=409070&action=review

Demonstration Script and Expected Output

# Feature Background

* BigInts store arbitrarily large integers as a primitive data type, where they may be constructed with a `BigInt` function or by using new syntax of appending an `n` to an integer number.
  - BigInt support just landed on Desktop Safari ( https://developer.apple.com/documentation/safari-release-notes/safari-14-beta-release-notes#JavaScript ).
  - My version: 14.0 (15610.1.28.1.9, 15610).
    - I did download the latest WebKit Build Archives version as of the writing of this ticket and found the issue to still be present, though it was hard to tell due to Catalina's aggressive attempts to prevent it from running.
* Maps store key-value pairs, where keys must be unique and their equality is judged by sameValueZero ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Description ).
* Sets store values, where values must be unique and their equality is judged by sameValueZero ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set ).



# Problem Discovery

I was working on my json-complete library and found an error in my tests that only appeared to affect Safari, which had just been updated this morning.
  - json-complete - https://github.com/cierelabs/json-complete
  - The library saves some space in the output encoded string by deduplicating equal values.
  - My deduplication tests failed on Safari when dealing with BigInt.
  - Tracking this down, I discovered that multiple "equal" BigInt values were not being treated as equal in my Map object, which forms the core of that part of the library.
  - This is unacceptable because it will allow for a situation where Safari browsers using my library can sometimes create a different output for the exact same data, even if the versions are identical.
  - To work around this, I would have to add an exception for BigInt types that requires either all data or just BigInt data to fall back to the slower methodology of checking value equality of every previous entry when trying to deduplicate items.



# Issue Description

* Safari 14 appears to sometimes treat function-constructed BigInt values as non-equal to equal BigInt values for the purposes of deduplication in Map keys and Set values.
* Additionally, the "sometimes" aspect of this non-equality appears to be a race-condition, as the way in which Safari will incorrectly store duplicate entries varies from page load to page load.
* In my testing, it is always wrong, but how wrong it is varies.
* Finally, the order of the incorrect insertions are also incorrect. Occasionally, the output will show entries out of order, even if BigInt values were not strictly value-equal to each other.
* This issue is not present in Google Chrome, Mozilla Firefox, and Brave.



# Expected Behavior

1. When adding a new key-value pair with the same BigInt value as the key as a previous entry, regardless of being constructed with a function or the new syntax, the Map should store only the last added key-value pair that uses that BigInt key. There should not be duplicates and the values of the same key entry should always be overwritten.
2. When adding a new value with the same BigInt value as a previous value, regardless of being constructed with a function or the new syntax, the Set should only store the last added BigInt of that value. There should not be duplicates.



# Actual Behavior

1. Some number of duplications of the same BigInt key will be stored in the Map. The times this occurs varies from page load to page load.
2. Some number of duplications of the same BigInt value will be stored in the Map. The times this occurs varies from page load to page load.



# Samples of Incorrect Output

As noted above, I get different incorrect results per page load. Here are some examples of different variants:

```
Map:
[
    0, zero 4
    0, BigInt zero 4
    1, BigInt one function 1
    1, BigInt one function 2
    1, BigInt one function 3
    1, BigInt one function 4
    1, BigInt one
]

Set:
[
    0
    0
    1
    1
]
```

```
Map:
[
    0, zero 4
    0, BigInt zero 4
    1, BigInt one function 1
    1, BigInt one
    1, BigInt one function 3
    1, BigInt one function 4
]

Set:
[
    0
    0
    1
    1
    1
]
```

```
Map:
[
    0, zero 4
    0, BigInt zero 4
    1, BigInt one function 1
    1, BigInt one function 2
    1, BigInt one function 3
    1, BigInt one
]

Set:
[
    0
    0
    1
    1
]
```



# Steps to Reproduce

* Please see sample code provided in the attached file, which demonstrates both problems.
* Reload the page multiple times in Safari to see the variances.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20200917/0aa3b1fe/attachment.htm>


More information about the webkit-unassigned mailing list