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

Jenkins git plugin incorrect hyperlink when file name has # character

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • git-plugin
    • None
    • git-plugin:5.7.0
      jenkins-core:2.479.1

      If a file contains a '#' in it the hyperlink generated to the file in the changes view is not correct.

      The generated hyperlink is:
      https://github.com/PROJECT/REPO/blob/c1c9643ce9303e7f3eb10eefdf761a9344e5d7e1/my#file.txt

      It should be:
      https://github.com/PROJECT/REPO/blob/c1c9643ce9303e7f3eb10eefdf761a9344e5d7e1/my%23file.txt

      Steps to reproduce:
      1. Create a github repository
      2. Create a file called "my#file.txt"
      3. Create a Jenkinsfile

      pipeline {
          agent any
      
          stages {
              stage('Hello') {
                  steps {
                      echo 'Hello World'
                  }
              }
          }
      }
      

      4. Setup a Jenkins job pointing to the above repository
      5. Run the above job once
      6. Make a change to "my#file.txt" and push it
      7. Run the build again
      8. Inspect the link to the file in the "Changes". The link will not work.

      <td>
        <a href="https://github.com/PROJECT/REPO/blob/c1c9643ce9303e7f3eb10eefdf761a9344e5d7e1/my#file.txt">my#file.txt</a>
        &nbsp;
        <a href="https://github.com/PROJECT/REPO/commit/c1c9643ce9303e7f3eb10eefdf761a9344e5d7e1#diff-0">(diff)</a>
      </td>
      

      URL encoding is a pain and a game of whack-a-mole. Unfortunately the URI trick doesn't work in all cases. The URLEncoder is sometimes recommended and Jenkins core Functions has it but that doesn't handle some nuances around how different parts of the URL should be encoded. Worst of all, APIs are inconsistent. Some middleware is more lenient than others and will let incorrectly formatted URLs through. Some have different settings such as how to treat encoding and double encoding '/'.

      I've found the best approach is to use Guava's URLEscapers. It forces the caller to select the correct escaper based on the context of which part of a URL is encoded. It also prevents generic "urlEncode" abuse where people run it on strings then selectively convert certain characters back with a String replace. It's best augmented with a "urlEncodePathExceptSlash" method which tends to be quite convenient. Finally, it forces the caller to do the encoding instead of a "do-it-all method" which can't always understand user intent (i.e. is '/' part of a path or an element of a path that needs to be encoded? Is the '#' character I see a genuine fragment separator or part of an element that needs to be encoded?)

            code_arnab Arnab
            mrichar2 Mark R
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: