Typed data whose message leaves out a declared field, or gives a bool field a value other than true or false, is now refused on the sign screen and in the background (#552). ethers signs a bool by whether its value is truthy, so the string "false" was shown as false and signed as true, and a field left out was signed as false.
typedDataMessageRefusal() in src/shared/approvalVerify.js walks the message from the type ethers signs, through nested structs and lists, and names the first field that is missing or holds a bool that is not true or false (details[1].nonce).
The popup's typedDataRefusal() calls it, so the error line shows that sentence and Sign is disabled. The background's sign response handler calls it beside the chain check and answers the site with the same sentence.
signedPrimaryType() moves unchanged from the popup into the shared module, so the background reads the message as the same type.
Things the diff does not show:
A field counts as present only if it is one of the message's own keys, so a field named constructor is not found on the object's prototype.
Any declared field left out is refused, not only a bool; for other types ethers already failed at signing.
A list field whose value is not a list is left to ethers, which refuses to sign it.
Judgement call: the wording of the two error sentences.
Model: opus-5-5
Typed data whose message leaves out a declared field, or gives a `bool` field a value other than `true` or `false`, is now refused on the sign screen and in the background (https://git.eeqj.de/sneak/AutistMask/issues/552). ethers signs a `bool` by whether its value is truthy, so the string `"false"` was shown as false and signed as true, and a field left out was signed as false.
- `typedDataMessageRefusal()` in `src/shared/approvalVerify.js` walks the message from the type ethers signs, through nested structs and lists, and names the first field that is missing or holds a `bool` that is not `true` or `false` (`details[1].nonce`).
- The popup's `typedDataRefusal()` calls it, so the error line shows that sentence and Sign is disabled. The background's sign response handler calls it beside the chain check and answers the site with the same sentence.
- `signedPrimaryType()` moves unchanged from the popup into the shared module, so the background reads the message as the same type.
Things the diff does not show:
- A field counts as present only if it is one of the message's own keys, so a field named `constructor` is not found on the object's prototype.
- Any declared field left out is refused, not only a `bool`; for other types ethers already failed at signing.
- A list field whose value is not a list is left to ethers, which refuses to sign it.
Judgement call: the wording of the two error sentences.
Model: opus-5-5
ethers signs a bool field by whether its value is truthy, so the string
"false" was shown as false and signed as true, and a bool field left out
was shown as nothing and signed as false. The sign screen now refuses
typed data whose message leaves out a declared field, at any level of
nesting, or holds a bool that is not true or false: the error line names
the field and Sign is disabled. The background refuses a signature for it
too. Presence is an own-key test, so a field named like a built-in
property such as constructor is not found by accident. signedPrimaryType()
moves to the shared module so the background reads the message as the
same type.
Model: opus-5-5
PASS: typed data whose message leaves out a declared field or holds a bool that is not true or false is now refused on the sign screen and in the background, as #552 requires.
Model: opus-5-5
PASS: typed data whose message leaves out a declared field or holds a `bool` that is not true or false is now refused on the sign screen and in the background, as https://git.eeqj.de/sneak/AutistMask/issues/552 requires.
Model: opus-5-5
clawbot
merged commit 70a41ed70e into next2026-10-16 03:33:40 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Typed data whose message leaves out a declared field, or gives a
boolfield a value other thantrueorfalse, is now refused on the sign screen and in the background (#552). ethers signs aboolby whether its value is truthy, so the string"false"was shown as false and signed as true, and a field left out was signed as false.typedDataMessageRefusal()insrc/shared/approvalVerify.jswalks the message from the type ethers signs, through nested structs and lists, and names the first field that is missing or holds aboolthat is nottrueorfalse(details[1].nonce).typedDataRefusal()calls it, so the error line shows that sentence and Sign is disabled. The background's sign response handler calls it beside the chain check and answers the site with the same sentence.signedPrimaryType()moves unchanged from the popup into the shared module, so the background reads the message as the same type.Things the diff does not show:
constructoris not found on the object's prototype.bool; for other types ethers already failed at signing.Judgement call: the wording of the two error sentences.
Model: opus-5-5
PASS: typed data whose message leaves out a declared field or holds a
boolthat is not true or false is now refused on the sign screen and in the background, as #552 requires.Model: opus-5-5