commit - 01b7ba6b7375d24a087d44aa48c0b78d66a6187e
commit + f77a24b0362de269128c9588d65818958a9ec9a9
blob - f6f99ad590182ea6fbbc1c325681cd23eda29ec4
blob + 65ff442b096e36f03c632555fd6def55aea92bc4
--- include/got_error.h
+++ include/got_error.h
#define GOT_ERR_UUID_INVALID 62
#define GOT_ERR_UUID 63
#define GOT_ERR_LOCKFILE_TIMEOUT 64
+#define GOT_ERR_BAD_REF_NAME 65
static const struct got_error {
int code;
{ GOT_ERR_UUID_INVALID, "uuid invalid" },
{ GOT_ERR_UUID, "uuid error" },
{ GOT_ERR_LOCKFILE_TIMEOUT,"lockfile timeout" },
+ { GOT_ERR_BAD_REF_NAME, "bad reference name" },
};
/*
blob - adbeed13ac643c78f48533f886ec943ad7de7be0
blob + 9e9655183bf6af53d89c2fcea53352d7d2a47b3e
--- lib/reference.c
+++ lib/reference.c
#include <sys/types.h>
#include <sys/queue.h>
+#include <ctype.h>
#include <dirent.h>
#include <sha1.h>
#include <stdio.h>
#include "got_lib_delta.h"
#include "got_lib_inflate.h"
#include "got_lib_object.h"
+#include "got_lib_lockfile.h"
#ifndef nitems
#define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
return strdup(got_repo_get_path_git_dir(repo));
return got_repo_get_path_refs(repo);
+}
+
+static int
+is_valid_ref_name(const char *name)
+{
+ const char *s, *slash, *seg;
+ const char forbidden[] = { ' ', '~', '^', ':', '?', '*', '[' , '\\' };
+ const char *forbidden_seq[] = { "//", "..", "@{" };
+ const char *lfs = GOT_LOCKFILE_SUFFIX;
+ const size_t lfs_len = sizeof(GOT_LOCKFILE_SUFFIX) - 1;
+ int i;
+
+ if (name[0] == '@' && name[1] == '\0')
+ return 0;
+
+ slash = strchr(name, '/');
+ if (slash == NULL)
+ return 0;
+
+ s = name;
+ seg = s;
+ if (seg[0] == '\0' || seg[0] == '.' || seg[0] == '/')
+ return 0;
+ while (*s) {
+ for (i = 0; i < nitems(forbidden); i++) {
+ if (*s == forbidden[i])
+ return 0;
+ }
+ for (i = 0; i < nitems(forbidden_seq); i++) {
+ if (s[0] == forbidden_seq[i][0] &&
+ s[1] == forbidden_seq[i][1])
+ return 0;
+ }
+ if (iscntrl((unsigned char)s[0]))
+ return 0;
+ if (s[0] == '.' && s[1] == '\0')
+ return 0;
+ if (*s == '/') {
+ const char *nextseg = s + 1;
+ if (nextseg[0] == '\0' || nextseg[0] == '.' ||
+ nextseg[0] == '/')
+ return 0;
+ if (seg <= s - lfs_len &&
+ strncmp(s - lfs_len, lfs, lfs_len) == 0)
+ return 0;
+ seg = nextseg;
+ }
+ s++;
+ }
+
+ if (seg <= s - lfs_len &&
+ strncmp(s - lfs_len, lfs, lfs_len) == 0)
+ return 0;
+
+ return 1;
}
const struct got_error *
{
const struct got_error *err = NULL;
+ if (!is_valid_ref_name(name))
+ return got_error(GOT_ERR_BAD_REF_NAME);
+
*ref = calloc(1, sizeof(**ref));
if (*ref == NULL)
return got_error_from_errno();