From: Olivier Valentin <valentio@free.fr>
When static buffers are used, PATH_MAX becomes the size of the provided
buffer, and is passed as a parameters to the underlying implementation.
---
frontends/framebuffer/fetch.c | 2 +-
frontends/gtk/fetch.c | 2 +-
frontends/gtk/gui.c | 2 +-
frontends/monkey/fetch.c | 2 +-
frontends/monkey/main.c | 2 +-
frontends/windows/fetch.c | 2 +-
utils/filepath.c | 143 ++++++++++++++++++----------------
utils/filepath.h | 39 +++-------
8 files changed, 92 insertions(+), 102 deletions(-)
diff --git a/frontends/framebuffer/fetch.c b/frontends/framebuffer/fetch.c
index d58a82205..f917bddf3 100644
--- a/frontends/framebuffer/fetch.c
+++ b/frontends/framebuffer/fetch.c
@@ -54,7 +54,7 @@ static nsurl *get_resource_url(const char *path)
if (strcmp(path, "favicon.ico") == 0)
path = "favicon.png";
- if (filepath_sfind(respaths, buf, path) == NSERROR_OK)
+ if (filepath_sfind(respaths, buf, PATH_MAX, path) == NSERROR_OK)
netsurf_path_to_nsurl(buf, &url);
return url;
diff --git a/frontends/gtk/fetch.c b/frontends/gtk/fetch.c
index 36ee36c17..98682ffc4 100644
--- a/frontends/gtk/fetch.c
+++ b/frontends/gtk/fetch.c
@@ -257,7 +257,7 @@ static nsurl *nsgtk_get_resource_url(const char *path)
if (strcmp(path, "favicon.ico") == 0) {
nsurl_create("resource:favicon.png", &url);
} else {
- if (filepath_sfind(respaths, buf, path) == NSERROR_OK)
+ if (filepath_sfind(respaths, buf, PATH_MAX, path) == NSERROR_OK)
netsurf_path_to_nsurl(buf, &url);
}
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index fa0c4063b..2c5558ddb 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -987,7 +987,7 @@ static nserror nsgtk_setup(int argc, char** argv, char **respath)
.pma = true,
});
- filepath_sfinddef(respath, buf, "mime.types", "/etc/");
+ filepath_sfinddef(respath, buf, PATH_MAX, "mime.types", "/etc/");
gtk_fetch_filetype_init(buf);
save_complete_init();
diff --git a/frontends/monkey/fetch.c b/frontends/monkey/fetch.c
index 96ba28d67..f6d554915 100644
--- a/frontends/monkey/fetch.c
+++ b/frontends/monkey/fetch.c
@@ -39,7 +39,7 @@ static nsurl *gui_get_resource_url(const char *path)
char buf[PATH_MAX];
nsurl *url = NULL;
- if (filepath_sfind(respaths, buf, path) == NSERROR_OK)
+ if (filepath_sfind(respaths, buf, PATH_MAX, path) == NSERROR_OK)
netsurf_path_to_nsurl(buf, &url);
return url;
diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c
index 2d6c1bd1b..35af25235 100644
--- a/frontends/monkey/main.c
+++ b/frontends/monkey/main.c
@@ -452,7 +452,7 @@ main(int argc, char **argv)
die("NetSurf failed to initialise");
}
- filepath_sfinddef(respaths, buf, "mime.types", "/etc/");
+ filepath_sfinddef(respaths, buf, PATH_MAX, "mime.types", "/etc/");
monkey_fetch_filetype_init(buf);
urldb_load(nsoption_charp(url_file));
diff --git a/frontends/windows/fetch.c b/frontends/windows/fetch.c
index cad99446b..bb5290e59 100644
--- a/frontends/windows/fetch.c
+++ b/frontends/windows/fetch.c
@@ -79,7 +79,7 @@ static nsurl *nsw32_get_resource_url(const char *path)
char buf[PATH_MAX];
nsurl *url = NULL;
- if (filepath_sfind(G_resource_pathv, buf, path) == NSERROR_OK)
+ if (filepath_sfind(G_resource_pathv, buf, PATH_MAX, path) == NSERROR_OK)
netsurf_path_to_nsurl(buf, &url);
return url;
diff --git a/utils/filepath.c b/utils/filepath.c
index 5cfcba548..82568e298 100644
--- a/utils/filepath.c
+++ b/utils/filepath.c
@@ -33,7 +33,6 @@
#include <unistd.h>
#include <string.h>
-#include "utils/dirent.h" /** \todo why is this necessary for atari to get PATH_MAX and is there a better way */
#include "utils/utils.h"
#include "utils/config.h"
#include "utils/filepath.h"
@@ -41,119 +40,121 @@
/** maximum number of elements in the resource vector */
#define MAX_RESPATH 128
-/* exported interface documented in filepath.h */
-nserror filepath_vsfindfile(char *str, const char *format, va_list ap)
+static nserror filepath_vprintpath(const char *format, va_list ap, char **retstr)
{
- char *realpathname;
- char *pathname;
- int len;
+ char *pathname = NULL;
+ int len = 0;
- pathname = malloc(PATH_MAX);
- if (pathname == NULL)
- return NSERROR_NOMEM; /* unable to allocate memory */
+ do {
+ len = vsnprintf(pathname, len, format, ap);
+ if (len <= 0)
+ return NSERROR_INVALID;
- len = vsnprintf(pathname, PATH_MAX, format, ap);
+ if (pathname != NULL) break;
- if ((len < 0) || (len >= PATH_MAX)) {
- /* error or output exceeded PATH_MAX length so
- * operation is doomed to fail.
- */
- free(pathname);
- NSERROR_BAD_SIZE;
- }
+ pathname = malloc(len + 1);
+ } while (pathname != NULL);
- realpathname = realpath(pathname, str);
+ if (pathname == NULL)
+ return NSERROR_NOMEM; /* unable to allocate memory */
- free(pathname);
+ *retstr = realpath(pathname, NULL);
- if (realpathname != NULL) {
- /* sucessfully expanded pathname */
- if (access(realpathname, R_OK) != 0) {
- /* unable to read the file */
- return NSERROR_NOT_FOUND;
- }
- }
+ if (*retstr == NULL)
+ *retstr = pathname;
+ else
+ free(pathname);
return NSERROR_OK;
}
-
-/* exported interface documented in filepath.h */
-nserror filepath_sfindfile(char *str, const char *format, ...)
-{
- va_list ap;
+static nserror filepath_printpath(char **retstr, const char *format, ...) {
nserror ret;
+ va_list ap;
va_start(ap, format);
- ret = filepath_vsfindfile(str, format, ap);
+ ret = filepath_vprintpath(format, ap, retstr);
va_end(ap);
return ret;
}
-
/* exported interface documented in filepath.h */
nserror filepath_findfile(char **retstr, const char *format, ...)
{
nserror ret;
va_list ap;
- *retstr = malloc(PATH_MAX);
- if (*retstr == NULL)
- return NSERROR_NOMEM; /* unable to allocate memory */
-
va_start(ap, format);
- ret = filepath_vsfindfile(*retstr, format, ap);
+ ret = filepath_vprintpath(format, ap, retstr);
va_end(ap);
- if (ret != NSERROR_OK) {
- free(*retstr);
- *retstr = NULL;
+ if (ret == NSERROR_OK) {
+ if (access(*retstr, F_OK) != 0) {
+ /* File not found */
+ free(*retstr);
+ *retstr = NULL;
+
+ return NSERROR_NOT_FOUND;
+ }
+
+ if (access(*retstr, R_OK) != 0) {
+ /* unable to read the file */
+ free(*retstr);
+ *retstr = NULL;
+
+ return NSERROR_PERMISSION;
+ }
}
return ret;
}
/* exported interface documented in filepath.h */
-nserror filepath_sfind(char **respathv, char *filepath, const char *filename)
+nserror filepath_sfind(char **respathv, char *filepath, size_t size, const char *filename)
{
- int respathc = 0;
+ nserror ret;
+ char *allocatedfilepath;
- if ((respathv == NULL) || (respathv[0] == NULL) || (filepath == NULL))
+ if (filepath == NULL || size == 0)
return NSERROR_INVALID;
- while (respathv[respathc] != NULL) {
- if (filepath_sfindfile(filepath, "%s/%s", respathv[respathc], filename) == NSERROR_OK) {
- return NSERROR_OK;
- }
+ ret = filepath_find(respathv, filename, &allocatedfilepath);
+ if (ret == NSERROR_OK) {
+ if (strlen(allocatedfilepath) >= size)
+ ret = NSERROR_NOSPACE;
- respathc++;
+ strncpy(filepath, allocatedfilepath, size);
+ filepath[size - 1] = '\0';
+
+ free(allocatedfilepath);
}
- return NSERROR_NOT_FOUND;
+ return ret;
}
/* exported interface documented in filepath.h */
nserror filepath_find(char **respathv, const char *filename, char **retstr)
{
- nserror ret;
+ int respathc = 0;
if ((respathv == NULL) || (respathv[0] == NULL))
return NSERROR_INVALID;
- *retstr = malloc(PATH_MAX);
- if (*retstr == NULL)
- return NSERROR_NOMEM;
+ while (respathv[respathc] != NULL) {
+ nserror ret;
- ret = filepath_sfind(respathv, *retstr, filename);
+ ret = filepath_findfile(retstr, "%s/%s", respathv[respathc], filename);
+ if (ret == NSERROR_OK)
+ return NSERROR_OK;
+ if (ret != NSERROR_NOT_FOUND)
+ return ret;
- if (ret == NSERROR_OK) {
- free(*retstr);
- *retstr = NULL;
+ respathc++;
}
- return ret;
+ return NSERROR_NOT_FOUND;
}
@@ -161,29 +162,37 @@ nserror filepath_find(char **respathv, const char *filename, char **retstr)
nserror
filepath_sfinddef(char **respathv,
char *filepath,
+ size_t size,
const char *filename,
const char *def)
{
- char t[PATH_MAX];
+ char *allocatedfilepath;
nserror ret;
if ((respathv == NULL) || (respathv[0] == NULL) || (filepath == NULL))
return NSERROR_INVALID;
- ret = filepath_sfind(respathv, filepath, filename);
+ ret = filepath_find(respathv, filename, &allocatedfilepath);
if ((ret != NSERROR_OK) && (def != NULL)) {
/* search failed, return the path specified */
- ret = NSERROR_OK;
if (def[0] == '~') {
- snprintf(t, PATH_MAX, "%s/%s/%s", getenv("HOME"), def + 1, filename);
+ ret = filepath_printpath(&allocatedfilepath, "%s/%s/%s", getenv("HOME"), def + 1, filename);
} else {
- snprintf(t, PATH_MAX, "%s/%s", def, filename);
- }
- if (realpath(t, filepath) == NULL) {
- strncpy(filepath, t, PATH_MAX);
+ ret = filepath_printpath(&allocatedfilepath, "%s/%s", def, filename);
}
}
+
+ if (ret == NSERROR_OK) {
+ if (strlen(allocatedfilepath) >= size)
+ ret = NSERROR_NOSPACE;
+
+ strncpy(filepath, allocatedfilepath, size);
+ filepath[size - 1] = '\0';
+
+ free(allocatedfilepath);
+ }
+
return ret;
}
diff --git a/utils/filepath.h b/utils/filepath.h
index e87437d90..c44f5af7e 100644
--- a/utils/filepath.h
+++ b/utils/filepath.h
@@ -32,32 +32,13 @@
* Create a normalised file name.
*
* If the file described by the format exists and is accessible the
- * normalised path is placed in str and a pointer to str returned
- * otherwise NULL is returned. The string in str is always modified.
+ * normalised path is placed in retstr. The returned string is allocated
+ * and it is the responsibility of the caller to free it via free().
*
- * @param str A buffer to contain the normalised file name must be at
- * least PATH_MAX bytes long.
+ * @param retstr A pointer the the allocated result string.
* @param format A printf format for the filename.
- * @param ap The list of arguments for the format.
* @return NSERROR_OK on success or error code on failure.
*/
-nserror filepath_vsfindfile(char *str, const char *format, va_list ap);
-
-
-/**
- * Create a normalised file name.
- *
- * Similar to vsfindfile but takes variadic (printf like) parameters
- */
-nserror filepath_sfindfile(char *str, const char *format, ...);
-
-
-/**
- * Create a normalised file name.
- *
- * Similar to sfindfile but allocates its own storage for the
- * returned string in retstr. The caller must free this storage.
- */
nserror filepath_findfile(char **retstr, const char *format, ...);
@@ -65,22 +46,21 @@ nserror filepath_findfile(char **retstr, const char *format, ...);
* Searches an array of resource paths for a file.
*
* Iterates through a vector of resource paths and returns the
- * normalised file name of the first acessible file or NULL if no file
- * can be found in any of the resource paths.
+ * normalised file name of the first acessible file.
*
* @param respathv The resource path vector to iterate.
* @param filepath The buffer to place the result in.
* @param filename The filename of the resource to search for.
* @return NSERROR_OK on success or error code on failure.
*/
-nserror filepath_sfind(char **respathv, char *filepath, const char *filename);
+nserror filepath_sfind(char **respathv, char *filepath, size_t size, const char *filename);
/**
* Searches an array of resource paths for a file.
*
* Similar to filepath_sfind except it allocates its own storage for
- * the returned string. The caller must free this sorage.
+ * the returned string. The caller must free this storage.
*/
nserror filepath_find(char **respathv, const char *filename, char **retstr);
@@ -94,13 +74,14 @@ nserror filepath_find(char **respathv, const char *filename, char **retstr);
* path and the filename.
*
* @param respathv The resource path vector to iterate.
- * @param filepath The buffer to place the result in. Must have space for PATH_MAX bytes.
+ * @param filepath The buffer to place the result in.
+ * @param size The size of the filepath buffer.
* @param filename The filename of the resource to search for.
* @param def The default path to use
* @return NSERROR_OK on success or error code on failure.
*/
-nserror filepath_sfinddef(char **respathv, char *filepath, const char *filename,
- const char *def);
+nserror filepath_sfinddef(char **respathv, char *filepath, size_t size,
+ const char *filename, const char *def);
/**
--
2.45.2
No comments:
Post a Comment