您使用 TR 24731“安全”吗? 功能?

发布于 2024-07-11 13:47:29 字数 1708 浏览 8 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

眼眸印温柔 2024-07-18 13:47:29

自这些 TR 诞生以来(当它是单个 TR 时),我一直是直言不讳的批评者,并且永远不会在我的任何软件中使用它们。 它们掩盖了症状而不是解决原因,我认为,如果有的话,它们将对软件设计产生负面影响,因为它们提供了错误的安全感,而不是促进可以更有效地实现相同目标的现有实践。 我并不孤单,事实上,我不知道在制定这些 TR 的委员会之外还有哪个主要支持者。

我使用 glibc,因此知道我将不必处理这些废话,正如 glibc 的首席维护者 Ulrich Drepper 所言,谈到该主题

建议的 safe(r) ISO C 库
未能彻底解决问题。
... 提议让生活
程序员更努力也不会
帮助。 但这正是
建议的。 ...他们都需要更多
有待完成的工作或只是简单的工作
愚蠢。

他接着详细说明了许多拟议功能的问题,并在其他地方表示 glibc 永远不会支持这一点。

奥斯汀小组(负责维护 POSIX)对 TR 进行了非常严格的审查,他们的意见和委员会的回应可此处。 Austin Group 的评论做得非常好,详细说明了 TR 的许多问题,因此我不会在这里详细介绍具体细节。

所以底线是:我不使用支持或将支持此功能的实现,我不打算使用这些功能,并且我在 TR 中看不到任何积极的价值。 我个人认为,TR 以任何形式仍然存在的唯一原因是因为微软正在大力推动它,微软最近证明,尽管存在广泛的反对,但微软非常有能力让标准委员会强行通过。 如果这些功能被标准化,我认为它们永远不会被广泛使用,因为该提案已经存在了几年,并且未能获得任何真正的社区支持。

I have been a vocal critic of these TRs since their inception (when it was a single TR) and would never use them in any of my software. They mask symptoms instead of addressing causes and it is my opinion that if anything they will have a negative impact on software design as they provide a false sense of security instead of promoting existing practices that can accomplish the same goals much more effectively. I am not alone, in fact I am not aware of a single major proponent outside of the committee developing these TRs.

I use glibc and as such know that I will be spared having to deal with this nonsense, as Ulrich Drepper, lead maintainer for glibc, said about the topic:

The proposed safe(r) ISO C library
fails to address to issue completely.
... Proposing to make the life of a
programmer even harder is not going to
help. But this is exactly what is
proposed. ... They all require more
work to be done or are just plain
silly.

He goes on to detail problems with a number of the proposed functions and has elsewhere indicated that glibc would never support this.

The Austin Group (responsible for maintaining POSIX) provided a very critical review of the TR, their comments and the committee responses available here. The Austin Group review does a very good job detailing many of the problems with the TR so I won't go into individual details here.

So the bottom line is: I don't use an implementation that supports or will support this, I don't plan on ever using these functions, and I see no positive value in the TR. I personally believe that the only reason the TR is still alive in any form is because it is being pushed hard by Microsoft who has recently proved very capable of getting things rammed though standards committees despite wide-spread opposition. If these functions are ever standardized I don't think they will ever become widely used as the proposal has been around for a few years now and has failed to garner any real community support.

他夏了夏天 2024-07-18 13:47:29

直接回答问题

