GNU Chess 5.0.7 Bugs

by Xan Gregg, 2005-12-15
blog entry (for comments)

Below is a list of bugs and suspicious code fragments found in GNU Chess 5.0.7 while porting it to Java. I have previously reported most of these to the GNU Chess mailing list with only a mild response.

Some of these were found by the Java compiler or runtime. I think it says something about the languages that a popular (i.e., one that should have the benefit of “enough eyeballs“) open source C project can have dormant errors that get revealed mechanically by a port to Java.

  1. In BookBuilderOpen() [book.c], there appears to be an unnecessary close()
    of rfp.

        res = read_book(rfp);
        if (res != BOOK_SUCCESS) {
          return res;

    Harmless, I assume.

  2. Also in BookBuilderOpen() [book.c], read_book(wfp) should probably be a read_book(rfp).

        fclose(wfp) ...
        rfp = fopen(BOOKRUN, "rb");
        /* We use read_book() here only to allocate memory */
        if (read_book(wfp) == BOOK_ENOMEM) {
          return BOOK_ENOMEM;

    Looks like writing book files would always produce an error, but maybe the error is ignored by the caller.

  3. In ParseEPD() [EPD.c], there’s a “if (!++p)” that should probably be a “if (!*++p)“. Will prevent the EPD parsing from failing gracefully on certain bad input files.

  4. In ScoreK() [eval.c], need to check that the king isn’t on the last rank
    before looking for pawns in front of the king.
    Causes an array index out of bounds when looking for pawns that are “off the board”. Immediate runtime failure in Java.

  5. InitHashCode() should be called before InitVars() [init.c], because the
    latter makes use of the hashcodes computed by the former.
    Can’t remember how this manifested itself, but any problems would probably get cleared once a New Game command is issued.

  6. Misplaced parenthesis in ValidateMove() [move.c].
       if (piece_id(mvstr[2] != empty)) 

    Looks like moves with the format “AxB” where A and B are piece letters will not be handled correctly, but that’s a rare format these days.

  7. In ValidateMove() [move.c], it redundantly removes certain characters from the move string and then looks for them (and others) in the resultant string for zeroing out.
        * The thing to do now is to clean up the move string.  This
        * gets rid of things like 'x', '+', '=' and so forth.
       p = mvstr;
          if (*s != 'x' && *s != '+' && *s != '=' && !isspace(*s))
             *p++ = *s; 
       } while (*s++ != '\0' );
       /* Flush castles that check */
       if (mvstr[strlen(mvstr)-1] == '+' || mvstr[strlen(mvstr)-1] == '#' ||
           mvstr[strlen(mvstr)-1] == '=') mvstr[strlen(mvstr)-1] = '\000'; 

    Apparently harmless, but I have the Java version just remove the ‘#’ along with thhe other characters so the zeroing out step was unnecessary.

  8. In IsLegalMove() [move.c], need to check that moving a pawn to the 8th rank
    is marked as a promotion.
    Manifested while trying BT2630.epd when the
    move g2-g1 was cached as a “killer” move when it was legal (maybe a rook on
    g2) and considered later when there was a pawn on g2. IsLegalMove()
    let it pass, which caused an array index out of bounds while later
    processing the position with a pawn on the 8th rank (something the evaluator wasn’t prepared to handle).

  9. In PhasePick1() [sort.c], there’s a ‘while‘ that could be an ‘if‘–the body ends with a ‘return‘.
    	 while (p[ply] < TreePtr[ply+1])
                pick (p[ply], ply);
                *p1 = p[ply]++;
                return (true);

    Harmless unless someone really expected it to loop.

  10. About a dozen unused variables or values.
    Harmless unless someone really expected them to be used.

One thought on “GNU Chess 5.0.7 Bugs”

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.