Bug 14228 - [PATCH] R ignores PATH_MAX and fails in long directories
[PATCH] R ignores PATH_MAX and fails in long directories
Status: RESOLVED FIXED
Product: R
Classification: Unclassified
Component: Low-level
old
All Linux
: P5 normal
Assigned To: Simon Urbanek
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-03-06 05:08 UTC by Jitterbug compatibility account
Modified: 2010-03-09 08:43 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jitterbug compatibility account 2010-03-06 05:08:15 UTC
From: mstokely@google.com
Full_Name: Murray Stokely
Version: 2.10.1
OS: Linux
Submission from: (NULL) (216.239.45.4)


The Defn.h header includes limits.h for PATH_MAX and then checks if it hasn't
been defined and if not sets something manually.  Some of the R code uses
PATH_MAX but a lot of other functions in unix/sys-unix.c and main/startup.c just
hardcodes a limit of 256 characters.

In my environment this is not always enough, so I ran into this being a problem,
and verified that the attached fix resolves the problem with R 2.10.1.

To duplicate the problem:

1. Create a large directory:
echo `seq 80` | tr ' ' '_' | sed -e 's|\(.*\)|/tmp/\1/\1/\1|g' | xargs mkdir -p
2. Copy R into it
3. Launch R from that directory / with that R_HOME
You don't be able to load the base module or run other functions.

I have prepared 2 patches, one against the trunk in Subversion :
http://people.FreeBSD.org/~murray/maxpath-svn-trunk.patch

And one against the 2.10 release branch :

http://people.FreeBSD.org/~murray/maxpath-svn-2-10-branch.patch

Trunk patch pasted below :

Index: src/unix/sys-unix.c
===================================================================
--- src/unix/sys-unix.c (revision 51208)
+++ src/unix/sys-unix.c (working copy)
@@ -61,7 +61,7 @@
 attribute_hidden
 FILE *R_OpenInitFile(void)
 {
-    char buf[256], *home, *p = getenv("R_PROFILE_USER");
+    char buf[PATH_MAX], *home, *p = getenv("R_PROFILE_USER");
     FILE *fp;

     fp = NULL;
@@ -72,7 +72,7 @@
            return fp;
        if((home = getenv("HOME")) == NULL)
            return NULL;
-       sprintf(buf, "%s/.Rprofile", home);
+       snprintf(buf, PATH_MAX, "%s/.Rprofile", home);
        if((fp = R_fopen(buf, "r")))
            return fp;
     }
Index: src/main/startup.c
===================================================================
--- src/main/startup.c  (revision 51208)
+++ src/main/startup.c  (working copy)
@@ -52,10 +52,10 @@
 attribute_hidden
 FILE *R_OpenLibraryFile(const char *file)
 {
-    char buf[256];
+    char buf[PATH_MAX];
     FILE *fp;

-    snprintf(buf, 256, "%s/library/base/R/%s", R_Home, file);
+    snprintf(buf, PATH_MAX, "%s/library/base/R/%s", R_Home, file);
     fp = R_fopen(buf, "r");
     return fp;
 }
@@ -71,10 +71,10 @@
 attribute_hidden
 FILE *R_OpenSysInitFile(void)
 {
-    char buf[256];
+    char buf[PATH_MAX];
     FILE *fp;

-    snprintf(buf, 256, "%s/library/base/R/Rprofile", R_Home);
+    snprintf(buf, PATH_MAX, "%s/library/base/R/Rprofile", R_Home);
     fp = R_fopen(buf, "r");
     return fp;
 }
@@ -82,7 +82,7 @@
 attribute_hidden
 FILE *R_OpenSiteFile(void)
 {
-    char buf[256];
+    char buf[PATH_MAX];
     FILE *fp;

     fp = NULL;
@@ -90,10 +90,10 @@
        if ((fp = R_fopen(getenv("R_PROFILE"), "r"))) return fp;
        if ((fp = R_fopen(getenv("RPROFILE"), "r"))) return fp;
 #ifdef R_ARCH
-       snprintf(buf, 256, "%s/etc/%s/Rprofile.site", R_Home, R_ARCH);
+       snprintf(buf, PATH_MAX, "%s/etc/%s/Rprofile.site", R_Home, R_ARCH);
        if ((fp = R_fopen(buf, "r"))) return fp;
 #endif
-       snprintf(buf, 256, "%s/etc/Rprofile.site", R_Home);
+       snprintf(buf, PATH_MAX, "%s/etc/Rprofile.site", R_Home);
        if ((fp = R_fopen(buf, "r"))) return fp;
     }
     return fp;
Index: src/main/main.c
===================================================================
--- src/main/main.c     (revision 51208)
+++ src/main/main.c     (working copy)
@@ -862,9 +862,9 @@
     }

     if (strcmp(R_GUIType, "Tk") == 0) {
-       char buf[256];
+       char buf[PATH_MAX];

-       snprintf(buf, 256, "%s/library/tcltk/exec/Tk-frontend.R", R_Home);
+       snprintf(buf, PATH_MAX, "%s/library/tcltk/exec/Tk-frontend.R", R_Home);
        R_LoadProfile(R_fopen(buf, "r"), R_GlobalEnv);
     }

Comment 1 Brian Ripley 2010-03-09 08:43:22 UTC
Fixed in 2.11.0 (and some other instances)