我喜欢罗伯特的回答,但我对我提出的问题也有一些看法。

  • 您是否使用支持 TR24731-1 函数的库或编译器?

    <块引用>

    不,我不。

  • 如果是,哪个编译器或库以及在哪个平台上?

    <块引用>

    我相信这些功能是由 MS Visual Studio(例如 MS VC++ 2008 Edition)提供的,并且有警告鼓励您使用它们。

  • 修复代码以使用这些函数后,您是否发现任何错误?

    <块引用>

    还没有。 我不希望在我的代码中发现很多东西。 我使用的一些其他代码 - 也许。 但我还没有被说服。

  • 哪些功能提供最大价值?

    <块引用>

    我喜欢 printf_s() 系列函数不接受“%n”格式说明符。

  • 有没有提供任何价值或负值的?

    <块引用>

    tmpfile_s()tmpnam_s() 函数令人非常失望。 他们确实需要更像 mkstemp() 那样工作,既创建文件又打开文件,以确保不存在 TOCTOU(检查时间、使用时间)漏洞。 就目前而言,这两者提供的价值非常小。

    我还认为 strerrorlen_s() 提供的价值非常小。

  • 您将来打算使用该图书馆吗?

    <块引用>

    我对此有两种想法。 我开始开发一个库,该库将通过标准 C 库实现 TR 24731 的功能,但被证明其正常工作所需的大量单元测试所困扰。 我不确定是否要继续这样。 我有一些代码想要移植到 Windows(主要是出于在所有平台上提供支持的反常愿望 - 它已经在 Unix 衍生品上工作了几十年)。 不幸的是,为了让它在没有 MSVC 编译器警告的情况下进行编译,我必须在代码中添加一些东西,以防止 MSVC 对我使用完全可靠的(当仔细使用时)标准 C 库函数进行抱怨。 那并不令人胃口大开。 这已经够糟糕了,我必须处理那个时期开发的一个系统的大部分价值;这已经够糟糕的了。 必须处理某人的有趣想法(让人们在不需要时采用 TR 24731)很烦人。 这就是我开始库开发的部分原因 - 让我能够在 Unix 和 Windows 上使用相同的界面。 但我不确定接下来要做什么。

  • 您是否正在跟踪 TR24731-2 的工作?

    <块引用>

    直到我访问标准网站并收集问题的数据时,我才开始跟踪它。 asprintf()vasprintf() 函数可能很有价值; 我会用那些。 我不确定内存流 I/O 功能。 在 C 级别标准化 strdup() 将是一个巨大的进步。 对我来说,这似乎比第 1 部分(边界检查)接口的争议要小。

总的来说,我不相信第 1 部分“边界检查接口”。 第 2 部分“动态分配函数”草稿中的材料更好。

如果由我决定,我会稍微按照第 1 部分的思路进行操作,但我还修改了 C99 标准 C 库中的接口,这些接口将 char * 返回到字符串(例如 strcpy()strcat()),这样它们就不会返回指向开头的指针,而是返回指向结尾处的空字节的指针新字符串。 这将使一些常见的习惯用法(例如重复地将字符串连接到另一个字符串的末尾)更加有效,因为它可以轻松避免重复使用 strcat() 的代码所表现出的二次行为。 所有替换都将确保输出字符串的空终止,就像 TR24731 版本所做的那样。 我并不完全反对检查接口的想法,也不完全反对异常处理函数。 这是一件棘手的事情。


Microsoft 的实现与标准规范不同

更新 (2011-05-08)

另请参阅此问题。 遗憾的是,对于 TR24731 函数的实用性来说,致命的是,某些函数的定义在 Microsoft 实现和标准之间有所不同,导致它们毫无用处(对我而言)。 我的回答引用了 vsnprintf_s()

例如,TR 24731-1 表示 vsnprintf_s() 的接口是:

<前><代码>#define __STDC_WANT_LIB_EXT1__ 1
#include;
#include;
int vsnprintf_s(char * 限制 s, rsize_t n,
const char * 限制格式,va_list arg);

不幸的是,MSDN 说界面vsnprintf_s() 是:

int vsnprintf_s( 
     字符*缓冲区, 
     size_t 缓冲区大小, 
     size_t 计数, 
     常量字符*格式, 
     va_list argptr  
  ); 
  

参数

  • buffer - 输出的存储位置。
  • sizeOfBuffer - 输出缓冲区的大小。
  • count - 要写入的最大字符数(不包括终止 null)或 _TRUNCATE。
  • 格式 - 格式规范。
  • argptr - 指向参数列表的指针。

请注意,这不仅仅是类型映射的问题:固定参数的数量不同,因此是不可调和的。 我也不清楚(大概标准委员会也不清楚)同时拥有“sizeOfBuffer”和“count”有什么好处; 它看起来像是相同的信息两次(或者,至少,通常会使用两个参数的相同值编写代码)。

同样,scanf_s() 及其相关函数也存在问题。 Microsoft 表示缓冲区长度参数的类型是无符号的(明确指出“大小参数的类型为unsigned,而不是size_t”)。 相反,在附件 K 中,大小参数的类型为 rsize_t,它是 size_t 的受限变体(rsize_trsize_t 的另一个名称) code>size_t,但 RSIZE_MAX 小于 SIZE_MAX)。 因此,对于 Microsoft C 和标准 C,调用 scanf_s() 的代码必须以不同的方式编写。

