build(deps-dev): bump squizlabs/php_codesniffer to 3.13.6 (CVE-2026-67434) Clears the Dependabot alert for GHSA-hmqg-cxww-wqhq. PHP_CodeSniffer before 3.13.6 is vulnerable to command injection in the Gitblame, Hgblame and Svnblame reports when a scanned filename contains shell metacharacters (CWE-78, CVSS 4.0 7.3). Exposure in this repo was nil: php_codesniffer is a dev-only dependency, none of its code ships in the released package, and neither CI nor .phpcs.xml uses any of the affected *blame reports. Bumping anyway so the advisory is closed at the source. Verified on 3.13.6: phpcs clean over 52 files, full suite green (1889 tests, 4359 assertions), composer audit reports no advisories.
Recent Commits to Mobile-Detect
-
build(deps-dev): bump squizlabs/php_codesniffer to 3.13.6 (CVE-2026-6…
-
fix(cache): bound in-memory Cache to prevent unbounded growth (GHSA-m…
fix(cache): bound in-memory Cache to prevent unbounded growth (GHSA-mgj4-qjmw-v56v) The bundled Detection\Cache\Cache is now bounded by default (1000 entries, FIFO eviction). Prevents unbounded in-memory growth when one MobileDetect instance is reused across many distinct User-Agents in a long-running PHP runtime (RoadRunner, Laravel Octane, FrankenPHP worker mode, Swoole, ReactPHP, queue workers). Classic PHP-FPM / mod_php deployments are not affected (cache dies with the request). Custom PSR-16 adapters (Redis, APCu, Memcached, Filesystem) are unaffected; their eviction policy is the operator's responsibility. The README "Long-Running Processes" worker example now uses clear() instead of evictExpired() — the latter is a no-op against fresh entries under the default 86400s TTL and was misleading users into thinking it bounded the cache by cardinality. - Cache::__construct(int $maxEntries = Cache::DEFAULT_MAX_ENTRIES) - Cache::getMaxEntries() accessor - evictExpired() docblock clarified (bounds by TTL only, not cardinality) - Regression tests in CacheTest + MobileDetectWithCacheTest mirroring the advisory PoC - README-EXAMPLES.md "Long-Running Processes" rewritten - Version bumped to 4.11.0
-
perf(bench): overhaul phpbench suite + advisory CI + release hygiene …
perf(bench): overhaul phpbench suite + advisory CI + release hygiene (#1015)
-
docs(known-limitations): add full-page edge cache incompatibility note
docs(known-limitations): add full-page edge cache incompatibility note Documents that CDN / page-cache layers serving cached HTML without varying on User-Agent defeat server-side detection. Cites the canonical reports (#980 WP Engine, #447 W3 Total Cache, #945 Cloudflare SXG) and lists host-side mitigations.
-
docs(readme): point 2.x/3.x Tests badges at the renamed workflows
docs(readme): point 2.x/3.x Tests badges at the renamed workflows
-
docs(readme): restore badge links, add packagist version + workflow b…
docs(readme): restore badge links, add packagist version + workflow badges - Wrap header badges in links (build, packagist version, latest tag, downloads, license); add packagist stable-version badge; pin the build badge to branch=4.x with a 'build' label. - Re-add per-row Tests badges and branch links in the versions table.
-
chore(release): 4.10.0
chore(release): 4.10.0 - Bump $VERSION / @version / MobileDetect.json to 4.10.0. - composer.json: require PHP >=8.2 (was >=8.0); PHP 8.0/8.1 are EOL and dev install has required 8.2+ since 4.9.0. - README: reflect the PHP 8.2 floor in the 4.* row. - CHANGELOG: 4.10.0 entry (PSR-16 LSP compat, PHP floor bump, BC note).
-
Merge pull request #1014 from serbanghita/fix/989-psr16-v1-compat
Merge pull request #1014 from serbanghita/fix/989-psr16-v1-compat fix(cache): restore PSR-16 v1/v2 LSP compatibility (#989) Widens Cache public method signatures to match psr/simple-cache v1/v2 as well as v3. This keeps the class loadable in hosts where another plugin has already registered an older CacheInterface (typical in WordPress stacks). Runtime validation is preserved via the new checkKey/checkTtl/checkIterable helpers. - composer: psr/simple-cache constraint widened to '^1.0 || ^2.0 || ^3.0' - CI: new psr16-compat matrix verifies LSP on all three majors.
-
chore: adopt rolling 4.x branch scheme (one branch per major)
chore: adopt rolling 4.x branch scheme (one branch per major) - Branches 2.8.x, 3.74.x, 4.9.x renamed on origin to 2.x, 3.x, 4.x. - Rename .github/workflows/4.9.x-test.yml -> 4.x-test.yml; update branch triggers and workflow name. - README: single row per major (Version, Namespace, Branch, PHP, Purpose). - CLAUDE.md: document the rolling branch convention.
-
ci: auto-publish GitHub Release on tag push
ci: auto-publish GitHub Release on tag push Triggered by tags matching a numeric version pattern (e.g. 4.9.1, 4.9.0-rc1). Uses gh release create --generate-notes to draft the body from merged PRs since the previous tag. Release body can be edited post-publish if CHANGELOG-derived notes are preferred.
-
docs(readme): add 4.9.x row, mark 4.8.x as maintenance, update main C…
docs(readme): add 4.9.x row, mark 4.8.x as maintenance, update main CI badge
-
chore: open 4.9.x line (bump to 4.9.1-dev, rename workflow, update docs)
chore: open 4.9.x line (bump to 4.9.1-dev, rename workflow, update docs) - Rename .github/workflows/4.8.x-test.yml -> 4.9.x-test.yml; update branch triggers and workflow name. - Update CLAUDE.md: active branch is now 4.9.x. - Backfill 4.9.0 CHANGELOG entry. - Bump @version, $VERSION, MobileDetect.json to 4.9.1-dev.
-
chore(release): 4.9.0
chore(release): 4.9.0
-
ci(psr16-compat): drop redundant composer install step
ci(psr16-compat): drop redundant composer install step composer require --update-with-dependencies performs a full resolve and install on a fresh checkout, so the prior composer install just did the work twice. Rename the remaining step to be honest about installing.
-
fix(test): drop orphan phpstan-ignore on widened Cache signatures
fix(test): drop orphan phpstan-ignore on widened Cache signatures PSR-16 LSP fix loosened get/set/*Multiple parameter types, so passing non-string/non-iterable values is no longer a static type error. PHPStan flags the five @phpstan-ignore-next-line directives as ignore.unmatchedLine, failing the quality job.
-
fix(cache): restore PSR-16 v1/v2 LSP compatibility (#989)
fix(cache): restore PSR-16 v1/v2 LSP compatibility (#989) Widen Cache public method parameters to omit scalar type declarations so the class is LSP-compatible with any psr/simple-cache major. Previously, when another plugin's autoloader (common in WordPress) registered an older Psr\SimpleCache\CacheInterface before ours, PHP fatal'd at class load because our narrower signatures violated variance rules. - Drop param types on $key, $ttl, $keys, $values in public methods; validate at runtime via checkKey/checkTtl/checkIterable helpers. - Return types are preserved (covariance-safe). - Broaden composer.json to "^1.0 || ^2.0 || ^3.0" so transitive deps can resolve any supported major without conflict. - Add CI matrix job that runs the test suite against psr/simple-cache ^1.0, ^2.0, and ^3.0 so a future interface change that breaks LSP against our widened signatures is caught automatically. - Add reflection-based regression test asserting the listed parameters stay untyped.
-
feat(lenovo): add broad 'Lenovo TB' prefix for modern tablets (#1013)
feat(lenovo): add broad 'Lenovo TB' prefix for modern tablets (#1013)
-
Make VERSION_TYPE_* consts public (#991)
Make VERSION_TYPE_* consts public (#991)
-
feat(lsb): consistent late static binding for subclass extensibility …
feat(lsb): consistent late static binding for subclass extensibility (#1012)
-
fix(test): allow multi-char pre-release suffix in version regex
fix(test): allow multi-char pre-release suffix in version regex The testScriptVersion regex only matched a single character after the hyphen (e.g. 4.8.11-d), rejecting valid pre-release tags like "dev".
-
feat(samsung): add 2025 Samsung tablet models (Tab S11, S10 Lite, A11)
feat(samsung): add 2025 Samsung tablet models (Tab S11, S10 Lite, A11) Add 15 new Samsung tablet model variants: - Galaxy Tab S11 Ultra (SM-X930, SM-X930N, SM-X936B, SM-X936N) - Galaxy Tab S11 (SM-X730, SM-X736, SM-X736B) - Galaxy Tab S10 Lite (SM-X400, SM-X406, SM-X406B) - Galaxy Tab A11+ (SM-X230, SM-X236B) - Galaxy Tab A11 (SM-X133, SM-X135, SM-X135F) Bump version to 4.8.11-dev. Add RESEARCH.md documenting the methodology for finding new device models.
-
fix(ci): drop PHP 8.0 and 8.1 from CI matrix
fix(ci): drop PHP 8.0 and 8.1 from CI matrix Both versions are EOL and phpbench 1.6.1 requires PHP ^8.2, causing composer install to fail on older PHP versions.
-
fix(compat): add explicit type hints for PHP 8.4+ compatibility
fix(compat): add explicit type hints for PHP 8.4+ compatibility - Add return type `bool` to __call() magic method in MobileDetect.php - Remove unnecessary @ error suppression in prepareVersionNo() - Add explicit parameter type hints to all test methods that lacked them - Remove redundant isset() and is_string/is_bool checks made obsolete by typed params
-
fix(deps): pin composer dependencies to exact versions
fix(deps): pin composer dependencies to exact versions Replaced caret (^) range constraints with exact version pins in composer.json. Also trimmed CLAUDE.md.
-
Fix the method name from getTimeStamp() to getTimestamp() in Cache.ph…
Fix the method name from getTimeStamp() to getTimestamp() in Cache.php (#1007)
-
fix(workflow): update github actions to their latest versions
fix(workflow): update github actions to their latest versions
-
fix(cache): PSR-16 compliance for has() method and add evictExpired()…
fix(cache): PSR-16 compliance for has() method and add evictExpired() (#1003)
-
PHP 8.4 - implicit nulls are deprecated (#960)
PHP 8.4 - implicit nulls are deprecated (#960)
-
Declare support for older psr/simple-cache version (#953)
Declare support for older psr/simple-cache version (#953)