Forráskód Böngészése

Validate file checksums before parsing

Andrew Swistak 6 éve
szülő
commit
a294ff9af3
1 módosított fájl, 31 hozzáadás és 2 törlés
  1. 31 2
      pokemon-parsing/gen7/parse.go

+ 31 - 2
pokemon-parsing/gen7/parse.go

@@ -14,8 +14,8 @@ import (
 // with all applicable fields populated or an error depicting the reason for
 // failure.
 func Parse(rawPokemon p.RawPokemon) (*p.Pokemon, error) {
-	if l := len(rawPokemon); l < 232 {
-		return nil, fmt.Errorf("Invalid length for generation 7 pokemon: %d bytes", l)
+	if err := validateRawPokemon(rawPokemon); err != nil {
+		return nil, err
 	}
 
 	var pkmn p.Pokemon
@@ -97,3 +97,32 @@ func binaryToUTF16leString(b []byte) string {
 
 	return s
 }
+
+func calculateChecksum(b []byte) uint16 {
+	var sum uint16
+	for i := 8; i < 232; i += 2 {
+		sum += toUint16(b[i : i+2])
+	}
+	return sum & 0xffff
+}
+
+func toUint16(b []byte) uint16 {
+	return binary.LittleEndian.Uint16(b)
+}
+
+func validateRawPokemon(rawPokemon p.RawPokemon) error {
+	if l := len(rawPokemon); l != 232 && l != 260 {
+		return fmt.Errorf("Invalid length for generation 7 pokemon: %d bytes", l)
+	}
+
+	checksumValue := toUint16(rawPokemon[0x06:0x08])
+	if calculatedChecksum := calculateChecksum(rawPokemon); calculatedChecksum != checksumValue {
+		return fmt.Errorf("Invalid checksum for generation 7 pokemon")
+	}
+
+	if toUint16(rawPokemon[0x04:0x06]) == 1 || rawPokemon[0x58] == 1 || rawPokemon[0x90] == 1 || rawPokemon[0xc8] == 1 {
+		return fmt.Errorf("Invalid bytes supplied for generation 7 pokemon")
+	}
+
+	return nil
+}