最初,我计划使用“安全”函数作为获取某些代码的方法。在 Windows 和 Unix 上干净地编译,无需编写条件代码。 由于 Microsoft 和 ISO 的功能并不总是相同,这一点被击败了,所以几乎是时候放弃了。


Visual Studio 2015 中 Microsoft vsnprintf() 的更改

在 Visual Studio 2015 文档中的 vsnprintf(),它指出接口已更改:

从 Visual Studio 2015 和 Windows 10 中的 UCRT 开始,vsnprintf 不再与 _vsnprintf 相同。 vsnprintf函数符合C99标准; 保留 _vnsprintf 是为了向后兼容。

但是,vsnprintf_s() 没有改变。


Microsoft 和附件 K 之间差异的其他示例

localtime_s() 的 C11 标准变体在 ISO/IEC 9899:2011 附件 K.3.8.2.4 中定义为:

struct tm *localtime_s(const time_t * restrict timer,
                       struct tm * restrict result);

localtime_s() 定义为:

errno_t localtime_s(struct tm* _tm, const time_t *time);

以及 POSIX 变体 < a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime_r.html" rel="noreferrer">localtime_r() 定义为:

struct tm *localtime_r(const time_t *restrict timer,
                       struct tm *restrict result);

C11 标准和 POSIX 函数除了名称之外是等效的。 Microsoft 函数尽管与 C11 标准同名,但在接口上有所不同。

另一个差异示例是 Microsoftstrtok_s()< /code> 和附件 K 的 strtok_s()

char *strtok_s(char *strToken, const char *strDelimit, char **context); 

vs:

char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr);

请注意,Microsoft 变体有 3 个参数,而 Annex K 变体有 4 个。这意味着 Microsoft 的 strtok_s()< 的参数列表/code> 与 POSIX 的 strtok_r() - 因此,如果您更改函数名称(例如通过宏),对这些函数的调用实际上是可以互换的 - 但标准 C(附件 K)版本与带有额外参数的两者不同。

问题不同的声明qsort_r( Mac 和 Linux 上的 ) 有一个答案,其中还讨论了 Microsoft 定义的 qsort_s() 和 TR24731-1 定义的 qsort_s() ——同样,接口是不同的。


ISO/IEC 9899:2011 — C11 标准

C11 标准 (2010 年 12 月草案;您可以一次性获得最终标准的 PDF 副本,ISO/IEC 9899:2011,来自 ANSI 网上商店,售价 30 美元)确实包含 TR24731-1 功能,作为可选部分标准。 它们在附件 K(边界检查接口)中定义,它是“规范性”而不是“信息性”,但它是可选的。

C11 标准中没有 TR24731-2 函数,这很遗憾,因为 vasprintf() 函数及其相关函数可能非常有用。

快速摘要:

  • C11 包含 TR24731-1
  • C11 不包含 TR24731-2
  • C18 与 C11 与 TR24731 相同。

建议从 C11 的后继版本中删除附件 K。

Deduplicator 中指出, com/questions/906599/why-cant-i-use-fopen/907549?noredirect=1#comment55009555_907549">对另一个问题的评论,ISO C 标准委员会 (ISO/IEC JTC1/ SC22/WG14)

它包含对附件 K 函数的一些现有实现的引用——它们都没有被广泛使用(但如果您感兴趣,您可以通过文档找到它们)。

该文件以建议结尾:

因此,我们建议从 C 标准的下一个修订版中删除附件 K,或者弃用然后删除。

我支持该建议。

C18标准并没有改变Annex K的地位。有一篇论文N2336 主张对附件 K 进行一些更改,修复其缺陷而不是完全删除它。

Direct answer to question

