当程序写入选定的文件(暂时覆盖它)时,它还会写入 struct 中的下一个成员

#include <stdio.h>
#include <string.h>
#include <sodium.h>
#include <tomcrypt.h>
struct user {
  char uName[32];
  char salt[16];
  char hash[32];
};
int main(int argc, char **argv){
  if (sodium_init() < 0) {
      return 1;
  }
  if(argc != 4){puts("Invalid number of arguments"); return 0;}
  struct user users[1];
  char passSalt[32 + 16];
  char hash[32];
  char salt[16];
  for(int i = 0; i < 16; i++){
    salt[i] = randombytes_uniform(127);
  }
  strcpy(passSalt, argv[3]);
  strncpy(passSalt, salt, 16);
  hash_state md;
  sha256_init(&md);
  sha256_process(&md, passSalt, 16);
  sha256_done(&md, hash);
  strncpy(users[0].uName, argv[2], 32);
  strncpy(users[0].hash, hash, 32);
  strncpy(users[0].salt, salt, 16);
  FILE *fp = fopen(argv[1], "w+");
  fprintf(fp, "%s %s %s\n", users[0].uName, users[0].hash, users[0].salt);
  fclose(fp);
}

Arguments used: ./write db abc qwertyuiop What is written to file: abc [ôÓBmdÂûÆ_LÂ¥ïÖ]lG31GfPmŽ@ÙûªŒU to~497s\0JmA[ôÓBmdÂûÆ_LÂ¥ïÖ]lG31GfPmŽ@ÙûªŒU

[ôÓBmdÂûÆ_LÂ¥ïÖ]lG31GfPmŽ@ÙûªŒU is written twice and @ÙûªŒU should not be written at all because the hash is only 32 bytes long

推荐答案

%S格式说明符写入一个字符序列,直到一个终止空字节(不复制).

因为您的‘salt’是16个随机字节,所以可能有也可能没有终止空字节,所以fprint tf可能会也可能不会结束.

与"hash"类似.

您可以使用%.16s%.32s来控制这种溢出,但是将非文本字节作为文本字符串进行打印的整个概念是有缺陷的.首先,如果SALT恰好包含零字节,这就是‘打印’停止的地方.找一种不同的方法.

C++相关问答推荐

初始化char数组-用于初始化数组的字符串是否除了存储数组的位置之外单独存储在内存中

Pure Win32 C(++)-除了替换控件的窗口程序之外,还有其他方法可以在输入时禁用按钮吗?

GCC不警告隐式指针到整数转换'

为什么写入系统调用打印的字符数不正确?

标准的C17标准是用括号将参数包装在函数声明中吗

数据包未从DPDK端口传输到内核端口

将fget()与strcMP()一起使用不是正确的比较

二进制计算器与gmp

向上强制转换C中的数值类型总是可逆的吗?

tick.q中的Kdb+键控表语法

在C语言中,指针指向一个数组

如何将C中的两个字符串与从文件接收的字符串中的字符数进行比较

为什么编译器不能简单地将数据从EDI转移到EAX?

C程序向服务器发送TCPRST

Valgrind用net_pton()抱怨

生成一个半RNG,结果用C表示(无随机/随机)

根据输入/输出将 C 编译过程分为预处理、编译、汇编和链接步骤

使用 c 中的 write() 函数将非 ASCII 字符写入标准输出

是什么阻止编译器优化手写的 memcmp()?

保存有符号整数结果的变量是否会溢出(后增量的副作用),并且此后从未在任何表达式中使用过它,是否会导致 UB?