qwen-code/packages/cli
pomelo-nwu 93199a46ed fix(auth): fourth round of PR #4287 review fixes
Critical:
- settingsWriter JSONC scanner: \uXXXX is a 6-char escape, not 2.
  The previous stripJsonComments / stripTrailingCommas used j+=2 for
  every backslash, so a value containing \u0022 would let the embedded
  quote terminate the string early — turning a single string value into
  multiple top-level keys after the strip passes. That's a parser
  differential vs JSON.parse and enables settings.json key injection
  (e.g. an attacker-controlled API_KEY string could inject env.NODE_OPTIONS).
  Now we branch on text[j+1] === 'u' and skip 6, satisfying both scanners.
- resolveBaseUrl no longer crashes on an empty baseUrl array. The
  previous config.baseUrl[0].url threw 'Cannot read undefined.url' on []
  and brought down the whole install flow. Falls back to selectedBaseUrl
  or '' instead.
- providerMatchesCredentials now resolves function-typed envKey by
  calling it with (protocol, baseUrl). The previous typeof-string gate
  made the custom provider invisible to findProviderByCredentials —
  /doctor and system-info diagnostics couldn't see custom-provider users.
  Catches the function call so a misbehaving custom envKey can't crash
  the matcher.

Suggestions:
- AuthDialog: defaultMainIndex now also returns 2 for uiGroup === 'custom'
  so a custom-provider user lands on the Custom Provider tab instead of
  Alibaba ModelStudio.
- install.ts: env-var rollback loop is now wrapped in try/catch matching
  the same shape as the settings.restore() and reloadModelProviders
  rollbacks. A process.env write throwing (custom property descriptors,
  some sandboxes) won't skip the runtime-providers rollback below.
- readSettings: SyntaxError is now wrapped in an actionable Error
  ('Cannot parse ~/.qwen/settings.json ($name: $message). Standard
  JSONC is supported... Please fix or delete $path...') so users facing
  a corrupt file get a clear message instead of a bare SyntaxError. The
  cause is preserved via Error.cause.

Tests:
- settingsWriter: new \u0022 injection regression — asserts that a
  string containing \u0022 stays a single string and no injected key
  lands at the top level.
- provider-config: new edge-case suite for resolveBaseUrl with [] and
  providerMatchesCredentials with function-typed envKey (matching path,
  wrong-key path, function-throws path). Re-imports via the relative
  source path so the new behaviour is exercised even before dist/ is
  rebuilt.

Not addressed:
- handleProviderSubmit error-path test (Comment 3264567491) was already
  added in 7d8b4785ad — same test, same surface (refreshAuth rejection
  + authError set + dialog reopen + isAuthenticating false + no success
  toast + pendingAuthType populated).

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-19 16:36:07 +08:00
..
src fix(auth): fourth round of PR #4287 review fixes 2026-05-19 16:36:07 +08:00
index.ts fix(cli): stop double-wrapping and double-printing API errors in non-interactive mode (#3749) 2026-05-03 08:39:31 +08:00
package.json feat(core,cli): add generic atomicWriteFile, wire into Write/Edit tools, upgrade @types/node (#4096) 2026-05-15 17:52:50 +08:00
test-setup.ts perf(cli): code-split lowlight to cut startup V8 parse cost (#4070) 2026-05-15 17:26:18 +08:00
tsconfig.json fix(serve): align build and integration test coverage (#4248) 2026-05-18 00:01:47 +08:00
vitest.config.ts refactor(core): Unify package exports and improve dev experience 2026-02-01 11:59:05 +08:00