From ba2f9aa95ee55f3672cd59474c65b959d0fe7fb5 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Wed, 26 Feb 2014 23:52:45 -0500 Subject: [PATCH] Do not grant fork CLONE permissions to users/teams with implied regex CLONE permissions (issue-320) --- src/main/java/com/gitblit/utils/JGitUtils.java | 100 ++++++++++++++++++++++++++++---------------------- 1 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/gitblit/utils/JGitUtils.java b/src/main/java/com/gitblit/utils/JGitUtils.java index 75a4405..212a90a 100644 --- a/src/main/java/com/gitblit/utils/JGitUtils.java +++ b/src/main/java/com/gitblit/utils/JGitUtils.java @@ -15,10 +15,8 @@ */ package com.gitblit.utils; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.text.DecimalFormat; import java.text.MessageFormat; import java.util.ArrayList; @@ -755,18 +753,8 @@ ObjectId entid = tw.getObjectId(0); FileMode entmode = tw.getFileMode(0); if (entmode != FileMode.GITLINK) { - RevObject ro = rw.lookupAny(entid, entmode.getObjectType()); - rw.parseBody(ro); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - ObjectLoader ldr = repository.open(ro.getId(), Constants.OBJ_BLOB); - byte[] tmp = new byte[4096]; - InputStream in = ldr.openStream(); - int n; - while ((n = in.read(tmp)) > 0) { - os.write(tmp, 0, n); - } - in.close(); - content = os.toByteArray(); + ObjectLoader ldr = repository.open(entid, Constants.OBJ_BLOB); + content = ldr.getCachedBytes(); } } } catch (Throwable t) { @@ -810,17 +798,8 @@ byte[] content = null; try { RevBlob blob = rw.lookupBlob(ObjectId.fromString(objectId)); - rw.parseBody(blob); - ByteArrayOutputStream os = new ByteArrayOutputStream(); ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB); - byte[] tmp = new byte[4096]; - InputStream in = ldr.openStream(); - int n; - while ((n = in.read(tmp)) > 0) { - os.write(tmp, 0, n); - } - in.close(); - content = os.toByteArray(); + content = ldr.getCachedBytes(); } catch (Throwable t) { error(t, repository, "{0} can't find blob {1}", objectId); } finally { @@ -1049,10 +1028,10 @@ List<TreeFilter> suffixFilters = new ArrayList<TreeFilter>(); for (String extension : extensions) { if (extension.charAt(0) == '.') { - suffixFilters.add(PathSuffixFilter.create("\\" + extension)); + suffixFilters.add(PathSuffixFilter.create(extension)); } else { // escape the . since this is a regexp filter - suffixFilters.add(PathSuffixFilter.create("\\." + extension)); + suffixFilters.add(PathSuffixFilter.create("." + extension)); } } TreeFilter filter; @@ -1470,23 +1449,6 @@ String target = null; try { target = repository.getFullBranch(); - if (!target.startsWith(Constants.R_HEADS)) { - // refers to an actual commit, probably a tag - // find latest tag that matches the commit, if any - List<RefModel> tagModels = getTags(repository, true, -1); - if (tagModels.size() > 0) { - RefModel tag = null; - Date lastDate = new Date(0); - for (RefModel tagModel : tagModels) { - if (tagModel.getReferencedObjectId().getName().equals(target) && - tagModel.getDate().after(lastDate)) { - tag = tagModel; - lastDate = tag.getDate(); - } - } - target = tag.getName(); - } - } } catch (Throwable t) { error(t, repository, "{0} failed to get symbolic HEAD target"); } @@ -1540,7 +1502,7 @@ */ public static boolean setBranchRef(Repository repository, String branch, String commitId) { String branchName = branch; - if (!branchName.startsWith(Constants.R_HEADS)) { + if (!branchName.startsWith(Constants.R_REFS)) { branchName = Constants.R_HEADS + branch; } @@ -2096,4 +2058,54 @@ } return StringUtils.decodeString(content); } + + /** + * Automatic repair of (some) invalid refspecs. These are the result of a + * bug in JGit cloning where a double forward-slash was injected. :( + * + * @param repository + * @return true, if the refspecs were repaired + */ + public static boolean repairFetchSpecs(Repository repository) { + StoredConfig rc = repository.getConfig(); + + // auto-repair broken fetch ref specs + for (String name : rc.getSubsections("remote")) { + int invalidSpecs = 0; + int repairedSpecs = 0; + List<String> specs = new ArrayList<String>(); + for (String spec : rc.getStringList("remote", name, "fetch")) { + try { + RefSpec rs = new RefSpec(spec); + // valid spec + specs.add(spec); + } catch (IllegalArgumentException e) { + // invalid spec + invalidSpecs++; + if (spec.contains("//")) { + // auto-repair this known spec bug + spec = spec.replace("//", "/"); + specs.add(spec); + repairedSpecs++; + } + } + } + + if (invalidSpecs == repairedSpecs && repairedSpecs > 0) { + // the fetch specs were automatically repaired + rc.setStringList("remote", name, "fetch", specs); + try { + rc.save(); + rc.load(); + LOGGER.debug("repaired {} invalid fetch refspecs for {}", repairedSpecs, repository.getDirectory()); + return true; + } catch (Exception e) { + LOGGER.error(null, e); + } + } else if (invalidSpecs > 0) { + LOGGER.error("mirror executor found {} invalid fetch refspecs for {}", invalidSpecs, repository.getDirectory()); + } + } + return false; + } } -- Gitblit v1.9.1