DSH / Atlas
2026-08-28implementedbug-fixarchived 2026-09-04

read_image accepts extension-less image paths

read_image 接受无扩展名图片路径

`read_image` mapped `file_path` to a media type by extension alone and refused a path with no extension. Valid extension-less images therefore required a renamed copy before the model could inspect them. Normalized local attachment objects exposed to the model use content digests without extensions, so their published read-only paths triggered the same refusal.

English

Problem

read_image mapped file_path to a media type by extension alone and refused a path with no extension. Valid extension-less images therefore required a renamed copy before the model could inspect them. Normalized local attachment objects exposed to the model use content digests without extensions, so their published read-only paths triggered the same refusal.

Decision

read_image treats a file extension as a media-type declaration. PNG, JPEG, WebP, and GIF extensions select their declared types; another non-empty extension is refused before filesystem I/O, and the attachment store's full decode rejects a declaration that does not match the bytes. A path with no extension is read through ctx.fs under the existing maxImageBytes and tighter maxMessageImageBytes cap, then a tool-local sniffImageMediaType helper identifies one of the four supported file signatures. The detected type passes through the same deployment media-type policy and saveImage admission, whose full decode remains authoritative. This narrows the sniffing rejection in the minimal read_image tool note to extension-bearing paths.

The mounted ctx.fs backend is the complete path-authorization authority for read_image. Extensions and file signatures decide only whether the tool accepts bytes that the backend returned. Any valid extension-less image readable through that backend can enter the current session, including a normalized attachment object; the tool performs no session-reference proof and the attachment service exposes no reverse path lookup.

Admission failures name the offending path. An extension-less mismatch names the signature that supplied the declaration, while unsupported bytes report no file content.

Alternatives considered

Export signature identification from the attachment Service Definition package. Only read_image needs this pre-admission declaration. Publishing the helper would make one Consumer's filename policy part of the provider-independent attachment API while the store already owns authoritative decoding.

Special-case normalized attachment object paths. Resolving a path back to a Session reference would make two files readable through the same ctx.fs behave differently according to their origin and would leave ordinary extension-less images unsupported. Filesystem access remains the read authorization decision.

Add extensions to stored attachment objects. This would change the storage layout and every object-path consumer to satisfy one tool's media-type declaration rule.

Consequences

The model can read ordinary extension-less images and normalized attachment paths directly in native and PTC modes. Wrong extensions retain their pre-I/O refusal and mismatch repair. A non-image path without an extension is read up to the image byte cap before rejection, and a normalized object re-enters source admission instead of bypassing the current deployment limits. The behavior changes only dsh-tool-fs; the attachment Service Definition and local provider keep their existing APIs and storage behavior.

中文

问题

read_image 只按扩展名把 file_path 映射到媒体类型,并拒绝没有扩展名的路径。因此,模型必须先创建一份改名副本,才能查看合法的无扩展名图片。向模型公开的规范化本地附件对象以内容摘要命名,不带扩展名,所以其已发布的只读路径也会触发同一项拒绝。

决定

read_image 把文件扩展名视为媒体类型声明。PNG、JPEG、WebP 与 GIF 扩展名选择各自声明的类型;其他非空扩展名在文件系统 I/O 前被拒绝,附件存储的完整解码会拒绝与字节不匹配的声明。对于无扩展名路径,工具通过 ctx.fs 在既有 maxImageBytes 和更严格的 maxMessageImageBytes 上限内读取文件,再由工具内部的 sniffImageMediaType 辅助函数识别四种受支持的文件签名。识别结果经过同一套部署媒体类型策略和 saveImage 准入,后者的完整解码保持权威。这把最小 read_image 工具 Agent Note中对嗅探的拒绝收窄到带扩展名的路径。

挂载的 ctx.fs 后端是 read_image 路径授权的完整依据。扩展名和文件签名只决定工具是否接受后端返回的字节。该后端可读的每个合法无扩展名图片都能进入当前会话,包括规范化附件对象;工具不证明 Session 引用,附件服务也不提供反向路径查找。

准入失败会指出出错路径。无扩展名路径的类型不匹配会指出提供声明的文件签名,而不受支持的字节不会出现在错误消息中。

考虑过的替代方案

从附件 Service Definition 包导出文件签名识别。 只有 read_image 需要这项准入前声明。公开该辅助函数会把单个消费方的文件名策略加入提供方无关的附件 API,而存储已经负责权威解码。

特殊处理规范化附件对象路径。 把路径反查为 Session 引用,会使 ctx.fs 以相同方式提供的两个文件根据来源产生不同读取结果,而且普通无扩展名图片仍然不受支持。文件系统访问保持读取授权决定。

为存储的附件对象增加扩展名。 这会为了满足一个工具的媒体类型声明规则而修改存储布局和每个对象路径消费方。

影响

模型可以在 native 和 PTC 模式下直接读取普通无扩展名图片与规范化附件路径。错误扩展名保留 I/O 前拒绝和类型不匹配修复提示。无扩展名非图片路径会在拒绝前读取到图片字节上限,规范化对象也会重新经过来源准入,而不会绕过当前部署限额。行为改动只位于 dsh-tool-fs;附件 Service Definition 与本地提供方保持现有 API 和存储行为。