Repository navigation
Fix StringService edge cases: mask, isPalindrome, random, truncate and more - #393
Merged
techmahedy merged 2 commits intoOct 30, 2026
Merged
Conversation
…lug/studly/snake/between/countWord
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Checklist
Description
A review of
StringServicefound several methods that return wrong results or unsafe output on edge-case input. Most of them count bytes where the rest of the class is Unicode-aware, and a few have logic errors.The most serious one:
mask('1234567890', 3, 0)returned123*******1234567890, so the whole value was exposed.substr($string, -0)issubstr($string, 0), which returns the entire string.Fixes
maskisPalindrome'привет'returnedtrue, because non-ASCII letters were stripped.randomstr_shuffle(not cryptographically secure). A negative length threw aValueError.random_int. A negative length returns''.uuidmt_rand.random_bytes, with the v4 version and variant bits set.truncatesnakesnake('ÉcoleNom')gaveÉcole_nomandsnake('éNom')gaveénom.slug''.containsstartsWithandendsWith, which skip it.limitWordsTypeError.longestCommonSubstringhighlightKeyword'0'was treated as empty. Case-insensitive matching ignored non-ASCII.toUppertoUpper('éa')gaveéA.mb_strtoupper.suffixAppendstr()helper, so it threw outside a booted container. It crashed on''.$this->endsWith(). An empty input returns the suffix.removeSuffixremoveSuffix('hello', 'xyz')returnedhe, and an empty suffix returned''.PHPStan baseline
phpstan-baseline.neonallows exactly 3 "undefined property" errors each forBuilder::$attributesandBuilder::$originalAttributes. The insert fix in #392 added a fourth of each, so PHPStan was failing on4.x. The trait is shared byModelandBuilder, and onlyModeldeclares those properties. This PR raises both counts from 3 to 4. It is unrelated toStringService, and can be split into its own PR if you prefer.Backward Compatibility
removeSuffix.snakefor ASCII input is unchanged, so table names and computed-property keys stay the same.contains('x', '')now returnsfalseinstead oftrue.random()anduuid()keep their formats, and now use a cryptographically secure source.Checklist