summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: de2eb7f)
raw | patch | inline | side by side (parent: de2eb7f)
author | Linus Torvalds <torvalds@g5.osdl.org> | |
Wed, 27 Jul 2005 22:29:38 +0000 (15:29 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Thu, 28 Jul 2005 01:57:13 +0000 (18:57 -0700) |
The old mode conversion was not only complex, it also refused to change
the length of a mode, which made it fragile. By moving the mode
conversion around a bit, we can not only simplify it, it also ends up
being more powerful.
Also fix a memory leak that made it impossible to convert huge archives
without tons and tons of memory.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
the length of a mode, which made it fragile. By moving the mode
conversion around a bit, we can not only simplify it, it also ends up
being more powerful.
Also fix a memory leak that made it impossible to convert huge archives
without tons and tons of memory.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
convert-cache.c | patch | blob | history |
diff --git a/convert-cache.c b/convert-cache.c
index ee599f1c027fc829ab98a3ba489a5c4bfd7e9977..8916a3692f89df0d96e8bbdf885f6b9eae6a1212 100644 (file)
--- a/convert-cache.c
+++ b/convert-cache.c
struct entry *entry;
if (get_sha1_hex(buffer, sha1))
- die("bad sha1");
+ die("expected sha1, got '%s'", buffer);
entry = convert_entry(sha1);
memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
}
+static unsigned int convert_mode(unsigned int mode)
+{
+ unsigned int newmode;
+
+ newmode = mode & S_IFMT;
+ if (S_ISREG(mode))
+ newmode |= (mode & 0100) ? 0755 : 0644;
+ return newmode;
+}
+
static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
{
char *new = xmalloc(size);
if (!path || sscanf(buffer, "%o", &mode) != 1)
die("bad tree conversion");
+ mode = convert_mode(mode);
path++;
if (memcmp(path, base, baselen))
break;
@@ -116,34 +127,6 @@ static int write_subdirectory(void *buffer, unsigned long size, const char *base
return used;
}
-static int convert_mode(char *buffer)
-{
- char *end;
- unsigned short mode = strtoul(buffer, &end, 8);
- unsigned short newmode;
- char num[10];
- int len;
-
- if (*end != ' ')
- die("corrupt tree object");
- switch (mode) {
- case S_IFREG | 0644:
- case S_IFREG | 0755:
- case S_IFLNK:
- case S_IFDIR:
- return 0;
- }
- newmode = 0;
- if (S_ISREG(mode))
- newmode = (mode & 0100) ? 0755 : 0644;
- newmode |= mode & S_IFMT;
- len = sprintf(num, "%o", newmode);
- if (len != end - buffer)
- return error("unable to convert tree entry mode %o to %o", mode, newmode);
- memcpy(buffer, num, len);
- return 0;
-}
-
static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
{
void *orig_buffer = buffer;
@@ -152,7 +135,6 @@ static void convert_tree(void *buffer, unsigned long size, unsigned char *result
while (size) {
int len = 1+strlen(buffer);
- convert_mode(buffer);
convert_binary_sha1(buffer + len);
len += 20;
@@ -289,6 +271,8 @@ static void convert_commit(void *buffer, unsigned long size, unsigned char *resu
void *orig_buffer = buffer;
unsigned long orig_size = size;
+ if (memcmp(buffer, "tree ", 5))
+ die("Bad commit '%s'", buffer);
convert_ascii_sha1(buffer+5);
buffer += 46; /* "tree " + "hex sha1" + "\n" */
while (!memcmp(buffer, "parent ", 7)) {
die("unknown object type '%s' in %s", type, sha1_to_hex(sha1));
entry->converted = 1;
free(buffer);
+ free(data);
return entry;
}