home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / sys / next / programm / 5872 < prev    next >
Encoding:
Text File  |  1992-08-30  |  5.3 KB  |  179 lines

  1. Newsgroups: comp.sys.next.programmer
  2. Path: sparky!uunet!elroy.jpl.nasa.gov!usc!rpi!usenet
  3. From: gad@eclipse.its.rpi.edu (Garance A. Drosehn)
  4. Subject: Re: bug/fix for sort !!!
  5. Message-ID: <1wtysja@rpi.edu>
  6. Nntp-Posting-Host: eclipse.its.rpi.edu
  7. References: <1992Aug27.202530.28111@u.washington.edu>
  8. Date: Mon, 31 Aug 1992 04:33:30 GMT
  9. Lines: 168
  10.  
  11. I'm basically reposting this just in case no one sees comp.sys.next these  
  12. days (as well they should not, seeing it hasn't officially existed for a  
  13. year or so now...  :-).
  14.  
  15. The author claims this bug is in NeXTSTEP 2.1.  Does anyone know if it's in  
  16. NeXTSTEP 3.0?
  17. ---
  18. Garance Alistair Drosehn     =     gad@eclipse.its.rpi.edu
  19. ITS Systems Programmer            (handles NeXT-type mail)
  20. Rensselaer Polytechnic Institute;           Troy NY    USA
  21.  
  22.  - - - - - - - - [start quoted article]
  23.  
  24. In article <1992Aug27.202530.28111@u.washington.edu>
  25.     in newsgroup comp.sys.next
  26.     corey@milton.u.washington.edu (Corey Satten) writes:
  27. > As hard as it is to believe, after all these years of use, I found a bug
  28. > in /usr/bin/sort when used with the -u flag.  The bug only shows up for
  29. > relatively large inputs and causes a few of the last lines of output to
  30. > be omitted.  Below is a script you can feed both to /bin/sh to test your
  31. > sort and to "patch" to (hopefully - but as always, no guarantees) fix
  32. > your sort.c.  The context diff is for BSD 4.3 sort.c, however the exact
  33. > same code exists (at different line numbers) in Ultrix 4.1 sort.c so
  34. > you can still apply the patch verbatim.
  35. > --------
  36. > Corey Satten, corey@cac.washington.edu
  37. > Networks and Distributed Computing
  38. > University of Washington
  39.  
  40.   [patch from the article, but not quoted with the ">"s - garance]
  41. #!/bin/sh
  42. #
  43. # Test for sort -u bug.  The bug causes a small number of lines to be
  44. # omitted from the sort -u output for relatively large sort inputs.
  45. #
  46. # It is caused by the merge code not handling EOF properly in the  
  47. next-to-last
  48. # temp-file generated by sort.  In order to trigger the bug, enough input
  49. # must be presented that sort merges a larger number of tempfiles into a
  50. # smaller number and then merges the smaller number.  Alternatively,
  51. # the uninitialized memory which is compared against the last value
  52. # could accidently contain that value.
  53. #
  54. # This bug is known to be present in:
  55. #    BSD 4.3 Tahoe
  56. #    Sequent Dynix V3.1.4
  57. #    NeXT version 2.1
  58. #    Ultrix version 4.1, 4.2a
  59. #    AT&T 7300/3b1 version 3.51
  60. #
  61. # It appears not to be present in SunOS 4.x, OSF/1 however this may only
  62. # be because the size of the input required to trigger the bug has been
  63. # raised (the size of the tempfiles and memory arrays has been raised).
  64. #
  65. # A context diff of what I hope is a fix to the 4.3BSD version is
  66. # appended at the end of this script.  Use at your own risk.
  67. #
  68. # Corey Satten, corey@cac.washington.edu, July 31, 1992
  69.  
  70. TMP=/tmp/data$$
  71. trap "rm -f $TMP.c $TMP; exit 0" 0 1 2 13 15
  72.  
  73. COUNT=${1-45}        # value supplied as $1, else default to 45
  74.  
  75. lines=`echo "$COUNT^3 * 1.015625 / 10 * 10" | bc`
  76. echo testing sort with input of roughly $lines lines 1>&2
  77.  
  78. cat <<EOF >$TMP.c
  79. #include <stdio.h>
  80. #define r(x) ("qwertyuiopasdfghjklzxcvbnm"[pos(x)%26])
  81. #define pos(x) ((x)>0?(x):5-(x))
  82.  
  83. main() {
  84.     int lines = 0;
  85.     int i,j,k;
  86.     for (i=0; i<$COUNT; ++i) {
  87.     for (j=0; j<$COUNT; ++j) {
  88.         for (k=0; k<$COUNT; ++k) {
  89.         if ( (++lines & 63) == 0) printf("zzzzzzzzzzz - OK\n");
  90.         printf("%c%c%c%c%c%c\n",
  91.             r(k), r(j+k), r(j-k), r(i+k), r(i-k), r(i+j+k));
  92.             }
  93.         }
  94.         }
  95.     }
  96. EOF
  97. cc $TMP.c -o $TMP || {
  98.     rm -f $TMP.o
  99.     echo
  100.     echo " Sorry, your C compiler didn't compile my program." 1>&2
  101.     exit 1
  102.     }
  103.  
  104. if $TMP | sort -u | grep -s '^zzzzzzzzzzz' ; then
  105.     echo
  106.     echo " sort -u worked for this input (COUNT=$COUNT) but to be safe, you"
  107.     echo ' might wish to try again with a larger value of COUNT.  You may'
  108.     echo ' supply a value for COUNT as an argument to this script.'
  109.     echo ' The number of lines is roughly COUNT to the 3rd power.'
  110.     exit 0
  111. else
  112.     echo
  113.     echo ' sort -u failed on this system.  The line beginning with  
  114. zzzzzzzzzz'
  115.     echo ' was omitted from the sort -u output.  You might wish to compare'
  116.     echo ' sort -u output with output from sort|uniq to see if there are  
  117. any'
  118.     echo ' other differences.'
  119.     exit 1
  120. fi
  121.  
  122. # I believe this change applied to the 4.3BSD code fixes the problem.
  123. # Use at your own risk.  -Corey
  124. #
  125. *** sort.c    Fri Jul 31 08:35:33 1992
  126. --- new_sort.c    Fri Jul 31 14:33:20 1992
  127. ***************
  128. *** 387,392 ****
  129. --- 387,393 ----
  130.       int    j;
  131.       int    k, l;
  132.       int    muflg;
  133. +     int    last_muflg;
  134.   
  135.       p = (struct merg *)lspace;
  136.       j = 0;
  137. ***************
  138. *** 432,438 ****
  139.                   term();
  140.               }
  141.           }
  142. !         if(muflg){
  143.               cp = ibuf[i-1]->l;
  144.               dp = p->l;
  145.               do {
  146. --- 433,439 ----
  147.                   term();
  148.               }
  149.           }
  150. !         if(last_muflg = muflg){    /* yes assignment. Corey */
  151.               cp = ibuf[i-1]->l;
  152.               dp = p->l;
  153.               do {
  154. ***************
  155. *** 452,458 ****
  156.                   *ip = *(ip-1);
  157.                   *(ip-1) = jp;
  158.               }
  159. !             if(!muflg)
  160.                   break;
  161.               j = (*compare)(ibuf[i-1]->l,p->l);
  162.               if(cflg) {
  163. --- 453,466 ----
  164.                   *ip = *(ip-1);
  165.                   *(ip-1) = jp;
  166.               }
  167. !         /*
  168. !          * Instead of testing muflg, I introduce last_muflg
  169. !          * because when i-- reaches 1 and the value of muflg
  170. !          * changes, the code suddenly compares against p->l
  171. !          * which hasn't had a recent value copied into it.
  172. !          * Corey.
  173. !          */
  174. !             if(!last_muflg)
  175.                   break;
  176.               j = (*compare)(ibuf[i-1]->l,p->l);
  177.               if(cflg) {
  178.