安全地使用gets() [英] Using gets() safely

查看:140
本文介绍了安全地使用gets()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道是否有一种便携式方式可以安全地使用get()

,并想出了这个:


#include< stdio.h>

#include< stdlib.h>


int main()

{

FILE * temp;

char buf [L_tmpnam];

char * readin,* tfn;

int len;

tfn = tmpnam(buf);

if(!tfn)abort();

temp = fopen(tfn," w");

if(!temp)abort();

len = fprintf(temp,"%s%d。\ n"," Hello,world!" ,42);

fclose(temp);

if(!freopen(tfn," r",stdin)){remove(tfn); abort();};

readin = malloc(len + 1);

if(readin)

{

得到(读取); / *希望安全* /

printf(%s包含%s \ n",tfn,readin);

免费(阅读);

}

fclose(stdin);

删除(tfn);

返回0;

} $ / $

这里,freopen用于控制stdin的输入,因此读入

的字符串必须符合readin(其长度)已经由早期的printf计算了

)。程序本身演示了一种可能(低效)编写asprintf()函数的方法:写入

一个临时文件,然后从该文件中读回数据。 (

当然,在实际代码中会使用fgets()而不是gets(),并且

stdin不会被重定向!)。我认为像fclose(stdin)

这样的东西可能会导致UB或者最好是实现定义的,但是从阅读

标准来看它似乎是有效的。

I was just wondering whether there was a portable way to use gets()
safely, and came up with this:

#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE* temp;
char buf[L_tmpnam];
char* readin, *tfn;
int len;
tfn = tmpnam(buf);
if(!tfn) abort();
temp = fopen(tfn,"w");
if(!temp) abort();
len = fprintf(temp, "%s %d.\n", "Hello, world!", 42);
fclose(temp);
if(!freopen(tfn, "r", stdin)) {remove(tfn); abort();};
readin = malloc(len+1);
if(readin)
{
gets(readin); /* hopefully safe */
printf("%s contained %s\n", tfn, readin);
free(readin);
}
fclose(stdin);
remove(tfn);
return 0;
}

Here, freopen is used to control the input to stdin, so the string that
will be read in will have to fit in readin (whose length has been
calculated by an earlier printf). The program itself demonstrates one
possible (inefficient) way of writing an asprintf() function: write to
a temporary file, and then read back the data from that file. (Of
course, in real code fgets() would be used, rather than gets(), and
stdin wouldn''t be redirected!). I thought something like fclose(stdin)
might cause UB or at best be implementation-defined, but from reading
the standard it seems to be valid.

推荐答案

ais523认为:
ais523 opined:
我只是想知道是否有一种可移植的方式来使用gets(安全地,并且想出了这个:

#include< stdio.h>
#include< stdlib.h>

int main()
{FILE * temp;
char buf [L_tmpnam];
char * readin,* tfn;
int len;
tfn = tmpnam(buf);
if(!tfn)abort();
temp = fopen(tfn," w");
if(!temp)abort();
len = fprintf(temp,"%s%d。\ n"," Hello,world!",42);
fclose(temp);
if(!freopen(tfn) ,r,stdin)){remove(tfn); abort();};
readin = malloc(len + 1);
if(readin)
{
获取(readin); / *希望安全* /
printf(%s包含%s \ n,tfn,readin);
免费(读取);
}
fclose(stdin) );
删除(tfn);
返回0;
}
这里,freopen用于控制stdin的输入,所以字符串
将被读入的将必须适合readin(其长度已经由早期的printf计算)。程序本身演示了编写asprintf()函数的一种可能(低效)方法:写入临时文件,然后从该文件读回数据。 (当然,在实际代码中,将使用fgets(),而不是使用get(),并且stdin不会被重定向!)。我认为像fclose(stdin)这样的东西可能会导致UB或者最好是实现定义的,但是从阅读标准来看它似乎是有效的。
I was just wondering whether there was a portable way to use gets()
safely, and came up with this:

#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE* temp;
char buf[L_tmpnam];
char* readin, *tfn;
int len;
tfn = tmpnam(buf);
if(!tfn) abort();
temp = fopen(tfn,"w");
if(!temp) abort();
len = fprintf(temp, "%s %d.\n", "Hello, world!", 42);
fclose(temp);
if(!freopen(tfn, "r", stdin)) {remove(tfn); abort();};
readin = malloc(len+1);
if(readin)
{
gets(readin); /* hopefully safe */
printf("%s contained %s\n", tfn, readin);
free(readin);
}
fclose(stdin);
remove(tfn);
return 0;
}

Here, freopen is used to control the input to stdin, so the string
that will be read in will have to fit in readin (whose length has
been calculated by an earlier printf). The program itself
demonstrates one possible (inefficient) way of writing an asprintf()
function: write to a temporary file, and then read back the data from
that file. (Of course, in real code fgets() would be used, rather
than gets(), and stdin wouldn''t be redirected!). I thought something
like fclose(stdin) might cause UB or at best be
implementation-defined, but from reading the standard it seems to be
valid.




您是否考虑过非托管实现(例如嵌入式系统)

根本没有文件系统(以及`stdin`,`stdout`和`stderr`

连接到一个串口)?


-

我们都知道Linux很棒.. .it在5秒钟内完成无限循环。

