Changeset 34391 in vbox
- Timestamp:
- Nov 26, 2010 11:12:17 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/manifest.h
r34381 r34391 212 212 * the expected results.) 213 213 * @param pszEntry The entry name. 214 * @param fAttrs The attributes to create for this stream. 214 * @param fAttrs The attributes to create for this stream. See 215 * RTMANIFEST_ATTR_XXX. 215 216 */ 216 217 RTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, uint32_t fAttrs); -
trunk/include/iprt/vfs.h
r34031 r34391 711 711 712 712 713 /** @defgroup grp_vfs_file VFS Miscellaneous 714 * @{ 715 */ 716 717 /** 718 * Memorizes the I/O stream as a file backed by memory. 719 * 720 * @returns VBox status code. 721 * 722 * @param hVfsIos The VFS I/O stream to memorize. This will be read 723 * to the end on success, on failure its position is 724 * undefined. 725 * @param fFlags A combination of RTFILE_O_READ and RTFILE_O_WRITE. 726 * @param phVfsFile Where to return the handle to the memory file on 727 * success. 728 */ 729 RTDECL(int) RTVfsMemorizeIoStreamAsFile(RTVFSIOSTREAM hVfsIos, uint32_t fFlags, PRTVFSFILE phVfsFile); 730 731 /** @} */ 732 733 713 734 /** @defgroup grp_rt_vfs_chain VFS Chains 714 735 * -
trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp
r34381 r34391 234 234 } 235 235 236 237 /** 238 * Validates a name in an extension pack. 239 * 240 * We restrict the charset to try make sure the extension pack can be unpacked 241 * on all file systems. 242 * 243 * @returns Program exit code, failure with message. 244 * @param pszName The name to validate. 245 */ 246 static RTEXITCODE ValidateNameInExtPack(const char *pszName) 247 { 248 if (RTPathStartsWithRoot(pszName)) 249 return RTMsgErrorExit(RTEXITCODE_FAILURE, "'%s': starts with root spec", pszName); 250 251 const char *pszErr = NULL; 252 const char *psz = pszName; 253 int ch; 254 while ((ch = *psz) != '\0') 255 { 256 /* Character set restrictions. */ 257 if (ch < 0 || ch >= 128) 258 { 259 pszErr = "Only 7-bit ASCII allowed"; 260 break; 261 } 262 if (ch <= 31 || ch == 127) 263 { 264 pszErr = "No control characters are not allowed"; 265 break; 266 } 267 if (ch == '\\') 268 { 269 pszErr = "Only backward slashes are not allowed"; 270 break; 271 } 272 if (strchr("'\":;*?|[]<>(){}", ch)) 273 { 274 pszErr = "The characters ', \", :, ;, *, ?, |, [, ], <, >, (, ), { and } are not allowed"; 275 break; 276 } 277 278 /* Take the simple way out and ban all ".." sequences. */ 279 if ( ch == '.' 280 && psz[1] == '.') 281 { 282 pszErr = "Double dot sequence are not allowed"; 283 break; 284 } 285 } 286 287 if (pszErr) 288 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Bad member name '%s' (pos %zu): %s", pszName, (size_t)(psz - pszName), pszErr); 289 return RTEXITCODE_SUCCESS; 290 } 291 292 293 /** 294 * Validates a file in an extension pack. 295 * 296 * @returns Program exit code, failure with message. 297 * @param pszName The name of the file. 298 * @param hVfsObj The VFS object. 299 */ 300 static RTEXITCODE ValidateFileInExtPack(const char *pszName, RTVFSOBJ hVfsObj) 301 { 302 RTEXITCODE rcExit = ValidateNameInExtPack(pszName); 303 if (rcExit == RTEXITCODE_SUCCESS) 304 { 305 RTFSOBJINFO ObjInfo; 306 int rc = RTVfsObjQueryInfo(hVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING); 307 if (RT_SUCCESS(rc)) 308 { 309 if (ObjInfo.cbObject >= 9*_1G64) 310 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "'%s': too large (%'RU64 bytes)", 311 pszName, (uint64_t)ObjInfo.cbObject); 312 if (!RTFS_IS_FILE(ObjInfo.Attr.fMode)) 313 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, 314 "The alleged file '%s' has a mode mask saying differently (%RTfmode)", 315 pszName, ObjInfo.Attr.fMode); 316 } 317 else 318 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsObjQueryInfo failed on '%s': %Rrc", pszName, rc); 319 } 320 return rcExit; 321 } 322 323 324 /** 325 * Validates a directory in an extension pack. 326 * 327 * @returns Program exit code, failure with message. 328 * @param pszName The name of the directory. 329 * @param hVfsObj The VFS object. 330 */ 331 static RTEXITCODE ValidateDirInExtPack(const char *pszName, RTVFSOBJ hVfsObj) 332 { 333 RTEXITCODE rcExit = ValidateNameInExtPack(pszName); 334 if (rcExit == RTEXITCODE_SUCCESS) 335 { 336 RTFSOBJINFO ObjInfo; 337 int rc = RTVfsObjQueryInfo(hVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING); 338 if (RT_SUCCESS(rc)) 339 { 340 if (!RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 341 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, 342 "The alleged directory '%s' has a mode mask saying differently (%RTfmode)", 343 pszName, ObjInfo.Attr.fMode); 344 } 345 else 346 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsObjQueryInfo failed on '%s': %Rrc", pszName, rc); 347 } 348 return rcExit; 349 } 350 351 /** 352 * Validates a member of an extension pack. 353 * 354 * @returns Program exit code, failure with message. 355 * @param pszName The name of the directory. 356 * @param enmType The object type. 357 * @param hVfsObj The VFS object. 358 */ 359 static RTEXITCODE ValidateMemberOfExtPack(const char *pszName, RTVFSOBJTYPE enmType, RTVFSOBJ hVfsObj) 360 { 361 RTEXITCODE rcExit; 362 if ( enmType == RTVFSOBJTYPE_FILE 363 || enmType == RTVFSOBJTYPE_IO_STREAM) 364 rcExit = ValidateFileInExtPack(pszName, hVfsObj); 365 else if ( enmType == RTVFSOBJTYPE_DIR 366 || enmType == RTVFSOBJTYPE_BASE) 367 rcExit = ValidateDirInExtPack(pszName, hVfsObj); 368 else 369 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "'%s' is not a file or directory (enmType=%d)", pszName, enmType); 370 return rcExit; 371 } 372 373 236 374 /** 237 375 * Validates the extension pack tarball prior to unpacking. … … 304 442 RTMANIFEST hManifest; 305 443 int rc = RTManifestCreate(0 /*fFlags*/, &hManifest); 306 307 /** @todo continue coding here! */ 308 AssertRC(rc); 309 310 return RTEXITCODE_FAILURE; 444 if (RT_SUCCESS(rc)) 445 { 446 /* 447 * Process the tarball. 448 */ 449 RTVFSFILE hXmlFile = NIL_RTVFSFILE; 450 RTVFSFILE hManifestFile = NIL_RTVFSFILE; 451 RTVFSFILE hSignFile = NIL_RTVFSFILE; 452 for (;;) 453 { 454 /* 455 * Get the next stream object. 456 */ 457 char *pszName; 458 RTVFSOBJ hVfsObj; 459 RTVFSOBJTYPE enmType; 460 rc = RTVfsFsStrmNext(hTarFss, &pszName, &enmType, &hVfsObj); 461 if (RT_FAILURE(rc)) 462 { 463 if (rc != VERR_EOF) 464 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsFsStrmNext failed: %Rrc", rc); 465 break; 466 } 467 468 /* 469 * Check the type & name validity. 470 */ 471 rcExit = ValidateMemberOfExtPack(pszName, enmType, hVfsObj); 472 if (rcExit == RTEXITCODE_SUCCESS) 473 { 474 /* 475 * Check if this is one of the standard files. 476 */ 477 const char *pszAdjName = pszName[0] == '.' && pszName[1] == '/' ? &pszName[2] : pszName; 478 PRTVFSFILE phVfsFile; 479 if (!strcmp(pszAdjName, VBOX_EXTPACK_DESCRIPTION_NAME)) 480 phVfsFile = &hXmlFile; 481 else if (!strcmp(pszAdjName, VBOX_EXTPACK_MANIFEST_NAME)) 482 phVfsFile = &hManifestFile; 483 else if (!strcmp(pszAdjName, VBOX_EXTPACK_SIGNATURE_NAME)) 484 phVfsFile = &hSignFile; 485 else 486 phVfsFile = NULL; 487 if (phVfsFile) 488 { 489 /* 490 * Make sure it's a file and that it isn't too large. 491 */ 492 if (*phVfsFile != NIL_RTVFSFILE) 493 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "There can only be one '%s'", pszAdjName); 494 else if (enmType != RTVFSOBJTYPE_IO_STREAM && enmType != RTVFSOBJTYPE_FILE) 495 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Standard member '%s' is not a file", pszAdjName); 496 else 497 { 498 RTFSOBJINFO ObjInfo; 499 rc = RTVfsObjQueryInfo(hVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING); 500 if (RT_SUCCESS(rc)) 501 { 502 if (!RTFS_IS_FILE(ObjInfo.Attr.fMode)) 503 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Standard member '%s' is not a file", pszAdjName); 504 else if (ObjInfo.cbObject >= _1M) 505 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, 506 "Standard member '%s' is too large: %'RU64 bytes (max 1 MB)", 507 pszAdjName, (uint64_t)ObjInfo.cbObject); 508 else 509 { 510 /* 511 * Make an in memory copy of the stream. 512 */ 513 RTVFSIOSTREAM hVfsIos = RTVfsObjToIoStream(hVfsObj); 514 rc = RTVfsMemorizeIoStreamAsFile(hVfsIos, RTFILE_O_READ, phVfsFile); 515 if (RT_SUCCESS(rc)) 516 { 517 /* 518 * To simplify the code below, replace 519 * hVfsObj with the memorized file. 520 */ 521 RTVfsObjRelease(hVfsObj); 522 hVfsObj = RTVfsObjFromFile(*phVfsFile); 523 } 524 else 525 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, 526 "RTVfsMemorizeIoStreamAsFile failed on '%s': %Rrc", pszName, rc); 527 RTVfsIoStrmRelease(hVfsIos); 528 } 529 } 530 else 531 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsObjQueryInfo failed on '%s': %Rrc", pszName, rc); 532 } 533 } 534 } 535 536 /* 537 * Add any I/O stream to the manifest 538 */ 539 if ( rcExit == RTEXITCODE_SUCCESS 540 && ( enmType == RTVFSOBJTYPE_FILE 541 || enmType == RTVFSOBJTYPE_IO_STREAM)) 542 { 543 RTVFSIOSTREAM hVfsIos = RTVfsObjToIoStream(hVfsObj); 544 rc = RTManifestEntryAddIoStream(hManifest, hVfsIos, pszName, RTMANIFEST_ATTR_SIZE | RTMANIFEST_ATTR_SHA256); 545 if (RT_FAILURE(rc)) 546 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTManifestEntryAddIoStream failed on '%s': %Rrc", pszName, rc); 547 RTVfsIoStrmRelease(hVfsIos); 548 } 549 550 /* 551 * Clean up and break out on failure. 552 */ 553 RTVfsObjRelease(hVfsObj); 554 RTStrFree(pszName); 555 if (rcExit != RTEXITCODE_SUCCESS) 556 break; 557 } 558 559 /* 560 * If we've successfully processed the tarball, verify that the 561 * mandatory files are present. 562 */ 563 if (rcExit == RTEXITCODE_SUCCESS) 564 { 565 if (hXmlFile == NIL_RTVFSFILE) 566 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Mandator file '%s' is missing", VBOX_EXTPACK_DESCRIPTION_NAME); 567 if (hManifestFile == NIL_RTVFSFILE) 568 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Mandator file '%s' is missing", VBOX_EXTPACK_MANIFEST_NAME); 569 if (hSignFile == NIL_RTVFSFILE) 570 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Mandator file '%s' is missing", VBOX_EXTPACK_SIGNATURE_NAME); 571 } 572 573 574 575 RTManifestRelease(hManifest); /** @todo return this and use it during unpacking */ 576 } 577 RTVfsFsStrmRelease(hTarFss); 578 579 return rcExit; 311 580 } 312 581 -
trunk/src/VBox/Main/include/ExtPackUtil.h
r34307 r34391 26 26 * The name of the description file in an extension pack. */ 27 27 #define VBOX_EXTPACK_DESCRIPTION_NAME "ExtPack.xml" 28 /** @name VBOX_EXTPACK_DESCRIPTION_NAME 29 * The name of the manifest file in an extension pack. */ 30 #define VBOX_EXTPACK_MANIFEST_NAME "ExtPack.manifest" 31 /** @name VBOX_EXTPACK_SIGNATURE_NAME 32 * The name of the signature file in an extension pack. */ 33 #define VBOX_EXTPACK_SIGNATURE_NAME "ExtPack.signature" 28 34 /** @name VBOX_EXTPACK_SUFFIX 29 35 * The suffix of a extension pack tarball. */ -
trunk/src/VBox/Runtime/Makefile.kmk
r34381 r34391 372 372 common/vfs/vfsbase.cpp \ 373 373 common/vfs/vfschain.cpp \ 374 common/vfs/vfsmemory.cpp \ 374 375 common/vfs/vfsmisc.cpp \ 375 376 common/vfs/vfsstdfile.cpp \
Note:
See TracChangeset
for help on using the changeset viewer.