28. 존재 비트맵(presence bitmap) 역직렬화의 경계·예약 비트 검증 결함 (C#)

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 시나리오: 존 서버가 클라이언트로 엔티티 상태 변경(델타)을 보낼 때, 변한 필드만 골라
// 보내려고 "존재 비트맵(presence bitmap)"을 쓴다. 선두 2바이트(16비트) 각 비트가
// "해당 옵션 필드가 이 메시지에 포함됨"을 뜻하고, 켜진 비트 순서대로 각 필드의
// 고정 크기 값이 뒤따른다. 수신 측은 비트맵을 읽고 켜진 필드만 역직렬화한다.
//
// 요구사항:
//   - buf 는 신뢰할 수 없는 네트워크 입력이다(클라/원격이 보냄).
//   - 알려진(정의된) 필드는 인덱스 0..4뿐이고 5..15는 아직 미정의(예약)다.
//   - 잘못된/악의적 입력에도 서버가 안전하게 거부해야 한다(예외로 죽지 않기).
//
// 과제: (A)(B) 지점을 검토하라. 어떤 입력에서 버퍼 밖을 읽거나 예약 비트를
//       잘못 처리하는지 밝히고, 안전하게 거부/파싱하도록 고쳐라.

using System;

public struct EntityState
{
    public int    Hp;
    public float  X, Y;
    public ushort BuffMask;
    public byte   Level;
}

public sealed class StateReader
{
    public const int Fields = 16;
    // 정의된 필드는 0..4(크기 4,4,4,2,1), 5..15는 미정의(0)
    private static readonly int[] FieldSize =
        { 4,4,4,2,1, 0,0,0,0,0,0,0,0,0,0,0 };

    public bool Parse(byte[] buf, out EntityState outState)
    {
        outState = default;
        int cur = 0;
        ushort mask = (ushort)(buf[0] | (buf[1] << 8));   // 선두 2바이트 = 비트맵
        cur += 2;
        for (int i = 0; i < Fields; i++)
        {
            if ((mask & (1 << i)) != 0)
            {
                int sz = FieldSize[i];                    // (B)
                ApplyField(ref outState, i, buf, cur, sz);// (A)
                cur += sz;
            }
        }
        return true;
    }

    private static void ApplyField(ref EntityState s, int i, byte[] buf, int off, int sz)
    {
        switch (i)
        {
            case 0: s.Hp       = BitConverter.ToInt32(buf, off);  break;
            case 1: s.X        = BitConverter.ToSingle(buf, off); break;
            case 2: s.Y        = BitConverter.ToSingle(buf, off); break;
            case 3: s.BuffMask = BitConverter.ToUInt16(buf, off); break;
            case 4: s.Level    = buf[off];                        break;
            default: break;   // 미정의 필드
        }
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.