You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2026/09/28 09:18:00 UTC

[jira] [Assigned] (CAMEL-25084) camel-util - String, time, URI and file helpers: fix bugs found in a deep review

     [ https://issues.apache.org/jira/browse/CAMEL-25084?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen reassigned CAMEL-25084:
-----------------------------------

    Assignee: Claus Ibsen

> camel-util - String, time, URI and file helpers: fix bugs found in a deep review
> --------------------------------------------------------------------------------
>
>                 Key: CAMEL-25084
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25084
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core
>            Reporter: Claus Ibsen
>            Assignee: Claus Ibsen
>            Priority: Minor
>
> A review of the utilities in camel-util (and their callers in camel-support) found these bugs:
> # *URISupport.createQueryString* with an empty list value writes an extra {{&}} ({{a=1&&c=2}}, or a trailing {{&}} when it is last).
> # *URISupport.parseQuery* adds a parameter with an empty name for a double {{&}} ({{a=1&&b=2}}), so {{timer:a?period=1000&&delay=1}} fails with a cryptic {{Index 0 out of bounds}} error.
> # *FileUtil.stripExt("/.bashrc")* returns {{/}} (a hidden file in the root lost its name).
> # *FileUtil.compactPath("C:/a/../../b")* returns {{b}}, the {{..}} removes the windows drive.
> # *IOHelper.getCharsetNameFromContentType* matches a parameter that ends with {{charset=}}, so {{text/plain; mycharset=foo; charset=iso-8859-1}} returns {{foo}}.
> # *IOHelper.EncodingInputStream* turns a surrogate pair (such as an emoji) that is split at the end of its 4096 char buffer into {{??}}.
> # *TimeUtils.toMilliSeconds* silently returns 0 or a partial value for an invalid time pattern. As this is used for every numeric endpoint/component option, {{timer:a?period=five}} gives a period of 0, {{period=1m30}} gives 60000, {{period=5S}} gives 0 (the catalog accepts the upper case unit), {{period=-5s}} gives 0 (while {{-500ms}} gives -500), and {{"s"}} throws StringIndexOutOfBoundsException.
> # A time pattern too large for an {{int}} option overflows ({{25d}} becomes {{-2134967296}}) in PropertyConfigurerSupport and LanguageSupport.
> # *Scanner.hasNext()* returns true and then *next()* throws NoSuchElementException when a delimiter that can grow (such as {{\s*;\s*}}) is split at the end of its buffer at the end of the input (tokenize with {{regex=true}}).
> # *StringHelper.normalizeWhitespace* (the Simple {{normalizeWhitespace}} function) only collapses runs of spaces, so {{a \t b}} and {{a\t\tb}} are unchanged.
> # *EndpointUriFactorySupport.buildPathParameter* replaces the wrong text when the name of a path parameter is also part of another name, such as {{knative:type/typeId}} which builds {{knative:type/channelId}} instead of {{knative:channel/foo}}. The value is also used as a regular expression replacement, so {{C:\dir}} becomes {{C:dir}} and {{p$1}} fails. The same for *StringHelper.replaceFromSecondOccurrence*, which also only replaced every other occurrence.
> # *StringHelper.dashToCamelCase* with skipQuotedOrBracket stops protecting keys in {{[...]}} after any quoted section, so {{camel.foo['a'].bar[x-y].my-opt}} gives {{bar[xY]}}.
> # *StringHelper.removeStartingCharacters* throws StringIndexOutOfBoundsException for an empty text or when all characters match (such as {{jms:queue:/}}).
> # *BackOffTimerTask*: the delay grows above {{maxDelay}} (with a multiplier) and stays there, and after *reset()* every delay is 0.
> # *ObjectHelper.getException* (and createExceptionIterable) loops forever and runs out of memory when the cause chain has a cycle (used by onException and doCatch).
> # *ObjectHelper.loadClass* cannot load primitive arrays ({{int[]}}), short name wrapper arrays ({{Integer[]}}) or multi dimensional arrays ({{String[][]}}).
> # *AnnotationHelper.findMethodsWithAnnotation* returns bridge methods and the overridden method of the super class too, so camel-flink calls a callback twice and camel-jpa fails with "Only one method can be annotated" for an entity that overrides an annotated callback.
> # *ThreadPoolRejectedPolicy.Block* silently drops a task when the pool is shutdown (the task is not rejected, so the exchange never completes).
> Not changed:
> * URISupport.normalizeUri does not give the same uri when a normalized uri is normalized again (the fast and the complex path encode the query differently since CAMEL-24524). Fixing it changes the encoding of existing endpoint uris, so it needs a decision of its own.
> * StringQuoteHelper.splitSafeQuote trims quoted values that are not last - the file is changed by CAMEL-25081.
> * BaseOrderedProperties (OrderedLocationProperties) does not override forEach, getOrDefault, putIfAbsent, compute, merge and more, so camel-main does not log the "Property not auto-configured" warnings. Fixing forEach needs a change in camel-main at the same time (consumed camel.variable keys are not removed), so this is left for a separate ticket.
> * ObjectHelper in camel-support (type coercion and iterators) is handled in a separate ticket.
> _Claude Code on behalf of Claus Ibsen_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)