I like Robert's answer, but I also have some views on the questions I raised.

  • Do you use a library or compiler with support for the TR24731-1 functions?

    No, I don't.

  • If so, which compiler or library and on which platform(s)?

    I believe the functions are provided by MS Visual Studio (MS VC++ 2008 Edition, for example), and there are warnings to encourage you to use them.

  • Did you uncover any bugs as a result of fixing your code to use these functions?

    Not yet. And I don't expect to uncover many in my code. Some of the other code I work with - maybe. But I've yet to be convinced.

  • Which functions provide the most value?

    I like the fact that the printf_s() family of functions do not accept the '%n' format specifier.

  • Are there any that provide no value or negative value?

    The tmpfile_s() and tmpnam_s() functions are a horrible disappointment. They really needed to work more like mkstemp() which both creates the file and opens it to ensure there is no TOCTOU (time-of-check, time-of-use) vulnerability. As it stands, those two provide very little value.

    I also think that strerrorlen_s() provides very little value.

  • Are you planning to use the library in the future?

    I am in two minds about it. I started work on a library that would implement the capabilities of TR 24731 over a standard C library, but got caught by the amount of unit testing needed to demonstrate that it is working correctly. I'm not sure whether to continue that. I have some code that I want to port to Windows (mainly out of a perverse desire to provide support on all platforms - it's been working on Unix derivatives for a couple of decades now). Unfortunately, to get it to compile without warnings from the MSVC compilers, I have to plaster the code with stuff to prevent MSVC wittering about me using the perfectly reliable (when carefully used) standard C library functions. And that is not appetizing. It is bad enough that I have to deal with most of two decades worth of a system that has developed over that period; having to deal with someone's idea of fun (making people adopt TR 24731 when they don't need to) is annoying. That was partly why I started the library development - to allow me to use the same interfaces on Unix and Windows. But I'm not sure what I'll do from here.

  • Are you tracking the TR24731-2 work at all?

    I'd not been tracking it until I went to the standards site while collecting the data for the question. The asprintf() and vasprintf() functions are probably valuable; I'd use those. I'm not certain about the memory stream I/O functions. Having strdup() standardized at the C level would be a huge step forward. This seems less controversial to me than the part 1 (bounds checking) interfaces.

Overall, I'm not convinced by part 1 'Bounds-Checking Interfaces'. The material in the draft of part 2 'Dynamic Allocation Functions' is better.

If it were up to me, I'd move somewhat along the lines of part 1, but I'd also revised the interfaces in the C99 standard C library that return a char * to the start of the string (e.g. strcpy() and strcat()) so that instead of returning a pointer to the start, they'd return a pointer to the null byte at the end of the new string. This would make some common idioms (such as repeatedly concatenating strings onto the end of another) more efficient because it would make it trivial to avoid the quadratic behaviour exhibited by code that repeatedly uses strcat(). The replacements would all ensure null-termination of output strings, like the TR24731 versions do. I'm not wholly averse to the idea of the checking interface, nor to the exception handling functions. It's a tricky business.


Microsoft's implementation is not the same as the standard specification

Update (2011-05-08)

See also this question. Sadly, and fatally to the usefulness of the TR24731 functions, the definitions of some of the functions differs between the Microsoft implementation and the standard, rendering them useless (to me). My answer there cites vsnprintf_s().

For example, TR 24731-1 says the interface to vsnprintf_s() is:

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdarg.h>
#include <stdio.h>
int vsnprintf_s(char * restrict s, rsize_t n,
                const char * restrict format, va_list arg);

Unfortunately, MSDN says the interface to vsnprintf_s() is:

int vsnprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   va_list argptr 
);

Parameters

  • buffer - Storage location for output.
  • sizeOfBuffer - The size of the buffer for output.
  • count - Maximum number of characters to write (not including the terminating null), or _TRUNCATE.
  • format - Format specification.
  • argptr - Pointer to list of arguments.

Note that this is not simply a matter of type mapping: the number of fixed arguments is different, and therefore irreconcilable. It is also unclear to me (and presumably to the standards committee too) what benefit there is to having both 'sizeOfBuffer' and 'count'; it looks like the same information twice (or, at least, code will commonly be written with the same value for both parameters).

Similarly, there are also problems with scanf_s() and its relatives. Microsoft says that the type of the buffer length parameter is unsigned (explicitly stating 'The size parameter is of type unsigned, not size_t'). In contrast, in Annex K, the size parameter is of type rsize_t, which is the restricted variant of size_t (rsize_t is another name for size_t, but RSIZE_MAX is smaller than SIZE_MAX). So, again, the code calling scanf_s() would have to be written differently for Microsoft C and Standard C.

