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!\"#$%&'()*+,\\-./:;<=>?¡¿^{}\\\\\\[~\\]|"
+ = "^[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