fix(desktop): keep non-ASCII desktop entries out of Open In matching (#3403)

desktopEntryMatchesApp normalized haystack values without dropping empty
ones, so a .desktop entry with no ASCII letters or digits in Name, id,
file name, or Exec (e.g. Name=抖音) normalized to "" and
needle.includes("") matched every requested app — hijacking the
installed-apps list and Open In launch specs. Empty normalized haystack
values are now filtered, matching the existing needles handling.

discovered-apps.json gains a version field (INSTALLED_APPS_CACHE_VERSION
= 2); caches written before the fix are treated as stale and refresh
through the existing TTL-expiry path instead of serving the poisoned
list for the rest of the 24h TTL.
This commit is contained in:
ouyangjian28
2026-09-07 20:25:30 +03:00
committed by GitHub
parent c779b765d9
commit bf4262dbc9
3 changed files with 99 additions and 3 deletions
+5 -1
View File
@@ -145,7 +145,11 @@ export const readLinuxDesktopEntries = async (options = {}) => {
const desktopEntryMatchesApp = (entry, appName, appId = '') => {
const needles = uniqueStrings([appName, appId]).flatMap((value) => [normalizeComparable(value), normalizeCompactComparable(value)]).filter(Boolean);
const haystacks = [entry.name, entry.id, path.basename(entry.filePath || ''), entry.exec]
.flatMap((value) => [normalizeComparable(value), normalizeCompactComparable(value)]);
.flatMap((value) => [normalizeComparable(value), normalizeCompactComparable(value)])
// A value with no ASCII letters or digits (e.g. a CJK-only Name) normalizes to the empty
// string, and needle.includes('') is true for every app — drop it so such entries can
// only match through a field that still carries comparable text.
.filter(Boolean);
return needles.some((needle) => haystacks.some((haystack) => haystack === needle || haystack.includes(needle) || needle.includes(haystack)));
};