[p5.js 2.0+ Bug Report]: getURLParams() mis-parses valueless parameters and never percent-decodes values
Maintainer thường phản hồi trong vòng 2 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 88/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- javascript
- Lĩnh vực
- frontend
Hướng nghiên cứu
Bắt đầu tại getURLParams trong src/core/environment.js:1058 và chạy bốn trường hợp độc lập từ issue (đoạn regex inline) để thấy lỗi parse trước khi động vào bất cứ thứ gì. Phương án thay thế được đề xuất là Object.fromEntries(new URLSearchParams(location.search)), xử lý khóa không có giá trị, giải mã phần trăm và + như dấu cách; bỏ workaround lastIndex cùng với nó. Thêm kiểm thử hồi quy cho ?debug&x=1, ?a=1&b, ?name=Hello%20World và ?q=a+b trong các unit test của environment, và kiểm tra tài liệu tham chiếu getURLParams để tìm ghi chú double-decode.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Most appropriate sub-area of p5.js?
- Core/Environment/Rendering
p5.js version
2.3.2 (verified on main @ 94fb07d)
Web browser and version
All — the parser is a hand-rolled regex, not a browser API.
Operating system
All
Steps to reproduce this
Steps:
- Open any sketch with
?debug&x=1appended to the URL. - Log
getURLParams(). - It returns
{ debug: "x" }— a pair that does not exist in the query string — andx=1is gone entirely. - Try
?name=Hello%20World: the value comes back still percent-encoded.
Snippet:
function setup() {
print(getURLParams());
}
The parser can be run standalone to see all the cases:
const re = /[?&]([^&=]+)(?:[&=])([^&=]+)/gim;
function current(search) {
let m; const v = {};
while ((m = re.exec(search)) != null) {
if (m.index === re.lastIndex) re.lastIndex++;
v[m[1]] = m[2];
}
return v;
}
current('?debug&x=1'); // { debug: "x" } expected { debug: "", x: "1" }
current('?a=1&b'); // { a: "1" } expected { a: "1", b: "" }
current('?name=Hello%20World'); // { name: "Hello%20World" } expected { name: "Hello World" }
current('?q=a+b'); // { q: "a+b" } expected { q: "a b" }
Cause
// src/core/environment.js:1058
fn.getURLParams = function () {
const re = /[?&]([^&=]+)(?:[&=])([^&=]+)/gim;
let m;
const v = {};
while ((m = re.exec(location.search)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
v[m[1]] = m[2];
}
return v;
};
Three problems:
- The separator group accepts
&as well as=.(?:[&=])means a parameter with no value matches&debug&xas keydebug, separator&, valuex— it absorbs the next parameter's name as its own value, and consumes the realx=1pair along with it. A valueless parameter does not just get skipped; it corrupts its neighbour. - Nothing is decoded. No
decodeURIComponent, and+is not translated to a space, so any value containing a space,&,/or a non-ASCII character arrives in its encoded form. - A repeated key keeps only the last occurrence, and the returned object is a
{}literal, so it inheritstoString,constructor,hasOwnPropertyand friends. Code that testsif (params.constructor)gets a surprising truthy value.
Expected behaviour
Query strings should be parsed per the URL standard: values decoded, + treated as a space, and a parameter with no value reported as an empty string rather than absorbing the parameter after it.
Suggested fix
The platform already does all of this correctly, and URLSearchParams has been available in every browser p5 2.x supports for years:
fn.getURLParams = function () {
return Object.fromEntries(new URLSearchParams(location.search));
};
That also removes the lastIndex workaround (needed only because of the zero-length-match hazard in the hand-rolled loop) and the prototype-inherited keys.
Two notes on compatibility, since this is a behaviour change and not purely a fix:
- Valueless parameters start appearing as
''instead of being mis-parsed. Any sketch relying on the current output for?flagwas getting wrong data, but it is still a change worth a line in the release notes. - Values arrive decoded. A sketch that was calling
decodeURIComponent()on the result itself would now double-decode. Worth mentioning in the reference docs forgetURLParams().
If you'd prefer to preserve repeated keys as arrays while you're in there, that is easy to add on top — but it is a separate decision, so I've left it out of the suggestion.
I'd be glad to open a PR with the replacement and tests covering all four cases above.
- Ngôn ngữ chính
- JavaScript
- Star
- 24.1k
- Fork
- 3.9k
- Merge trung bình
- 3 ngày 19 giờ
- Pull request đã merge (30 ngày)
- 33
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của processing/p5.js
-
[p5.js 2.0+ Bug Report]: SVG importer does not respect preserveAspectRatio="none" for <symbol>/<use>Có thể đã có người làm @Danyccsf đã nhận hôm nay. Đang mởArea:Core p5.js 2.0+
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
processing/p5.js#9257 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Add unit tests for noiseDetail()Có thể đã có người làm @Pcmhacker-piro đã nhận 2 ngày trước. Đang mởArea:Math Enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
processing/p5.js#9253 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[p5.js 2.0+ Bug Report]: storeItem() validation branches are missing `return`, so bad input throws a TypeError or is stored anywayCó thể đã có người làm @iUjjwalRaj đã nhận 3 ngày trước. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
processing/p5.js#9242 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[p5.js 2.0+ Bug Report]: Typo in Spanish reference documentation for ellipseMode()Có thể đã có người làm @cgutierrezval đã nhận 5 ngày trước. Đang mởInternationalization p5.js 2.0+
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 95/100
processing/p5.js#9231 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[p5.js 2.0+ Bug Report]: ReferenceError: p5 is not defined when calling loadPixels/get/copy/mask on p5.MediaElement in ESMCó thể đã có người làm @Pcmhacker-piro đã nhận 10 ngày trước. Đang mởArea:Core Area:DOM
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
processing/p5.js#9189 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của processing/p5.js
Issue tương tự
-
`yarn vitest:update` (documented) throws locally; local Cypress scripts target an unserved portĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
rescript-lang/rescript-lang.org#1415 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Deepak3699/Ai_Mentor#244 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
antithesishq/bombadil#361 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
ungroomed
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
dequelabs/axe-core#5455 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
DietrichGebert/ponytail#1072 ·
Maintainer thường phản hồi trong vòng 3 ngày