Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
edfa9da
Generate a spec using Kiro for custom CRC params
onethumb Jul 4, 2025
76355ff
Update stub file (Kiro Task 1)
onethumb Jul 4, 2025
d362d66
Regenerate arginfo file from updated stub (Task 2)
onethumb Jul 4, 2025
a0a6b8e
Implement CrcFast\Params class in C extension (Task 3)
onethumb Jul 4, 2025
07c1faf
Update existing functions to support custom parameters
onethumb Jul 4, 2025
dc18767
Use container_of instead of XtOffsetOf
onethumb Jul 6, 2025
de1852a
Merge branch 'main' into add-custom-parameter-support
onethumb Jul 6, 2025
6fdfdc3
Update CrcFast\Digest class to support custom parameters
onethumb Jul 6, 2025
fa3d67b
Add steering commands for Kiro
onethumb Jul 6, 2025
1c17397
Update steering docs to improve testing strategies
onethumb Jul 6, 2025
1ba7835
Add comprehensive error handling (Task 6)
onethumb Jul 6, 2025
9aacc42
Create unit tests for CrcFast\Params class
onethumb Jul 8, 2025
6952345
Update steering docs
onethumb Jul 8, 2025
399e966
Test CrcFast\hash() with custom parameters
onethumb Jul 8, 2025
ed3d6ea
Test CrcFast\hash_file() with custom parameters
onethumb Jul 8, 2025
fa4a797
Test CrcFast\combine() with custom parameters
onethumb Jul 8, 2025
c61dbfa
Test CrcFast\Digest class with custom parameters
onethumb Jul 8, 2025
7399b9f
Create backward compatibility tests
onethumb Jul 9, 2025
326f07a
Build and test extension
onethumb Jul 9, 2025
7e1d9ba
Fix build warnings for zend_long format specifiers
onethumb Jul 9, 2025
9961501
WIP. Fix keys storage.
onethumb Nov 9, 2025
78aa9e7
WIP. Use container_of/offsetof instead of XOffsetOf
onethumb Nov 9, 2025
9bf3674
WIP. Fix inconsistent format specifier
onethumb Nov 9, 2025
f74fcda
Add .vscode to .gitignore
onethumb Nov 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ tmp-php.ini
.idea
*~
vendor
scratch
scratch
.vscode
205 changes: 205 additions & 0 deletions .kiro/specs/custom-crc-parameters/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# Design Document

## Overview

This design extends the existing PHP CRC extension to support custom CRC parameters while maintaining full backward compatibility. The underlying crc_fast library has been updated with custom parameter support through the `CrcFastParams` struct and related functions. We will expose this functionality through a new `CrcFast\Params` class and extend existing functions to accept either algorithm constants or custom parameter objects.

## Architecture

### Core Components

1. **CrcFast\Params Class**: A new PHP class that wraps the C `CrcFastParams` struct
2. **Extended Function Signatures**: Modify existing functions to accept both `int` (algorithm constants) and `CrcFast\Params` objects
3. **Helper Functions**: Add utility functions for creating custom parameters from Rocksoft model parameters
4. **Backward Compatibility Layer**: Ensure all existing code continues to work without modification

### Design Principles

- **Backward Compatibility**: All existing APIs must continue to work exactly as before
- **Type Safety**: Use PHP's type system to validate parameters at runtime
- **Performance**: Custom parameters should not impact performance of predefined algorithms
- **Consistency**: Custom parameters should work seamlessly with all existing functions

## Components and Interfaces

### CrcFast\Params Class

```php
namespace CrcFast {
class Params {
public function __construct(
int $width,
int $poly,
int $init,
bool $refin,
bool $refout,
int $xorout,
int $check,
?array $keys = null // Optional array of 23 pre-computed keys for performance
);

public function getWidth(): int;
public function getPoly(): int;
public function getInit(): int;
public function getRefin(): bool;
public function getRefout(): bool;
public function getXorout(): int;
public function getCheck(): int;
public function getKeys(): array; // Returns the keys (generated if not provided in constructor)
}
}
```

### Direct Parameter Construction

Users can directly create custom CRC parameters using the `CrcFast\Params` constructor. The constructor accepts the standard Rocksoft model parameters and automatically handles the conversion internally, including generating the required keys.

