google-gemini / google-gemini/gemini-cli
bug: read-many-files treats substring overlap as 'explicitly requested' binary asset, inlining unrequested images
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 45
Description
## What happened?
`read-many-files` decides whether a matched binary asset was "explicitly requested" using **substring containment** between the glob pattern string and the file's stem/extension — not actual pattern matching. Any overlap between a directory-name fragment in the pattern and a binary file's stem marks the asset as requested, so it gets embedded as a base64 `inlineData` part even though the user never asked for binaries. The two checks are also inconsistently cased (extension compare is case-insensitive, stem compare case-sensitive).
## Affected code
`packages/core/src/tools/read-many-files.ts:306-310`:
```ts
const requestedExplicitly = include.some(
(pattern: string) =>
pattern.toLowerCase().includes(fileExtension) ||
pattern.includes(fileNameWithoutExtension),
);
```
## How can this be reproduced?
```json
{ "include": ["**/*report*/**"], "exclude": [] }
```
With a matched file `quarterlyreport.png`: stem `quarterlyreport` is a substring of the pattern → `requestedExplicitly === true` → the PNG is inlined as an image part, consuming large context and surprising the user.
Conversely, a genuine request like `"assets/logo.png"` fails the intent for `logo.PNG` on case-sensitive filesystems due to the asymmetric casing.
## What did you expect to happen?
"Explicitly requested" should mean the include pattern actually matches this specific binary file (e.g., run the pattern through the same matcher used for discovery), not fuzzy string overlap.
## Impact
Unexpected large binary payloads injected into model context; token bloat; potential policy surprises for users who believed they only requested text.
## Suggested direction
Match the file's path against each include pattern with the project's glob engine (`minimatch`/`glob`) instead of `includes()`, normalizing case consistently.
---
*Found by source audit on current `main` (commit `5411f113c`); platform-independent. No open issue/PR covering this was found (searched: read-many-files binary explicitly requested).*
Contributor guide
Research direction
Start in packages/core/src/tools/read-many-files.ts around lines 306-310 and trace the glob matcher used for file discovery. Reproduce the issue with **/*report*/** and quarterlyreport.png, then verify explicit requests such as assets/logo.png and logo.PNG. Done means binary assets are inlined only when the matching include pattern explicitly selects them, with casing handled consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100