home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume05 / getsafe < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  4.1 KB

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