From b0ad0cbf99c835ff346f0cd0f3aa0d2e45686923 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Wed, 24 Jul 2013 10:05:02 +0200 Subject: [PATCH] Get rid of the usage of PATH_MAX PATH_MAX is optional in POSIX, so avoid its unconditional usage allocating and freeing buffers as needed. To avoid too many malloc/free in the for loop in FindFileInXkbPath, a buffer is grown according to the size needed at each iteration. --- src/xkbcomp/include.c | 34 +++++++++++++++++++++++++++------- test/common.c | 41 ++++++++++++++++++++++++++++++++++------- test/test.h | 2 +- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/xkbcomp/include.c b/src/xkbcomp/include.c index b4a4014..280bbbd 100644 --- a/src/xkbcomp/include.c +++ b/src/xkbcomp/include.c @@ -199,17 +199,34 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name, { unsigned int i; FILE *file = NULL; - char buf[PATH_MAX]; + char *buf = NULL; const char *typeDir; + size_t buf_size = 0, typeDirLen, name_len; typeDir = DirectoryForInclude(type); + typeDirLen = strlen(typeDir); + name_len = strlen(name); for (i = 0; i < xkb_context_num_include_paths(ctx); i++) { - int ret = snprintf(buf, sizeof(buf), "%s/%s/%s", - xkb_context_include_path_get(ctx, i), - typeDir, name); - if (ret >= (ssize_t) sizeof(buf)) { - log_err(ctx, "File name (%s/%s/%s) too long\n", + size_t new_buf_size = strlen(xkb_context_include_path_get(ctx, i)) + + typeDirLen + name_len + 3; + int ret; + if (new_buf_size > buf_size) { + void *buf_new = realloc(buf, new_buf_size); + if (buf_new) { + buf_size = new_buf_size; + buf = buf_new; + } else { + log_err(ctx, "Cannot realloc for name (%s/%s/%s)\n", + xkb_context_include_path_get(ctx, i), typeDir, name); + continue; + } + } + ret = snprintf(buf, buf_size, "%s/%s/%s", + xkb_context_include_path_get(ctx, i), + typeDir, name); + if (ret < 0) { + log_err(ctx, "snprintf error (%s/%s/%s)\n", xkb_context_include_path_get(ctx, i), typeDir, name); continue; } @@ -242,11 +259,14 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name, xkb_context_failed_include_path_get(ctx, i)); } + free(buf); return NULL; } if (pathRtrn) - *pathRtrn = strdup(buf); + *pathRtrn = buf; + else + free(buf); return file; } diff --git a/test/common.c b/test/common.c index 7b4ee00..796904e 100644 --- a/test/common.c +++ b/test/common.c @@ -138,13 +138,22 @@ test_key_seq(struct xkb_keymap *keymap, ...) return ret; } -const char * +char * test_get_path(const char *path_rel) { - static char path[PATH_MAX]; + char *path; + size_t path_len; const char *srcdir = getenv("srcdir"); - snprintf(path, PATH_MAX - 1, + path_len = strlen(srcdir ? srcdir : ".") + + strlen(path_rel ? path_rel : "") + 12; + path = malloc(path_len); + if (!path) { + fprintf(stderr, "Failed to allocate path (%d chars) for %s\n", + (int) path_len, path); + return NULL; + } + snprintf(path, path_len, "%s/test/data/%s", srcdir ? srcdir : ".", path_rel ? path_rel : ""); @@ -155,10 +164,15 @@ char * test_read_file(const char *path_rel) { struct stat info; - char *ret, *tmp; + char *ret, *tmp, *path; int fd, count, remaining; - fd = open(test_get_path(path_rel), O_RDONLY); + path = test_get_path(path_rel); + if (!path) + return NULL; + + fd = open(path, O_RDONLY); + free(path); if (fd < 0) return NULL; @@ -195,6 +209,7 @@ test_get_context(enum test_context_flags test_flags) { enum xkb_context_flags ctx_flags; struct xkb_context *ctx; + char *path; ctx_flags = XKB_CONTEXT_NO_DEFAULT_INCLUDES; if (test_flags & CONTEXT_ALLOW_ENVIRONMENT_NAMES) { @@ -212,7 +227,12 @@ test_get_context(enum test_context_flags test_flags) if (!ctx) return NULL; - xkb_context_include_path_append(ctx, test_get_path("")); + path = test_get_path(""); + if (!path) + return NULL; + + xkb_context_include_path_append(ctx, path); + free(path); return ctx; } @@ -222,11 +242,16 @@ test_compile_file(struct xkb_context *context, const char *path_rel) { struct xkb_keymap *keymap; FILE *file; - const char *path = test_get_path(path_rel); + char *path; + + path = test_get_path(path_rel); + if (!path) + return NULL; file = fopen(path, "r"); if (!file) { fprintf(stderr, "Failed to open path: %s\n", path); + free(path); return NULL; } assert(file != NULL); @@ -237,10 +262,12 @@ test_compile_file(struct xkb_context *context, const char *path_rel) if (!keymap) { fprintf(stderr, "Failed to compile path: %s\n", path); + free(path); return NULL; } fprintf(stderr, "Successfully compiled path: %s\n", path); + free(path); return keymap; } diff --git a/test/test.h b/test/test.h index 804606e..95afbea 100644 --- a/test/test.h +++ b/test/test.h @@ -49,7 +49,7 @@ test_key_seq(struct xkb_keymap *keymap, ...); int test_key_seq_va(struct xkb_keymap *keymap, va_list args); -const char * +char * test_get_path(const char *path_rel); char * -- 1.8.3.2