atlet99/dtorrent_tracker_v2

[FEATURE] - Add request parameter validation;

オープン

#12 opened on 2025/11/03

 (0 件のコメント) (0 件のリアクション) (0 人の担当者)Dart (0 件のフォーク)auto 404
enhancementhelp wanted

Repository metrics

Stars
 (0 個のスター)
PR merge metrics
 (30d に merged PR はありません)

説明

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:

  1. port: Must be in range 1-65535
  2. numwant: Should be positive integer, BEP recommends maximum 50
  3. info_hash: Must be exactly 20 bytes
  4. peer_id: Must be exactly 20 bytes (if provided as binary)
  5. compact: Should be 0 or 1
  6. downloaded, 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)

Related Standards

コントリビューターガイド