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

sprintf()函数使用问题及read_from函数代码技术咨询

Fixing the sprintf() Issues in Your C read_from Function

Let's break down the critical problems with your current sprintf() usage and walk through a secure, reliable fix:

Key Problems with Your Current Code

1. Buffer Overflow Risk

Your formattedOutput buffer is sized at BUF_SIZE * 2 + 2, but there’s no guarantee the combined length of the username and incoming buf won’t exceed this limit. When sprintf() writes past the buffer’s bounds, it corrupts adjacent memory—this can cause crashes, unpredictable behavior, or even security vulnerabilities if an attacker sends crafted input.

2. Format String Injection Vulnerability

If the incoming buf contains format specifiers like %s, %d, or %x, sprintf() will try to read extra arguments from the stack that you haven’t provided. This leads to undefined behavior: it might leak sensitive stack data, crash the program, or open the door to further exploits.


Fixed Implementation with snprintf()

The safest drop-in replacement for sprintf() here is snprintf(), which lets you cap the number of bytes written to prevent overflow. We’ll also fix edge cases like failed reads and avoid echoing messages back to the sender:

int read_from(int client_index, struct sockname *usernames) { 
    int fd = usernames[client_index].sock_fd; 
    char buf[BUF_SIZE + 1]; 
    int num_read = read(fd, buf, BUF_SIZE); 

    // Handle read errors or client disconnects
    if (num_read <= 0) {
        usernames[client_index].sock_fd = -1;
        return fd;
    }
    buf[num_read] = '\0'; 

    char formattedOutput[BUF_SIZE * 2 + 2]; 
    // Use snprintf to limit writes and block format injection
    int bytes_written = snprintf(formattedOutput, sizeof(formattedOutput), 
                                "%s: %s", usernames[client_index].username, buf);
    
    // Optional: Warn if the message was truncated (useful for debugging)
    if (bytes_written >= sizeof(formattedOutput)) {
        fprintf(stderr, "Warning: Message from client %d was truncated\n", client_index);
    }

    // Send message to all connected clients (skip the original sender)
    for (int index = 0; index < MAX_CONNECTIONS; index++) { 
        if (usernames[index].sock_fd != -1 && usernames[index].sock_fd != fd) { 
            // Note: In production, wrap write in a loop to handle partial writes
            write(usernames[index].sock_fd, formattedOutput, strlen(formattedOutput));
        } 
    }

    return num_read;
}

Extra Best Practices

  • I fixed the read(fd, &buf, BUF_SIZE) call—buf is already a pointer to the array’s first element, so &buf is unnecessary (it points to the array itself, not its data).
  • Always handle num_read <= 0: a value of 0 means the client closed the connection, while -1 indicates a read error.
  • The write() call might not send all data in one go. For production code, write a helper function that loops until all bytes are sent or an error occurs.
  • If BUF_SIZE is large (e.g., 4096+), allocating formattedOutput on the stack could cause stack overflow. Use malloc() to create a dynamic buffer instead, and free() it when done.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:58:11