Class PathCodec

java.lang.Object
io.jenkins.plugins.batchcontrol.store.PathCodec

@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public final class PathCodec extends Object
The single place where job full names are turned into store file names and where store file names are validated. No other class may build file names from user-controlled input.

Encoding: UTF-8 percent-encoding. Only [A-Za-z0-9_-] pass through unchanged; every other byte (including / \ . % and control characters) becomes %XX. The result is a single printable path segment that round-trips losslessly via decode(java.lang.String). Names whose encoding exceeds 250 characters are shortened deterministically to <prefix>~<sha256 hex of the full name>, which keeps two long names differing only at the tail on different files (such shortened names no longer decode, but they stay stable).

Uniqueness. encode never emits ~ raw (it becomes %7E), so a shortened name always contains exactly one character no plain encoding contains and can never equal the encoding of another, shorter name. Unreleased builds joined the shortened form with -, which a plain encoding does emit; files in that form are neither read nor migrated (D-43): such a file can only be another item's plain encoding.

  • Method Details

    • encode

      public static String encode(String jobFullName)
      Encodes a job full name into a safe, deterministic, collision-free file-name segment.
    • decode

      public static String decode(String encoded)
      Decodes an encoded file-name segment back to the original job full name.
      Throws:
      IllegalArgumentException - if the input contains any character outside the encoding alphabet (in particular / \ ., so traversal strings are rejected) or a malformed %XX escape.
    • isId

      public static boolean isId(String id)
      Whether id has the shape of a store identifier: ASCII letters, digits and - only, at most 128 characters. New requests and windows get UUIDs (D-68) and history records yyyyMMdd-HHmmss-<6 random> ids (Ids), and both forms qualify.

      S-39-01: an identifier is turned into a file name only after this check, so it can name only its own file: without . it can never reach another file of the same directory under another suffix (a run request's <id>.values.xml, also in another letter case on a case-insensitive file system), and without ~ never a Windows 8.3 short name.

    • resolveId

      public static Path resolveId(Path baseDir, String id, String suffix)
      The file <id><suffix> under baseDir of the entity id (S-39-01).
      Throws:
      IllegalArgumentException - if id is not a store identifier (isId(java.lang.String)) or the file name is unsafe (resolveUnder(java.nio.file.Path, java.lang.String))
    • resolveUnder

      public static Path resolveUnder(Path baseDir, String fileName)
      Resolves fileName under baseDir, guaranteeing the result cannot escape.
      Throws:
      IllegalArgumentException - if the file name contains a path separator, is . or .., or the resolved path leaves baseDir.