Skip to content

Commit 72f52e0

Browse files
bwp91claude
andcommitted
test: cover camera stream start TLV parsing guards
Adds two RTPStreamManagement tests verifying the try/catch from 3405658: when a /selected-stream-configuration write contains malformed video/audio configuration TLVs (missing fields, undefined buffer reads), `_handleStartStream` must call back with HAPStatus.INVALID_VALUE_IN_REQUEST rather than throwing out of the characteristic write handler. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d87e20e commit 72f52e0

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ All notable changes to `@homebridge/hap-nodejs` will be documented in this file.
1616
- test: cover M1 reset prevention in pair-setup
1717
- test: cover safe accessory lookups in slow/timeout warnings
1818
- test: cover aid.iid format validation
19+
- test: cover camera stream start TLV parsing guards
1920

2021
### Homebridge Dependencies
2122

src/lib/camera/RTPStreamManagement.spec.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
} from "../camera";
2727
import { HDSProtocolSpecificErrorReason } from "../datastream";
2828
import "../definitions";
29+
import { HAPStatus } from "../HAPServer";
2930
import { HAPConnection } from "../util/eventedhttp";
3031
import * as tlv from "../util/tlv";
3132
import * as uuid from "../util/uuid";
@@ -166,6 +167,52 @@ function buildMockConnection(): HAPConnection {
166167
}
167168

168169
describe("RTPStreamManagement", () => {
170+
describe("_handleStartStream malformed TLV (fix 34056583)", () => {
171+
let controller: CameraController;
172+
173+
beforeEach(() => {
174+
controller = new CameraController(buildControllerOptions(baseStreamingOptions));
175+
controller.constructServices();
176+
controller.configureServices();
177+
});
178+
179+
afterEach(() => {
180+
controller.handleFactoryReset();
181+
});
182+
183+
test("empty video configuration should call callback with INVALID_VALUE_IN_REQUEST", () => {
184+
const rtp = controller.streamManagements[0] as RTPStreamManagement;
185+
const callback = jest.fn();
186+
187+
// empty video/audio config — every indexed buffer access (e.g.
188+
// `videoParameters[VideoCodecParametersTypes.PROFILE_ID][0]`) would
189+
// throw without the try/catch from 34056583.
190+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
191+
(rtp as any)._handleStartStream({}, {}, callback);
192+
193+
expect(callback).toHaveBeenCalledTimes(1);
194+
expect(callback.mock.calls[0][0]).toBe(HAPStatus.INVALID_VALUE_IN_REQUEST);
195+
});
196+
197+
test("video configuration missing CODEC_PARAMETERS should not throw", () => {
198+
const rtp = controller.streamManagements[0] as RTPStreamManagement;
199+
const callback = jest.fn();
200+
201+
// SelectedVideoParametersTypes.CODEC_TYPE = 0x01 — provide that but
202+
// omit CODEC_PARAMETERS / ATTRIBUTES / RTP_PARAMETERS so the inner
203+
// `tlv.decode(undefined)` would have crashed without the guard.
204+
const videoConfig = { 0x01: Buffer.from([0x00]) };
205+
206+
expect(() => {
207+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
208+
(rtp as any)._handleStartStream(videoConfig, {}, callback);
209+
}).not.toThrow();
210+
211+
expect(callback).toHaveBeenCalledTimes(1);
212+
expect(callback.mock.calls[0][0]).toBe(HAPStatus.INVALID_VALUE_IN_REQUEST);
213+
});
214+
});
215+
169216
describe("handleSetupEndpoints proxy rejection (fix 0ce74c4e)", () => {
170217
let controller: CameraController;
171218
let setupSpy: jest.SpyInstance;

0 commit comments

Comments
 (0)