Commit graph

582 commits

Author SHA1 Message Date
Luke Wilde
25e343464d LibJS: Cache length identifier for GetLengthWithThis
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
We cached the length identifier for GetLength, but not
GetLengthWithThis. This caused an `has_value()` verification failure
when accessing super.length. Found by Fuzzilli.
2025-04-07 14:40:48 +02:00
devgianlu
08cfd5ff1b LibJS: Set empty function parameters on ClassStaticInit scope
This prevents the variables declared inside a class static initializer
to escape to the nearest containing function causing all sorts of memory
corruptions.
2025-04-05 18:20:36 +01:00
Andreas Kling
fe1962d7fa LibJS: Make SetCompletionType bytecode instruction actually set type
This recovers 38 tests in test262 that regressed in a0bb31f7a0.
2025-04-05 15:00:05 +02:00
Jess
83e46b3728 LibRegex: Fix crash when parse result exceeds max cache size
Before, If the cache was empty we would try and evict non-existant
entries and crash. So the fix is to make sure that we don't saturate
the cache with a single parse result.
2025-04-04 16:10:25 +02:00
Lucien Fiorini
6b6e13e28c LibJS: Avoid emptying the return value register in try/finally
This works because at the end of the finally chunk, a
ContinuePendingUnwind is generated which copies the saved return value
register into the return value register. In cases where
ContinuePendingUnwind is not generated such as when there is a break
statement in the finally block, the fonction will return undefined which
is consistent with V8 and SpiderMonkey.
2025-03-27 12:18:30 +00:00
Jess
f3a937ee76 LibJS: Fix integer overflow in target_offset of TypedArray.set() 2025-03-25 07:45:42 +00:00
Tim Ledbetter
ed62aa6224 Revert "LibJS: Reduce number of proxy traps called during for..in…
…iteration"

This reverts commit 357eeba49c.
2025-03-21 11:44:21 -05:00
Andreas Kling
357eeba49c LibJS: Reduce number of proxy traps called during for..in iteration
Before this change, we would enumerate all the keys with
[[OwnPropertyKeys]], and then do [[GetOwnPropertyDescriptor]] twice for
each key as we went through them.

