You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fprintf写入结构体成员时出现数据冗余与越界问题排查

问题原因

你的程序出现额外写入、hash内容重复且超长的问题,核心原因是用%s格式化输出二进制数据:

  • hash和salt是二进制数组(并非以\0结尾的C字符串),而fprintf的%s格式符会持续读取内存,直到遇到第一个\0才停止。
  • 结构体user中hash字段紧邻salt字段,输出users[0].hash时,%s会把32字节的hash全部输出后,继续读取后续的salt内容(甚至更多内存数据),最终导致输出内容超长、重复。
解决方案

针对二进制数据的写入,有两种可靠的处理方式:

方式1:用fwrite直接写入指定长度的字节

fwrite可以精确控制写入的字节数,彻底避免越界读取:

FILE *fp = fopen(argv[1], "w+");
// 确保用户名以\0结尾(strncpy可能不会自动添加终止符)
users[0].uName[31] = '\0';
// 写入用户名
fputs(users[0].uName, fp);
fputc(' ', fp);
// 写入32字节的hash
fwrite(users[0].hash, 1, 32, fp);
fputc(' ', fp);
// 写入16字节的salt
fwrite(users[0].salt, 1, 16, fp);
fputc('\n', fp);
fclose(fp);

方式2:将二进制数据转为十六进制字符串输出

把二进制数据转成十六进制字符串后,可安全用%s输出(字符串自带\0终止符),还能提升内容可读性:

// 定义足够长度的十六进制字符串缓冲区
char hash_hex[65]; // 32字节*2 + 1(存储终止符)
char salt_hex[33]; // 16字节*2 + 1(存储终止符)

// 使用libsodium工具函数转换为十六进制
sodium_bin2hex(hash_hex, sizeof(hash_hex), users[0].hash, 32);
sodium_bin2hex(salt_hex, sizeof(salt_hex), users[0].salt, 16);

// 安全输出内容
FILE *fp = fopen(argv[1], "w+");
users[0].uName[31] = '\0';
fprintf(fp, "%s %s %s\n", users[0].uName, hash_hex, salt_hex);
fclose(fp);
额外优化点
  • 原代码中strcpy(passSalt, argv[3]);是多余操作,后续strncpy会覆盖passSalt的前16字节,且sha256_process仅处理前16字节,可直接删除该行。
  • 所有strncpy操作后,建议手动添加\0终止符,避免字符串处理时出现越界问题。

内容的提问来源于stack exchange,提问作者gent9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 09:15:06