Skip to content

console: isSystemRoute / isMetadataRoute 的子串判断把 /apps/未知app/system_log 认成伪路由,静默回退渲染另一个 app #3638

Description

@yinlianghui

越界发现,记录于 #3610(零应用下 component/metadata/* 白屏)期间。按纪律只报不改,单独立单,未认领,留给 PM 分诊。

实测基线:origin/main @ 8d5418e5(packages/app-shell/src/console/AppContent.tsx)。

现象

三个伪路由开关里有两个是子串判断,而不是路径段判断:

:183  const isCreateAppRoute = location.pathname.endsWith('/create-app');
:184  const isSystemRoute    = location.pathname.includes('/system');
:185  const isMetadataRoute  = location.pathname.includes('/metadata');

includes('/system') 会命中 /system 开头的任意段,不止 system 这一段本身:/apps/x/system_log/apps/x/system_setting/apps/x/systems 全为真。isMetadataRoute 同理(metadata_importmetadata_log……)。

后果:恰好绕开「绝不渲染另一个 app」那道守卫

isSpecialRoute 为真会同时改变两处判断(:188:198:207):

:198  ((!appName || isSpecialRoute)
:199     ? (launcherApps.find(a => a.isDefault === true) || launcherApps[0])
:200     : undefined);
:207  const requestedAppMissing = !!appName && !matchedApp && !isSpecialRoute;

于是访问 /apps/拼错的app名/system_log:

  1. matchedApp 为 undefined(app 名不存在);
  2. isSystemRoutesystem_log 误命中 → isSpecialRoute 为真;
  3. requestedAppMissing 因此为 false,:547 的「App not available」守卫不触发;
  4. activeApp 回退成 默认/第一个 app,渲染它的 shell,并把 system_log 当作该 app 下的 :objectName

:193-200 的注释正是为了防住这件事(原文:"A normal unmatched appName must NOT silently render a DIFFERENT app — the readiness guard below shows loading / not-available instead. (Fixes 'the preview / nav renders the WRONG app right after building a new one'.)")。子串判断在这条路径上把它绕开了 —— 用户看到的是另一个 app 的界面,没有任何提示说所请求的 app 不存在。

为什么不在 #3610 里顺手修

#3610 的裁定是:子串判断把请求引进分支这件事是对的,错在分支服务不了(那已由 PR #3636 补齐路由 + catch-all 修掉)。本单是另一个方向的后果 —— 判断过宽导致 requestedAppMissing 失灵 —— 与 #3610 的白屏无因果关系,单独成立。#3610 的文件面也明确不含这三行。

可能的修法(留给分诊)

改成按路径段判断,而不是子串。例如把 pathname 切段后判断某一段是否 === 'system' / === 'metadata',或用 /\/system(\/|$)/ 这类带边界的正则。

⚠️ 改动前需要先测量清楚当前依赖这层宽松的调用点:/apps/x/system/marketplace/.../apps/x/component/metadata/resource(段位置不在 :objectName 上)、宿主 extraRoutesdeveloper/*docs/* 等,都要确认收紧后仍为真。这正是「消费端宽松兜底」的典型代价 —— 收紧是对的,但得先把真实的输入面量出来。

严重度自评不可靠,交分诊

触发前提是「app 名不匹配」+「首段以 system / metadata 开头」。平台内建对象普遍用 sys_ 前缀而非 system_,所以命中率取决于业务对象的命名,我无法从仓内判定。按 objectstack#4949 的纪律原样上报,不预判轻重。

关联

已就关键词(isSystemRoute / isMetadataRoute / isSpecialRoute / requestedAppMissing / 子串 / includes / wrong app)搜过本仓开放 issue 与 PR,无同源单。


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions