Overview
tc-lib-file provides low-level file access and byte-reading primitives used by higher-level PDF and document libraries.
The package is intentionally small but critical: it centralizes stream safety and binary handling so dependent components can focus on document semantics instead of reimplementing I/O details.
Repository and API Docs
- GitHub: https://github.com/tecnickcom/tc-lib-file
- API docs: https://tcpdf.org/docs/srcdoc/tc-lib-file
- Packagist: https://packagist.org/packages/tecnickcom/tc-lib-file
Project Metadata
| Item | Value |
|---|---|
| Namespace | \Com\Tecnick\File |
| License | GNU LGPL v3 |
Installation
composer require tecnickcom/tc-lib-file
Where It Fits
Adopt this package when inputs may come from filesystem paths, inline data URIs, or mixed source abstractions.
Features
File Access
- Local and URL-backed file reading helpers
- Path-safety checks for local operations
- cURL-based retrieval options for remote resources
Binary Utilities
- Byte, integer, and structured binary reads
- Helpers used by parser and image/font import stacks
- Error handling through typed exceptions
Security Configuration (Required)
File defaults to strict-deny behavior for both host and path validation:
allowedHostsdefaults to an empty array, so remote URLs and host-based alternate path resolution are rejected unless you explicitly trust hosts.allowedPathsdefaults to an empty array, so local file operations are rejected unless you explicitly trust path prefixes.
Always pass explicit allowlists in the constructor (or set them immediately through the setters) in production:
$file = new \Com\Tecnick\File\File(
allowedHosts: ['example.com'],
allowedPaths: ['/srv/my-app/data'],
);
// Equivalent runtime configuration:
$file
->setAllowedHosts(['example.com'])
->setAllowedPaths(['/srv/my-app/data']);
Avoid wildcard trust ('*') unless you fully control every input and deployment boundary.
Redirect Handling
Redirect validation is driven by CURLOPT_MAXREDIRS:
CURLOPT_MAXREDIRS => 0(default): no redirect-follow validation callback is installed.CURLOPT_MAXREDIRS > 0: redirects are followed and eachLocationtarget is validated againstallowedHosts.
$file = new \Com\Tecnick\File\File(
allowedHosts: ['example.com', 'downloads.example.com'],
curlopts: [
CURLOPT_MAXREDIRS => 5,
],
);
Cross-Platform Path Handling
The library runs on Linux, macOS, and Windows, and path validation adapts to the host filesystem:
- Allowlist matching follows the filesystem case rules: case-sensitive on Linux, case-insensitive on Windows, and per-volume on macOS (the library probes the volume and falls back to case-insensitive when it cannot). Override with the
caseSensitivePathsconstructor argument orsetCaseSensitivePaths()when auto-detection is wrong for your deployment:
$file = new \Com\Tecnick\File\File(
allowedPaths: ['/srv/my-app/data'],
caseSensitivePaths: true, // or false; null (default) = auto-detect
);
// Equivalent runtime configuration:
$file->setCaseSensitivePaths(true);
- On macOS, paths are normalized to NFC before comparison when
ext-intlis installed, so composed and decomposed Unicode names match consistently; withoutext-intlthe comparison degrades to a byte comparison. fopenLocal()forces the binary stream flag, so byte-level reads are not altered by Windows text-mode CRLF translation.- Windows 8.3 short names, Alternate Data Streams, trailing dots/spaces, and reserved device names are intentionally not treated as canonical; UNC paths match only when explicitly allowlisted.
Requirements
- PHP 8.2 or later
- Extensions:
curl,pcre - Optional extension:
intl(enables Unicode NFC normalization when matching paths against the allowlist) - Composer
Development and Packaging
- QA and local checks:
make deps,make help,make qa - Packaging:
make rpm,make deb
Support and Contribution
- Sponsor: https://github.com/sponsors/tecnickcom
- Contribution guide: https://github.com/tecnickcom/tc-lib-file/blob/main/CONTRIBUTING.md
- Security policy: https://github.com/tecnickcom/tc-lib-file/blob/main/SECURITY.md
Integration Notes
- Whitelist accepted schemes and paths before loading untrusted references.
- Centralize asset resolution in one adapter to simplify auditing and testing.
- Validate MIME assumptions before embedding assets.
Example
<?php
require_once __DIR__ . '/vendor/autoload.php';
$file = new \Com\Tecnick\File\File(
allowedHosts: ['example.com', 'cdn.example.com'],
allowedPaths: [__DIR__, '/var/app/uploads'],
curlopts: [
CURLOPT_MAXREDIRS => 3,
],
);
$fh = $file->fopenLocal(__FILE__, 'rb');
$header = $file->fReadInt($fh);
var_dump($header);