From d2cdaa609da71f0c76b05a1e4a37eef004f25d95 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 23 Nov 2012 22:27:20 -0800 Subject: [PATCH] Make new message UUIDs more URL encoding friendly =, + and / require triplet encoding in URLs. Cleanup the base64 encoding string to use different characters. This only impacts newly created string, existing strings will continue to require a much longer encoding when sent in JSON messages from the REST API. Also strip leading 'A'. Most strings start with a run of 'A' due to the first few bytes of uuidPrefix always being 0. Avoid long runs of - in the resulting IDs by mixing the bits using the uuidPrefix as the salt for the mixer. Change-Id: I0a7da0aec071329c840447a0914d14118f2f20a4 --- .../java/com/google/gerrit/server/ChangeUtil.java | 12 +++++++++--- .../com/google/gerrit/server/util/IdGenerator.java | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java index 06213d8aa9..54bfe60d7a 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java @@ -14,6 +14,7 @@ package com.google.gerrit.server; +import com.google.common.base.CharMatcher; import com.google.gerrit.common.ChangeHooks; import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.ChangeMessage; @@ -35,6 +36,7 @@ import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.NoSuchChangeException; +import com.google.gerrit.server.util.IdGenerator; import com.google.gwtorm.server.AtomicUpdate; import com.google.gwtorm.server.OrmConcurrencyException; import com.google.gwtorm.server.OrmException; @@ -66,7 +68,6 @@ import java.util.Set; import java.util.regex.Matcher; public class ChangeUtil { - private static final Logger log = LoggerFactory.getLogger(ChangeUtil.class); private static int uuidPrefix; @@ -83,7 +84,12 @@ public class ChangeUtil { public static String messageUUID(final ReviewDb db) throws OrmException { final byte[] raw = new byte[8]; fill(raw, db); - return Base64.encodeBytes(raw); + + // Make the resulting base64 string more URL friendly. + return CharMatcher.is('A').trimLeadingFrom( + CharMatcher.is('=').trimTrailingFrom(Base64.encodeBytes(raw))) + .replace('+', '.') + .replace('/', '-'); } private static synchronized void fill(byte[] raw, ReviewDb db) @@ -93,7 +99,7 @@ public class ChangeUtil { uuidSeq = Integer.MAX_VALUE; } NB.encodeInt32(raw, 0, uuidPrefix); - NB.encodeInt32(raw, 4, uuidSeq--); + NB.encodeInt32(raw, 4, IdGenerator.mix(uuidPrefix, uuidSeq--)); } public static void touch(final Change change, ReviewDb db) diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/util/IdGenerator.java b/gerrit-server/src/main/java/com/google/gerrit/server/util/IdGenerator.java index b20bbf69e5..19c820e1d0 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/util/IdGenerator.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/util/IdGenerator.java @@ -43,13 +43,13 @@ public class IdGenerator { /** Produce the next identifier. */ public int next() { - return mix(gen.getAndIncrement()); + return mix(salt, gen.getAndIncrement()); } private static final int salt = 0x9e3779b9; /** A very simple bit permutation to mask a simple incrementer. */ - static int mix(final int in) { + public static int mix(final int salt, final int in) { short v0 = hi16(in); short v1 = lo16(in); v0 += ((v1 << 2) + 0 ^ v1) + (salt ^ (v1 >>> 3)) + 1;