已合并
fix: 修复下载pdf时getFilePath非法路径的处理;对@ohos.request的request.downloadFile不支持大写scheme(HTTP://)URL的情况,做规范化处理 #34
fix: 修复下载pdf时getFilePath非法路径的处理;对@ohos.request的request.downloadFile不支持大写scheme(HTTP://)URL的情况,做规范化处理 #34
已合并
mazheng创建于 25 天前
mazheng
25 天前

fix: 修复下载pdf时getFilePath非法路径的处理;对@ohos.request的request.downloadFile不支持大写scheme(HTTP://)URL的情况,做规范化处理

修改点

本次为文档下载与打开链路的缺陷修复,共修改 8 个文件:

harmony/doc-viewer/src/main/ets/turborModules.ts

  • getFilePath 重写:对 fileName / url 兜底取名做净化,剥离 query(?)、hash(#) 与 /、\ 路径分隔符;空串、.、.. 判为非法并返回 ''。
  • openDocb64 / useCache / download 增加 filePath 为空的兜底回调 invalid fileName:${fileName},避免非法路径继续下沉到下载/分享。
  • 新增 normalizeUrl:仅将 scheme 段小写归一化(保留 path 大小写);openDoc / openDocBinaryinUrl 入口与 download 内部统一调用,使 HTTP://、HTTPS://、FILE:// 等写法可被正确识别。
  • download 中 this.removeFile(filePath) 改为 await,消除"删除旧文件"与"启动下载任务"的时序竞争。
  • download 改为 await request.downloadFile(...) 并抽出 watchDownloadTask,catch 分支补齐 callback(13400002 判定为文件已存在,直接走 shareFile),同时把嵌套深度降到 4 层以内。
  • fail 回调带出错误码:callback('download fail, code:${err}'),便于 JS 侧定位失败原因。
  • shareFile 增加 try/catch,异常统一经 callback 返回;删除 onDownloadComplete 中已不可达的 try/catch 死代码(错误捕获由 shareFile 统一负责)。
  • 补全 normalizeUrl 等处缺失的分号,修复 codecheck 告警。

harmony/doc-viewer/src/main/ets/mime.ts

  • getMimeType 增加字符串类型判断,fileType 非 string 时不再直接调用 toLowerCase() 抛异常。

example/src/DocViewerTest.tsx

  • jpeg 测试 URL 中的 Unicode 乘号 × 修正为 ASCII x(sample_1280x853.jpeg),修复用例取不到资源的问题。

版本与资料

  • package.json / example/package.json / harmony/doc-viewer/oh-package.json5 / harmony/doc-viewer/BuildProfile.ets 同步升级至 2.8.3-beta.1。
  • CHANGELOG.md 补充 v2.8.3-beta.1 条目。

根因分析

  1. 非法文件路径导致下载失败且无回调:原 getFilePath 只做 ${tempDir}/${fileName} 简单拼接,未净化输入。当 fileName 未传而从 URL 兜底取名时,xxx.pdf?token=1 这类带 query 的片段、或含 /、\、.. 的名字会被直接当作文件名,生成鸿蒙侧非法的 filePath,request.downloadFile 随即失败;而原实现的 .catch / catch 分支只打日志、没有 callback,JS 侧完全无感知,表现为"点击打开 PDF 无任何反应"。
  2. scheme 大小写敏感:@ohos.request 的 request.downloadFile 不接受 HTTP:// 这类大写 scheme 的 URL;同时 master 分支判断本地文件用的是 url.startsWith('file://'),同样区分大小写,导致 FILE:// 开头的本地文件被误判为网络地址走进下载分支。
  3. 删除与下载的时序竞争:this.removeFile(filePath) 是 async 函数但未 await,删除旧文件的 IO 与新下载任务并发执行,存在删除动作落在下载写入之后、误删刚下载文件的可能。
  4. 失败信息缺失:fail 回调固定返回 download fail 字符串,不带 @ohos.request 的错误码,无法区分网络错误、路径错误还是任务被中断。
  5. 异常未收敛:fileUri.getUriFromPath 在 filePath 非法时会抛异常,原 shareFile 未捕获;而 onDownloadComplete 中包裹的 try/catch 因内部调用已同步返回,实际不可达,属于死代码。
  6. 类型防御缺失:getMimeType 假定入参恒为 string,JS 侧传入 undefined / 非字符串时 toLowerCase() 直接抛异常。
  7. codecheck 问题:download 原有 Promise 链嵌套超过 4 层,且存在缺失分号,触发扫描告警。
  8. 测试资源不可达:示例中 jpeg URL 使用了 Unicode 全角乘号 ×,与实际资源名的 ASCII x 不一致,请求 404。

方案说明

  • 路径净化前置:在 getFilePath 内集中完成"取名 → 去 query/hash → 去路径分隔符 → 非法名判定",把非法输入拦截在最上游,返回空串作为唯一的非法信号;三个调用点(openDocb64 / useCache / download)统一以 if (!filePath) { callback('invalid fileName:...'); return; } 兜底,保证任何入参下 JS 侧都能收到明确回调。
  • scheme 归一化收口:新增 normalizeUrl 只处理 :// 之前的 scheme 段并转小写,不触碰 path(避免破坏大小写敏感的服务端路径);在 openDoc / openDocBinaryinUrl 入口做一次归一化后再分发本地/网络分支,download 内再做一次幂等归一化以覆盖 useCache 的间接调用路径。
  • 下载流程线性化:download 由 Promise 链改为 async/await,await removeFile 消除竞争;监听逻辑抽成 watchDownloadTask 独立方法,既消除嵌套深度告警,也让 complete / fail 两条回调路径职责单一。
  • 错误统一经 callback 返回:catch 分支区分 13400002(文件已存在 → 直接分享)与其他错误(→ callback 报错);fail 回调透传错误码;shareFile 自行 try/catch 并成为错误捕获的唯一出口,据此删除上层不可达的死代码。
  • 兼容性保障:所有改动均为内部实现与错误处理增强,openDoc / openDocb64 / openDocBinaryinUrl 的接口签名、参数结构(FileInfo[] + Callback)与成功路径行为保持不变;对既有合法入参(小写 scheme、正常 fileName)的行为完全等价,仅错误回调的文案更详细。

触发的已有测试用例(按需)

  • 本工程 master 分支 example/src/DocViewerTest.tsx → ✅ 通过
    • Open PDF with function openDoc
    • Open MP3 with function openDoc
    • Open MP4 with function openDoc
    • Open DOC with function openDoc
    • Open JPEG with function openDoc(本次修正了该用例的 URL)
    • Open XLSX with function openDoc
    • Open Base64 with function openDocb64
    • Open BinaryinUrl with function openDocBinaryinUrl
  • RNT 工程 → 不涉及(本库为三方库工程,用例随 example 工程维护,未涉及 RNT 侧用例)

手动验证

  • 已验证修复有效:
    • 下载并打开 PDF(原偶现打开无响应场景)恢复正常;
    • HTTP:// / HTTPS:// 大写 scheme URL 可正常下载打开;
    • FILE:// 大写 scheme 的本地文件可正确走本地文件分支;
    • 不传 fileName、URL 带 query 参数时可正确取名下载;
    • 传入非法 fileName(空串 / .. / 含 /)时收到 invalid fileName:xxx 回调,不再静默失败;
    • 下载失败场景(断网 / 无效地址)回调返回 download fail, code:xxx,携带错误码;
    • cache: true 复用缓存与 cache: false 重新下载两条路径均正常。
  • 已确认不影响其他功能:openDocb64(base64 打开)、openDocBinaryinUrl、本地文件打开、mp3/mp4/doc/xlsx 等各类型打开均回归通过。
  • 验证环境:[请补充设备型号 / ROM 版本 / DevEco Studio 版本],example 工程 RN 0.82.1,编译 API12+。

资料修改

  • 是否已在 README 说明该接口/功能的变化:不涉及。三个对外方法的签名、参数(FileInfo[])与调用方式均未变化,仅错误回调文案增强(新增 invalid fileName:xxx、download fail, code:xxx),不改变 README 已描述的接口约定。
  • 是否已在 README 和 package.json 修改了版本信息:是(部分)。package.json、example/package.json、harmony/doc-viewer/oh-package.json5、harmony/doc-viewer/BuildProfile.ets 已统一升级至 2.8.3-beta.1,CHANGELOG.md 已补充对应条目;README 版本表中 master 分支以 ~ 2.8.1 的范围形式标注 2.8.x,已覆盖本版本,无需改动。

依赖关系变更

  • 无。未新增/升级任何 npm 依赖与 HAR 依赖,仅使用已引入的 @ohos.request、@ohos.file.fs、@ohos.file.fileuri;支持的 RN 版本(0.77 / 0.82 / 0.84)、编译 API 版本(API12+)、社区基线版本(2.7.8)均保持不变。
  • 下游影响:仅错误回调字符串内容变化,若业务侧对 callback 文案做了精确字符串匹配需相应调整(建议按前缀匹配)。
likedislike
Pull Request已成功合入, 合并人@openharmony_ci
(感谢 mazheng 的贡献)
openharmony_ci
openharmony_ci成员
25 天前 评论:

感谢提交 Pull Requests!
Thanks for submitting a pull request.

likedislike
openharmony_ciopenharmony_ci成员
25 天前 添加了label:dco检查成功
Mmazheng
24 天前 关联了issue:[Bug] openDoc 两个缺陷:① 含"../"的 fileName 致应用崩溃(401)② 大写 HTTP:// URL 下载失败
openharmony_ci
openharmony_ci成员
24 天前 评论:

首次触发
门禁构建开始,包含静态检查、代码编译【rntpc_br_rnoh0.77编译, rntpc_component编译, rntpc_br_rnoh0.72编译】,预计在60分钟内完成,门禁结果会同步发送到注册邮箱。您可以通过如下链接跟踪门禁进展:http://dcp.openharmony.cn/workbench/cicd/detail/6a97a0a064650f998bcdcbfd/runlist

likedislike
mazheng
24 天前 评论:

start build

likedislike
此处折叠了99条消息 查看更多
openharmony_ciopenharmony_ci成员
10 天前 添加了label:静态检查成功
openharmony_ciopenharmony_ci成员
10 天前 通过测试
openharmony_ci
openharmony_ci成员
10 天前 评论:

代码门禁通过
您可以通过如下链接查看门禁报告:http://dcp.openharmony.cn/workbench/cicd/detail/6aa9ec0c64650f998b4165c7/runlist

静态检查:

# check type result report
1 codeCheck pass >>>

编译测试:
# Device build result package
1 rntpc_component success >>>

likedislike
openharmony_ciopenharmony_ci成员
10 天前 关闭了关联的issue
openharmony_ciopenharmony_ci成员
10 天前 合入了pull request,合并节点 SHA:09359a15cd694b6df4f54e209486e0989a97e27b