Skip to content

fix: replace unsafe strcpy with memcpy in setLibNames - #398

Merged
pengfeixx merged 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/pms-bug-bot/e12114cdefbd
Sep 20, 2026
Merged

pengfeixx merged 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/pms-bug-bot/e12114cdefbd

Conversation

@pengfeixx

@pengfeixx pengfeixx commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

fix: replace unsafe strcpy with memcpy in setLibNames

  1. Root cause: setLibNames() used strcpy() which does not bound
    the copy length, flagged by clang-analyzer as CWE-119 risk
  2. Fix: extract size_t len = strlen(tmp.chDocumentPr) + 1, use
    memcpy with len for bounded copy, reuse len for malloc too
  3. Impact: no behavior change, memcpy copies identical content
    including null terminator, eliminates redundant strlen call

Influence:

  1. Verify application startup loads dynamic library path correctly
  2. Verify document processing functions work as expected
  3. No regression expected as copy semantics are identical

fix: 替换 setLibNames 中不安全的 strcpy 为 memcpy

  1. 根因:setLibNames() 使用 strcpy() 进行拷贝,该函数不限制拷贝
    长度,被 clang-analyzer 标记为 CWE-119 安全风险
  2. 方案:提取 size_t len = strlen(tmp.chDocumentPr) + 1 变量,
    使用 memcpy 配合 len 做有界拷贝,len 同时复用于 malloc
  3. 影响:无行为变化,memcpy 拷贝内容与 strcpy 完全一致(含
    null 终止符),同时消除冗余 strlen 调用

Influence:

  1. 验证应用启动时动态库路径正确加载
  2. 验证文档处理功能正常工作
  3. 拷贝语义完全一致,预期无回归

PMS: BUG-212

Summary by Sourcery

Bug Fixes:

  • Replace the unbounded library-path string copy in setLibNames with a length-bounded copy to address the identified memory-safety risk.

1. Root cause: setLibNames() used strcpy() which does not bound
   the copy length, flagged by clang-analyzer as CWE-119 risk
2. Fix: extract size_t len = strlen(tmp.chDocumentPr) + 1, use
   memcpy with len for bounded copy, reuse len for malloc too
3. Impact: no behavior change, memcpy copies identical content
   including null terminator, eliminates redundant strlen call

Influence:
1. Verify application startup loads dynamic library path correctly
2. Verify document processing functions work as expected
3. No regression expected as copy semantics are identical

fix: 替换 setLibNames 中不安全的 strcpy 为 memcpy

1. 根因:setLibNames() 使用 strcpy() 进行拷贝,该函数不限制拷贝
   长度,被 clang-analyzer 标记为 CWE-119 安全风险
2. 方案:提取 size_t len = strlen(tmp.chDocumentPr) + 1 变量,
   使用 memcpy 配合 len 做有界拷贝,len 同时复用于 malloc
3. 影响:无行为变化,memcpy 拷贝内容与 strcpy 完全一致(含
   null 终止符),同时消除冗余 strlen 调用

Influence:
1. 验证应用启动时动态库路径正确加载
2. 验证文档处理功能正常工作
3. 拷贝语义完全一致,预期无回归

PMS: BUG-212

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @pengfeixx, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 3 days and 15 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 18, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates setLibNames() to compute the document-library path length once, allocate the exact buffer size, and replace unbounded strcpy with a length-bounded memcpy while preserving existing behavior and error handling.

Sequence diagram for bounded library path copying

sequenceDiagram
    participant Caller
    participant setLibNames
    participant Memory
    Caller->>setLibNames: setLibNames(tmp)
    setLibNames->>setLibNames: strlen(tmp.chDocumentPr) + 1
    setLibNames->>Memory: malloc(len)
    alt allocation succeeds
        setLibNames->>Memory: memcpy(g_ldnames.chDocumentPr, tmp.chDocumentPr, len)
    else allocation fails
        setLibNames-->>Caller: return
    end
Loading

File-Level Changes

Change Details Files
Bound the library-path copy by computing the source length once and using it for both allocation and copying.
  • Calculate the path length including the null terminator.
  • Reuse the length for malloc allocation.
  • Replace strcpy with memcpy using the bounded length.
