【问题标题】:Should the host name array be declared MAXHOSTNAMELEN+1 for gethostname?主机名数组是否应该为 gethostname 声明为 MAXHOSTNAMELEN+1?
【发布时间】:2017-03-06 06:11:26
【问题描述】:

我正在修复对 gethostname() 的调用,其中旧代码将 hostName 数组声明为 10 个字符,导致边界错误,因为主机名比那个大。我的解决方法是使用MAXHOSTNAMELEN 声明hostName(我的平台的parm.h 声明为64)。另一位程序员现在说需要将数组声明为 hostName[MAXHOSTNAMELEN+1]清除,因为(来自他的电子邮件):

这是来自手册页: POSIX.1-2001 保证 “主机名(不包括终止空字节)限制为 HOST_NAME_MAX 字节”

所以要处理所有情况,你必须在缓冲区大小上加一,并用空字符初始化缓冲区。

现在我在网上看到的每个示例都在执行 char hostName[MAXHOSTNAMELEN] 并且由于调用要么有效要么无效,因此将 hostName 数组归零或将其初始化为 null 对我来说毫无意义,因为 if它可以工作,将数组设置为主机名,如果没有,则调用返回错误。

将参数声明或初始化为gethostname() 的稳健方法是什么?

【问题讨论】:

    标签: c sockets posix buffer-overrun


    【解决方案1】:

    POSIX spec 说:

    返回的名称应以空结尾,除非 namelen 的长度不足以容纳主机名,则返回的名称应被截断,并且未指定返回的名称是否以空结尾。

    主机名限制为 {HOST_NAME_MAX} 个字节。

    在您的系统上,我假设 MAXHOSTNAMELEN 对应于规范所称的 HOST_NAME_MAX。因此,制作缓冲区MAXHOSTNAMELEN+1 字节并将该大小传递给gethostname() 应该保证您不必进行零初始化。

    如果你没有进行零初始化,并且你没有那个额外的 +1 字节,你可能会遇到失败,因为它是“未指定返回的名称是否以 null 结尾" 当缓冲区不够长时。

    也就是说,如果您的平台不完全符合标准,则零填充可能有用或必要。告诉你这样做的程序员是有原因的——这个原因是否特定于你的平台的怪癖?

    编辑 spec 还表示nameLen 参数是“name 参数指向的数组的大小”。由于要存储在该数组中的是 array 的大小而不是 hostname 的大小,因此在 array 中为\0 终结者是一个很好的做法。从历史上看,大多数域名标签都不是 64 字节,因此没有+1 的代码过去可能工作得很好。不过,使用+1 更安全,无需假设或猜测。

    编辑 2 我认为“保存主机名的长度不足”可以说是模棱两可的。但是,规范不能打算让gethostname() 注销提供的数组的末尾。因此,我将“insufficient length to hold the host name”取为“insufficient length to hold the host name加上空终止符字节。”这是我个人的解释,但与我的经验一致.

    【讨论】:

    • 不,只是我希望 MAXHOSTNAMELEN 大小包含 NULL 终止符插槽,并且我在网上看到的所有调用示例都没有执行 MAXHOSTNAMELEN+1。我想如果这是一个问题,有人会采用 MAXHOSTNAMELEN+1 的方式。 gethostname() 正在其他 2 个 C++ 类中完成,所以如果它真的应该用 +1 完成,那么我需要解决其他 2 个问题,以便我们在软件中保持一致。
    • @user3416126 我在其他 API 调用中看到过+1,所以这并不让我感到惊讶。我将立即编辑以添加更多规格报价。 已编辑是的,我当然支持整个代码库的一致性!
    猜你喜欢
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 2011-04-11
    • 1970-01-01
    相关资源
    最近更新 更多