Staging
v0.5.1
https://github.com/git/git
Revision a2239b79e554bab92abe47d8568cbbfe5c77ce85 authored by Junio C Hamano on 16 October 2005, 00:30:15 UTC, committed by Junio C Hamano on 16 October 2005, 01:10:02 UTC
Contains the following changes since v0.99.8c.

Johannes Schindelin:
      Teach git-status about spaces in file names also on MacOSX
      t5400-send-pack relies on a working cpio

Jonas Fonseca:
      git.sh: quote all paths

Junio C Hamano:
      Also force LC_ALL in test scripts.
      OpenBSD needs the strcasestr replacement.
      git-check-ref-format: reject funny ref names.
      Refuse to create funny refs in clone-pack, git-fetch and receive-pack.
      Ignore funny refname sent from remote
      Introduce notation "ref^{type}".

Martin Langhoff:
      cvsimport: don't pass --cvs-direct if user options contradict us

Ralf Baechle:
      rsh.c: typo fix

Note that "funny ref" bits are not strictly fixes but rather
backport from the "master" branch.  They will prevent refs and
heads with funny names from being created.  In addition, what is
in the master branch will start feeding the clients unwrapped
tag information to help Martin's findtags and possibly later
Cogito.  These backported "funny ref" changes are to prevent
clients on the "maint" branch from getting confused when talking
with newer git-upload-pack and when reading from info/refs file
prepared with newer git-update-server-info.

Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 4baf5dd
Raw File
Tip revision: a2239b79e554bab92abe47d8568cbbfe5c77ce85 authored by Junio C Hamano on 16 October 2005, 00:30:15 UTC
GIT v0.99.8d
Tip revision: a2239b7
mktag.c
#include "cache.h"

/*
 * A signature file has a very simple fixed format: three lines
 * of "object <sha1>" + "type <typename>" + "tag <tagname>",
 * followed by some free-form signature that git itself doesn't
 * care about, but that can be verified with gpg or similar.
 *
 * The first three lines are guaranteed to be at least 63 bytes:
 * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
 * shortest possible type-line, and "tag .\n" at 6 bytes is the
 * shortest single-character-tag line. 
 *
 * We also artificially limit the size of the full object to 8kB.
 * Just because I'm a lazy bastard, and if you can't fit a signature
 * in that size, you're doing something wrong.
 */

// Some random size
#define MAXSIZE (8192)

/*
 * We refuse to tag something we can't verify. Just because.
 */
static int verify_object(unsigned char *sha1, const char *expected_type)
{
	int ret = -1;
	char type[100];
	unsigned long size;
	void *buffer = read_sha1_file(sha1, type, &size);

	if (buffer) {
		if (!strcmp(type, expected_type))
			ret = check_sha1_signature(sha1, buffer, size, type);
		free(buffer);
	}
	return ret;
}

static int verify_tag(char *buffer, unsigned long size)
{
	int typelen;
	char type[20];
	unsigned char sha1[20];
	const char *object, *type_line, *tag_line, *tagger_line;

	if (size < 64 || size > MAXSIZE-1)
		return -1;
	buffer[size] = 0;

	/* Verify object line */
	object = buffer;
	if (memcmp(object, "object ", 7))
		return -1;
	if (get_sha1_hex(object + 7, sha1))
		return -1;

	/* Verify type line */
	type_line = object + 48;
	if (memcmp(type_line - 1, "\ntype ", 6))
		return -1;

	/* Verify tag-line */
	tag_line = strchr(type_line, '\n');
	if (!tag_line)
		return -1;
	tag_line++;
	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
		return -1;

	/* Get the actual type */
	typelen = tag_line - type_line - strlen("type \n");
	if (typelen >= sizeof(type))
		return -1;
	memcpy(type, type_line+5, typelen);
	type[typelen] = 0;

	/* Verify that the object matches */
	if (get_sha1_hex(object + 7, sha1))
		return -1;
	if (verify_object(sha1, type))
		return -1;

	/* Verify the tag-name: we don't allow control characters or spaces in it */
	tag_line += 4;
	for (;;) {
		unsigned char c = *tag_line++;
		if (c == '\n')
			break;
		if (c > ' ')
			continue;
		return -1;
	}

	/* Verify the tagger line */
	tagger_line = tag_line;

	if (memcmp(tagger_line, "tagger", 6) || (tagger_line[6] == '\n'))
		return -1;

	/* The actual stuff afterwards we don't care about.. */
	return 0;
}

int main(int argc, char **argv)
{
	unsigned long size;
	char buffer[MAXSIZE];
	unsigned char result_sha1[20];

	if (argc != 1)
		usage("cat <signaturefile> | git-mktag");

	// Read the signature
	size = 0;
	for (;;) {
		int ret = read(0, buffer + size, MAXSIZE - size);
		if (!ret)
			break;
		if (ret < 0) {
			if (errno == EAGAIN)
				continue;
			break;
		}
		size += ret;
	}

	// Verify it for some basic sanity: it needs to start with "object <sha1>\ntype\ntagger "
	if (verify_tag(buffer, size) < 0)
		die("invalid tag signature file");

	if (write_sha1_file(buffer, size, "tag", result_sha1) < 0)
		die("unable to write tag file");
	printf("%s\n", sha1_to_hex(result_sha1));
	return 0;
}
back to top