[net.news.b] Bug in getnextart

dmmartindale@watcgl.UUCP (Dave Martindale) (11/30/84)

There is a very obscure bug in getnextart().  There is a while loop which
goes looking for the next useful newsgroup.  The first time that nextng()
fails, it increments "rfq" to 1 and then expects to pop out of the loop
and eventually drop out the bottom of getnextart() returning a value of 0.
This looks like it actually found another article, which keeps a test
inside readr() happy enough for it to print out the prompt asking if you
want to see the article - except that since "rfq" is set, it prints the
prompt as "Last article.  [qfr]".  Then, if you hit return, it notices
that it's finished with that article, calls getnextart() AGAIN, which
calls netxng() which fails AGAIN, which increments "rfq" to 2 and causes
getnextart() to return 1, causing readr() to break out of its loop and,
eventually, terminate the program.

Understand all that?  Well, there is a bug that shows up only if the
last newsgroup looked at by nextng() has no articles in it.  In this
case, "ngsize" is set to 0, which causes the while loop in getnextart()
to call nextng again immediately, rather than returning to readr()
having appeared to find an article.  After the second failure of
nextng(), getnextart() returns 1 as before and readr() wraps things
up, without ever having printed the "Last article" prompt.

I don't really understand the code well enough to see whether the method
of getting the "Last article" prompt printed needs to be quite so
convoluted, so I opted to make the minimal change that worked.
Just adding a "break" to ensure that the while loop terminates after
the first failure of nextng() fixes the problem:

*** readr.c.old	Mon Oct 29 10:54:50 1984
--- readr.c	Thu Nov 29 23:50:44 1984
***************
*** 929,934
  			} else
  				if (rfq++ || pflag || cflag)
  					return 1;
  		}
  		if (rflag)
  			bit = ngsize + 1;

--- 929,935 -----
  			} else
  				if (rfq++ || pflag || cflag)
  					return 1;
+ 			break;
  		}
  		if (rflag)
  			bit = ngsize + 1;
***********************************************************

Note: if you run 2.10.2 as distributed with SORTACTIVE set, you will
probably never see this problem, since newly-created groups (the only
groups likely to have 0 articles) get sorted to the front of the active
list.  But if you modify sortactive's compare routine to sort new groups
to the end, or don't define SORTACTIVE at all, you are likely to get
a zero-size group at the end of the list eventually.

	Dave Martindale,
	University of Waterloo