This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 459f273a62fd CAMEL-25356: camel-cm-sms - recognize <, >, the currency 
sign and form feed as GSM 03.38 characters (#27531)
459f273a62fd is described below

commit 459f273a62fd225c890d5814788f9ea8fd81b72a
Author: allthingssecurity <[email protected]>
AuthorDate: Thu Oct 8 14:16:21 2026 +0530

    CAMEL-25356: camel-cm-sms - recognize <, >, the currency sign and form feed 
as GSM 03.38 characters (#27531)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../org/apache/camel/component/cm/CMConstants.java |  2 +-
 .../camel/component/cm/test/CMGsm0338Test.java     | 74 ++++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_23.adoc    |  5 ++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git 
a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java
 
b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java
index 822ee1dfcd3d..dc875b2f7c3c 100644
--- 
a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java
+++ 
b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java
@@ -41,6 +41,6 @@ public interface CMConstants {
     // https://en.wikipedia.org/wiki/GSM_03.38
     // 
http://frightanic.com/software-development/regex-for-gsm-03-38-7bit-character-set/
     String GSM_0338_REGEX
-            = "^[A-Za-z0-9 
\\r\\n@£$\u0394_\u03A6\u0393\u039B\u03A9\u03A0\u03A8\u03A3\u0398\u039E!\"#$%&amp;'()*+,\\-./:;&lt;=&gt;?¡¿^{}\\\\\\[~\\]|"
+            = "^[A-Za-z0-9 
\\r\\n\\f@£$\u0394_\u03A6\u0393\u039B\u03A9\u03A0\u03A8\u03A3\u0398\u039E!\"#\u00a4%&'()*+,\\-./:;<=>?¡¿^{}\\\\\\[~\\]|"
               + 
"\u20AC\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\u00d8\u00f8\u00c5\u00e5\u00c6\u00e6\u00df\u00c9\u00c4\u00d6\u00d1\u00dc\u00a7\u00e4\u00f6\u00f1\u00fc\u00e0]*$";
 }
diff --git 
a/components/camel-cm-sms/src/test/java/org/apache/camel/component/cm/test/CMGsm0338Test.java
 
b/components/camel-cm-sms/src/test/java/org/apache/camel/component/cm/test/CMGsm0338Test.java
new file mode 100644
index 000000000000..1f59221a7fcb
--- /dev/null
+++ 
b/components/camel-cm-sms/src/test/java/org/apache/camel/component/cm/test/CMGsm0338Test.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.cm.test;
+
+import org.apache.camel.component.cm.CMConstants;
+import org.apache.camel.component.cm.CMMessage;
+import org.apache.camel.component.cm.CMUtils;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+/**
+ * Every character of the GSM 03.38 default alphabet and of its extension 
table (see
+ * https://unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT) can be sent in a GSM 
message.
+ */
+class CMGsm0338Test {
+
+    // the basic character set without ESC (0x1B), in the order of the table
+    private static final String GSM_BASIC = "@£$¥èéùìòÇ\nØø\rÅå"
+                                            + "Δ_ΦΓΛΩΠΨΣΘΞÆæßÉ"
+                                            + " 
!\"#¤%&'()*+,-./0123456789:;<=>?"
+                                            + 
"¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ"
+                                            + 
"¿abcdefghijklmnopqrstuvwxyzäöñüà";
+
+    // the extension table: form feed, ^ { } \ [ ~ ] | and the euro sign
+    private static final String GSM_EXTENSION = "\f^{}\\[~]|€";
+
+    @Test
+    void everyBasicCharacterIsGsm() {
+        assertEquals("", notGsm(GSM_BASIC), "characters of the GSM 03.38 basic 
character set reported as not GSM");
+    }
+
+    @Test
+    void everyExtensionCharacterIsGsm() {
+        assertEquals("", notGsm(GSM_EXTENSION), "characters of the GSM 03.38 
extension table reported as not GSM");
+    }
+
+    @Test
+    void textWithAngleBracketsIsSentAsGsm() {
+        // 310 characters: 3 GSM parts of 153 characters, but 5 unicode parts 
of 67 characters
+        String text = "if a < b and b > c then a < c. ".repeat(10);
+
+        CMMessage message = new CMMessage("+34612345678", text);
+        message.setUnicodeAndMultipart(CMConstants.DEFAULT_MULTIPARTS);
+
+        assertFalse(message.isUnicode(), "Should not be unicode");
+        assertEquals(3, message.getMultiparts());
+    }
+
+    private static String notGsm(String chars) {
+        StringBuilder sb = new StringBuilder();
+        for (char c : chars.toCharArray()) {
+            if (!CMUtils.isGsm0338Encodeable(String.valueOf(c))) {
+                sb.append(String.format("U+%04X ", (int) c));
+            }
+        }
+        return sb.toString().trim();
+    }
+}
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index 5236350ed66e..dcacf9f1a24e 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -643,6 +643,11 @@ otherwise `connectTimeout`. Each option now sets its own 
timeout: a request whos
 configured `readTimeout` now fails, and only `connectTimeout` sets the connect 
timeout. Blocking queries
 (`blockSeconds`) are not affected: the client computes the read timeout of a 
blocking query from its wait time.
 
+=== camel-cm-sms - GSM 03.38 detection
+
+A message that contains `<`, `>`, `¤` or a form feed, and otherwise only GSM 
03.38 characters, is now sent in the GSM
+encoding (160 characters, or 153 per part) instead of as unicode (70, or 67 
per part), so it may be sent in fewer parts.
+
 === camel-couchbase
 
 The `connectTimeout` option is now applied. It previously sat inside a 
condition that tested `queryTimeout`, so

Reply via email to