fix(cloud): type-guard EventValidator fields against malformed input

This commit is contained in:
유창욱 2026-07-11 23:46:38 +09:00
parent b5388b2a68
commit 2f88355071
2 changed files with 30 additions and 0 deletions

View file

@ -22,6 +22,16 @@ final class EventValidator
elseif (count($snaps) > 3) $errors[] = 'too_many:snapshots';
else foreach ($snaps as $s) if (!is_string($s)) { $errors[] = 'bad:snapshot_item'; break; }
// Type guards for required fields
if (!is_string($p['device_id'])) $errors[] = 'bad:device_id';
if (!is_string($p['camera_id'])) $errors[] = 'bad:camera_id';
if (!is_numeric($p['occurred_at'])) $errors[] = 'bad:occurred_at';
// Type guards for optional fields
if (isset($p['track_id']) && !is_numeric($p['track_id'])) $errors[] = 'bad:track_id';
if (isset($p['zone_id']) && !is_string($p['zone_id'])) $errors[] = 'bad:zone_id';
if (isset($p['duration_s']) && !is_numeric($p['duration_s'])) $errors[] = 'bad:duration_s';
if ($errors) return ['ok' => false, 'errors' => $errors, 'clean' => []];
$clean = [

View file

@ -31,4 +31,24 @@ final class EventValidatorTest extends TestCase
$p = $this->valid(); $p['snapshots'] = ['a', 'b', 'c', 'd'];
$this->assertFalse(EventValidator::validate($p)['ok']);
}
public function testRejectsNonNumericOccurredAt(): void {
$p = $this->valid(); $p['occurred_at'] = ['bad'];
$this->assertFalse(EventValidator::validate($p)['ok']);
}
public function testRejectsNonStringDeviceId(): void {
$p = $this->valid(); $p['device_id'] = ['x'];
$this->assertFalse(EventValidator::validate($p)['ok']);
}
public function testRejectsNonArraySnapshots(): void {
$p = $this->valid(); $p['snapshots'] = 'notarray';
$this->assertFalse(EventValidator::validate($p)['ok']);
}
public function testRejectsNonStringSnapshotItem(): void {
$p = $this->valid(); $p['snapshots'] = [123];
$this->assertFalse(EventValidator::validate($p)['ok']);
}
public function testRejectsNonStringZoneId(): void {
$p = $this->valid(); $p['zone_id'] = ['z'];
$this->assertFalse(EventValidator::validate($p)['ok']);
}
}