Skip to content

Create Notice#1

Open
XiaoningDing wants to merge 2 commits intomainfrom
Xiaoning
Open

Create Notice#1
XiaoningDing wants to merge 2 commits intomainfrom
Xiaoning

Conversation

@XiaoningDing
Copy link
Copy Markdown
Owner

Just a test

Just a test
@XiaoningDing
Copy link
Copy Markdown
Owner Author

/gemini review this PR

This is to test auto code review
@XiaoningDing
Copy link
Copy Markdown
Owner Author

@gemini-code-assist can you help review?

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds a new file named Notice containing a test placeholder. The review feedback suggests removing this file to prevent repository clutter or renaming it to a standard NOTICE format if it is intended for legal attributions.

@@ -0,0 +1 @@
To test auto code review in PRs
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Committing test placeholders like Notice to the repository root clutters the project structure. Such files should be removed before merging. If the intent is to add a legal notice, use the standard NOTICE filename and include the appropriate attribution text.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several utility modules, including Windows-specific path handling and conversion, a polyfill for Promise.withResolvers, and a random word slug generator. The review feedback focuses on improving performance and reliability in windowsPaths.ts by using the native fs module instead of spawning shell processes for file existence checks. Additionally, it is recommended to throw errors instead of calling process.exit in utility functions and to define the PromiseWithResolvers interface locally to ensure type safety in environments where the native implementation is missing.

@@ -0,0 +1,173 @@
import memoize from 'lodash-es/memoize.js'
import * as path from 'path'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Import the fs module to enable efficient file system checks without spawning external processes.

Suggested change
import * as path from 'path'
import * as fs from 'fs'
import * as path from 'path'

