Uploaded image for project: 'Maven Javadoc Plugin'
  1. Maven Javadoc Plugin
  2. MJAVADOC-585

Incorrect quoting and escaping of nonProxyHosts-information from settings.xml

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 3.1.0
    • next-release
    • jar, javadoc
    • None
    • Maven 3.6.0 on RHEL 7.6 using OpenJDK 1.8.9.191 and Bash; Maven 3.6.0 on Windows 7 using Oracle JDK 8 Update 201 and Windows-CMD

    Description

      At my development site, I am behind a proxy server. That proxy server is configured in my settings.xml in a corresponding proxies/proxy-section.

      For site-deployments I use an internal server named my-site-host.

      To bypass the proxy for access to my-site-host and several other hosts in the local network, there is a nonProxyHosts-element in the proxy-configuration-section of my settings.xml which looks like this:

      <nonProxyHosts>my-site-host|my-nexus-host</nonProxyHosts>
      

      In an internal project linking-project, which uses a class LinkTarget from another internal project link-target in its API, I would like to have the class LinkTarget in the Javadocs of project linking-project to be displayed as links to the Javadocs of project link-target. The Javadocs of project link-target are published on my-site-host as part of a maven-site. To achieve the linking I have configured the maven-javadoc-plugin in linking-project as follows:

      <configuration>
          <links>
              <link>http://my-site-host/link-target/0.1.0-SNAPSHOT/apidocs</link>
          </links>
      </configuration>
      

      When the report javadoc:javadoc or the goal javadoc:jar is executed during the build, I get the following warning:

      [WARNING] javadoc: warning - Error fetching URL: http://my-site-host/link-target/0.1.0-SNAPSHOT/apidocs/
      

      As a result, class LinkTarget in the generated Javadocs is displayed with its fully qualified class name and not as a link. The expected behavior would be class LinkTarget being displayed using its local name only and with an underlying link to the Javadocs of that class. The problem occurs on both Linux and Windows.

      The problem also occurs when executing the javadoc.(sh|bat) script, which is generated in target/site/apidocs when -Ddebug=true is used (on Linux using Bash; on Windows using Windows-CMD).

      The problem seems to be in the handling of the nonProxyHosts-information from the settings.xml in AbstractJavadocMojo. In method addProxyArg(Commandline) this information is (in two places) handled as follows:

      cmd.createArg().setValue( "-J-Dhttp.nonProxyHosts=\""
              + httpProxy.getNonProxyHosts().replace( "|", "^|" ) + "\"" );
      

      When the report/goal is executed, the Commandline-object is delegated to CommandLineUtils.executeCommandLine(...) which in the end delegates to the javadoc-program using Runtime.exec(...). Runtime.exec(...) is fed the command line parts as an array of Strings and apparently does not need any quoting and escaping. When looking at it in a debugger the nonProxyHosts-information – escaped with the code above – is passed to the javadoc-program as "-J-Dhttp.nonProxyHosts=\"my-site-host^|my-nexus-host\"". I guess this value is split by the javadoc-program at the pipe symbol, resulting in "my-site-host^ and my-nexus-host" as the two host names. Thus the javadoc-program bypasses the proxy for the nonexisting/nonsense host name "my-site-host^ (with a leading quote and a trailing caret) but uses the proxy for the actual host my-site-host causing the malfuntion and the warning.

      For the sake of the report/goal-execution the above code could be fixed as follows:

      cmd.createArg().setValue( "-J-Dhttp.nonProxyHosts=" + httpProxy.getNonProxyHosts() );
      

      i.e. no quoting and no escaping of pipe symbols.

      This code change albeit completely breaks the generated javadoc.(sh|bat)-scripts generated in target/site/apidocs with -Ddebug=true. While Runtime.exec(...) must not have quoting and escaping, Windows-CMD and Bash, for which the scripts are generated, need special handling. Otherwise the pipe symbols in nonProxyHosts will be interpreted as redirection of output to the input of another program.

      The following aspects need to be observed regarding the generation of the debug scripts:

      1. The scripts may be based on the Commandline-object but must have the pipe symbol escaped.
      2. Quoting is not necessary when the pipe symbol is properly escaped and the host-names do not contain whitespace – I would take no-whitespace-hostnames for granted.
      3. The pipe symbol must be escaped in the way that matches the platform – escaping the pip symbol with a caret ^ is specific to Windows-CMD, for Linux/Bash the escaping must be done with a backslash {{}}.

      This could be achieved with a code change in addition to the one above. The additional change could be in AbstractJavadocMojo.writeDebugJavadocScript(...) or – consistent with the existing code – in all places where CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" ) is called (three occurrences in AbstractJavadocMojo.executeJavadocCommandLine(...), one for logging and two for generating the debug script). The latter variant could look like this for the script generation, the logging code would be very similar:

      String pipeSymbolEscape = "\\\\|";
      if ( SystemUtils.IS_OS_WINDOWS )
      {
          pipeSymbolEscape = "^|";
      }
      
      cmdLine = CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" )
              .replaceAll( "\\|", pipeSymbolEscape );
      
      writeDebugJavadocScript( cmdLine, javadocOutputDirectory );
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            pbv22 Paul Busch
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated: