得到,fgets,scanf没有安全...... [英] gets, fgets, scanf none is safe...

查看:98
本文介绍了得到,fgets,scanf没有安全......的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好......

我不能提醒哪个函数用于安全输入...

获取,fgets,scanf导致缓冲区溢出。 ..


i在Windows 2000上使用gcc版本2.95.2编译该代码


char tmp0 [10] =" ABCDEFGHI \ 0"

char buff [5]; / *输入缓冲区。 * /

char tmp1 [10] =" ABCDEFGHI \ 0";


/ *从键盘获取数据。 * /

printf(" \ nGETS:请输入text = \ n");


得到(buff);


printf(" \ nGETS:长度是%d尺寸是%d#%s#\ n",strlen(buff),

sizeof(buff), buff);

printf("%s \ n%s \ n",tmp0,tmp1);


/ *从中获取数据键盘。 * /

printf(" \\\
FGETS:请输入text = \ n");


fgets(buff,sizeof(buff),stdin );


printf(" \\\
FGETS:长度是%d尺寸是%d#%s#\\ n'\\ n \\ n,strlen(buff),

sizeof(buff),buff);

printf("%s \ n%s \ n",tmp0,tmp1);


printf(" \ nSCANF:请输入text = \ n");


scanf("%s",buff);


printf(" \ nSCANF:长度是%d尺寸是%d#%s#\ n",strlen(buff),

sizeof(buff),buff);

printf("%s \ n%s \ n",tmp0,tmp1);


Hello all...
I can''t remind which function to use for safe inputs...
gets, fgets, scanf leads to buffer overflow...

i compiled that code with gcc version 2.95.2, on windows 2000

char tmp0[10] = "ABCDEFGHI\0";
char buff[5]; /* Input buffer. */
char tmp1[10] = "ABCDEFGHI\0";

/* Get data from the keyboard. */
printf("\nGETS : please enter text =\n");

gets(buff);

printf("\nGETS : length is %d size is %d #%s#\n", strlen(buff),
sizeof(buff), buff);
printf("%s\n%s\n", tmp0, tmp1);

/* Get data from the keyboard. */
printf("\nFGETS : please enter text =\n");

fgets(buff, sizeof(buff), stdin);

printf("\nFGETS : length is %d size is %d #%s#\n", strlen(buff),
sizeof(buff), buff);
printf("%s\n%s\n", tmp0, tmp1);

printf("\nSCANF : please enter text =\n");

scanf("%s", buff);

printf("\nSCANF : length is %d size is %d #%s#\n", strlen(buff),
sizeof(buff), buff);
printf("%s\n%s\n", tmp0, tmp1);


推荐答案

Xavoux写道:
Xavoux wrote:

大家好...

我不能提醒使用哪个功能安全输入...

获取,fgets,scanf导致缓冲区溢出...
Hello all...
I can''t remind which function to use for safe inputs...
gets, fgets, scanf leads to buffer overflow...



看看他们的原型,哪一个有输入大小限制?


-

Ian Collins。

Look at their prototypes, which one has an input size limit?

--
Ian Collins.


Xavoux写道:
Xavoux wrote:

>

大家好...

我不能提醒哪个函数用于安全输入...

获取,fgets,scanf导致缓冲区溢出...
>
Hello all...
I can''t remind which function to use for safe inputs...
gets, fgets, scanf leads to buffer overflow...



grade.c显示如何使用fscanf作为安全输入字符串

表示可以忽略的特定情况

输入超出输入缓冲区的大小。

字符串然后可以转换为数字数据。


pops_device.c还显示了如何使用fscanf

来安全输入字符串

对于特定情况,可以忽略输入缓冲区大小的
输入。


line_to_string.c显示如何读取字符串任意

长度到链表中,使用动态分配。


/ * BEGIN grade.c * /


#include< stdlib.h>

#include< stdio.h>


#define LENGTH 3

#define str(x)#x

#define xstr(x)str(x)


int main(void)

