summaryrefslogtreecommitdiff
path: root/solenv/bin
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2012-08-08 23:30:40 +0200
committerMichael Stahl <mstahl@redhat.com>2012-08-08 23:36:37 +0200
commit3ea6b1c1594fa3fdb7e13c544b3beecd369b67d0 (patch)
tree56df58adfa169e9403a6d70d6c3ea9d0dd832ea9 /solenv/bin
parent45a3e4dd7941e3cf5c1be5e966872338c3be1110 (diff)
concat-deps: fix crashes due to modifying hash keys:
After a string has been passed as key parameter to hash_store, it must not be modified, as happens in the print_nodotdot and print_fullpaths functions; if it doesn't crash then the dep files are twice as large in a MSVC build because duplicates are not eliminated. (regression from c2b467b84a81bd45ca9df1f7f07e2700fd6e396a) Change-Id: I0ae96a7fbcefa20b118717d923f60b4f2255a642
Diffstat (limited to 'solenv/bin')
-rw-r--r--solenv/bin/concat-deps.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/solenv/bin/concat-deps.c b/solenv/bin/concat-deps.c
index 4c2aaf44adbc..38d251f2b592 100644
--- a/solenv/bin/concat-deps.c
+++ b/solenv/bin/concat-deps.c
@@ -687,52 +687,58 @@ int fd;
return buffer;
}
-static inline void print_nodotdot(char* path)
+static void _cancel_relative(char* base, char** ref_cursor, char** ref_cursor_out, char* end)
{
-char* pathpart;
-char* lastnondotdot;
- pathpart = path;
- lastnondotdot = NULL;
- while(pathpart != NULL)
+ char* cursor = *ref_cursor;
+ char* cursor_out = *ref_cursor_out;
+
+ do
{
- if(strncmp(pathpart, "/../", 4) == 0)
- {
- if(!lastnondotdot)
- break; /* this should never happen with abs. paths */
- memmove(lastnondotdot, pathpart+4, strlen(pathpart)-3);
- lastnondotdot = NULL;
- pathpart = path;
- }
- else
- {
- lastnondotdot = pathpart+1;
- pathpart = strchr(pathpart+1,'/');
- }
+ cursor += 3;
+ while(cursor_out > base && cursor_out[-1] == '/')
+ cursor_out--;
+ while(cursor_out > base && *--cursor_out != '/');
+ }
+ while(cursor + 3 < end && !memcmp(cursor, "/../", 4));
+ *ref_cursor = cursor;
+ *ref_cursor_out = cursor_out;
+}
+
+static inline void eat_space(char ** token)
+{
+ while ((' ' == **token) || ('\t' == **token)) {
+ ++(*token);
}
- fputs(path, stdout);
}
/* prefix paths to absolute */
static inline void print_fullpaths(char* line)
{
char* token;
+char* end;
- token = strtok(line," ");
- while(token != NULL)
+ token = line;
+ eat_space(&token);
+ while (*token)
{
+ end = token;
+ while (*end && (' ' != *end) && ('\t' != *end)) {
+ ++end;
+ }
if(*token == ':' || *token == '\\' || *token == '/' || *token == '$'
|| ':' == token[1])
{
- fputs(token, stdout);
+ fwrite(token, end - token, 1, stdout);
}
else
{
fputs(base_dir_var, stdout);
fputc('/', stdout);
- print_nodotdot(token);
+ fwrite(token, end - token, 1, stdout);
}
fputc(' ', stdout);
- token = strtok(NULL," ");
+ token = end;
+ eat_space(&token);
}
}
@@ -767,6 +773,13 @@ off_t size;
}
else if(*cursor == '/')
{
+ if(cursor + 3 < end)
+ {
+ if(!memcmp(cursor, "/../", 4))
+ {
+ _cancel_relative(base, &cursor, &cursor_out, end);
+ }
+ }
*cursor_out++ = *cursor++;
}
else if(*cursor == '\n')
@@ -785,6 +798,8 @@ off_t size;
*/
if(hash_store(dep_hash, base, (int)(cursor_out - base)))
{
+ /* DO NOT modify base after it has been added
+ as key by hash_store */
print_fullpaths(base);
putc('\n', stdout);
}