Comment on lines +15 to +22
function checkPathExists(path: string): boolean {
try {
execSync_DEPRECATED(`dir "${path}"`, { stdio: 'pipe' })
return true
} catch {
return false
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using execSync to run the dir command is an expensive operation because it spawns a new shell process. Using the built-in fs.existsSync is significantly faster and more reliable.

function checkPathExists(path: string): boolean {
  return fs.existsSync(path)
}

`Claude Code was unable to find CLAUDE_CODE_GIT_BASH_PATH path "${process.env.CLAUDE_CODE_GIT_BASH_PATH}"`,
)
// eslint-disable-next-line custom-rules/no-process-exit
process.exit(1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Directly exiting the process in a utility function can make the library difficult to use in different contexts (e.g., tests or other applications). Consider throwing a descriptive error instead, allowing the caller to decide how to handle the failure.

* Polyfill for Promise.withResolvers() (ES2024, Node 22+).
* package.json declares "engines": { "node": ">=18.0.0" } so we can't use the native one.
*/
export function withResolvers<T>(): PromiseWithResolvers<T> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since this polyfill is for environments where Promise.withResolvers is not natively available, the PromiseWithResolvers type might also be missing from the global scope. Defining it locally ensures type safety and compatibility.

Suggested change
export function withResolvers<T>(): PromiseWithResolvers<T> {
export interface PromiseWithResolvers<T> {
promise: Promise<T>
resolve: (value: T | PromiseLike<T>) => void
reject: (reason?: any) => void
}
export function withResolvers<T>(): PromiseWithResolvers<T> {

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds utilities for Windows path manipulation, a Promise.withResolvers polyfill, and a random word slug generator. The review identifies security concerns regarding command injection and process execution in path utilities, suggesting the use of native Node.js functions instead. Other feedback includes improving the robustness of line-ending handling, replacing process exits with errors, defining missing types for the Promise polyfill, and addressing modulo bias in random number generation.

Comment on lines +49 to +52
const result = execSync_DEPRECATED(`where.exe ${executable}`, {
stdio: 'pipe',
encoding: 'utf8',
}).trim()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Potential command injection vulnerability. The executable variable is interpolated directly into a shell command string. If the input is not strictly controlled, an attacker could execute arbitrary commands by including shell metacharacters. Consider using execFileSync or another method that avoids shell execution.

Comment on lines +1 to +8
import memoize from 'lodash-es/memoize.js'
import * as path from 'path'
import * as pathWin32 from 'path/win32'
import { getCwd } from './cwd.js'
import { logForDebugging } from './debug.js'
import { execSync_DEPRECATED } from './execSyncWrapper.js'
import { memoizeWithLRU } from './memoize.js'
import { getPlatform } from './platform.js'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add existsSync to the imports to support a more efficient and secure path existence check in checkPathExists.

Suggested change
import memoize from 'lodash-es/memoize.js'
import * as path from 'path'
import * as pathWin32 from 'path/win32'
import { getCwd } from './cwd.js'
import { logForDebugging } from './debug.js'
import { execSync_DEPRECATED } from './execSyncWrapper.js'
import { memoizeWithLRU } from './memoize.js'
import { getPlatform } from './platform.js'
import memoize from 'lodash-es/memoize.js'
import { existsSync } from 'node:fs'
import * as path from 'path'
import * as pathWin32 from 'path/win32'
import { getCwd } from './cwd.js'
import { logForDebugging } from './debug.js'
import { execSync_DEPRECATED } from './execSyncWrapper.js'
import { memoizeWithLRU } from './memoize.js'
import { getPlatform } from './platform.js'

Comment on lines +15 to +22
function checkPathExists(path: string): boolean {
try {
execSync_DEPRECATED(`dir "${path}"`, { stdio: 'pipe' })
return true
} catch {
return false
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The checkPathExists function is inefficient and insecure. Spawning a shell process (dir) to check for file existence is significantly slower than using Node.js built-in functions and is vulnerable to command injection if the path contains double quotes (e.g., " & calc). Additionally, the parameter name path shadows the imported path module. Use existsSync from node:fs instead.

function checkPathExists(filePath: string): boolean {
  return existsSync(filePath)
}


// SECURITY: Filter out any results from the current directory
// to prevent executing malicious git.bat/cmd/exe files
const paths = result.split('\r\n').filter(Boolean)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Splitting by \r\n specifically may fail if the environment returns only \n (LF). Using a regex like /\r?\n/ is more robust for handling different line ending conventions on Windows.

Suggested change
const paths = result.split('\r\n').filter(Boolean)
const paths = result.split(/\r?\n/).filter(Boolean)

`Claude Code was unable to find CLAUDE_CODE_GIT_BASH_PATH path "${process.env.CLAUDE_CODE_GIT_BASH_PATH}"`,
)
// eslint-disable-next-line custom-rules/no-process-exit
process.exit(1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using process.exit(1) in a utility function is discouraged as it terminates the entire application, making it difficult for callers to handle errors or for the code to be unit tested. Consider throwing an error instead.

Suggested change
process.exit(1)
throw new Error(`Claude Code was unable to find CLAUDE_CODE_GIT_BASH_PATH path "${process.env.CLAUDE_CODE_GIT_BASH_PATH}"`)

* Polyfill for Promise.withResolvers() (ES2024, Node 22+).
* package.json declares "engines": { "node": ">=18.0.0" } so we can't use the native one.
*/
export function withResolvers<T>(): PromiseWithResolvers<T> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The type PromiseWithResolvers<T> is likely missing in the targeted Node environments (>=18). You should define the interface locally to ensure type safety and successful compilation.

Suggested change
export function withResolvers<T>(): PromiseWithResolvers<T> {
export interface PromiseWithResolvers<T> {
promise: Promise<T>
resolve: (value: T | PromiseLike<T>) => void
reject: (reason?: any) => void
}
export function withResolvers<T>(): PromiseWithResolvers<T> {

// Use crypto.randomBytes for better randomness than Math.random
const bytes = randomBytes(4)
const value = bytes.readUInt32BE(0)
return value % max
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of the modulo operator (%) introduces a slight bias in the distribution of random numbers (modulo bias). While acceptable for non-critical applications like word slugs, a truly 'cryptographically random' implementation should handle this bias to ensure uniform distribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant