Skip to content

Commit 04d71da

Browse files
authored
Treat leading-zero slugs as numeric conflicts (#1046)
Previously, numeric detection parsed the slug as an integer and compared the result, causing values such as `00123` to be treated as non-numeric. The check now matches ASCII digits directly. Includes a regression test for leading-zero numeric slugs. (I ran into this issue when an international phone number was accidentally use as a slug)
1 parent 9c0faf7 commit 04d71da

3 files changed

Lines changed: 16 additions & 5 deletions

File tree

‎Changelog.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
We would like to think our many [contributors](https://github.com/norman/friendly_id/graphs/contributors) for
44
suggestions, ideas and improvements to FriendlyId.
55

6+
## Unreleased
7+
8+
* Fix: Treat leading-zero slugs as numeric conflicts. ([#1046](https://github.com/norman/friendly_id/pull/1046))
9+
610
## 5.6.0 (2025-12-07)
711

812
* Add: `treat_numeric_as_conflict` option to prevent ambiguous numeric slugs. ([#1037](https://github.com/norman/friendly_id/pull/1037))

‎lib/friendly_id/slug_generator.rb‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,8 @@ def generate(candidates)
2828

2929
def purely_numeric_slug?(slug)
3030
return false unless slug
31-
begin
32-
Integer(slug, 10).to_s == slug.to_s
33-
rescue ArgumentError, TypeError
34-
false
35-
end
31+
32+
slug.to_s.match?(/\A[0-9]+\z/)
3633
end
3734
end
3835
end

‎test/numeric_slug_test.rb‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
class Article < ActiveRecord::Base
44
extend FriendlyId
5+
56
friendly_id :name, use: :slugged
67
end
78

89
class ArticleWithNumericPrevention < ActiveRecord::Base
910
self.table_name = "articles"
1011
extend FriendlyId
12+
1113
friendly_id :name, use: :slugged
1214
friendly_id_config.treat_numeric_as_conflict = true
1315
end
@@ -71,6 +73,14 @@ def model_class
7173
end
7274
end
7375

76+
test "should handle numbers with leading zeroes as numeric when treat_numeric_as_conflict is enabled" do
77+
transaction do
78+
record = ArticleWithNumericPrevention.create! name: "00123"
79+
refute_equal "00123", record.slug
80+
assert_match(/\A00123-[0-9a-f-]{36}\z/, record.slug)
81+
end
82+
end
83+
7484
test "should handle large numbers as numeric when treat_numeric_as_conflict is enabled" do
7585
transaction do
7686
record = ArticleWithNumericPrevention.create! name: "999999999"

0 commit comments

Comments
 (0)