atlet99/dtorrent_tracker_v2
[FEATURE] - Add request parameter validation;
Aperta
#12 aperta il 3 nov 2025
enhancementhelp wanted
Metriche repository
- Star
- (0 stelle)
- Metriche merge PR
- (Nessuna PR mergiata in 30 g)
Descrizione
Description
There is no validation of input parameters before sending tracker requests. Invalid parameters (e.g., out-of-range ports, incorrect data lengths) can be sent to trackers, leading to errors or unexpected behavior.
Location
Files:
lib/src/tracker/http_tracker.dart(method:generateQueryParameters)lib/src/tracker/udp_tracker.dart(method:generateSecondTouchMessage)lib/src/tracker/tracker.dart(constructor validation)
Current Code
Parameters are used directly without validation:
// HTTP tracker - no validation
params['port'] = options['port'].toString();
params['numwant'] = options['numwant'].toString();
// UDP tracker - no validation
list.addAll(num2Uint32List(options['numwant']));
list.addAll(num2Uint16List(options['port']));
Expected Behavior
Validate all input parameters according to BEP specifications:
port: Must be in range 1-65535numwant: Should be positive integer, BEP recommends maximum 50info_hash: Must be exactly 20 bytespeer_id: Must be exactly 20 bytes (if provided as binary)compact: Should be 0 or 1downloaded,uploaded,left: Should be non-negative integers
Invalid parameters should throw clear, descriptive exceptions.
Proposed Implementation
Constructor Validation
Tracker(this.id, this.announceUrl, this.infoHashBuffer, {this.provider}) {
// Validate info_hash length
if (infoHashBuffer.length != 20) {
throw ArgumentError.value(
infoHashBuffer.length,
'infoHashBuffer',
'Info hash must be exactly 20 bytes',
);
}
}
HTTP Tracker Validation
@override
Map<String, String> generateQueryParameters(Map<String, dynamic> options) {
// Validate port
var port = options['port'] as int?;
if (port == null || port < 1 || port > 65535) {
throw ArgumentError.value(
port,
'port',
'Port must be in range 1-65535',
);
}
// Validate numwant
var numwant = options['numwant'] as int? ?? 50;
if (numwant < 0 || numwant > 50) {
throw ArgumentError.value(
numwant,
'numwant',
'numwant must be between 0 and 50 (BEP recommendation)',
);
}
// Validate peer_id length if provided as binary
var peerId = options['peerId'];
if (peerId is Uint8List && peerId.length != 20) {
throw ArgumentError.value(
peerId.length,
'peerId',
'Peer ID must be exactly 20 bytes',
);
}
// Validate downloaded/uploaded/left are non-negative
var downloaded = options['downloaded'] as int? ?? 0;
var uploaded = options['uploaded'] as int? ?? 0;
var left = options['left'] as int? ?? 0;
if (downloaded < 0 || uploaded < 0 || left < 0) {
throw ArgumentError(
'downloaded, uploaded, and left must be non-negative integers',
);
}
// ... rest of implementation ...
}
UDP Tracker Validation
Similar validation in generateSecondTouchMessage:
@override
Uint8List generateSecondTouchMessage(Uint8List connectionId, Map options) {
// Validate port
var port = options['port'] as int?;
if (port == null || port < 1 || port > 65535) {
throw ArgumentError.value(port, 'port', 'Port must be in range 1-65535');
}
// Validate numwant
var numwant = options['numwant'] as int? ?? 50;
if (numwant < 0 || numwant > 50) {
throw ArgumentError.value(numwant, 'numwant', 'numwant must be 0-50');
}
// Validate peer_id length
var peerId = options['peerId'];
if (peerId is String && peerId.length != 20) {
throw ArgumentError.value(peerId.length, 'peerId', 'Peer ID must be 20 bytes');
}
// ... rest of implementation ...
}
Impact
- Severity: Medium (Quality Improvement)
- Affected: All tracker requests
- Benefits:
- Prevents sending invalid requests to trackers
- Clear error messages for debugging
- Better compliance with BEP specifications
- Catches errors early (fail-fast principle)
Additional Context
Parameter validation should happen:
- Early (in constructors/methods that accept parameters)
- With clear error messages
- According to BEP specifications
- Without breaking backward compatibility (use sensible defaults)