home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume5 / getsafe < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  4.0 KB

  1. Path: xanth!nic.MR.NET!hal!ncoast!allbery
  2. From: ok@quintus.UUCP
  3. Newsgroups: comp.sources.misc
  4. Subject: v05i053: A "safe" replacement for gets()
  5. Message-ID: <674@quintus.UUCP>
  6. Date: 15 Nov 88 23:28:26 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: ok@quintus.UUCP
  9. Organization: Quintus Computer Systems, Inc.
  10. Lines: 123
  11. Approved: allbery@ncoast.UUCP
  12.  
  13. Posting-number: Volume 5, Issue 53
  14. Submitted-by: "A. Nonymous" <ok@quintus.UUCP>
  15. Archive-name: getsafe
  16.  
  17. [Aaaaagh.  I always suspected gets() was a potential bomb.  How about
  18.  
  19. #define gets(s) fgets(s, sizeof s, stdin)
  20.  
  21. as a quick fix?  ++bsa]
  22.  
  23. #!/bin/sh
  24. # This is a shell archive, meaning:                              
  25. # 1. Remove everything above the #!/bin/sh line.                
  26. # 2. Save the resulting test in a file.                          
  27. # 3. Execute the file with /bin/sh (not csh) to create the files:
  28. #    README
  29. #    getsafe.c
  30. sed -e 's/^X//' >README <<'------ EOF ------'
  31. XThe recent Usenet worm demonstrated yet again that using gets() is asking
  32. Xfor trouble.  However, gets() is often much more convenient than fgets().
  33. XIt would be pleasant to combine the convenience of gets() with the safety
  34. Xof fgets().  getsafe() -- reading from stdin -- and fgetsafe -- reading
  35. Xfrom a stream passed as an argument -- are such combinations.
  36. X
  37. XJust compile with
  38. X    cc -c getsafe.c
  39. Xand use.  No warrentees, no promises, no copyrights.
  40. ------ EOF ------
  41. ls -l README
  42. sed -e 's/^X//' >getsafe.c <<'------ EOF ------'
  43. X/*  File   : getsafe.c
  44. X    Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc.
  45. X    Updated: 11 November 1988
  46. X
  47. X    Defines: getsafe() and fgetsafe() -- safe replacements for gets()
  48. X
  49. X    This file is not covered by a copyright.  Do what you like with it.
  50. X*/
  51. X
  52. X#include <stdio.h>
  53. X
  54. X#if    0
  55. X
  56. X    int getsafe(char *buffer, int length)
  57. X    int fgetsafe(char *buffer, int length, FILE *stream)
  58. X
  59. X    The functions read characters (getsafe reads from the standard input
  60. X    stream, fgetsafe from its stream argument) until a new-line character
  61. X    is read or the end of the stream is reached.  Characters are stored
  62. X    in buffer until length-1 of them have been stored, and a NUL is put
  63. X    after the stored characters.  The terminating new-line character is
  64. X    not stored in the buffer.  If the input line has more than length-1
  65. X    characters preceding the new-line, the excess characters are lost.
  66. X
  67. X    If a new-line character is encountered, the return value is the
  68. X    number of characters which were read, including the new-line.  This
  69. X    result also includes characters which were not stored, so you can
  70. X    tell whether the line was truncated by doing
  71. X
  72. X    n = getsafe(buffer, sizeof buffer);
  73. X    if (n > sizeof buffer) { the line was truncated }
  74. X
  75. X    If a new-line character is not encountered, characters will have been
  76. X    read until the end of the stream was reached, and the return value is
  77. X    0 to indicate end of stream.  This means that a last "line" which is
  78. X    not terminated by a new-line will be lost.
  79. X
  80. X    Loops which used to read
  81. X    char buffer[ITSIZE];
  82. X    while (gets(buffer)) { process line }
  83. X    can be converted to
  84. X    while (getsafe(buffer, sizeof buffer)) { process line }
  85. X
  86. X#endif 0
  87. X
  88. Xint fgetsafe(buffer, length, stream)
  89. X    register char *buffer;
  90. X             int   length;
  91. X    register FILE *stream;
  92. X    {
  93. X    register int c;
  94. X    register int n;
  95. X
  96. X    for (n = 0;;) {
  97. X        c = getc(stream);
  98. X        if (c == EOF ) { *buffer = '\0'; return 0; }
  99. X        if (c == '\n') { *buffer = '\0'; return n; }
  100. X        n++;
  101. X        if (n < length) *buffer++ = c;
  102. X    }
  103. X    }
  104. X
  105. X
  106. Xint getsafe(buffer, length)
  107. X    char *buffer;
  108. X    int   length;
  109. X    {
  110. X    return fgetsafe(buffer, length, stdin);
  111. X    }
  112. X
  113. X
  114. X#ifdef    TEST
  115. X
  116. X/*  To test this, I did
  117. X    cc -O -DTEST getsafe.c
  118. X    cat /usr/dict/words | paste - - - - - - - - - - | a.out
  119. X*/
  120. X
  121. Xmain()
  122. X    {
  123. X    char buffer[81];
  124. X    int n;
  125. X
  126. X    while (n = getsafe(buffer, sizeof buffer))
  127. X        printf("%7d %7d\n", n, strlen(buffer));
  128. X    exit(0);
  129. X    }
  130. X
  131. X#endif    TEST
  132. X
  133. ------ EOF ------
  134. ls -l getsafe.c
  135. exit 0
  136.