physfs.c
changeset 685 f2aee9b67a4f
parent 684 435510363ae4
child 687 f76dffa43fa2
equal deleted inserted replaced
684:435510363ae4 685:f2aee9b67a4f
  1228 int __PHYSFS_verifySecurity(DirHandle *h, char *fname, int allowMissing)
  1228 int __PHYSFS_verifySecurity(DirHandle *h, char *fname, int allowMissing)
  1229 {
  1229 {
  1230     int retval = 1;
  1230     int retval = 1;
  1231     char *start;
  1231     char *start;
  1232     char *end;
  1232     char *end;
  1233     char *str;
       
  1234 
  1233 
  1235     if (*fname == '\0')  /* quick rejection. */
  1234     if (*fname == '\0')  /* quick rejection. */
  1236         return(1);
  1235         return(1);
  1237 
  1236 
  1238     if (h->mountPoint != NULL)  /* NULL mountpoint means "/". */
  1237     if (h->mountPoint != NULL)  /* NULL mountpoint means "/". */
  1247         BAIL_IF_MACRO(retval != 0, ERR_NO_SUCH_PATH, 0);
  1246         BAIL_IF_MACRO(retval != 0, ERR_NO_SUCH_PATH, 0);
  1248         fname += mntpntlen;  /* move to start of actual archive path. */
  1247         fname += mntpntlen;  /* move to start of actual archive path. */
  1249         retval = 1;
  1248         retval = 1;
  1250     } /* if */
  1249     } /* if */
  1251 
  1250 
  1252     /* !!! FIXME: Can we ditch this malloc()? */
  1251     start = fname;
  1253     start = str = malloc(strlen(fname) + 1);
       
  1254     BAIL_IF_MACRO(str == NULL, ERR_OUT_OF_MEMORY, 0);
       
  1255     strcpy(str, fname);
       
  1256 
       
  1257     if (!allowSymLinks)
  1252     if (!allowSymLinks)
  1258     {
  1253     {
  1259         while (1)
  1254         while (1)
  1260         {
  1255         {
  1261             end = strchr(start, '/');
  1256             end = strchr(start, '/');
  1262             if (end != NULL)
  1257             if (end != NULL)
  1263                 *end = '\0';
  1258                 *end = '\0';
  1264 
  1259 
  1265             if (h->funcs->isSymLink(h->opaque, str, &retval))
  1260             if (h->funcs->isSymLink(h->opaque, fname, &retval))
  1266             {
  1261                 BAIL_MACRO(ERR_SYMLINK_DISALLOWED, 0);   /* insecure. */
  1267                 __PHYSFS_setError(ERR_SYMLINK_DISALLOWED);
       
  1268                 free(str);
       
  1269                 return(0); /* insecure. */
       
  1270             } /* if */
       
  1271 
  1262 
  1272             /* break out early if path element is missing. */
  1263             /* break out early if path element is missing. */
  1273             if (!retval)
  1264             if (!retval)
  1274             {
  1265             {
  1275                 /*
  1266                 /*
  1295 
  1286 
  1296 
  1287 
  1297 int PHYSFS_mkdir(const char *_dname)
  1288 int PHYSFS_mkdir(const char *_dname)
  1298 {
  1289 {
  1299     DirHandle *h;
  1290     DirHandle *h;
  1300     char *str;
       
  1301     char *start;
  1291     char *start;
  1302     char *end;
  1292     char *end;
  1303     int retval = 0;
  1293     int retval = 0;
  1304     int exists = 1;  /* force existance check on first path element. */
  1294     int exists = 1;  /* force existance check on first path element. */
  1305     char *dname;
  1295     char *dname;
  1310 
  1300 
  1311     __PHYSFS_platformGrabMutex(stateLock);
  1301     __PHYSFS_platformGrabMutex(stateLock);
  1312     BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0);
  1302     BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0);
  1313     h = writeDir;
  1303     h = writeDir;
  1314     BAIL_IF_MACRO_MUTEX(!__PHYSFS_verifySecurity(h,dname,1),NULL,stateLock,0);
  1304     BAIL_IF_MACRO_MUTEX(!__PHYSFS_verifySecurity(h,dname,1),NULL,stateLock,0);
  1315     start = str = dname;
  1305     start = dname;
  1316     BAIL_IF_MACRO_MUTEX(str == NULL, ERR_OUT_OF_MEMORY, stateLock, 0);
       
  1317     strcpy(str, dname);
       
  1318 
  1306 
  1319     while (1)
  1307     while (1)
  1320     {
  1308     {
  1321         end = strchr(start, '/');
  1309         end = strchr(start, '/');
  1322         if (end != NULL)
  1310         if (end != NULL)
  1323             *end = '\0';
  1311             *end = '\0';
  1324 
  1312 
  1325         /* only check for existance if all parent dirs existed, too... */
  1313         /* only check for existance if all parent dirs existed, too... */
  1326         if (exists)
  1314         if (exists)
  1327             retval = h->funcs->isDirectory(h->opaque, str, &exists);
  1315             retval = h->funcs->isDirectory(h->opaque, dname, &exists);
  1328 
  1316 
  1329         if (!exists)
  1317         if (!exists)
  1330             retval = h->funcs->mkdir(h->opaque, str);
  1318             retval = h->funcs->mkdir(h->opaque, dname);
  1331 
  1319 
  1332         if (!retval)
  1320         if (!retval)
  1333             break;
  1321             break;
  1334 
  1322 
  1335         if (end == NULL)
  1323         if (end == NULL)