File rpm2targz-9.0.0.4g-lzma.patch of Package rpm2targz

Description: Unpack lzma compressed rpms.
Index: rpmoffset.c
===================================================================
--- rpmoffset.c.orig
+++ rpmoffset.c
@@ -25,6 +25,15 @@ typedef struct {
 	const size_t len;
 } magic_t;
 
+/* LZMA is some fuzzy crap */
+int is_magic_lzma(const char *buf)
+{
+	return (buf[0] == 0x5d && buf[4] < 0x20) &&
+		(!memcmp(buf + 10, "\x00\x00\x00", 3) ||
+		 !memcmp(buf +  5, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8));
+}
+#define magic_lzma_len 13
+
 static const unsigned char magic_gzip[]  = { '\037', '\213', '\010' };
 static const unsigned char magic_bzip2[] = { 'B', 'Z', 'h' };
 static const unsigned char magic_xz[]    = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
@@ -36,12 +45,21 @@ static const magic_t magics[] = {
 #undef DECLARE_MAGIC_T
 };
 #define MAGIC_SIZE_MIN 3
-#define MAGIC_SIZE_MAX 6
+#define MAGIC_SIZE_MAX 13
+
+static int show_magic;
+
+static int magic_finish(const char *magic, size_t offset)
+{
+	if (show_magic)
+		printf("%s ", magic);
+	printf("%zu\n", offset);
+	return 0;
+}
 
 int main(int argc, char *argv[])
 {
-	int show_magic = 0;
-	size_t i, read_cnt, offset, left;
+	size_t i, read_cnt, offset, left, lzma_offset;
 	FILE *fp = stdin;
 	char p[BUFSIZ];
 
@@ -56,6 +74,7 @@ int main(int argc, char *argv[])
 	}
 	/* fp = fopen(argv[1], "r"); */
 
+	lzma_offset = 0;
 	offset = left = 0;
 	while (1) {
 		read_cnt = fread(p + left, 1, sizeof(p) - left, fp);
@@ -69,12 +88,17 @@ int main(int argc, char *argv[])
 				continue;
 
 			needle = memmem(p, sizeof(p), magics[i].magic, magics[i].len);
-			if (needle) {
-				if (show_magic)
-					printf("%s ", magics[i].type);
-				printf("%zu\n", offset + (needle - p));
-				return 0;
-			}
+			if (needle)
+				return magic_finish(magics[i].type, offset + (needle - p));
+		}
+
+		/* Scan for LZMA magic, but don't return yet ... */
+		if (!lzma_offset && read_cnt + left >= magic_lzma_len) {
+			for (i = 0; i <= read_cnt + left - magic_lzma_len; ++i)
+				if (is_magic_lzma(p + i)) {
+					lzma_offset = offset + i;
+					break;
+				}
 		}
 
 		memmove(p, p + left + read_cnt - MAGIC_SIZE_MIN + 1, MAGIC_SIZE_MIN - 1);
@@ -86,6 +110,10 @@ int main(int argc, char *argv[])
 		}
 	}
 
+	/* Delay till the end for LZMA archives since it is too fuzzy */
+	if (lzma_offset)
+		return magic_finish("lzma", lzma_offset);
+
 	if (ferror(stdin))
 		perror(argv[0]);
 
openSUSE Build Service is sponsored by