summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c448357)
raw | patch | inline | side by side (parent: c448357)
author | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Thu, 2 Jun 2005 14:57:25 +0000 (07:57 -0700) | ||
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Thu, 2 Jun 2005 14:57:25 +0000 (07:57 -0700) |
Make a separate helper for parsing the header of an object file
(really carefully) and for unpacking the rest. This means that
anybody who uses the "unpack_sha1_header()" interface can easily
look at the header and decide to unpack the rest too, without
doing any extra work.
(really carefully) and for unpacking the rest. This means that
anybody who uses the "unpack_sha1_header()" interface can easily
look at the header and decide to unpack the rest too, without
doing any extra work.
cache.h | patch | blob | history | |
sha1_file.c | patch | blob | history |
index 69b63ba1d40d7891b9814fa97535fc6489564ad8..aa74bcc0179fc20c4ddc490d6da4bf0730a2fb9e 100644 (file)
--- a/cache.h
+++ b/cache.h
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern void * map_sha1_file(const unsigned char *sha1, unsigned long *size);
extern int unpack_sha1_header(z_stream *stream, void *map, unsigned long mapsize, void *buffer, unsigned long size);
+extern int parse_sha1_header(char *hdr, char *type, unsigned long *sizep);
extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size);
extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size);
extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
diff --git a/sha1_file.c b/sha1_file.c
index bc3d70fdd63bba3e508a23bc983590e5bbd3f8f5..af39e8860ec55d420c724a079be02379288e3f61 100644 (file)
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -320,31 +320,85 @@ int unpack_sha1_header(z_stream *stream, void *map, unsigned long mapsize, void
return inflate(stream, 0);
}
+void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)
+{
+ int bytes = strlen(buffer) + 1;
+ char *buf = xmalloc(1+size);
+
+ memcpy(buf, buffer + bytes, stream->total_out - bytes);
+ bytes = stream->total_out - bytes;
+ if (bytes < size) {
+ stream->next_out = buf + bytes;
+ stream->avail_out = size - bytes;
+ while (inflate(stream, Z_FINISH) == Z_OK)
+ /* nothing */;
+ }
+ buf[size] = 0;
+ inflateEnd(stream);
+ return buf;
+}
+
+/*
+ * We used to just use "sscanf()", but that's actually way
+ * too permissive for what we want to check. So do an anal
+ * object header parse by hand.
+ */
+int parse_sha1_header(char *hdr, char *type, unsigned long *sizep)
+{
+ int i;
+ unsigned long size;
+
+ /*
+ * The type can be at most ten bytes (including the
+ * terminating '\0' that we add), and is followed by
+ * a space.
+ */
+ i = 10;
+ for (;;) {
+ char c = *hdr++;
+ if (c == ' ')
+ break;
+ if (!--i)
+ return -1;
+ *type++ = c;
+ }
+ *type = 0;
+
+ /*
+ * The length must follow immediately, and be in canonical
+ * decimal format (ie "010" is not valid).
+ */
+ size = *hdr++ - '0';
+ if (size > 9)
+ return -1;
+ if (size) {
+ for (;;) {
+ unsigned long c = *hdr - '0';
+ if (c > 9)
+ break;
+ hdr++;
+ size = size * 10 + c;
+ }
+ }
+ *sizep = size;
+
+ /*
+ * The length must be followed by a zero byte
+ */
+ return *hdr ? -1 : 0;
+}
+
void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size)
{
- int ret, bytes;
+ int ret;
z_stream stream;
- char buffer[8192];
- unsigned char *buf;
+ char hdr[8192];
- ret = unpack_sha1_header(&stream, map, mapsize, buffer, sizeof(buffer));
- if (ret < Z_OK || sscanf(buffer, "%10s %lu", type, size) != 2)
+ ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
+ if (ret < Z_OK || parse_sha1_header(hdr, type, size) < 0)
return NULL;
- bytes = strlen(buffer) + 1;
- buf = xmalloc(1+*size);
-
- memcpy(buf, buffer + bytes, stream.total_out - bytes);
- bytes = stream.total_out - bytes;
- if (bytes < *size && ret == Z_OK) {
- stream.next_out = buf + bytes;
- stream.avail_out = *size - bytes;
- while (inflate(&stream, Z_FINISH) == Z_OK)
- /* nothing */;
- }
- buf[*size] = 0;
- inflateEnd(&stream);
- return buf;
+ return unpack_sha1_rest(&stream, hdr, *size);
}
void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)