reader/load_libs.c
Preserve existing library-name initialization and error-handling behavior while removing the analyzer-reported unsafe string operation.
  • Retain null handling for an absent document path.
  • Retain allocation-failure logging and early return.
  • Copy the same null-terminated content with no intended runtime behavior change.
reader/load_libs.c

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

AI 代码审查报告

项目: linuxdeepin/deepin-reader
PR: #398
标题: fix: replace unsafe strcpy with memcpy in setLibNames
作者: pengfeixx
分支: agent/pms-bug-bot/e12114cdefbd → master
分析模式: 全量分析
审查时间: 2026-09-18 21:18:00


总体评分

维度 得分 满分 状态
语法逻辑 25 25
代码质量 25 25
代码性能 20 20
代码安全 30 30
总分 100 100 ✓ 通过

总体评价: 代码审查通过

本次变更将 setLibNames 函数中不安全的 strcpy 替换为 memcpy,使用预计算长度进行内存复制,消除了潜在的缓冲区溢出风险。代码变更正确、简洁,未引入新的安全漏洞。OCR 审查发现一处预存在的内存泄漏问题(多次调用 setLibNames 时旧内存未释放),建议后续修复。


漏洞统计

统计项 数量
当前漏洞总数 0
新增漏洞 0
修复漏洞 0
持平漏洞 0

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个


变更文件

文件 变更类型
reader/load_libs.c 修改

变更内容分析

变更说明

本次 PR 的目的是将 setLibNames 函数中不安全的 strcpy 替换为 memcpy,使用预计算的字符串长度进行内存复制,提高代码安全性。

代码 diff

--- a/reader/load_libs.c
+++ b/reader/load_libs.c
@@ -115,12 +115,12 @@ void setLibNames(LoadLibNames tmp)
         g_ldnames.chDocumentPr = NULL;
     } else {
         fprintf(stderr, "INFO: Copying library path: %s\n", tmp.chDocumentPr);
-        g_ldnames.chDocumentPr = (char*)malloc(strlen(tmp.chDocumentPr)+1);
+        size_t len = strlen(tmp.chDocumentPr) + 1;
+        g_ldnames.chDocumentPr = (char*)malloc(len);
         if (!g_ldnames.chDocumentPr) {
             fprintf(stderr, "ERROR: Failed to allocate memory for library path\n");
             return;
         }
-        strcpy(g_ldnames.chDocumentPr,tmp.chDocumentPr);
+        memcpy(g_ldnames.chDocumentPr, tmp.chDocumentPr, len);
     }
 }

四维度详细分析

维度1:语法逻辑(25/25)✓

语法正确,逻辑清晰

分析要点:

  1. size_t len = strlen(tmp.chDocumentPr) + 1; — 正确计算字符串长度(含终止符 \0),类型为 size_t,与 strlen 返回类型一致
  2. g_ldnames.chDocumentPr = (char*)malloc(len); — 分配正确大小的内存
  3. malloc 返回值进行了 NULL 检查,防止空指针解引用
  4. memcpy(g_ldnames.chDocumentPr, tmp.chDocumentPr, len); — 复制 len 字节(含终止符),确保目标字符串正确终止
  5. 变量 len 的声明位置符合 C99/C11 标准
  6. 无编译错误,无语法问题

预存在建议(非本次 PR 引入):

  1. reader/load_libs.csetLibNames 函数,第 118-119 行:预存在问题 — 若 setLibNames 被多次调用且 chDocumentPr 非空,先前分配的 g_ldnames.chDocumentPr 内存未被释放即被新指针覆盖,导致内存泄漏。此问题在本次变更前已存在,非本次 PR 引入。建议在 malloc 前添加 free(g_ldnames.chDocumentPr) 释放旧内存

维度2:代码质量(25/25)✓

代码结构清晰,注释完整