### Extended Function Signatures

All existing functions will be modified to accept `int|CrcFast\Params` for the algorithm parameter:

```php
namespace CrcFast {
function hash(int|Params $algorithm, string $data, bool $binary = false): string;
function hash_file(int|Params $algorithm, string $filename, bool $binary = false): string;
function combine(int|Params $algorithm, string $checksum1, string $checksum2, int $length2, bool $binary = false): string;

class Digest {
public function __construct(int|Params $algorithm);
// ... other methods remain unchanged
}
}
```

## Data Models

### PHP CrcFast\Params Object Structure

```c
typedef struct _php_crc_fast_params_obj {
CrcFastParams params; // C struct from libcrc_fast.h
zend_object std;
} php_crc_fast_params_obj;
```

### Parameter Validation Rules

- **Width**: Must be 32 or 64 bits (the only widths supported by the crc_fast library)
- **Polynomial**: Must fit within the specified width
- **Init/Xorout**: Must fit within the specified width
- **Check**: Used for validation - computed checksum of "123456789" must match this value
- **Keys**: If provided, must be an array of exactly 23 integer values. If null, keys will be computed on-demand by the C library

## Error Handling

### Parameter Validation Errors

- **InvalidArgumentException**: For invalid parameter values (width, polynomial out of range)
- **ValueError**: For parameters that don't produce the expected check value
- **TypeError**: For incorrect parameter types in function calls

### Runtime Errors

- **RuntimeException**: For memory allocation failures or C library errors
- **Exception**: For general digest operation failures

### Error Messages

All error messages will be descriptive and indicate:
- Which parameter is invalid
- What the valid range/values are
- How to correct the issue

## Testing Strategy

### Unit Tests

1. **Parameter Validation Tests**
- Valid parameter combinations
- Invalid parameter combinations
- Edge cases (min/max values)

2. **Functionality Tests**
- Custom parameters with hash() function
- Custom parameters with hash_file() function
- Custom parameters with combine() function
- Custom parameters with Digest class

3. **Backward Compatibility Tests**
- All existing tests must continue to pass
- Existing code patterns must work unchanged

4. **Integration Tests**
- Custom parameters producing known checksums
- Rocksoft model parameter conversion
- Cross-validation with reference implementations

### Test Data

- Use well-known CRC algorithms as test cases (e.g., CRC-32/ISCSI, CRC-32/ISO-HDLC, CRC-64/NVME)
- Include edge cases for both width=32 and width=64
- Test both reflected and non-reflected algorithms
- Validate custom parameters by recreating existing predefined algorithms and comparing results

## Implementation Details

### C Extension Changes

1. **New Object Type**: Add `php_crc_fast_params_obj` structure and handlers
2. **Parameter Detection**: Add helper functions to detect if parameter is int or Params object
3. **C Struct Conversion**: Convert PHP Params object to C `CrcFastParams` struct
4. **Function Overloading**: Modify existing functions to handle both parameter types

### Memory Management

- **Params Objects**: Standard PHP object lifecycle management
- **C Structs**: Stack-allocated `CrcFastParams` structs for function calls
- **Digest Objects**: Extended to store either algorithm constant or custom parameters

### Performance Considerations

- **Fast Path**: Predefined algorithms use existing fast path with `crc_fast_digest_new()`
- **Custom Path**: Custom parameters use `crc_fast_digest_new_with_params()` and related functions
- **Validation**: Validate parameters once during PHP object creation
- **Key Pre-computation**: When keys are provided in constructor, they are used directly for optimal performance. When keys are null, they are computed once during object creation and stored in the C struct
- **Key Reuse**: The C library handles key management internally - once computed, keys are reused for all operations on that digest

## Backward Compatibility Guarantees

### API Compatibility

- All existing function signatures remain valid
- All existing constants remain unchanged
- All existing behavior is preserved exactly

### Binary Compatibility

- Extension version will be incremented appropriately
- No breaking changes to existing compiled code
- Graceful handling of version mismatches

### Migration Path

- Existing code requires no changes
- New functionality is opt-in only
- Clear documentation for adopting custom parameters

## Security Considerations

### Input Validation

- All custom parameters are validated before use
- Polynomial values are checked for validity
- Width constraints are enforced strictly

### Memory Safety

