Page MenuHomeFreeBSD

D12785.id34315.diff
No OneTemporary

D12785.id34315.diff

Index: include/stdio.h
===================================================================
--- include/stdio.h
+++ include/stdio.h
@@ -36,9 +36,7 @@
#ifndef _STDIO_H_
#define _STDIO_H_
-#include <sys/cdefs.h>
-#include <sys/_null.h>
-#include <sys/_types.h>
+#include <stddef.h>
__NULLABILITY_PRAGMA_PUSH
@@ -263,6 +261,9 @@
int getc(FILE *);
int getchar(void);
char *gets(char *);
+#if defined(__EXT1_VISIBLE) && __EXT1_VISIBLE == 1
+char *gets_s(char *, rsize_t);
+#endif
void perror(const char *);
int printf(const char * __restrict, ...);
int putc(int, FILE *);
Index: lib/libc/stdio/Makefile.inc
===================================================================
--- lib/libc/stdio/Makefile.inc
+++ lib/libc/stdio/Makefile.inc
@@ -49,7 +49,8 @@
ferror.3 feof.3 ferror.3 feof_unlocked.3 \
ferror.3 fileno.3 ferror.3 fileno_unlocked.3
MLINKS+=fflush.3 fpurge.3
-MLINKS+=fgets.3 gets.3
+MLINKS+=fgets.3 gets.3 gets_s.3
+MLINKS+=fgets.3 gets_s.3
MLINKS+=flockfile.3 ftrylockfile.3 flockfile.3 funlockfile.3
MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3 fopen.3 fmemopen.3
MLINKS+=fputs.3 puts.3
Index: lib/libc/stdio/Symbol.map
===================================================================
--- lib/libc/stdio/Symbol.map
+++ lib/libc/stdio/Symbol.map
@@ -165,6 +165,7 @@
FBSD_1.4 {
fdclose;
fopencookie;
+ gets_s;
};
FBSDprivate_1.0 {
Index: lib/libc/stdio/fgets.3
===================================================================
--- lib/libc/stdio/fgets.3
+++ lib/libc/stdio/fgets.3
@@ -46,6 +46,8 @@
.Ft char *
.Fn fgets "char * restrict str" "int size" "FILE * restrict stream"
.Ft char *
+.Fn gets_s "char *str" "rsize_t size"
+.Ft char *
.Fn gets "char *str"
.Sh DESCRIPTION
The
@@ -65,6 +67,17 @@
character is appended to end the string.
.Pp
The
+.Fn gets_s
+function
+is equivalent to
+.Fn fgets
+with a
+.Fa stream
+of
+.Dv stdin ,
+except that the newline character (if any) is not stored in the string.
+.Pp
+The
.Fn gets
function
is equivalent to
@@ -80,7 +93,8 @@
if any, is sufficiently short to fit in the string.
.Sh RETURN VALUES
Upon successful completion,
-.Fn fgets
+.Fn fgets ,
+.Fn gets_s
and
.Fn gets
return
@@ -94,7 +108,8 @@
.Dv NULL
and the buffer contents are indeterminate.
The
-.Fn fgets
+.Fn fgets ,
+.Fn gets_s
and
.Fn gets
functions
Index: lib/libc/stdio/gets.c
===================================================================
--- lib/libc/stdio/gets.c
+++ lib/libc/stdio/gets.c
@@ -37,31 +37,41 @@
__FBSDID("$FreeBSD$");
#include "namespace.h"
+#include <errno.h>
#include <unistd.h>
+#include <stdint.h>
#include <stdio.h>
#include <sys/cdefs.h>
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
-__warn_references(gets, "warning: this program uses gets(), which is unsafe.");
-
+/* ISO/IEC 9899:2011 K.3.7.4.1 */
+static
char *
-gets(char *buf)
+_gets_s(char *buf, rsize_t *n)
{
int c;
+ int nn;
char *s, *ret;
- static int warned;
- static const char w[] =
- "warning: this program uses gets(), which is unsafe.\n";
+
+#define GETS_S_CALL (n != NULL)
+ if ( GETS_S_CALL ) {
+ /* gets_s() */
+ nn = *n;
+ } else {
+ /* Old school gets() call, not a gets_s() call. */
+ /* nn could be anything, it's inconsequential at this */
+ /* point. It's not used by old school gets(). This is */
+ /* done to pet the compiler. */
+ nn = 0;
+ }
FLOCKFILE_CANCELSAFE(stdin);
ORIENT(stdin, -1);
- if (!warned) {
- (void) _write(STDERR_FILENO, w, sizeof(w) - 1);
- warned = 1;
- }
- for (s = buf; (c = __sgetc(stdin)) != '\n'; ) {
+
+ for (s = buf, nn--; ((c = __sgetc(stdin)) != '\n' &&
+ ((nn > 0 && GETS_S_CALL) || ! GETS_S_CALL)); nn--) {
if (c == EOF)
if (s == buf) {
ret = NULL;
@@ -71,9 +81,62 @@
else
*s++ = c;
}
+
+ /****************************************************************/
+ /* */
+ /* If end of buffer reached, discard until \n or eof. */
+ /* Then throw an error. */
+ /* */
+ /****************************************************************/
+ if ( GETS_S_CALL && nn == 0) {
+ /* discard */
+ while (((c = __sgetc(stdin)) != '\n') && c != EOF);
+ /* throw the error */
+ __throw_constraint_handler_s("gets_s : end of buffer", E2BIG);
+ return(NULL);
+ }
+
*s = 0;
ret = buf;
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
+
+/* ISO/IEC 9899:2011 K.3.7.4.1 */
+char *
+gets_s(char *buf, rsize_t n)
+{
+ if (buf == NULL) {
+ __throw_constraint_handler_s("gets_s : str is NULL", EINVAL);
+ return(NULL);
+ } else if (n > RSIZE_MAX) {
+ __throw_constraint_handler_s("gets_s : n > RSIZE_MAX",
+ EINVAL);
+ return(NULL);
+ } else if (n == 0) {
+ __throw_constraint_handler_s("gets_s : n == 0", EINVAL);
+ return(NULL);
+ }
+ return(_gets_s(buf, &n));
+}
+
+#define __GETS_ENABLED
+#ifdef __GETS_ENABLED
+__warn_references(gets, "warning: this program uses gets(), which is unsafe.");
+
+char *
+gets(char *buf)
+{
+ static int warned;
+ static const char w[] =
+ "warning: this program uses gets(), which is unsafe.\n";
+
+ if (!warned) {
+ (void) _write(STDERR_FILENO, w, sizeof(w) - 1);
+ warned = 1;
+ }
+
+ return(_gets_s(buf, NULL));
+}
+#endif

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 19, 1:19 AM (25 m, 26 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25574458
Default Alt Text
D12785.id34315.diff (5 KB)

Event Timeline