Originally, I was planning to use the 'safe' functions as a way of getting some code to compile cleanly on Windows as well as Unix, without needing to write conditional code. Since this is defeated because the Microsoft and ISO functions are not always the same, it is pretty much time to give up.


Changes in Microsoft's vsnprintf() in Visual Studio 2015

In the Visual Studio 2015 documentation for vsnprintf(), it notes that the interface has changed:

Beginning with the UCRT in Visual Studio 2015 and Windows 10, vsnprintf is no longer identical to _vsnprintf. The vsnprintf function complies with the C99 standard; _vnsprintf is retained for backward compatibility.

However, the Microsoft interface for vsnprintf_s() has not changed.


Other examples of differences between Microsoft and Annex K

The C11 standard variant of localtime_s() is defined in ISO/IEC 9899:2011 Annex K.3.8.2.4 as:

struct tm *localtime_s(const time_t * restrict timer,
                       struct tm * restrict result);

compared with the MSDN variant of localtime_s() defined as:

errno_t localtime_s(struct tm* _tm, const time_t *time);

and the POSIX variant localtime_r() defined as:

struct tm *localtime_r(const time_t *restrict timer,
                       struct tm *restrict result);

The C11 standard and POSIX functions are equivalent apart from name. The Microsoft function is different in interface even though it shares a name with the C11 standard.

Another example of differences is Microsoft's strtok_s() and Annex K's strtok_s():

char *strtok_s(char *strToken, const char *strDelimit, char **context); 

vs:

char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr);

Note that the Microsoft variant has 3 arguments whereas the Annex K variant has 4. This means that the argument list to Microsoft's strtok_s() is compatible with POSIX's strtok_r() — so calls to these are effectively interchangeable if you change the function name (e.g. by a macro) — but the Standard C (Annex K) version is different from both with the extra argument.

The question Different declarations of qsort_r() on Mac and Linux has an answer that also discusses qsort_s() as defined by Microsoft and qsort_s() as defined by TR24731-1 — again, the interfaces are different.


ISO/IEC 9899:2011 — C11 Standard

The C11 standard (December 2010 Draft; you could at one time obtain a PDF copy of the definitive standard, ISO/IEC 9899:2011, from the ANSI web store for 30 USD) does have the TR24731-1 functions in it as an optional part of the standard. They are defined in Annex K (Bounds-checking Interfaces), which is 'normative' rather than 'informational', but it is optional.

The C11 standard does not have the TR24731-2 functions in it — which is sad because the vasprintf() function and its relatives could be really useful.

Quick summary:

  • C11 contains TR24731-1
  • C11 does not contain TR24731-2
  • C18 is the same as C11 w.r.t TR24731.

Proposal to remove Annex K from the successor to C11

Deduplicator pointed out in a comment to another question that there is a proposal before the ISO C standard committee (ISO/IEC JTC1/SC22/WG14)

It contains references to some of the extant implementations of the Annex K functions — none of them widely used (but you can find them via the document if you are interested).

The document ends with the recommendation:

Therefore, we propose that Annex K be either removed from the next revision of the C standard, or deprecated and then removed.

I support that recommendation.

The C18 standard did not alter the status of Annex K. There is a paper N2336 advocating for making some changes to Annex K, repairing its defects rather than removing it altogether.

欲拥i 2024-07-18 13:47:29

好的,现在支持 TR24731-2:

是的,自从我看到以来,我一直在使用 asprintf()/vasprintf()它们在 glibc 中,是的,我是它们的坚定拥护者。

为什么?
因为它们一次又一次准确地提供了我所需要的东西:一种强大、灵活、安全且(相对)易于使用的方法,可将任何文本格式化为新分配的字符串。

我也非常支持 memstream 函数:如 asprintf()open_memstream() (不是 fmemopen()) code>!!!) 为您分配一个足够大的缓冲区,并为您提供一个 FILE* 来进行打印,因此您的打印函数可以完全不知道它们是打印到字符串还是文件中,您可以简单地忘记您需要多少空间。

Ok, now a stand for TR24731-2:

Yes, I've used asprintf()/vasprintf() ever since I've seen them in glibc, and yes I am a very strong advocate of them.

Why?
Because they deliver precisely what I need over and over again: A powerful, flexible, safe and (relatively) easy to use way to format any text into a freshly allocated string.

