Form fields go haywire if they match Object.prototype properties
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the bug
If you have a form like this...
import { form } from '$app/server';
import * as v from 'valibot';
export const myform = form(v.object({
toString: v.pipe(v.string(), v.minLength(5)),
}), (data) => {
console.log(data);
});
<script lang="ts">
import { myform } from './remote';
</script>
<form {...myform}>
<input {...myform.fields.toString.as('text')} />
<button>submit</button>
</form>
...two strange things happen. Firstly the input is populated with function toString() { [native code] }, because deep_get doesn't do an Object.hasOwn check:
Secondly, if you delete the text (so that the field is invalid) and submit, an error occurs:
result[name].push is not a function
That's because result inside flatten_issues is a plain object, when it needs to be Object.create(null).
The following patch fixes both issues:
diff --git a/packages/kit/src/runtime/form-utils.js b/packages/kit/src/runtime/form-utils.js
index f2bb444cc8..52cd00d5ce 100644
--- a/packages/kit/src/runtime/form-utils.js
+++ b/packages/kit/src/runtime/form-utils.js
@@ -578,7 +578,7 @@ export function normalize_issue(issue, server = false) {
*/
export function flatten_issues(issues) {
/** @type {Record<string, InternalRemoteFormIssue[]>} */
- const result = {};
+ const result = Object.create(null);
for (const issue of issues) {
(result.$ ??= []).push(issue);
@@ -610,7 +610,7 @@ export function flatten_issues(issues) {
export function deep_get(object, path) {
let current = object;
for (const key of path) {
- if (current === null || typeof current !== 'object') return undefined;
+ if (current === null || typeof current !== 'object' || !Object.hasOwn(current, key)) return undefined;
current = current[key];
}
return current;
Reproduction
see above
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/kit/src/runtime/form-utils.js at flatten_issues and deep_get, using the supplied form reproduction as the first check. Done means fields named after Object.prototype properties no longer receive inherited values and invalid submissions no longer trigger the reported error; run the relevant form tests or reproduction to verify both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- full-stack
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100