(Linus Torvalds关于Linux在阿姆斯特丹的优势

Linux研讨会)


< http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>



Have you considered non-hosted implementations (e.g. embedded systems)
with no file system at all (and where `stdin`, `stdout`, and `stderr`
are connected to, say, a serial port)?

--
"We all know Linux is great...it does infinite loops in 5 seconds."
(Linus Torvalds about the superiority of Linux on the Amsterdam
Linux Symposium)

<http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>




Vladimir Oka写道:

Vladimir Oka wrote:
ais523认为:
ais523 opined:
我只是想知道是否有一种可移植的方式来使用gets()
安全地,想出了这个:

#include< stdio.h>
#include< stdlib.h>



{* FILE * temp;
char buf [L_tmpnam];
char * readin ,* tfn;
int len;
tfn = tmpnam(buf);
if(!tfn)abort();
temp = fopen(tfn," w") ;
if(!temp)abort();
len = fprintf(temp,"%s%d。\ n"," Hello,world!",42);
fclose(temp);
if(!freopen(tfn," r",stdin)){remove(tfn); abort();};
readin = malloc(len + 1);
if(readin)
{
获取(readin); / *希望安全* /
printf(%s包含%s \ n,tfn,readin);
免费(读取);
}
fclose(stdin) );
删除(tfn);
返回0;
}
这里,freopen用于控制stdin的输入,所以字符串
将被读入的将必须适合readin(其长度已经由早期的printf计算)。程序本身演示了编写asprintf()函数的一种可能(低效)方法:写入临时文件,然后从该文件读回数据。 (当然,在实际代码中,将使用fgets(),而不是使用get(),并且stdin不会被重定向!)。我认为像fclose(stdin)这样的东西可能会导致UB或者最好是实现定义的,但是从阅读标准来看它似乎是有效的。
I was just wondering whether there was a portable way to use gets()
safely, and came up with this:

#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE* temp;
char buf[L_tmpnam];
char* readin, *tfn;
int len;
tfn = tmpnam(buf);
if(!tfn) abort();
temp = fopen(tfn,"w");
if(!temp) abort();
len = fprintf(temp, "%s %d.\n", "Hello, world!", 42);
fclose(temp);
if(!freopen(tfn, "r", stdin)) {remove(tfn); abort();};
readin = malloc(len+1);
if(readin)
{
gets(readin); /* hopefully safe */
printf("%s contained %s\n", tfn, readin);
free(readin);
}
fclose(stdin);
remove(tfn);
return 0;
}

Here, freopen is used to control the input to stdin, so the string
that will be read in will have to fit in readin (whose length has
been calculated by an earlier printf). The program itself
demonstrates one possible (inefficient) way of writing an asprintf()
function: write to a temporary file, and then read back the data from
that file. (Of course, in real code fgets() would be used, rather
than gets(), and stdin wouldn''t be redirected!). I thought something
like fclose(stdin) might cause UB or at best be
implementation-defined, but from reading the standard it seems to be
valid.



您是否考虑过非托管实现(例如嵌入式系统)
根本没有文件系统(并且`stdin`,`stdout`和`stderr`
连接到哪里,比如说,串口)?



Have you considered non-hosted implementations (e.g. embedded systems)
with no file system at all (and where `stdin`, `stdout`, and `stderr`
are connected to, say, a serial port)?



在这种情况下,至少freopen,可能是tmpnam或fopen,

都会失败,导致abort()叫做。无论如何,非托管的

实现甚至不需要printf()。大多数C程序

不会在没有修改的情况下运行在独立实现上,因为这样的实现几乎没有标准库。 (他们差不多

都有他们自己的非标准库,但是这将是OT /

讨论它们。)


In that case, at least the freopen, and probably the tmpnam or fopen,
will fail, causing abort() to be called. Anyway, a non-hosted
implementation need not even be able to printf(). Most C programs
wouldn''t run on a freestanding implementation without modification, as
such implementations have virtually no standard library. (They nearly
all have nonstandard libraries of their own, but it would be OT to
discuss them).

< br>

ais523写道:
我只是想知道是否有一种便携式方式可以安全地使用gets()
,[...]


No.

[...]并想出了这个:[...无论删除未读]
I was just wondering whether there was a portable way to use gets()
safely, [...]
No.
[...] and came up with this: [... whatever deleted unread]




那很好,答案仍然没有。你最好的选择是

以下内容:


#include< stdio.h>

#include< stdlib .h>


#undef获得

int(获取)(char * p){

p = p;

删除(__FILE__);

puts(不要因任何原因使用gets();

exit(EXIT_FAILURE);

返回0;

}


问题是__FILE__可能受到正确保护,并且可能获得

被重新定义为某个头文件中的宏,所以这并不是真的可以保证正常运行。


-

Paul Hsieh
http://www.pobox.com / ~qed /
http://bstring.sf.net/



That''s nice, the answer is still no. Your best bet is something like
the following:

#include <stdio.h>
#include <stdlib.h>

#undef gets
int (gets) (char * p) {
p = p;
remove (__FILE__);
puts ("Don''t ever use gets() for any reason");
exit (EXIT_FAILURE);
return 0;
}

The problem is that __FILE__ might be right protected, and gets might
be redefined as a macro in some header file, so this isn''t really
guaranteed to function correctly.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/


这篇关于安全地使用gets()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