- All C struct operations are bounds-checked
- PHP object lifecycle prevents use-after-free
- Error handling prevents undefined behavior

### Resource Limits

- Custom parameter objects have reasonable memory footprint
- No unbounded resource allocation
- Proper cleanup on errors
72 changes: 72 additions & 0 deletions .kiro/specs/custom-crc-parameters/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Requirements Document

## Introduction

This feature extends the existing PHP CRC extension to support custom CRC parameters, allowing users to define their own CRC algorithms beyond the predefined set. The underlying crc_fast library has been updated with custom parameter support, and we need to expose this functionality through the PHP extension while maintaining full backward compatibility with existing APIs.

## Requirements

### Requirement 1

**User Story:** As a PHP developer, I want to create custom CRC algorithms with specific parameters, so that I can calculate checksums for proprietary or specialized CRC variants not included in the predefined algorithms.

#### Acceptance Criteria

1. WHEN a user provides custom CRC parameters (width, polynomial, init, refin, refout, xorout, check) THEN the system SHALL create a custom CRC algorithm instance
2. WHEN custom parameters are invalid (e.g., unsupported width) THEN the system SHALL throw a descriptive exception
3. WHEN custom parameters are valid THEN the system SHALL allow all existing operations (hash, hash_file, combine, Digest class) to work with the custom algorithm
4. IF custom parameters match a predefined algorithm THEN the system SHALL still function correctly without optimization requirements

### Requirement 2

**User Story:** As a PHP developer, I want to use a helper function to create custom CRC parameters from Rocksoft model parameters, so that I can easily convert standard CRC specifications into the required parameter format.

#### Acceptance Criteria

1. WHEN a user provides Rocksoft model parameters (name, width, poly, init, reflected, xorout, check) THEN the system SHALL return a custom CRC parameter object
2. WHEN Rocksoft parameters are invalid THEN the system SHALL throw a descriptive exception
3. WHEN the helper function is called THEN the system SHALL validate all parameters before creating the custom parameter object

### Requirement 3

**User Story:** As a PHP developer, I want all existing CRC functions to accept custom parameter objects, so that I can use custom algorithms seamlessly with the current API.

#### Acceptance Criteria

1. WHEN CrcFast\hash() receives a custom parameter object instead of an algorithm constant THEN the system SHALL calculate the checksum using the custom algorithm
2. WHEN CrcFast\hash_file() receives a custom parameter object THEN the system SHALL calculate the file checksum using the custom algorithm
3. WHEN CrcFast\combine() receives a custom parameter object THEN the system SHALL combine checksums using the custom algorithm
4. WHEN the Digest class constructor receives a custom parameter object THEN the system SHALL create a digest instance for the custom algorithm

### Requirement 4

**User Story:** As a PHP developer, I want the extension to maintain backward compatibility, so that my existing code continues to work without modifications after the update.

#### Acceptance Criteria

1. WHEN existing code uses predefined algorithm constants THEN the system SHALL continue to work exactly as before
2. WHEN existing function signatures are used THEN the system SHALL maintain the same behavior and return types
3. WHEN existing class methods are called THEN the system SHALL maintain the same behavior and return types
4. IF new functionality is added THEN the system SHALL not break any existing functionality

### Requirement 5

**User Story:** As a PHP developer, I want proper error handling for custom parameters, so that I can debug issues with my custom CRC configurations.

#### Acceptance Criteria

1. WHEN invalid custom parameters are provided THEN the system SHALL throw specific exceptions with clear error messages
2. WHEN custom parameter validation fails THEN the system SHALL indicate which parameter is invalid and why
3. WHEN custom algorithms fail during computation THEN the system SHALL provide meaningful error information
4. WHEN memory allocation fails for custom algorithms THEN the system SHALL handle the error gracefully

### Requirement 6

**User Story:** As a PHP developer, I want the stub file to remain the source of truth for the API, so that the extension maintains consistency with PHP's standard practices.

#### Acceptance Criteria

1. WHEN API changes are made THEN the system SHALL update the stub file first
2. WHEN the arginfo file needs updates THEN the system SHALL regenerate it from the stub file
3. WHEN new functions or classes are added THEN the system SHALL define them in the stub file
4. WHEN documentation is updated THEN the system SHALL update it in the stub file
Loading