From 5ae7f860576f9704634c5e85179abc28a2cb3342 Mon Sep 17 00:00:00 2001 From: Romain Poirot Date: Mon, 1 Aug 2022 15:36:59 +0200 Subject: [PATCH] fix edge case in truncate function allowing too long slugs --- slug.go | 20 +++++++------------- slug_test.go | 1 + 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/slug.go b/slug.go index 14acce7..a336d4d 100644 --- a/slug.go +++ b/slug.go @@ -150,21 +150,15 @@ func smartTruncate(text string) string { return text } - var truncated string - words := strings.SplitAfter(text, "-") - // If MaxLength is smaller than length of the first word return word - // truncated after MaxLength. - if len(words[0]) > MaxLength { - return words[0][:MaxLength] - } - for _, word := range words { - if len(truncated)+len(word)-1 <= MaxLength { - truncated = truncated + word - } else { - break + // If slug is too long, we need to find the last '-' before MaxLength, and + // we cut there. + // If we don't find any, we have only one word, and we cut at MaxLength. + for i := MaxLength - 1; i >= 0; i-- { + if text[i] == '-' { + return text[:i] } } - return strings.Trim(truncated, "-") + return text[:MaxLength] } // IsSlug returns True if provided text does not contain white characters, diff --git a/slug_test.go b/slug_test.go index baace64..4c920ee 100644 --- a/slug_test.go +++ b/slug_test.go @@ -273,6 +273,7 @@ func TestSlugMakeSmartTruncate(t *testing.T) { {"DOBROSLAWZYBORT", 100, "dobroslawzybort"}, {"Dobroslaw Zybort", 100, "dobroslaw-zybort"}, {"Dobroslaw Zybort", 12, "dobroslaw"}, + {"Dobroslaw Zybort", 15, "dobroslaw"}, {" Dobroslaw Zybort ?", 12, "dobroslaw"}, {"Ala ma 6 kotów.", 10, "ala-ma-6"}, {"Dobrosław Żybort", 5, "dobro"},