From 7a4371dce7c42922e27f895d33a316f821925656 Mon Sep 17 00:00:00 2001 From: David Barr Date: Tue, 25 May 2010 23:52:13 +1000 Subject: [PATCH] Implement token buffers from parser through repo_tree. A little dodgy regarding overruns. Sample test not passing at the moment. Signed-off-by: David Barr --- repo_tree.c | 33 +++++++++++---------------------- repo_tree.h | 11 ++++++----- string_pool.c | 4 +++- svndump.c | 20 +++++++------------- 4 files changed, 27 insertions(+), 41 deletions(-) diff --git a/repo_tree.c b/repo_tree.c index 7c4a70f..35a1595 100644 --- a/repo_tree.c +++ b/repo_tree.c @@ -106,19 +106,13 @@ static repo_dir_t *repo_clone_dir(repo_dir_t *orig_dir, uint32_t padding) return dir_pointer(new_o); } -static char repo_path_buffer[REPO_MAX_PATH_LEN]; -static repo_dirent_t *repo_read_dirent(uint32_t revision, char *path) +static repo_dirent_t *repo_read_dirent(uint32_t revision, uint32_t *path) { - char *ctx = NULL; uint32_t name = 0; repo_dir_t *dir = NULL; repo_dirent_t *dirent = NULL; dir = repo_commit_root_dir(commit_pointer(revision)); - strncpy(repo_path_buffer, path, REPO_MAX_PATH_LEN); - repo_path_buffer[REPO_MAX_PATH_LEN - 1] = '\0'; - path = repo_path_buffer; - for (name = pool_tok_r(path, "/", &ctx); - ~name; name = pool_tok_r(NULL, "/", &ctx)) { + while (~(name = *path++)) { dirent = repo_dirent_by_name(dir, name); if (dirent == NULL) { return NULL; @@ -132,22 +126,17 @@ static repo_dirent_t *repo_read_dirent(uint32_t revision, char *path) } static void -repo_write_dirent(char *path, uint32_t mode, uint32_t content_offset, +repo_write_dirent(uint32_t *path, uint32_t mode, uint32_t content_offset, uint32_t del) { - char *ctx; - uint32_t name, revision, dirent_o, dir_o, parent_dir_o; + uint32_t name, revision, dirent_o = ~0, dir_o = ~0, parent_dir_o = ~0; repo_dir_t *dir; repo_dirent_t *dirent = NULL; revision = active_commit; dir = repo_commit_root_dir(commit_pointer(revision)); dir = repo_clone_dir(dir, 0); commit_pointer(revision)->root_dir_offset = dir_offset(dir); - strncpy(repo_path_buffer, path, REPO_MAX_PATH_LEN); - repo_path_buffer[REPO_MAX_PATH_LEN - 1] = '\0'; - path = repo_path_buffer; - for (name = pool_tok_r(path, "/", &ctx); ~name; - name = pool_tok_r(NULL, "/", &ctx)) { + while (~(name = *path++)) { parent_dir_o = dir_offset(dir); dirent = repo_dirent_by_name(dir, name); if (dirent == NULL) { @@ -188,7 +177,7 @@ repo_write_dirent(char *path, uint32_t mode, uint32_t content_offset, } } -uint32_t repo_copy(uint32_t revision, char *src, char *dst) +uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst) { uint32_t mode = 0, content_offset = 0; repo_dirent_t *src_dirent; @@ -201,12 +190,12 @@ uint32_t repo_copy(uint32_t revision, char *src, char *dst) return mode; } -void repo_add(char *path, uint32_t mode, uint32_t blob_mark) +void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark) { repo_write_dirent(path, mode, blob_mark, 0); } -uint32_t repo_replace(char *path, uint32_t blob_mark) +uint32_t repo_replace(uint32_t *path, uint32_t blob_mark) { uint32_t mode = 0; repo_dirent_t *src_dirent; @@ -218,12 +207,12 @@ uint32_t repo_replace(char *path, uint32_t blob_mark) return mode; } -void repo_modify(char *path, uint32_t mode, uint32_t blob_mark) +void repo_modify(uint32_t *path, uint32_t mode, uint32_t blob_mark) { repo_write_dirent(path, mode, blob_mark, 0); } -void repo_delete(char *path) +void repo_delete(uint32_t *path) { repo_write_dirent(path, 0, 0, 1); } @@ -298,7 +287,7 @@ repo_diff_r(uint32_t depth, uint32_t *path, repo_dir_t *dir1, } } -static uint32_t path_stack[1000]; +static uint32_t path_stack[REPO_MAX_PATH_DEPTH]; void repo_diff(uint32_t r1, uint32_t r2) { repo_diff_r(0, diff --git a/repo_tree.h b/repo_tree.h index 2d645dc..4a1c60d 100644 --- a/repo_tree.h +++ b/repo_tree.h @@ -10,16 +10,17 @@ #define REPO_MODE_LNK 0120000 #define REPO_MAX_PATH_LEN 4096 +#define REPO_MAX_PATH_DEPTH 1000 -uint32_t repo_copy(uint32_t revision, char *src, char *dst); +uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst); -void repo_add(char *path, uint32_t mode, uint32_t blob_mark); +void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark); -uint32_t repo_replace(char *path, uint32_t blob_mark); +uint32_t repo_replace(uint32_t *path, uint32_t blob_mark); -void repo_modify(char *path, uint32_t mode, uint32_t blob_mark); +void repo_modify(uint32_t *path, uint32_t mode, uint32_t blob_mark); -void repo_delete(char *path); +void repo_delete(uint32_t *path); void repo_commit(uint32_t revision, char *author, char *log, char *uuid, char *url, time_t timestamp); diff --git a/string_pool.c b/string_pool.c index cffb9ce..7b3cf5c 100644 --- a/string_pool.c +++ b/string_pool.c @@ -82,9 +82,11 @@ uint32_t pool_tok_seq(uint32_t max, uint32_t *seq, char *delim, char *str) char *context; uint32_t length, token; for (length = 0, token = pool_tok_r(str, delim, &context); - length < max && ~token; + length < max; length++, token = pool_tok_r(NULL, delim, &context)) { seq[length] = token; + if (token == ~0) + break; } return length; } diff --git a/svndump.c b/svndump.c index 8d40c70..9b6c5f6 100644 --- a/svndump.c +++ b/svndump.c @@ -44,7 +44,7 @@ static char* log_copy(uint32_t length, char *log) static struct { uint32_t action, propLength, textLength, srcRev, srcMode, mark, type; - char *src, *dst; + uint32_t src[REPO_MAX_PATH_DEPTH], dst[REPO_MAX_PATH_DEPTH]; } node_ctx; static struct { @@ -63,14 +63,10 @@ static void reset_node_ctx(char *fname) node_ctx.action = NODEACT_UNKNOWN; node_ctx.propLength = LENGTH_UNKNOWN; node_ctx.textLength = LENGTH_UNKNOWN; - if (node_ctx.src) - free(node_ctx.src); - node_ctx.src = NULL; + node_ctx.src[0] = ~0; node_ctx.srcRev = 0; node_ctx.srcMode = 0; - if (node_ctx.dst) - free(node_ctx.dst); - node_ctx.dst = fname; + pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.dst, "/", fname); node_ctx.mark = 0; } @@ -148,7 +144,7 @@ static void handle_node(void) read_props(); } - if (node_ctx.src && node_ctx.srcRev) { + if (node_ctx.srcRev) { node_ctx.srcMode = repo_copy(node_ctx.srcRev, node_ctx.src, node_ctx.dst); } @@ -169,7 +165,7 @@ static void handle_node(void) node_ctx.srcMode = repo_replace(node_ctx.dst, node_ctx.mark); } } else if (node_ctx.action == NODEACT_ADD) { - if (node_ctx.src && node_ctx.srcRev && + if (node_ctx.srcRev && node_ctx.propLength == LENGTH_UNKNOWN && node_ctx.textLength != LENGTH_UNKNOWN) { node_ctx.srcMode = repo_replace(node_ctx.dst, node_ctx.mark); @@ -218,7 +214,7 @@ static void svndump_read(char *url) reset_rev_ctx(atoi(val)); } else if (!strcmp(t, "Node-path")) { active_ctx = NODE_CTX; - reset_node_ctx(strdup(val)); + reset_node_ctx(val); } else if (!strcmp(t, "Node-kind")) { if (!strcmp(val, "dir")) { node_ctx.type = REPO_MODE_DIR; @@ -241,9 +237,7 @@ static void svndump_read(char *url) node_ctx.action = NODEACT_UNKNOWN; } } else if (!strcmp(t, "Node-copyfrom-path")) { - if (node_ctx.src) - free(node_ctx.src); - node_ctx.src = strdup(val); + pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.src, "/", val); } else if (!strcmp(t, "Node-copyfrom-rev")) { node_ctx.srcRev = atoi(val); } else if (!strcmp(t, "Text-content-length")) { -- 2.11.4.GIT