--- a/src/chess/rules.c Thu Jul 23 11:37:35 2026 +0200 +++ b/src/chess/rules.c Fri Jul 24 12:42:57 2026 +0200 @@ -337,8 +337,9 @@ static int validate_move_rules(GameState *gamestate, Move *move) { /* validate indices (don't trust opponent) */ - if (!chkidx(move)) { - return INVALID_POSITION; + if (!isidx(move->fromrow) || !isidx(move->fromfile) || + !isidx(move->torow) || !isidx(move->tofile)) { + return INVALID_MOVE_SYNTAX; } /* must move */ @@ -844,8 +845,13 @@ move->piece |= color; - if (!chkidx_to(move)) { - return INVALID_POSITION; + /* up to this point + * destination indices must be specified and valid + * source indices must either be valid or unspecified + */ + if (!isidxr(move->fromrow) || !isidxr(move->fromfile) || + !isidx(move->torow) || !isidx(move->tofile)) { + return INVALID_MOVE_SYNTAX; } return VALID_MOVE_SYNTAX; @@ -858,8 +864,6 @@ if (move->fromfile == POS_UNSPECIFIED || move->fromrow == POS_UNSPECIFIED) { return getlocation(gamestate, move); - } else if (!chkidx_from(move)) { - return INVALID_POSITION; } } return result;