Changeset 69705 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Nov 15, 2017 4:42:59 PM (7 years ago)
- Location:
- trunk/src/VBox/Runtime/common/vfs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r69111 r69705 1191 1191 1192 1192 1193 1194 /**1195 * Removes dots from the path.1196 *1197 * @returns The new @a pszDst value.1198 * @param pPath The path parsing buffer.1199 * @param pszDst The current szPath position. This will be1200 * updated and returned.1201 * @param fTheEnd Indicates whether we're at the end of the path1202 * or not.1203 * @param piRestartComp The component to restart parsing at.1204 */1205 static char *rtVfsParsePathHandleDots(PRTVFSPARSEDPATH pPath, char *pszDst, bool fTheEnd, uint16_t *piRestartComp)1206 {1207 if (pszDst[-1] != '.')1208 return pszDst;1209 1210 if (pszDst[-2] == '/')1211 {1212 pPath->cComponents--;1213 pszDst = &pPath->szPath[pPath->aoffComponents[pPath->cComponents]];1214 }1215 else if (pszDst[-2] == '.' && pszDst[-3] == '/')1216 {1217 pPath->cComponents -= pPath->cComponents > 1 ? 2 : 1;1218 pszDst = &pPath->szPath[pPath->aoffComponents[pPath->cComponents]];1219 if (piRestartComp && *piRestartComp + 1 >= pPath->cComponents)1220 *piRestartComp = pPath->cComponents > 0 ? pPath->cComponents - 1 : 0;1221 }1222 else1223 return pszDst;1224 1225 /*1226 * Drop the trailing slash if we're at the end of the source path.1227 */1228 if (fTheEnd && pPath->cComponents == 0)1229 pszDst--;1230 return pszDst;1231 }1232 1233 1234 1193 RTDECL(int) RTVfsParsePathAppend(PRTVFSPARSEDPATH pPath, const char *pszPath, uint16_t *piRestartComp) 1235 1194 { 1236 AssertReturn(*pszPath != '/' , VERR_INTERNAL_ERROR_4);1195 AssertReturn(*pszPath != '/' && *pszPath != '\\', VERR_INTERNAL_ERROR_4); 1237 1196 1238 1197 /* In case *piRestartComp was set higher than the number of components … … 1244 1203 * Append a slash to the destination path if necessary. 1245 1204 */ 1246 char *pszDst = &pPath->szPath[pPath->cch]; 1205 char * const pszDst = pPath->szPath; 1206 size_t offDst = pPath->cch; 1247 1207 if (pPath->cComponents > 0) 1248 1208 { 1249 *pszDst++= '/';1250 if ( pszDst - &pPath->szPath[0]>= RTVFSPARSEDPATH_MAX)1209 pszDst[offDst++] = '/'; 1210 if (offDst >= RTVFSPARSEDPATH_MAX) 1251 1211 return VERR_FILENAME_TOO_LONG; 1252 1212 } 1253 Assert(pszDst[-1] == '/'); 1213 if (pPath->fAbsolute) 1214 Assert(pszDst[offDst - 1] == '/' && pszDst[0] == '/'); 1215 else 1216 Assert(offDst == 0 || (pszDst[0] != '/' && pszDst[offDst - 1] == '/')); 1254 1217 1255 1218 /* … … 1258 1221 const char *pszSrc = pszPath; 1259 1222 pPath->fDirSlash = false; 1260 while (pszSrc[0]) 1261 { 1262 /* Skip unncessary slashes. */ 1263 while (pszSrc[0] == '/') 1264 pszSrc++; 1265 1223 for (;;) 1224 { 1266 1225 /* Copy until we encounter the next slash. */ 1267 pPath->aoffComponents[pPath->cComponents++] = pszDst - &pPath->szPath[0]; 1268 while (pszSrc[0]) 1269 { 1270 if (pszSrc[0] == '/') 1226 pPath->aoffComponents[pPath->cComponents++] = (uint16_t)offDst; 1227 for (;;) 1228 { 1229 char ch = *pszSrc++; 1230 if ( ch != '/' 1231 && ch != '\\' 1232 && ch != '\0') 1271 1233 { 1272 psz Src++;1273 if ( pszSrc[0])1274 *pszDst++ = '/';1234 pszDst[offDst++] = ch; 1235 if (offDst < RTVFSPARSEDPATH_MAX) 1236 { /* likely */ } 1275 1237 else 1276 pPath->fDirSlash = true; 1277 pszDst = rtVfsParsePathHandleDots(pPath, pszDst, pszSrc[0] == '\0', piRestartComp); 1238 return VERR_FILENAME_TOO_LONG; 1239 } 1240 else 1241 { 1242 /* Deal with dot components before we processes the slash/end. */ 1243 if (pszDst[offDst - 1] == '.') 1244 { 1245 if ( offDst == 1 1246 || pszDst[offDst - 2] == '/') 1247 { 1248 pPath->cComponents--; 1249 offDst = pPath->aoffComponents[pPath->cComponents]; 1250 } 1251 else if ( offDst > 3 1252 && pszDst[offDst - 2] == '.' 1253 && pszDst[offDst - 3] == '/') 1254 { 1255 if ( pPath->fAbsolute 1256 || offDst < 5 1257 || pszDst[offDst - 4] != '.' 1258 || pszDst[offDst - 5] != '.' 1259 || (offDst >= 6 && pszDst[offDst - 6] != '/') ) 1260 { 1261 pPath->cComponents -= pPath->cComponents > 1 ? 2 : 1; 1262 offDst = pPath->aoffComponents[pPath->cComponents]; 1263 if (piRestartComp && *piRestartComp + 1 >= pPath->cComponents) 1264 *piRestartComp = pPath->cComponents > 0 ? pPath->cComponents - 1 : 0; 1265 } 1266 } 1267 } 1268 1269 if (ch != '\0') 1270 { 1271 /* Skip unnecessary slashes and check for end of path. */ 1272 while ((ch = *pszSrc) == '/' || ch == '\\') 1273 pszSrc++; 1274 1275 if (ch == '\0') 1276 pPath->fDirSlash = true; 1277 } 1278 1279 if (ch == '\0') 1280 { 1281 /* Drop trailing slash unless it's the root slash. */ 1282 if ( offDst > 0 1283 && pszDst[offDst - 1] == '/' 1284 && ( !pPath->fAbsolute 1285 || offDst > 1)) 1286 offDst--; 1287 1288 /* Terminate the string and enter its length. */ 1289 pszDst[offDst] = '\0'; 1290 pszDst[offDst + 1] = '\0'; /* for aoffComponents[pPath->cComponents] */ 1291 pPath->cch = (uint16_t)offDst; 1292 pPath->aoffComponents[pPath->cComponents] = (uint16_t)(offDst + 1); 1293 return VINF_SUCCESS; 1294 } 1295 1296 /* Append component separator before continuing with the next component. */ 1297 if (offDst > 0 && pszDst[offDst - 1] != '/') 1298 pszDst[offDst++] = '/'; 1299 if (offDst >= RTVFSPARSEDPATH_MAX) 1300 return VERR_FILENAME_TOO_LONG; 1278 1301 break; 1279 1302 } 1280 1281 *pszDst++ = *pszSrc++; 1282 if (pszDst - &pPath->szPath[0] >= RTVFSPARSEDPATH_MAX) 1283 return VERR_FILENAME_TOO_LONG; 1284 } 1285 } 1286 pszDst = rtVfsParsePathHandleDots(pPath, pszDst, true /*fTheEnd*/, piRestartComp); 1287 1288 /* Terminate the string and enter its length. */ 1289 pszDst[0] = '\0'; 1290 pszDst[1] = '\0'; /* for aoffComponents */ 1291 pPath->cch = (uint16_t)(pszDst - &pPath->szPath[0]); 1292 pPath->aoffComponents[pPath->cComponents] = pPath->cch + 1; 1293 1294 return VINF_SUCCESS; 1303 } 1304 } 1295 1305 } 1296 1306 … … 1301 1311 if (*pszPath != '/') 1302 1312 { 1303 /* 1304 * Relative, recurse and parse pszCwd first. 1305 */ 1306 int rc = RTVfsParsePath(pPath, pszCwd, NULL /*crash if pszCwd is not absolute*/); 1307 if (RT_FAILURE(rc)) 1308 return rc; 1313 if (pszCwd) 1314 { 1315 /* 1316 * Relative with a CWD. 1317 */ 1318 int rc = RTVfsParsePath(pPath, pszCwd, NULL /*crash if pszCwd is not absolute*/); 1319 if (RT_FAILURE(rc)) 1320 return rc; 1321 } 1322 else 1323 { 1324 /* 1325 * Relative. 1326 */ 1327 pPath->cch = 0; 1328 pPath->cComponents = 0; 1329 pPath->fDirSlash = false; 1330 pPath->fAbsolute = false; 1331 pPath->aoffComponents[0] = 0; 1332 pPath->aoffComponents[1] = 1; 1333 pPath->szPath[0] = '\0'; 1334 pPath->szPath[1] = '\0'; 1335 } 1309 1336 } 1310 1337 else … … 1317 1344 pPath->cComponents = 0; 1318 1345 pPath->fDirSlash = false; 1346 pPath->fAbsolute = true; 1319 1347 pPath->aoffComponents[0] = 1; 1320 1348 pPath->aoffComponents[1] = 2; … … 2276 2304 */ 2277 2305 PRTVFSPARSEDPATH pPath; 2278 int rc = RTVfsParsePathA(pszPath, "/", &pPath);2306 int rc = RTVfsParsePathA(pszPath, NULL, &pPath); 2279 2307 if (RT_SUCCESS(rc)) 2280 2308 { … … 2342 2370 */ 2343 2371 PRTVFSPARSEDPATH pPath; 2344 rc = RTVfsParsePathA(pszPath, "/", &pPath);2372 rc = RTVfsParsePathA(pszPath, NULL, &pPath); 2345 2373 if (RT_SUCCESS(rc)) 2346 2374 { … … 2411 2439 2412 2440 /* 2413 * Parse the path, assume current directory is root since we've got no 2414 * caller context here. Then traverse to the parent directory. 2441 * Parse the relative path. Then traverse to the parent directory. 2415 2442 */ 2416 2443 PRTVFSPARSEDPATH pPath; 2417 int rc = RTVfsParsePathA(pszPath, "/", &pPath);2444 int rc = RTVfsParsePathA(pszPath, NULL, &pPath); 2418 2445 if (RT_SUCCESS(rc)) 2419 2446 { -
trunk/src/VBox/Runtime/common/vfs/vfschain.cpp
r69674 r69705 145 145 { 146 146 /* 147 * First element: T transform into 'stdfile' or 'stddir' if registered.147 * First element: Transform into 'stdfile' or 'stddir' if registered. 148 148 */ 149 149 const char *pszNewProvider = pElement->enmType == RTVFSOBJTYPE_DIR ? "stddir" : "stdfile"; … … 177 177 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 178 178 } 179 } 179 return rc; 180 } 181 180 182 181 183 /* … … 184 186 if (pElement->cArgs > 1) 185 187 return VERR_VFS_CHAIN_AT_MOST_ONE_ARG; 188 pElement->uProvider = 0; 186 189 return VINF_SUCCESS; 187 190 }
Note:
See TracChangeset
for help on using the changeset viewer.