{

int rc;

char数组[LENGTH + 1];

长数;

const char letter [4] =" DCBA";


fputs(" Enter the Numeric grade:",stdout);

fflush(stdout);

rc = fscanf(stdin,"%" xstr(LENGTH)" [^ \ n]%* [^ \ n]",array);

if(!feof(stdin)){

getc(stdin);

}

while(rc == 1){

number = strtol(array,NULL,10);

if(number 59){

if(number 99){

number = 99;

}

数组[0] =字母[(数字 - 60)/ 10];

开关(数字%10){

情况0:

案例1:

array [1] ='' - '';

array [2] =''\''';

休息;

案例8:

案例9:

array [1] =''+'' ;

array [2] =''\ 0'';

休息;

默认:

array [1] =''\ 0'';

休息;

}

}其他{

array [0] =''F'';

array [1] =''\ 0'';

}

printf(字母等级为:%s \ n,数组);

fputs("输入数字等级:",stdout);

fflush(stdout);

rc = fscanf(stdin,"%" xstr(LENGTH)" [^ \ n]%* [^ \ n]",array);

if(!feof(stdin)){

getc(stdin);

}

}

返回0;

}


/ * END grade.c * /


/ * BEGIN pops_device.c * /

/ *

**如果rc等于0,则输入一个空行

**和数组包含垃圾值。

**如果rc等于EOF,则达到文件结尾,

**或存在输出问题。

**如果rc等于1,则数组中有一个字符串。

**最多读取LENGTH个字符数

**来自一行一个文本流。

**如果该行超过LENGTH,

**则会丢弃额外的字符。

* /

#include< stdio.h>


#define LENGTH 50

#define str(x)#x

#define xstr(x)str(x)


int main(无效)

{

int rc;

char数组[LENGTH + 1] ;


puts(LENGTH macro is; xstr(LENGTH));

fputs("输入带空格的字符串:",stdout);

fflush(stdout);

rc = fscanf(stdin,"%" xstr(LENGTH)" [^ \ n]%* [^ \ n]",array);

if(!feof (stdin)){

getc(stdin);

}

而(rc == 1){

printf(你的字符串是:%s \ n \\ nn>

"点击Enter键结束,\ nor输入"

" ;另一个要继续的字符串:",array);

fflush(stdout);

rc = fscanf(stdin,"%" xstr(LENGTH)" [^ \ n]%* [^ \ n]",array);

if(!feof(stdin)){

getc(stdin);

}

if(rc == 0){

* array =''\ 0'';

}

}

返回0;

}


/ * END pops_device.c * /


/ * BEGIN line_to_string.c * /


#include< stdio.h>

#include< stdlib.h>

#in clude< limits.h>

#include< string.h>

/ *

** INITIAL_BUFFER_SIZE可以是任意数字。

**从malloc获得非NULL返回值,更低的数字更可能是

**

**更高的数字更有可能防止

**需要进一步分配。

* /

#define INITIAL_BUFFER_SIZE 0


struct list_node {

struct list_node * next;

void * data;

};


int line_to_string(FILE * fp,char ** line,size_t * size);

struct list_node * string_node(struct list_node ** head,

struct list_node * tail,

char * data);

void list_free(struct list_node * node,void(* free_data)(void *));

int list_fputs(FILE * stream,struct list_node * node);


int main(void)

{

struct list_node * head,* tail;

int rc;

char * buff _ptr;

size_t buff_size;

long unsigned line_count;


buff_size = INITIAL_BUFFER_SIZE;

buff_ptr = malloc(buff_size);

if(buff_ptr == NULL&& buff_size!= 0){

printf(" malloc(%lu)== NULL \ n",(long unsigned)buff_size);

exit(EXIT_FAILURE) ;

}

tail = head = NULL;

line_count = 0;

puts(

" \ n该程序制作并打印从标准输入中输入的所有行的列表\ n



"只需点击Enter键结束,\ n"

"或输入任意一行字符即可继续。

);

while((rc = line_to_string(stdin,& buff_ptr,& buff_size))1){

++ line_count;

tail = string_node( & head,tail,buff_ptr);

if(tail == NULL){

break;

}

put(

" \\\
只需点击Enter键结束,\ n"

"或输入任何其他字符行继续。

);

}

开关(rc){

案例EOF:

如果(不ff_ptr!= NULL&& strlen(buff_ptr)!= 0){

puts(" rc equals EOF \\\
buff_ptr中的字符串是:");

puts(buff_ptr);

++ line_count;

tail = string_node(& head,tail,buff_ptr);

}

休息;

案例0:

puts(realloc返回空指针值);

if (buff_size 1){

puts(rc等于0 \ n buff_ptr中的字符串是:);

puts(buff_ptr);

++ line_count;

tail = string_node(& head,tail,buff_ptr);

}

break;

默认值:

/ *

**如果在代码中此时要评估rc,

** rc

**的值现在等于(1 + strlen(buff_ptr))。

* /

break;

}

if(line_count!= 0&& tail == NULL){

puts(节点分配失败。);

puts("输入的最后一行没有进入list:");

puts(buff_ptr);

}

free(buff_ptr);

puts (\行缓冲区已被释放。\ n);

printf(输入%lu行文字。\ nn,line_count);

puts(它们是:\ n);

list_fputs(stdout,head);

list_free(head,free);

puts(\ n列表已被释放。\ n);

返回0;

}

int line_to_string(FILE * fp,char ** line,size_t * size)

{

int rc;

void * p;

size_t count;


count = 0;

while((rc = getc(fp))!= EOF){

++ count;

if(count + 2 * size){

p = realloc(* line,count + 2) ;

if(p == NULL){

if(* size count){

(* line) [count] =''\''';

(* line)[count - 1] =(char)rc;

} else {

ungetc(rc,fp);

}

count = 0;

休息;

}

* line = p;

* size = count + 2;

}

if(rc = =''\ n''){

(*行)[count - 1] =''\ 0'';

休息;

}

(*行)[count - 1] =(char)rc;

}

if(rc!= EOF){

rc =计算INT_MAX? INT_MAX:count;

} else {

if(* size count){

(* line)[count] =''\ 0'';

}

}

返回rc;

}


struct list_node * string_node(struct list_node ** head,

struct list_node * tail,

char * data)

{< br $>
struct list_node * node;


node = malloc(sizeof * node);

if(node!= NULL){

node -next = NULL;

node -data = malloc(strlen(data)+ 1);

if(node -data!= NULL){

if(* head == NULL){

* head = node;

} else {

tail -next = node;

}

strcpy(node -data,data);

} else {

free(节点);

node = NULL;

}

}

返回节点; < br $>
}


void list_free(struct list_node * node,void(* free_data)(void *))

{

struct list_node * next_node;


while (node!= NULL){

next_node = node -next;

free_data(node -data);

free(node);

node = next_node;

}

}


int list_fputs(FILE * stream,struct list_node *节点)

{

while(node!= NULL

&& fputs(node -data,stream)!= EOF

&& putc(''\ n'',stream)!= EOF)

{

node = node -next;

}

返回节点== NULL? ''\ n'':EOF;

}


/ * END line_to_string.c * /

-

pete

grade.c shows how to use fscanf for the safe input of strings
for the specific case of when it is OK to ignore
input that excedes the size of the input buffer.
The strings can then be converted to numeric data.

pops_device.c also shows how to use fscanf
for the safe input of strings
for the specific case of when it is OK to ignore
input that excedes the size of the input buffer.

line_to_string.c shows how to read strings of arbitrary
length into a linked list, using dynamic allocation.

/* BEGIN grade.c */

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

#define LENGTH 3
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
int rc;
char array[LENGTH + 1];
long number;
const char letter[4] = "DCBA";

fputs("Enter the Numeric grade: ", stdout);
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
while (rc == 1) {
number = strtol(array, NULL, 10);
if (number 59) {
if (number 99) {
number = 99;
}
array[0] = letter[(number - 60) / 10];
switch (number % 10) {
case 0:
case 1:
array[1] = ''-'';
array[2] = ''\0'';
break;
case 8:
case 9:
array[1] = ''+'';
array[2] = ''\0'';
break;
default:
array[1] = ''\0'';
break;
}
} else {
array[0] = ''F'';
array[1] = ''\0'';
}
printf("The Letter grade is: %s\n", array);
fputs("Enter the Numeric grade: ", stdout);
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
}
return 0;
}

/* END grade.c */

/* BEGIN pops_device.c */
/*
** If rc equals 0, then an empty line was entered
** and the array contains garbage values.
** If rc equals EOF, then the end of file was reached,
** or there is some output problem.
** If rc equals 1, then there is a string in array.
** Up to LENGTH number of characters are read
** from a line of a text stream.
** If the line is longer than LENGTH,
** then the extra characters are discarded.
*/
#include <stdio.h>

#define LENGTH 50
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
int rc;
char array[LENGTH + 1];

puts("The LENGTH macro is " xstr(LENGTH));
fputs("Enter a string with spaces:", stdout);
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
while (rc == 1) {
printf("Your string is:%s\n\n"
"Hit the Enter key to end,\nor enter "
"another string to continue:", array);
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
if (rc == 0) {
*array = ''\0'';
}
}
return 0;
}

/* END pops_device.c */

/* BEGIN line_to_string.c */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
/*
** INITIAL_BUFFER_SIZE can be any number.
** Lower numbers are more likely
** to get a non-NULL return value from malloc.
** Higher numbers are more likely to prevent
** any further allocation from being needed.
*/
#define INITIAL_BUFFER_SIZE 0

struct list_node {
struct list_node *next;
void *data;
};

int line_to_string(FILE *fp, char **line, size_t *size);
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data);
void list_free(struct list_node *node, void (*free_data)(void *));
int list_fputs(FILE *stream, struct list_node *node);

int main(void)
{
struct list_node *head, *tail;
int rc;
char *buff_ptr;
size_t buff_size;
long unsigned line_count;

buff_size = INITIAL_BUFFER_SIZE;
buff_ptr = malloc(buff_size);
if (buff_ptr == NULL && buff_size != 0) {
printf("malloc(%lu) == NULL\n", (long unsigned)buff_size);
exit(EXIT_FAILURE);
}
tail = head = NULL;
line_count = 0;
puts(
"\nThis program makes and prints a list of all the lines\n"
"of text entered from standard input.\n"
"Just hit the Enter key to end,\n"
"or enter any line of characters to continue."
);
while ((rc = line_to_string(stdin, &buff_ptr, &buff_size)) 1) {
++line_count;
tail = string_node(&head, tail, buff_ptr);
if (tail == NULL) {
break;
}
puts(
"\nJust hit the Enter key to end,\n"
"or enter any other line of characters to continue."
);
}
switch (rc) {
case EOF:
if (buff_ptr != NULL && strlen(buff_ptr) != 0) {
puts("rc equals EOF\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
case 0:
puts("realloc returned a null pointer value");
if (buff_size 1) {
puts("rc equals 0\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
default:
/*
** If rc were to be evaluated at this point in the code,
** the value of rc
** would now be equal to (1 + strlen(buff_ptr)).
*/
break;
}
if (line_count != 0 && tail == NULL) {
puts("Node allocation failed.");
puts("The last line entered didn''t make it onto the list:");
puts(buff_ptr);
}
free(buff_ptr);
puts("\nThe line buffer has been freed.\n");
printf("%lu lines of text were entered.\n", line_count);
puts("They are:\n");
list_fputs(stdout, head);
list_free(head, free);
puts("\nThe list has been freed.\n");
return 0;
}

int line_to_string(FILE *fp, char **line, size_t *size)
{
int rc;
void *p;
size_t count;

count = 0;
while ((rc = getc(fp)) != EOF) {
++count;
if (count + 2 *size) {
p = realloc(*line, count + 2);
if (p == NULL) {
if (*size count) {
(*line)[count] = ''\0'';
(*line)[count - 1] = (char)rc;
} else {
ungetc(rc, fp);
}
count = 0;
break;
}
*line = p;
*size = count + 2;
}
if (rc == ''\n'') {
(*line)[count - 1] = ''\0'';
break;
}
(*line)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count INT_MAX ? INT_MAX : count;
} else {
if (*size count) {
(*line)[count] = ''\0'';
}
}
return rc;
}

struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data)
{
struct list_node *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -next = NULL;
node -data = malloc(strlen(data) + 1);
if (node -data != NULL) {
if (*head == NULL) {
*head = node;
} else {
tail -next = node;
}
strcpy(node -data, data);
} else {
free(node);
node = NULL;
}
}
return node;
}

void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;

while (node != NULL) {
next_node = node -next;
free_data(node -data);
free(node);
node = next_node;
}
}

int list_fputs(FILE *stream, struct list_node *node)
{
while (node != NULL
&& fputs(node -data, stream) != EOF
&& putc( ''\n'', stream) != EOF)
{
node = node -next;
}
return node == NULL ? ''\n'' : EOF;
}

/* END line_to_string.c */
--
pete


谢谢,


fgets不会导致缓冲区溢出(我的错误)......但是char不读是

离开...并且爆炸下一次读取如scanf("%d",& i);


怎么能我是空的stdin缓冲区吗?


" Ian Collins" < ia ****** @ hotmail.com写信息

新闻:4t ************* @ mid.individual.net ...
thanks,

fgets dont lead to buffer overflow (my mistake)... but char not read are
leaving... and explode next read such as scanf("%d", &i);

how can i empty stdin buffer?

"Ian Collins" <ia******@hotmail.comwrote in message
news:4t*************@mid.individual.net...

Xavoux写道:
Xavoux wrote:

Hello all ...

我可以''提醒哪个函数用于安全输入...

获取,fgets,scanf导致缓冲区溢出...
Hello all...
I can''t remind which function to use for safe inputs...
gets, fgets, scanf leads to buffer overflow...



看看他们的原型,其中一个有输入大小限制?


-

Ian Collins。

Look at their prototypes, which one has an input size limit?

--
Ian Collins.



这篇关于得到,fgets,scanf没有安全......的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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