public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] portage r15734 - main/branches/prefix/src
@ 2010-03-03 18:39 Fabian Groffen (grobian)
  0 siblings, 0 replies; only message in thread
From: Fabian Groffen (grobian) @ 2010-03-03 18:39 UTC (permalink / raw
  To: gentoo-commits

Author: grobian
Date: 2010-03-03 18:39:31 +0000 (Wed, 03 Mar 2010)
New Revision: 15734

Modified:
   main/branches/prefix/src/chpathtool.c
Log:
change approach not to use padding zero bytes, but leading slashes to get around subtle problems that are caused by a changing string length

Modified: main/branches/prefix/src/chpathtool.c
===================================================================
--- main/branches/prefix/src/chpathtool.c	2010-03-03 10:16:07 UTC (rev 15733)
+++ main/branches/prefix/src/chpathtool.c	2010-03-03 18:39:31 UTC (rev 15734)
@@ -1,4 +1,4 @@
-/* Copyright Gentoo Foundation 2006-2009
+/* Copyright Gentoo Foundation 2006-2010
  * Author: Fabian Groffen <grobian@gentoo.org>
  * $Id$
  *
@@ -38,6 +38,7 @@
  * value, hoping it is enough */
 #define MAX_PATH 1024
 
+/* structure to track and trace hardlinks */
 typedef struct _file_hlink {
 	dev_t    st_dev;            /* device inode resides on */
 	ino_t    st_ino;            /* inode's number */
@@ -102,6 +103,10 @@
 	return(NULL);
 }
 
+/**
+ * Copies the given file to the output file with prefix transformations
+ * on the fly.
+ */
 static int chpath(const char *fi, const char *fo) {
 	FILE *fin;
 	FILE *fout;
@@ -110,6 +115,9 @@
 	size_t padding;
 	char *tmp;
 	char buf[BUFSIZE + 1];
+	char firstblock;
+	char *lvalue = value;
+	size_t lvaluelen = valuelen;
 
 	/* make sure there is a trailing zero-byte, such that strstr and
 	 * strchr won't go out of bounds causing segfaults.  */
@@ -128,9 +136,40 @@
 
 	pos = 0;
 	padding = 0;
+	firstblock = 1;
 	while ((len = fread(buf + pos, 1, BUFSIZE - pos, fin)) != 0 || pos > 0) {
+		if (firstblock == 1) {
+			firstblock = 0;
+			/* examine the bytes we read to judge if they are binary or
+			 * text; in case of the latter we can avoid writing ugly
+			 * paths with zilions of backslashes */
+			for (pos = 0; pos < len; pos++) {
+				/* this is a very stupid assumption, but I don't know
+				 * anything better: if we find a byte that's out of
+				 * ASCII character scope, we assume this is binary */
+				if (buf[pos] < ' ' || buf[pos] > '~') {
+					/* Make sure we don't mess up code, GCC for instance
+					 * hardcodes the result of strlen("string") in
+					 * object code.  This means we can nicely replace
+					 * this string with a shorter NULL-terminated one,
+					 * but that won't change the hardcoded output of the
+					 * original strlen.  Hence, pad the value with
+					 * slashes until it is of same size as magic. */
+					lvalue = alloca(sizeof(char) * (magiclen + 1));
+					lvaluelen = magiclen;
+					snprintf(lvalue, lvaluelen + 1, "%*s",
+							(int)magiclen, value);
+					tmp = lvalue;
+					while (*tmp == ' ')
+						*tmp++ = '/';
+					break;
+				}
+			}
+			pos = 0;
+		}
 		len += pos;
 		if ((tmp = memstr(buf, magic, len)) != NULL) {
+			/* if binary : */
 			if (tmp == buf) {
 				if (len < magiclen) {
 					/* must be last piece */
@@ -138,9 +177,9 @@
 					break;
 				}
 				/* do some magic, overwrite it basically */
-				fwrite(value, valuelen, 1, fout);
+				fwrite(lvalue, lvaluelen, 1, fout);
 				/* store what we need to correct */
-				padding += magiclen - valuelen;
+				padding += magiclen - lvaluelen;
 				/* move away the magic */
 				pos = len - magiclen;
 				memmove(buf, buf + magiclen, pos);
@@ -190,7 +229,7 @@
 	char *tt;
 
 	if (lstat(trg, &s) != 0) {
-		/* initially create directory read/writably by owner, set
+		/* initially create directory read/writable by owner, set
 		 * permissions like src when we're done processing this
 		 * directory. */
 		if (mkdir(trg, S_IRWXU) != 0) {
@@ -445,6 +484,8 @@
 		fprintf(stderr, "usage: [-q] in-file out-file magic value\n");
 		fprintf(stderr, "       if in-file is a directory, out-file is "
 				"treated as one too\n");
+		fprintf(stderr, " -q  suppress messages about being unable to "
+				"write padding bytes\n");
 		return(-1);
 	}
 




^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-03-03 18:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-03 18:39 [gentoo-commits] portage r15734 - main/branches/prefix/src Fabian Groffen (grobian)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox