From af268aa7bb1b97002fc523f0f0e0ca355c50a380 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 8 Jun 2015 20:32:56 +0100 Subject: [PATCH] gets: correct behaviour of gets_s --- Library/libs/gets.c | 102 ++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/Library/libs/gets.c b/Library/libs/gets.c index 52308e60..b261fb20 100644 --- a/Library/libs/gets.c +++ b/Library/libs/gets.c @@ -1,42 +1,60 @@ -/* stdio.c - * Copyright (C) 1996 Robert de Bath - * This file is part of the Linux-8086 C library and is distributed - * under the GNU Library General Public License. - */ - -/* This is an implementation of the C standard IO package. */ - -#include "stdio-l.h" - -char *gets(char *str) /* BAD function; DON'T use it! */ -{ - /* Auwlright it will work but of course _your_ program will crash */ - /* if it's given a too long line */ - register int c; - register char *p = str; - - while (((c = getc(stdin)) != EOF) && (c != '\n')) - *p++ = c; - *p = '\0'; - return (((c == EOF) && (p == str)) ? NULL : str);/* NULL == EOF */ -} - -char *gets_s(char *str,size_t maxlen) -{ - register int c; - register char *p=str; - - while ( (((c = getc(stdin)) != EOF) && (c != '\n')) && ( p - str < maxlen) ) - *p++=c; - *p='\0'; - return (((c == EOF) && (p == str)) ? NULL : str);/* NULL == EOF */ -} - -int puts(const void *str) -{ - register int n; - if (((n = fputs(str, stdout)) == EOF) - ||(putc('\n', stdout) == EOF)) - return (EOF); - return (++n); -} +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" +#include + +char *gets(char *str) +{ /* BAD function; DON'T use it! */ + /* Auwlright it will work but of course _your_ program will crash */ + /* if it's given a too long line */ + register int c; + register char *p = str; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ +} + +char *gets_s(char *str, size_t maxlen) +{ + register int c; + register char *p = str; + char *end = p + maxlen - 1; + uint8_t over = 0; + + /* NULL is defined as an error so we don't need to consume data */ + if (str == NULL || maxlen == 0) + goto fail; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) { + /* < because we need space for the \0 */ + if (p < end) + *p++ = c; + else + over = 1; + } + *p = '\0'; + + /* NULL == EOF */ + if (!over) + return (((c == EOF) && (p == str)) ? NULL : str); +fail: + errno = ERANGE; + return NULL; +} + +int puts(const void *str) +{ + register int n; + if (((n = fputs(str, stdout)) == EOF) + || (putc('\n', stdout) == EOF)) + return (EOF); + return (++n); +} -- 2.34.1