We now only do one [[GetOwnPropertyDescriptor]] per key, which
drastically reduces the number of proxy traps when those are involved.
The new trap sequence matches what you get with V8, so I don't think
anyone will be unpleasantly surprised here.
2025-03-20 17:50:02 -05:00
Andreas Kling
660d533b50 LibJS: Don't assume [[GetOwnPropertyDescriptor]] always succeeds
It can fail if we're talking to a badly-behaved proxy when enumerating
object properties for iteration.
2025-03-20 12:51:21 -05:00
Jess
12cbefbee7 LibJS+LibCrypto: Use a bitwise approach for BigInt's as*IntN methods
This speeds up expressions such as `BigInt.asIntN(0x4000000000000, 1n)`
(#3615). And those involving very large bigints.
2025-03-20 09:44:12 +01:00
Jess
f5a6704219 LibJS: Fix UAF in ECMAScriptFunctionObject::internal_construct
Currently, we create `this_argument` with
`ordinary_create_from_constructor`, then we use `arguments_list` to
build the callee_context.

The issue is we don't properly model the side-effects of
`ordinary_create_from_constructor`, if `new_target` is a proxy object
then when we `get` the prototype, arbitrary javascript can run.

This javascript could perform a function call with enough arguments to
reallocate the interpreters m_argument_values_buffer vector. This is
dangerous and leads to a use-after-free, as our stack frame maintains a
pointer to m_argument_values_buffer (`arguments_list`).
2025-03-19 10:31:00 +01:00
Timothy Flynn
00d00b84d3 LibJS: Ensure relevant extension keys are included in ICU locale data
This is a normative change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/7508197

In our implementation, we don't have the affected AOs directly, as we
delegate to ICU. So instead, we must ensure we provide ICU a locale with
the relevant extension keys present.
2025-03-18 11:47:23 -04:00
Timothy Flynn
37b8ba96f1 LibJS: Use currency digits for NumberFormat only for standard notation
This is a normative change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/9140da2
2025-03-18 11:47:23 -04:00
aplefull
80b2c11c81 LibJS: Implement Math.sumPrecise 2025-03-03 21:46:22 +01:00
aplefull
53cdb04ee8 LibJS: Fix parseFloat(-0) returning -0 instead of +0
The optimization that skips the string conversion for number values was
causing -0 to be returned as-is. This patch adds a check for this case.
2025-03-02 11:30:34 -05:00
Timothy Flynn
080d32c7d0 LibJS: Use Intl.DurationFormat for Temporal.Duration.p.toLocaleString
This is an normative change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/ffb4fb5
2025-03-01 14:49:20 +01:00
Timothy Flynn
8f51d1dd04 LibJS: Integrate Temporal.Duration into Intl.DurationFormat
This is a normative change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/2d97205
2025-03-01 14:49:20 +01:00
Ali Mohammad Pur
ea3b7efd91 LibRegex: Treat the UnicodeSets flag as Unicode
Fixes /.../v not being interpreted as a unicode pattern.
2025-02-28 14:31:45 -05:00
Jess
8ed7dee0f0 LibJS: Propogate allocation errors in BigInt constructor functions 2025-02-19 09:00:59 -05:00
Luke Wilde
105096e75a LibJS: Stop executing successful regex if it's past the end of the input
If the regex always matches the input, even if it's past the end, then
we need to stop execution of the regex when it's past the end. This
corresponds to step 13.a and prevents it from infinitely looping.

Reduced from: d98672060f/packages/react-i18n/src/utilities/money.ts (L10-L14)
2025-02-16 09:22:37 +01:00
Jess
356728b1e0 LibJS: Fix bytecode generation for super property stores and loads
The new test case crashes during bytecode generation due to
`emit_super_reference` not correctly generating the reference record
for the property access.
2025-02-15 06:59:59 -05:00
Psychpsyo
f92d037752 LibJS: Parse dates like "Jan 15, 2025" 2025-02-14 06:27:37 -05:00
jg99
51434c2ed0 LibJS: Parse dates like "1 Jan 2001 00:00:00 GMT" 2025-02-05 15:06:54 -07:00
Timothy Flynn
911b915763 LibJS: Handle call stack limit exceptions in NewPromiseReactionJob
The promise job's fulfillment / rejection handlers may push an execution
context onto the VM, which will throw an internal error if our ad-hoc
call stack size limit has been reached. Thus, we cannot blindly VERIFY
that the result of invoking these handlers is non-abrupt.

This patch will propagate any internal error forward, and retains the
condition that any other error type is not thrown.
2025-02-05 08:05:01 -05:00
Luke Wilde
30507681f7 LibJS: Parse dates like "2021-04-21T15:00:00+0000"
This is used on figma.com
2025-01-21 21:36:05 +01:00
Luke Wilde
3ab4efb7ef LibJS: Parse dates like "2025-01-13 00:00:00.000"
This is used on figma.com.
2025-01-21 21:36:05 +01:00
Timothy Flynn
b64a355a30 LibJS: Remove support for the "assert" keyword for import attributes
This was removed from the spec some time ago. See:
https://github.com/tc39/proposal-import-attributes/commit/14286bb
2025-01-21 14:58:32 +01:00
Timothy Flynn
47ba231a9b LibJS: Do not consume "with" tokens in import statements as identifiers
The "with" statement is its own token (TokenType::With), and thus would
fail to parse as an identifier. We've already asserted that the token
we are parsing is "with" or "assert", so just consume it.
2025-01-21 14:58:32 +01:00
Timothy Flynn
049109452e LibJS: Do not attempt to link modules which have failed to load
Linking a module has assertions about the module's state, namely that
the state is not "new". The state remains "new" if loading the module
has failed. See: https://tc39.es/ecma262/#figure-module-graph-missing

    In any case, this exception causes a loading failure, which results
    in A's [[Status]] remaining new.

So we must propagate that failure, instead of blindly moving on to the
linking steps.
2025-01-21 14:58:32 +01:00
Timothy Flynn
6a564376fc Meta+LibUnicode+LibJS: Upgrade to ICU 76.1
This updates our local ICU overlay port to use ICU 76.1. This includes
Unicode 16 and CLDR 46.

Upstream vcpkg is not able to supply versions past 74 yet due to various
dependency issues, but we are able to use this version ourselves. The
overlay port now includes a patch to revert ICU's dependence on autoconf
2.72 for now, as this version is not yet available on all systems.

All of the test changes were cross-referenced with Firefox to ensure
correctness.
2025-01-18 17:56:40 -05:00
Timothy Flynn
0763997591 LibJS: Ensure tests using the "ar" locale use the "arab" number system
In ICU 76, the default was changed from "arab" to "latn". See:
c149724509

The whole point of these tests was to use a non-Latin numbering system.
This patch ensures that is the case to make following patches easier to
grok.
2025-01-18 17:56:40 -05:00
Timothy Flynn
26c2484c2f LibJS: Implement the AsyncDisposableStack interface
This is very similar to the DisposableStack interface, except disposal
of resources is promise-based.
2025-01-17 20:46:32 +01:00
Luke Wilde
a588756105 LibJS: Use correct this value for tagged template literals with members
Required by creepjs, which does Date().split` `[3] to get the current
year.
2025-01-17 17:15:12 +01:00
Luke Wilde
5f33383a7b LibJS: Propagate direct eval presence if the current scope is screwed
Previously it only deoptimized the parent scope if the current scope
contains direct eval, which is incorrect because code ran in direct
eval mode has access to the entire scope chain it was executed in.
The fix is to also propagate direct eval's presence if the current
scope is marked as being screwed by direct eval.

This fixes Google's botguard failing to complete on Google sign in, as
it tried to access local variables outside of a direct parent function
with eval, causing it throw "unhandled" exceptions. Unhandled is in
quotes because their bytecode VM _technically_ caught it, but it was
considered an unhandled exception. This was determined by removing get
optimizations and then adding debug output for every get operation.
Using this, I noticed that for these errors, it would access the
'message' and 'stack' properties. This is because their error handler
function noticed this was not a synthesised error, which is never
expected to happen. That was determined by using Chrome Devtools 'pause
on handled exception' feature, and noticing it never threw a '[var] is
not defined' exception, but only synthesized error objects which
contained a sentinel value to let it know it was synthesized.

I added debug output to eval to print out what was being eval'd because
it makes heavy use of eval. This revealed that the exceptions only came
from eval.

I then dumped every generated executable and noticed the variables it
was trying to access were generated as local variables in the top
scope. This led to checking what makes a variable considered local or
not, which then lead to this block of code in ~ScopePusher that
propagates eval presence only to the immediate parent scope. This
variable directly controls whether to create all variables properly
with variable environments and bindings or allow them to be stored as
local registers tied to that function's executable.

Since this now lets botguard run to completion, it no longer considers
us to be an insecure/potential bot browser when signing in, now
allowing us to be able to sign in to Google.
2025-01-17 14:36:03 +01:00
Timothy Flynn
59162c8155 LibJS: Adjust ad-hoc clamping behavior in RegulateISODate
Instead of clamping to the limits allowed by ISOYearMonthWithinLimits,
clamp to the limits allowed by the type we are converting to (i32). This
allows some callers to then reject years outside that range.
2025-01-17 10:08:06 +01:00
Timothy Flynn
d5b26183f3 LibJS: Convert errant MUST to TRY in Temporal.PlainDateTime.with 2025-01-17 10:08:06 +01:00
Shannon Booth
5aeae5e583 LibJS: Parse dates like "Wednesday, Jan 15, 2025"
This was getting called on abc.com
2025-01-15 10:42:29 +01:00
Nicolas Ramz
423d106fd8 LibJS: Support date strings of the form "Thu, 09 Jan 2025 23:00:00" 2025-01-08 18:45:43 +01:00
Shannon Booth
c804d08d34 LibJS: Parse dates like "2025-01-02 14:00:00+0000"
This was getting spammed in the console by a website in the wild.
2025-01-03 14:43:13 -08:00
Timothy Flynn
ada36e5c0a LibJS: Allow async functions named "async" as function properties
For example, https://locals.com/site/discover has a script with an
object of the form:

    var f = {
        parser: {
            sync() {},
            async async() {},
        }
    };

We were previously throwing a syntax error on the async function, as we
specifically did not allow using "async" as a function name here.
2024-12-26 17:23:10 +01:00
Timothy Flynn
a5455ac121 LibJS: Ensure a function follows an async identifier in objects 2024-12-26 17:23:10 +01:00
Timothy Flynn
5947c37637 LibJS: Return the allocated dst register from deleting super properties
Even though calling delete on a super property will ultimately throw a
ReferenceError, we must return the allocated register for the result of
the delete operation (which would normally be a boolean). If the delete
operation is used in a return statement, the bytecode generator for the
return statement must be able to assume the statement had some output.
2024-12-14 12:08:50 -08:00
Timothy Flynn
962441b3cf LibJS: Avoid internal assertion accessing detached TA internal slots
This defers accessing TA internal slots until we know we have a valid,
attached TA. Our implementation has assertions that guard against this.
2024-12-13 07:09:39 -08:00
Timothy Flynn
234f218803 LibJS: Ensure GetDateTimeFormat returns nonnull for the best format
This is an editorial change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/8a52801
2024-12-06 11:13:10 -05:00
Timothy Flynn
6dfa6993e5 LibJS: Add workaround for invalid ISODateTimes in DifferenceISODateTime
The assertions can be hit when Temporal.Duration.prototype.round / total
are provided a PlainDate at the very limits of valid date-times. Tests
were recently added to test262 which trip these assertions, thus we are
now crashing in those tests. Let's throw a RangeError instead, as this
is the behavior expected by the tests.
2024-12-05 15:29:08 -05:00
Timothy Flynn
db87f173fb LibJS: Implement the RegExp.escape proposal
https://tc39.es/proposal-regex-escaping/
2024-12-05 13:56:21 +01:00
Timothy Flynn
5e534f4d83 LibJS+LibUnicode: Designate a sort order for Intl.PluralRules categories
This is a normative change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/62fe5db
2024-12-05 09:49:55 +01:00
Timothy Flynn
3c64e4595a LibJS: Use exact mathematical values for Intl.DurationFormat
We can't use doubles due to precision loss for extremely large values.
2024-12-04 08:01:35 -05:00
Timothy Flynn
53a507303c LibJS: Prevent extensions of TypedArray exotic objects
This is a normative change in the ECMA-262 spec. See:
https://github.com/tc39/ecma262/commit/c1040ff
2024-11-30 11:18:26 +01:00
Timothy Flynn
0468463e2e LibJS: Implement the ECMA-402 ZonedDateTime.prototype.toLocaleString.js 2024-11-29 09:52:12 +01:00