Claus Ibsen created CAMEL-25043:
-----------------------------------
Summary: camel-core - Tokenize language: fix bugs found in a deep
review
Key: CAMEL-25043
URL: https://issues.apache.org/jira/browse/CAMEL-25043
Project: Camel
Issue Type: Bug
Components: camel-core
Reporter: Claus Ibsen
A deep review of the tokenize language (TokenizeLanguage, and the pair and xml
iterators in camel-support) found the bugs below. Each one was reproduced
against 4.23.0-SNAPSHOT and has a test that fails without the fix.
# *A message without a body fails with a NullPointerException.*
{{split().tokenize(",")}} of a message without a body (or with a {{source}}
that has no value) failed with {{NullPointerException: source}} from the
scanner, where an empty body has no tokens. This is a regression from
CAMEL-12688 (2018), which removed the fallback to an empty scanner.
# *skipFirst on an empty body fails with NoSuchElementException.* Without
{{group}}, skipFirst called {{next()}} on the iterator without checking
{{hasNext()}}, so an empty file failed the exchange. With {{group}} this was
already handled (CAMEL-12607).
# *Pair mode ignores source.*
{{token("[").endToken("]").source("header:data")}} always read the message
body. TokenizeLanguage called the overload of {{tokenizePairExpression}}
without the source, and the overload with a source dropped it too.
# *skipFirst is ignored in xml mode and in pair mode.* The skip-first wrapper
was only applied to the plain tokenizer, and xml mode with {{group}} always
passed {{false}} to the group iterator.
# *Pair mode with group puts the start token between the pairs.*
{{token("<a>").endToken("</a>").includeTokens(true).group(2)}} of
{{<a>1</a><a>2</a><a>3</a>}} gave {{<a>1</a><a><a>2</a>}}. The pairs are now
joined without a delimiter, as in xml mode, unless {{groupDelimiter}} is set.
# *A pair with the same start and end token has no tokens.* The end token is
the scanner delimiter, so a start token that is the same is never found, and
{{tokenizePair("'", "'")}} silently gave nothing. It is now refused with a
clear message when the route is created.
# *xml mode with inheritNamespaceTagName="*" builds broken XML when a comment
or DOCTYPE comes before the root.* The closing tags were built by treating
{{<!-- ... -->}} and {{<!DOCTYPE ...>}} as start tags, so each part ended with
{{</!-->}}.
# *xml mode with inheritNamespaceTagName="*" fails on a multi-byte character
before the first token.* The head was cut by the character offset of the
scanner match, but from the recorded bytes, so an attribute such as
{{name="æøå"}} failed with StringIndexOutOfBoundsException (or silently lost
the end of the head).
# *ValueBuilder.tokenize(token, null, skipFirst) fails when the route starts.*
It always wrapped the group iterator, also when there is no group, which failed
with "expression must be specified". The same code in MockValueBuilder had the
same bug.
Also: the group delimiter is now encoded in the exchange charset (it was
encoded in the platform charset and decoded in the exchange charset), and the
recording input stream of the xml wrap mode no longer drops a NUL byte.
*Not changed*
* A token with {{regex=false}} is still compiled as a regular expression, and
the end token of a pair is not quoted. That is CAMEL-25015, which asks which
compatible fix the committers prefer.
* {{SplitterTest.testEmptyBody}} asserted that a request without a body gives
no out message, which only held because the exchange failed with the
NullPointerException above. It now asserts that the exchange does not fail and
has no parts.
_Claude Code on behalf of Claus Ibsen_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)