Validation

Robot validation and security checks.

Robot Validator

class linkforge.core.RobotValidator(checks=None)[source]

Bases: object

Validates robot structure for URDF export and simulation.

Runs a configurable registry of ValidationCheck instances. By default, all standard checks run in dependency order. Callers can pass a custom list to run only a specific subset of validation rules.

Example

>>> from linkforge.core.models import Robot, Link
>>> from linkforge.core import RobotValidator
>>> robot = Robot(name="test_robot")
>>> robot.add_link(Link(name="base_link"))
>>> # Validating a robot
>>> result = RobotValidator().validate(robot)
>>> if result.is_valid:
...     print("Robot is valid!")
... else:
...     print(f"Found {result.error_count} errors")
Parameters:

checks (list[ValidationCheck] | None)

DEFAULT_CHECKS: list[type[ValidationCheck]] = [<class 'linkforge.core.validation.checks.HasLinksCheck'>, <class 'linkforge.core.validation.checks.DuplicateNameCheck'>, <class 'linkforge.core.validation.checks.JointReferenceCheck'>, <class 'linkforge.core.validation.checks.TreeStructureCheck'>, <class 'linkforge.core.validation.checks.MassPropertiesCheck'>, <class 'linkforge.core.validation.checks.GeometryCheck'>, <class 'linkforge.core.validation.checks.Ros2ControlCheck'>, <class 'linkforge.core.validation.checks.MimicChainCheck'>, <class 'linkforge.core.validation.checks.SemanticCheck'>, <class 'linkforge.core.validation.checks.SemanticConsistencyCheck'>]
__init__(checks=None)[source]

Initialize validator.

Parameters:

checks (list[ValidationCheck] | None) – Optional custom list of check instances to run. Defaults to DEFAULT_CHECKS (all standard checks).

validate(robot)[source]

Run all registered validation checks on a robot model.

Parameters:

robot (Robot) – The Robot model instance to validate.

Return type:

ValidationResult

Returns:

ValidationResult containing all errors and warnings.

Validation Result

class linkforge.core.ValidationResult(issues=<factory>, robot_name='')[source]

Bases: object

Result of robot validation.

Parameters:
  • issues (list[ValidationIssue])

  • robot_name (str)

issues: list[ValidationIssue]
robot_name: str = ''
property errors: list[ValidationIssue]

Get only errors.

property warnings: list[ValidationIssue]

Get only warnings.

property is_valid: bool

Check if validation passed (no errors).

Note: Warnings don’t block validity.

property has_warnings: bool

Check if there are any warnings.

property error_count: int

Number of errors.

property warning_count: int

Number of warnings.

add_error(title, message, affected_objects=None, suggestion=None, code=None, auto_fix=None)[source]

Add an error to the validation result.

Parameters:
Return type:

None

add_warning(title, message, affected_objects=None, suggestion=None, code=None, auto_fix=None)[source]

Add a warning to the validation result.

Parameters:
Return type:

None

__str__()[source]

String representation.

Return type:

str

__init__(issues=<factory>, robot_name='')
Parameters:
  • issues (list[ValidationIssue])

  • robot_name (str)

Security

Security validation functions for robot model parsing.

This module provides security checks to prevent malicious robot description files from accessing unauthorized file system locations or causing other security issues.

linkforge.core.validation.security.validate_mesh_path(mesh_filepath, source_directory, allow_absolute=False, sandbox_root=None)[source]

Validate that a mesh file path is safe to access.

This function prevents path traversal attacks by ensuring that mesh paths stay within the robot model’s directory or its subdirectories.

Security Note: Absolute paths are discouraged for portability and security. Use allow_absolute=True only when loading trusted robot description files.

Parameters:
  • mesh_filepath (Path) – The mesh file path from the URDF (may be relative or absolute)

  • source_directory (Path) – The directory containing the robot model file

  • allow_absolute (bool) – If True, allows absolute paths (default: False for security)

  • sandbox_root (Path | None) – The root directory for the sandbox. If None, source_directory is used. Access is restricted to files within this root and its subdirectories.

Return type:

Path

Returns:

The validated absolute path to the mesh file

Raises:
linkforge.core.validation.security.is_suspicious_location(path)[source]

Check if a path resolves to a suspicious system location.

Parameters:

path (Path)

Return type:

bool

linkforge.core.validation.security.validate_package_uri(uri)[source]

Validate a ROS package:// URI.

Parameters:

uri (str) – The package URI to validate (e.g., “package://my_robot/meshes/arm.stl”)

Return type:

str

Returns:

The validated URI

Raises:

RobotSecurityError – If the URI is malformed or contains suspicious components

linkforge.core.validation.security.find_sandbox_root(filepath)[source]

Find a sensible sandbox root for a given file.

For robotics projects, this frequently means going up one level if the file is inside a robot model folder (e.g., ‘urdf’ or ‘xacro’), or searching for a package.xml.

Parameters:

filepath (Path) – Path to the robot model file (URDF, XACRO, etc.)

Return type:

Path

Returns:

The detected sandbox root Path

Usage Examples

Validate Robot

from linkforge.core import RobotValidator

validator = RobotValidator()
result = validator.validate(robot)

if result.is_valid:
    print(" Robot is valid!")
else:
    print(" Validation errors:")
    for error in result.errors:
        print(f"  - {error}")

    print("\nWarnings:")
    for warning in result.warnings:
        print(f"  - {warning}")

Security Checks

from linkforge.core.validation import validate_mesh_path, find_sandbox_root
from linkforge.core import RobotSecurityError
from pathlib import Path

# Validate mesh path (prevents path traversal)
try:
    validate_mesh_path(Path("../../etc/passwd"), Path("/tmp"))  # Raises RobotSecurityError
except RobotSecurityError as e:
    print(f"Security error: {e}")

# Valid paths within sandbox
urdf_dir = Path("/my_robot/urdf")
validate_mesh_path(Path("meshes/robot.stl"), urdf_dir)  # OK

# Auto-detect sandbox root for sibling folder access
urdf_file = Path("/my_robot/urdf/robot.urdf")
sandbox = find_sandbox_root(urdf_file)  # Returns /my_robot
validate_mesh_path(Path("../meshes/part.stl"), urdf_dir, sandbox_root=sandbox)  # OK

Validation Checks

The validator performs the following checks:

Structure Validation

  • Robot has a name

  • At least one link exists

  • All links have unique names

  • All joints have unique names

  • Tree structure is valid (no cycles, single root)

Joint Validation

  • Parent and child links exist

  • Joint limits are valid (lower ≤ upper)

  • Axis is non-zero for revolute/prismatic joints

  • Mimic joints reference existing joints

Sensor Validation

  • Sensors are attached to existing links

  • Sensor-specific info is provided

  • Update rates are positive

Security Validation

  • Mesh paths don’t escape the sandbox root

  • Sandbox root auto-detection for sibling folders

  • Numeric values are within safe ranges

  • XML depth is limited (prevents XML bombs)