I am also much in favor of the memstream functions: Like asprintf(), open_memstream() (not fmemopen()!!!) allocates a sufficiently large buffer for you and gives you a FILE* to do your printing, so your printing functions can be entirely ignorant of whether they are printing into a string or a file, and you can simply forget about how much space you will need.

奶气 2024-07-18 13:47:29

您是否使用支持 TR24731-1 函数的库或编译器?
如果是,哪个编译器或库以及在哪个平台上?

是的,Visual Studio 2005 和 Visual Studio 2005 2008 年(显然是针对 Win32 开发)。

修复代码以使用这些函数后,您是否发现任何错误?

有点......我编写了自己的安全函数库(只有大约 15 个我们经常使用的函数),这些函数将在多个平台上使用——Linux、Windows、VxWorks、INtime、RTX 和 uItron。 创建安全函数的原因是:

  • 由于标准 C 函数使用不当,我们遇到了大量错误。
  • 我对 TR 函数传递或返回的信息不满意,或者在某些情况下,对它们的 POSIX 替代方案不满意。

函数编写完成后,更多的错误被发现。 所以是的,使用这些功能是有价值的。

哪些功能提供最大价值?

vsnprintf、strncpy、strncat 的更安全版本。

是否有任何不提供任何价值或负价值的东西?

fopen_s 和类似的函数对我个人来说几乎没有什么价值。 如果 fopen 返回 NULL 我没问题。 您应该始终检查函数的返回值。 如果有人忽略 fopen 的返回值,那么什么会让他们检查 fopen_s 的返回值呢? 我知道 fopen_s 将返回更具体的错误信息,这在某些情况下可能有用。 但对于我正在做的事情来说,这并不重要。

您将来打算使用该图书馆吗?

我们现在正在使用它——在我们自己的“安全”库中。

您是否正在跟踪 TR24731-2 的工作?

不。

Do you use a library or compiler with support for the TR24731-1 functions?
If so, which compiler or library and on which platform(s)?

Yes, Visual Studio 2005 & 2008 (for Win32 development obviously).

Did you uncover any bugs as a result of fixing your code to use these functions?

Sort of.... I wrote my own library of safe functions (only about 15 that we use frequently) that would be used on multiple platforms -- Linux, Windows, VxWorks, INtime, RTX, and uItron. The reason for creating the safe functions were:

  • We had encountered a large number of bugs due to improper use of the standard C functions.
  • I was not satisfied with the information passed into or returned from the TR functions, or in some cases, their POSIX alternatives.

Once the functions were written, more bugs were discovered. So yes, there was value in using the functions.

Which functions provide the most value?

Safer versions of vsnprintf, strncpy, strncat.

Are there any that provide no value or negative value?

fopen_s and similar functions add very little value for me personally. I'm OK if fopen returns NULL. You should always check the return value of the function. If someone ignores the return value of fopen, what is going to make them check the return value of fopen_s? I understand that fopen_s will return more specific error information which can be useful in some contexts. But for what I'm working on, this doesn't matter.

Are you planning to use the library in the future?

We are using it now -- inside our own "safe" library.

Are you tracking the TR24731-2 work at all?

No.

烟凡古楼 2024-07-18 13:47:29

不,这些函数绝对没有用,除了鼓励编写代码以使其只能在 Windows 上编译之外没有其他任何作用。

snprintf 是完全安全的(正确实现时),因此 snprintf_s 毫无意义。 如果缓冲区溢出(通过清除连接到的字符串),strcat_s 将销毁数据。 还有许多其他完全不了解事物如何运作的例子。

真正有用的函数是 BSD strlcpy 和 strlcat。 但 Microsoft 和 Drepper 出于自私的原因拒绝了这些,这让世界各地的 C 程序员感到烦恼。

No, these functions are absolutely useless and serve no purpose other than to encourage code to be written so it only compiles on Windows.

snprintf is perfectly safe (when implemented correctly) so snprintf_s is pointless. strcat_s will destroy data if the buffer is overflowed (by clearing the concatenated-to string). There are many many other examples of complete ignorance of how things work.

The real useful functions are the BSD strlcpy and strlcat. But both Microsoft and Drepper have rejected these for their own selfish reasons, to the annoyance of C programmers everywhere.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文