35. 길이 필드 부호 혼동(signed/unsigned)으로 인한 음수 길이 처리 (C#)
난이도 하 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 시나리오: 게임 클라이언트 → 서버 패킷 역직렬화 (C#)
//
// 패킷 페이로드는 [1바이트 필드 개수][각 필드마다: 2바이트 길이][길이만큼의 바이트]
// 형식이다. 길이 필드는 프로토콜 문서상 "부호 없는 16비트(0~65535)"로 정의되어 있다.
//
// 요구사항:
// - 각 필드 길이는 0~65535 범위의 부호 없는 값으로 해석한다.
// - 선언된 길이가 남은 버퍼를 초과하면 잘못된 패킷으로 거부한다.
// - 신뢰할 수 없는 입력이므로 어떤 값이 와도 크래시하지 않아야 한다.
//
// 아래 리더를 검토하라. 표시된 지점 (A)(B).
using System;
using System.Collections.Generic;
public static class FieldReader
{
// buf: 수신 페이로드, off: 시작 오프셋
public static List<byte[]> ParseFields(byte[] buf, int off)
{
var fields = new List<byte[]>();
int fieldCount = buf[off++];
for (int i = 0; i < fieldCount; i++)
{
// (A) 2바이트 길이 읽기 (빅엔디안)
short len = (short)((buf[off] << 8) | buf[off + 1]);
off += 2;
// (B) 길이 검증 후 복사
if (off + len > buf.Length)
throw new InvalidOperationException("잘린 필드");
var data = new byte[len];
Array.Copy(buf, off, data, 0, len);
off += len;
fields.Add(data);
}
return fields;
}
} 결함 코드 · C++
// 시나리오: 게임 클라이언트 → 서버 패킷 역직렬화 (C++)
//
// 패킷 페이로드는 [1바이트 필드 개수][각 필드마다: 2바이트 길이][길이만큼의 바이트]
// 형식이다. 길이 필드는 프로토콜 문서상 "부호 없는 16비트(0~65535)"다.
//
// 요구사항:
// - 각 필드 길이는 0~65535 범위의 부호 없는 값으로 해석한다.
// - 선언된 길이가 남은 버퍼를 초과하면 잘못된 패킷으로 거부한다.
// - 신뢰할 수 없는 입력이므로 어떤 값이 와도 크래시하지 않아야 한다.
//
// 아래 리더를 검토하라. 표시된 지점 (A)(B).
#include <cstdint>
#include <cstddef>
#include <cstring>
#include <vector>
#include <stdexcept>
std::vector<std::vector<std::uint8_t>>
ParseFields(const std::uint8_t* buf, std::size_t len, std::size_t off)
{
std::vector<std::vector<std::uint8_t>> fields;
int fieldCount = buf[off++];
for (int i = 0; i < fieldCount; ++i) {
// (A) 2바이트 길이 읽기 (빅엔디안)
char fieldLen = static_cast<char>((buf[off] << 8) | buf[off + 1]);
off += 2;
// (B) 길이 검증 후 복사
if (off + fieldLen > len)
throw std::runtime_error("잘린 필드");
std::vector<std::uint8_t> data(fieldLen);
std::memcpy(data.data(), buf + off, fieldLen);
off += fieldLen;
fields.push_back(std::move(data));
}
return fields;
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.
내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.