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

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:// 等写法可被正确识别。
  • downloadthis.removeFile(filePath) 改为 await,消除"删除旧文件"与"启动下载任务"的时序竞争。
  • download 改为 await request.downloadFile(...) 并抽出 watchDownloadTaskcatch 分支补齐 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 xsample_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.requestrequest.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/awaitawait 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:xxxdownload fail, code:xxx),不改变 README 已描述的接口约定。
  • 是否已在 README 和 package.json 修改了版本信息:是(部分)。package.jsonexample/package.jsonharmony/doc-viewer/oh-package.json5harmony/doc-viewer/BuildProfile.ets 已统一升级至 2.8.3-beta.1CHANGELOG.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
合并受阻
openharmony_ci
openharmony_ci成员
13 天前 评论:

感谢提交 Pull Requests !此PR未通过DCO校验。
校验失败可能原因:

1. 未签署“DCO协议”(开发者原创声明协议),在线签署、查看签署状态

2. Commits 中未包含 Signed-off-by信息,参考FAQ处理

修复上述问题后,在PR的评论框输入“check dco” ,单击”评论”,系统将再次进行DCO校验。

当前检测到如下Commits 未包含Signed-off-by信息:


Thanks for submitting a pull request. This pull request has not passed the DCO check.
Possible causes:

1. You have not signed the Developer Certificate of Origin (DCO). Sign the DCO and check DCO status.

2. The commits do not contain the Signed-off-by information. To resolve this issue, see FAQs.

After resolving the preceding issues, enter check dco in the comment box of this pull request and click Comment. The system will check DCO status again.

The following commits do not contain the Signed-off-by information:

likedislike
openharmony_ciopenharmony_ci成员
13 天前 添加了label:dco检查失败
cpf-manager
cpf-manager13 天前进行代码检视2
harmony/doc-viewer/src/main/ets/turborModules.ts
已过期
@@ -154,3 +174,3 @@
154174 downloadTask.on('complete', () => {
155175 Log.debug(`download complete:${fileName}`)
156- this.shareFile(filePath, fileType, callback)
176+ try {
cpf-manager
cpf-manager13 天前评论:

【AI-Review】【建议】【软件设计】【冗余重复代码】download complete 回调中的 try/catch 与 shareFile 内部 try/catch 重复

● 问题: 在 download 方法的 downloadTask.on('complete', ...) 回调中(turborModules.ts:176-181),新增的 try/catch 包裹了 this.shareFile(filePath, fileType, callback) 调用。但本 PR 同时给 shareFile 方法(turborModules.ts:202-211)也加上了 try/catch,其 catch 块已经会调用 callback(shareFile err:${JSON.stringify(e)}) 将错误传回。由于 shareFile 是同步函数且其整个方法体都在 try 内,同步异常已被 shareFile 自身捕获并消化,不会再向外抛出,因此 complete 回调里的 catch 分支在正常路径下不可达,属于冗余代码。

触发路径: downloadTask 'complete' 事件触发 → this.shareFile(filePath, fileType, callback) 执行 → shareFile 内部 try 块(fileUri.getUriFromPath 或 this.start)抛出同步异常 → shareFile 的 catch 捕获并调用 callback(shareFile err:...) → shareFile 正常返回(未向外抛出)→ complete 回调的 try 块未捕获到任何异常 → complete 回调的 catch 分支(179-180 行)不可达。

● 影响: 一般。正常路径下 catch 块为死代码,影响可维护性;在 shareFile 的 catch 块自身抛出异常的边缘场景下(例如 callback 回调本身 throw),外层 catch 会再次调用 callback(download complete err:...),导致 callback 被重复调用两次(先由 shareFile 的 catch 调用一次,再由 complete 回调的 catch 调用一次)。

● 建议: 二选一:

  1. 移除 complete 回调中冗余的 try/catch,直接调用 this.shareFile(filePath, fileType, callback);
  2. 或保留外层 try/catch 作为防御性兜底,但需确认与 shareFile 内部 catch 的职责边界,避免对同一 callback 重复触发错误回调。
likedislike
System
系统消息系统
12 天前 评论:

changed this line on 4dc49f5c view diff detail

Mmazheng
12 天前 强制推送  1 个提交:4dc49f5c-fix: 修复下载pdf时getFilePath非法路径的处理;对@ohos.request的request.downloadFile不支持大写scheme(HTTP://)URL的情况,做规范化处理
openharmony_ci
openharmony_ci成员
12 天前 评论:

感谢提交 Pull Requests !此PR未通过DCO校验。
校验失败可能原因:

1. 未签署“DCO协议”(开发者原创声明协议),在线签署、查看签署状态

2. Commits 中未包含 Signed-off-by信息,参考FAQ处理

修复上述问题后,在PR的评论框输入“check dco” ,单击”评论”,系统将再次进行DCO校验。

当前检测到如下Commits 未包含Signed-off-by信息:


Thanks for submitting a pull request. This pull request has not passed the DCO check.
Possible causes:

1. You have not signed the Developer Certificate of Origin (DCO). Sign the DCO and check DCO status.

2. The commits do not contain the Signed-off-by information. To resolve this issue, see FAQs.

After resolving the preceding issues, enter check dco in the comment box of this pull request and click Comment. The system will check DCO status again.

The following commits do not contain the Signed-off-by information:

likedislike
此处折叠了124条消息 查看更多
openharmony_ciopenharmony_ci成员
5 天前 通过测试
openharmony_ci
openharmony_ci成员
5 天前 评论:

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

静态检查:

# check type result report
1 codeCheck pass >>>

编译测试:
# Device build result package
1 rntpc_br_rnoh0.77 success >>>

likedislike
Mmazheng
5 天前 修改了pull request 的描述
openharmony_dcp
openharmony_dcp成员
3 天前 评论:

你因提交次数过多被限制提交,为保障上库效率、避免资源浪费,请先观看学习视频:https://dcp.openharmony.cn/workbench/video/videoDisplay

likedislike
openharmony_dcp
openharmony_dcp成员
3 天前 评论:

你因提交次数过多被限制提交,为保障上库效率、避免资源浪费,请先观看学习视频:https://dcp.openharmony.cn/workbench/video/videoDisplay

likedislike