分析要点:

  1. 注释完整性:文件顶部有版权声明和许可证信息;本次变更代码逻辑简单清晰,不需要额外注释
  2. 代码重复:无重复代码,引入 len 变量消除了 strlen 调用的重复
  3. 结构合理性:变更仅修改 setLibNames 函数中的 3 行代码,改动范围小,结构合理
  4. 调试信息清理fprintf(stderr, ...) 语句为预先存在的日志输出,非本次变更引入
  5. 可读性提升:引入 len 变量提高了代码可读性,使内存分配和复制的长度关系更加明确

维度3:代码性能(20/20)✓

性能良好,资源使用合理

分析要点:

  1. 算法复杂度合理strlen 时间复杂度 O(n),memcpy 时间复杂度 O(n),与原 strcpy 相同
  2. 性能优化:引入 len 变量后,strlen 只调用一次,结果被 mallocmemcpy 复用。原代码中 strcpy 内部需要再次遍历字符串查找终止符,新代码使用 memcpy 避免了这次额外遍历
  3. 无频繁系统调用:无不必要的系统调用
  4. 资源使用合理:内存分配大小精确,无浪费

维度4:代码安全(30/30)✓

存在0个安全漏洞

分析要点:

  1. 本次变更将不安全的 strcpy 替换为 memcpy,使用预计算的长度进行复制,消除了潜在的缓冲区溢出风险
  2. malloc(len) 分配的内存大小正确(含终止符 \0
  3. memcpy 复制指定长度(含终止符),确保目标字符串正确终止
  4. malloc 返回值已进行 NULL 检查,防止空指针解引用
  5. 无新增安全漏洞
  6. 本次变更是对安全性的改进

OCR 审查结果

OCR(OpenCodeReview)对变更文件进行了专业代码审查,发现以下问题:

编号 等级 类型 文件 行号 函数 描述 来源 预存在
1 中危 bug reader/load_libs.c 118-119 setLibNames setLibNames 被多次调用且 chDocumentPr 非空,先前分配的 g_ldnames.chDocumentPr 内存未被释放即被新指针覆盖,导致内存泄漏 OpenCodeReview

改进建议

建议修复预存在的内存泄漏问题

文件: reader/load_libs.c
函数: setLibNames

malloc 前添加 free(g_ldnames.chDocumentPr) 释放旧内存,同时在 chDocumentPr == NULL 分支中也应释放旧内存:

void setLibNames(LoadLibNames tmp)
{
    fprintf(stderr, "INFO: Setting library names\n");
    if(tmp.chDocumentPr == NULL) {
        fprintf(stderr, "WARNING: Received NULL document printer library path\n");
        free(g_ldnames.chDocumentPr);  // 释放旧内存
        g_ldnames.chDocumentPr = NULL;
    } else {
        fprintf(stderr, "INFO: Copying library path: %s\n", tmp.chDocumentPr);
        size_t len = strlen(tmp.chDocumentPr) + 1;
        free(g_ldnames.chDocumentPr);  // 释放旧内存
        g_ldnames.chDocumentPr = (char*)malloc(len);
        if (!g_ldnames.chDocumentPr) {
            fprintf(stderr, "ERROR: Failed to allocate memory for library path\n");
            return;
        }
        memcpy(g_ldnames.chDocumentPr, tmp.chDocumentPr, len);
    }
}

审查结论

本次 PR 的目的是将 setLibNames 函数中不安全的 strcpy 替换为 memcpy。变更正确实现了这一目标:

  1. 使用 size_t len 预计算字符串长度(含终止符),类型安全
  2. malloc(len) 分配正确大小的内存
  3. memcpy 使用预计算长度进行复制,避免了 strcpy 的安全隐患
  4. 保留了 malloc 返回值的 NULL 检查
  5. 代码可读性有所提升,性能略有优化

本次变更未引入任何新的安全漏洞或代码质量问题。OCR 审查发现的内存泄漏问题为预存在问题,建议在后续迭代中修复。

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, pengfeixx

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@pengfeixx
pengfeixx merged commit 8721086 into linuxdeepin:master Sep 20, 2026
9 checks passed
@pengfeixx
pengfeixx deleted the agent/pms-bug-bot/e12114cdefbd branch September 20, 2026 05:31
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.

3 participants