Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-37446

StringIndexOutOfBoundsException when editing Custom Configuration field

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Minor
    • Resolution: Unresolved
    • mercurial-plugin
    • Windows 7 x64
      Jenkins 1.580.3
      Mercurial plugin 1.54

    Description

      In the Jenkins configuration page, under Mercurial installations, I get an exception if I enter this specific text in the Custom Configuration field:

      [x]
      \:
      

      There can be any text around these elements, but this appears to be the minimal amount of text that produces the exception.

      The exception pops as a web page under the field, with Jenkins top header and sidebar, which is kinda weird, too (see attached image).

      Here's the full text of the exception that is displayed:

      javax.servlet.ServletException: java.lang.StringIndexOutOfBoundsException: String index out of range: 1
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:795)
      	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:875)
      	at org.kohsuke.stapler.MetaClass$6.doDispatch(MetaClass.java:249)
      	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:745)
      	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:875)
      	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:648)
      	at org.kohsuke.stapler.Stapler.service(Stapler.java:237)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
      	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:686)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1494)
      	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:96)
      	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:88)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
      	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:48)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
      	at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      	at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      	at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      	at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      	at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      	at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      	at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
      	at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67)
      	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
      	at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
      	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:164)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
      	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:46)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
      	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:81)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1474)
      	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:499)
      	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
      	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:533)
      	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
      	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
      	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
      	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
      	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
      	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
      	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
      	at org.eclipse.jetty.server.Server.handle(Server.java:370)
      	at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
      	at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:949)
      	at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1011)
      	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
      	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
      	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
      	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668)
      	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
      	at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      	at java.lang.Thread.run(Unknown Source)
      Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 1
      	at java.lang.String.charAt(Unknown Source)
      	at org.ini4j.spi.EscapeTool.unescape(EscapeTool.java:111)
      	at org.ini4j.spi.AbstractParser.unescapeFilter(AbstractParser.java:109)
      	at org.ini4j.spi.AbstractParser.parseOptionLine(AbstractParser.java:90)
      	at org.ini4j.spi.IniParser.parse(IniParser.java:101)
      	at org.ini4j.spi.IniParser.parse(IniParser.java:62)
      	at org.ini4j.Ini.load(Ini.java:109)
      	at org.ini4j.Ini.<init>(Ini.java:50)
      	at hudson.plugins.mercurial.MercurialInstallation$DescriptorImpl.doCheckConfig(MercurialInstallation.java:161)
      	at sun.reflect.GeneratedMethodAccessor1055.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      	at java.lang.reflect.Method.invoke(Unknown Source)
      	at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:298)
      	at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:161)
      	at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:96)
      	at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:121)
      	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:745)
      	... 61 more
      

      I'm not sure if that exception even has an effect on anything, and I have an easy workaround, which is to use [:] instead of \: in my regex.

      The config I was trying to use was this, if you're wondering why I even had that kind of pattern in there:

      [subpaths]
      (http|https|ssh)(\://.*)/src/(.*) = \1\2-subrepos/\3
      

      Attachments

        Issue Links

          Activity

            jglick Jesse Glick added a comment -

            I guess you have to attach a *.diff file. Does feel like the previous millenium.

            jglick Jesse Glick added a comment - I guess you have to attach a *.diff file. Does feel like the previous millenium.

            For the record, there's an issue filed for this, on the ini4j SourceForge project page, since 2012 : https://sourceforge.net/p/ini4j/bugs/45/

            I'm not sure how I'd be supposed to work with CVS and SourceForge to provide some patch though ! Feels otherworldly to me.

            michaelp Michael Piffret added a comment - For the record, there's an issue filed for this, on the ini4j SourceForge project page, since 2012 : https://sourceforge.net/p/ini4j/bugs/45/ I'm not sure how I'd be supposed to work with CVS and SourceForge to provide some patch though ! Feels otherworldly to me.
            jglick Jesse Glick added a comment -

            Offhand it does sound like a patched version of ini4j is likely to be needed.

            As a workaround, just define a wrapper script like

            hg --config whatever --other-options-you-need "$@"
            

            and set that as the executable.

            jglick Jesse Glick added a comment - Offhand it does sound like a patched version of ini4j is likely to be needed. As a workaround, just define a wrapper script like hg --config whatever --other-options-you-need "$@" and set that as the executable.

            This would be great.

            We could suggest a few modifications to the ini4j library, hopefully they'll take pull request (or patches or whatever) though releases seem to be few and far between.

            michaelp Michael Piffret added a comment - This would be great. We could suggest a few modifications to the ini4j library, hopefully they'll take pull request (or patches or whatever) though releases seem to be few and far between.

            If the parsing of the ini file is modified for this, it might also be possible to fix JENKINS-38038 at the same time so that the order of the confg lines is also preserved.

            samapico Samuel Delisle added a comment - If the parsing of the ini file is modified for this, it might also be possible to fix JENKINS-38038 at the same time so that the order of the confg lines is also preserved.

            I tracked it down to Ini4j : its IniParser defines "private static final" operators, ':' and '='. I does not manage escape characters properly, it does not seem to provide a way to override these operators.

            When given "option:suboption = value" it understands "option = 'suboption = value'". I suppose it was never able to handle Mercurial configuration files... I'm thinking about some kind of solution, any input is welcome !

            michaelp Michael Piffret added a comment - I tracked it down to Ini4j : its IniParser defines "private static final" operators, ':' and '='. I does not manage escape characters properly, it does not seem to provide a way to override these operators. When given "option:suboption = value" it understands "option = 'suboption = value'". I suppose it was never able to handle Mercurial configuration files... I'm thinking about some kind of solution, any input is welcome !

            I hit the same bug trying to specify hostname:minimumprotocol = tls1.x . It prevents me from using the plugin with our old company Mercurial server

            michaelp Michael Piffret added a comment - I hit the same bug trying to specify hostname:minimumprotocol = tls1.x . It prevents me from using the plugin with our old company Mercurial server

            It seems my workaround is not working either...

            Using this config:

            [subpaths]
            (http|https|ssh)([:]//.*)/src/(.*) = \1\2-subrepos/\3
            

            results in this when I run my job:

            [MyJob] $ hg --config "subpaths.(http|https|ssh)([=]//.*)/src/(.*) = 12-subrepos/3" --config auth.jenkins.prefix=* --config ******** --config ******** --config "auth.jenkins.schemes=http https" showconfig paths.default
            

            The ":" was transformed to a "=" somehow... I also noticed my backslashes got removed, so I had to escape them in the configuration field.

            samapico Samuel Delisle added a comment - It seems my workaround is not working either... Using this config: [subpaths] (http|https|ssh)([:]//.*)/src/(.*) = \1\2-subrepos/\3 results in this when I run my job: [MyJob] $ hg --config "subpaths.(http|https|ssh)([=]//.*)/src/(.*) = 12-subrepos/3" --config auth.jenkins.prefix=* --config ******** --config ******** --config "auth.jenkins.schemes=http https" showconfig paths.default The ":" was transformed to a "=" somehow... I also noticed my backslashes got removed, so I had to escape them in the configuration field.

            People

              jglick Jesse Glick
              samapico Samuel Delisle
              Votes:
              1 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: