Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughRefines parsing and execution of UMU/Steam wrapper commands: detects collapsed launcher patterns, adds a steamArgSeparator, reparses launcher prefixes when needed, guards against empty parse results, replaces wrapped executables with the canonical launch executable, and uses shell-based spawn for wrapper paths. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@application/src/electron/handlers/handler.library.ts`:
- Line 261: The spawn call in handler.library.ts is using shell: true which
causes pre-tokenized args to be joined and re-parsed by a shell; change the
spawn options to use shell: false (or remove the shell option to use default) so
the args array passed to spawn is used as a true argv vector; locate the spawn
invocation in this file (the function/method that calls spawn where shell: true
is set) and update the options object to shell: false, and if any arguments
currently rely on shell expansion or quoting, rework them to be safely passed as
separate entries in the args array or explicitly escape them before passing.
- Around line 233-237: The parsed result from shell-quote (parsed) may contain
non-string tokens (operator/comment/glob objects) which, when appended to
fixedArgs or coerced with .toString() later, become "[object Object]" and break
execution; update the logic around wrapperCommand parsing (parsed) and fixedArgs
construction to validate token types: explicitly ensure every token in parsed is
a string (or nicely stringify only safe token types), reject/return an error if
any non-string tokens are present, or filter/transform allowed tokens to strings
before building fixedArgs that includes appInfo.launchExecutable, and change the
code paths that rely on .toString() (lines that reference fixedArgs usage) to
assume only validated string tokens.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (1)
application/src/electron/handlers/handler.library.ts
| if (parsed.length === 0) { | ||
| return { success: false, error: 'Wrapper command could not be parsed' }; | ||
| } | ||
| const fixedArgs = [...parsed, appInfo.launchExecutable]; | ||
|
|
There was a problem hiding this comment.
❓ Verification inconclusive
Script executed:
# First, let's look at the file and the specific lines mentioned
cat -n application/src/electron/handlers/handler.library.ts | sed -n '230,265p'Repository: Nat3z/OpenGameInstaller
Repository: Nat3z/OpenGameInstaller
Exit code: 0
stdout:
230 }
231 }
232
233 if (parsed.length === 0) {
234 return { success: false, error: 'Wrapper command could not be parsed' };
235 }
236 const fixedArgs = [...parsed, appInfo.launchExecutable];
237
238 return await new Promise((resolve) => {
239 const effectiveLaunchEnv = getEffectiveLaunchEnv(appInfo);
240 const effectiveDllOverrides = getEffectiveDllOverrides(appInfo);
241 const dllOverrideString = buildDllOverrides(effectiveDllOverrides);
242 const baseEnv = {
243 ...process.env,
244 ...(launchEnv ?? {}),
245 ...effectiveLaunchEnv,
246 PROTON_LOG: '1',
247 };
248 const env = appInfo.umu
249 ? {
250 ...baseEnv,
251 STEAM_COMPAT_DATA_PATH: getUmuWinePrefix(appInfo.umu.umuId),
252 WINEPREFIX: getUmuWinePrefix(appInfo.umu.umuId),
253 ...(dllOverrideString ? { WINEDLLOVERRIDES: dllOverrideString } : {}),
254 }
255 : baseEnv;
256
257 const wrappedChild = spawn(
258 parsed[0].toString(),
259 fixedArgs.slice(1).map((x) => x.toString()),
260 {
261 shell: true,
262 cwd: appInfo.cwd,
263 env,
264 stdio: ['ignore', 'pipe', 'pipe'],
265 }
Script executed:
# Also check if shell-quote is in package.json or installed
find . -name "package.json" -type f -exec grep -l "shell-quote" {} \;Repository: Nat3z/OpenGameInstaller
Repository: Nat3z/OpenGameInstaller
Exit code: 0
stdout:
./application/package.json
shell-quote parse() return type token types operator objects
In shell-quote, parse() returns an array of “tokens”:
- TypeScript return type:
ParseEntry[](orArray<ParseEntry | T>with the generic overload). [1] - Token variants (
ParseEntry): [1]string(a normal word/argument){ op: ControlOperator }(a shell/control operator token){ op: "glob"; pattern: string }(a glob token){ comment: string }(a# ...comment token)
Operator token values (ControlOperator) include:
"||" | "&&" | ";;" | "|&" | "<(" | ">>" | ">&" | "&" | ";" | "(" | ")" | "|" | "<" | ">". [1]
Example outputs (operators/comments become objects):
parse('beep || boop > /byte') → ['beep', { op: '||' }, 'boop', { op: '>' }, '/byte']
parse('beep > boop # > kaboom') → ['beep', { op: '>' }, 'boop', { comment: '> kaboom' }] [2]
Env function overload detail: if env(key) returns an object, it’s inserted into the returned token array “like the operator objects”. [1]
Sources: [1] @types/shell-quote index.d.ts (UNPKG) (app.unpkg.com), [2] shell-quote README on npm (examples/behavior) (npmjs.com)
Citations:
- 1: https://app.unpkg.com/%40types/shell-quote%401.7.5/files/index.d.ts
- 2: https://www.npmjs.com/package/shell-quote/v/1.7.4?utm_source=openai
Script executed:
cat -n application/src/electron/handlers/handler.library.ts | sed -n '210,235p'Repository: Nat3z/OpenGameInstaller
Repository: Nat3z/OpenGameInstaller
Exit code: 0
stdout:
210 const verbWithSpaces = ` ${verb} `;
211 const steamArgSeparator = ' -- ';
212 const verbIndexInString = wrapperCommand.indexOf(verbWithSpaces);
213 let parsed: ReturnType<typeof shellQuoteParse>;
214 if (verbIndexInString !== -1) {
215 const prefix = wrapperCommand.slice(0, verbIndexInString).trimEnd();
216 parsed = shellQuoteParse(prefix);
217 parsed.push(verb);
218 // Everything after " waitforexitandrun " is the exe path (may contain spaces);
219 // we replace it with the canonical path, so we don't parse the suffix.
220 } else {
221 // Non-Proton command variants usually end with " -- <exe>".
222 // Parse only the prefix up to the last separator, then replace <exe>.
223 const lastSeparatorInString = wrapperCommand.lastIndexOf(steamArgSeparator);
224 if (lastSeparatorInString !== -1) {
225 const prefix = wrapperCommand.slice(0, lastSeparatorInString).trimEnd();
226 parsed = shellQuoteParse(prefix);
227 parsed.push('--');
228 } else {
229 parsed = shellQuoteParse(wrapperCommand);
230 }
231 }
232
233 if (parsed.length === 0) {
234 return { success: false, error: 'Wrapper command could not be parsed' };
235 }
Script executed:
# Search for where this function is called and what input is passed
rg -B 5 -A 5 "parse\(" application/src/electron/handlers/handler.library.ts | head -40Repository: Nat3z/OpenGameInstaller
Repository: Nat3z/OpenGameInstaller
Exit code: 0
Validate parsed token types before argv construction.
The wrapperCommand is user-supplied (lines 215, 225, 229) and parsed via shell-quote. The parse function returns mixed token types: strings, operator objects ({ op: '||' | '&&' | ... }), globs, and comments. Line 233 only checks emptiness; it does not validate token types. When non-string tokens reach lines 258–259, their .toString() coercion produces "[object Object]" strings, breaking the wrapper execution.
Suggested fix
- if (parsed.length === 0) {
+ if (parsed.length === 0 || parsed.some((t) => typeof t !== 'string')) {
return { success: false, error: 'Wrapper command could not be parsed' };
}
- const fixedArgs = [...parsed, appInfo.launchExecutable];
+ const parsedStrings = parsed as string[];
+ const fixedArgs = [...parsedStrings, appInfo.launchExecutable];
...
- parsed[0].toString(),
- fixedArgs.slice(1).map((x) => x.toString()),
+ fixedArgs[0],
+ fixedArgs.slice(1),Also applies to: 258–259
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@application/src/electron/handlers/handler.library.ts` around lines 233 - 237,
The parsed result from shell-quote (parsed) may contain non-string tokens
(operator/comment/glob objects) which, when appended to fixedArgs or coerced
with .toString() later, become "[object Object]" and break execution; update the
logic around wrapperCommand parsing (parsed) and fixedArgs construction to
validate token types: explicitly ensure every token in parsed is a string (or
nicely stringify only safe token types), reject/return an error if any
non-string tokens are present, or filter/transform allowed tokens to strings
before building fixedArgs that includes appInfo.launchExecutable, and change the
code paths that rely on .toString() (lines that reference fixedArgs usage) to
assume only validated string tokens.
|
[wrapper stderr] <3>pv-adverb[277355]: E: Failed to execute child process ?/home/deck/.local/share/Steam/steamapps/common/Proton? (No such file or directory) |
Summary by CodeRabbit