Changeset 34214 in vbox
- Timestamp:
- Nov 19, 2010 5:18:15 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 67956
- Location:
- trunk
- Files:
-
- 3 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/path.h
r34002 r34214 445 445 * NULL, in which case nothing is done. 446 446 * 447 * @remarks See the RTPathAppendEx remarks. 448 */ 449 RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend); 450 451 /** 452 * Appends one partial path to another. 453 * 454 * The main purpose of this function is to deal correctly with the slashes when 455 * concatenating the two partial paths. 456 * 457 * @retval VINF_SUCCESS on success. 458 * @retval VERR_BUFFER_OVERFLOW if the result is too big to fit within 459 * cbPathDst bytes. No changes has been made. 460 * @retval VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer 461 * than cbPathDst-1 bytes (failed to find terminator). Asserted. 462 * 463 * @param pszPath The path to append pszAppend to. This serves as both 464 * input and output. This can be empty, in which case 465 * pszAppend is just copied over. 466 * @param cbPathDst The size of the buffer pszPath points to, terminator 467 * included. This should NOT be strlen(pszPath). 468 * @param pszAppend The partial path to append to pszPath. This can be 469 * NULL, in which case nothing is done. 470 * @param cchAppendMax The maximum number or characters to take from @a 471 * pszAppend. RTSTR_MAX is fine. 472 * 447 473 * @remarks On OS/2, Window and similar systems, concatenating a drive letter 448 474 * specifier with a slash prefixed path will result in an absolute … … 456 482 * sizeof(szBuf), "bar") will result in "C:bar". 457 483 */ 458 RTDECL(int) RTPathAppend (char *pszPath, size_t cbPathDst, const char *pszAppend);484 RTDECL(int) RTPathAppendEx(char *pszPath, size_t cbPathDst, const char *pszAppend, size_t cchAppendMax); 459 485 460 486 /** … … 492 518 */ 493 519 RTDECL(char *) RTPathJoinA(const char *pszPathSrc, const char *pszAppend); 520 521 /** 522 * Extended version of RTPathJoin, both inputs can be specified as substrings. 523 * 524 * @retval VINF_SUCCESS on success. 525 * @retval VERR_BUFFER_OVERFLOW if the result is too big to fit within 526 * cbPathDst bytes. 527 * @retval VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer 528 * than cbPathDst-1 bytes (failed to find terminator). Asserted. 529 * 530 * @param pszPathDst Where to store the resulting path. 531 * @param cbPathDst The size of the buffer pszPathDst points to, 532 * terminator included. 533 * @param pszPathSrc The base path to copy into @a pszPathDst before 534 * appending @a pszAppend. 535 * @param cchPathSrcMax The maximum number of bytes to copy from @a 536 * pszPathSrc. RTSTR_MAX is find. 537 * @param pszAppend The partial path to append to pszPathSrc. This can 538 * be NULL, in which case nothing is done. 539 * @param cchAppendMax The maximum number of bytes to copy from @a 540 * pszAppend. RTSTR_MAX is find. 541 * 542 */ 543 RTDECL(int) RTPathJoinEx(char *pszPathDst, size_t cbPathDst, 544 const char *pszPathSrc, size_t cchPathSrcMax, 545 const char *pszAppend, size_t cchAppendMax); 494 546 495 547 /** -
trunk/src/VBox/Runtime/Makefile.kmk
r34045 r34214 289 289 common/path/RTPathAbsExDup.cpp \ 290 290 common/path/RTPathAppend.cpp \ 291 common/path/RTPathAppendEx.cpp \ 291 292 common/path/RTPathChangeToDosSlashes.cpp \ 292 293 common/path/RTPathChangeToUnixSlashes.cpp \ … … 299 300 common/path/RTPathJoin.cpp \ 300 301 common/path/RTPathJoinA.cpp \ 302 common/path/RTPathJoinEx.cpp \ 301 303 common/path/RTPathParse.cpp \ 302 304 common/path/RTPathRealDup.cpp \ … … 984 986 common/path/RTPathAbsExDup.cpp \ 985 987 common/path/RTPathAppend.cpp \ 988 common/path/RTPathAppendEx.cpp \ 986 989 common/path/RTPathExt.cpp \ 987 990 common/path/RTPathFilename.cpp \ … … 1457 1460 common/path/RTPathAbsExDup.cpp \ 1458 1461 common/path/RTPathAppend.cpp \ 1462 common/path/RTPathAppendEx.cpp \ 1459 1463 common/path/RTPathExt.cpp \ 1460 1464 common/path/RTPathFilename.cpp \ -
trunk/src/VBox/Runtime/common/path/RTPathAppend.cpp
r30320 r34214 32 32 #include <iprt/path.h> 33 33 34 #include <iprt/assert.h>35 #include <iprt/ctype.h>36 #include <iprt/err.h>37 34 #include <iprt/string.h> 38 39 40 /**41 * Figures the length of the root part of the path.42 *43 * @returns length of the root specifier.44 * @retval 0 if none.45 *46 * @param pszPath The path to investigate.47 *48 * @remarks Unnecessary root slashes will not be counted. The caller will have49 * to deal with it where it matters. (Unlike rtPathRootSpecLen which50 * counts them.)51 */52 static size_t rtPathRootSpecLen2(const char *pszPath)53 {54 /* fend of wildlife. */55 if (!pszPath)56 return 0;57 58 /* Root slash? */59 if (RTPATH_IS_SLASH(pszPath[0]))60 {61 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)62 /* UNC? */63 if ( RTPATH_IS_SLASH(pszPath[1])64 && pszPath[2] != '\0'65 && !RTPATH_IS_SLASH(pszPath[2]))66 {67 /* Find the end of the server name. */68 const char *pszEnd = pszPath + 2;69 pszEnd += 2;70 while ( *pszEnd != '\0'71 && !RTPATH_IS_SLASH(*pszEnd))72 pszEnd++;73 if (RTPATH_IS_SLASH(*pszEnd))74 {75 pszEnd++;76 while (RTPATH_IS_SLASH(*pszEnd))77 pszEnd++;78 79 /* Find the end of the share name */80 while ( *pszEnd != '\0'81 && !RTPATH_IS_SLASH(*pszEnd))82 pszEnd++;83 if (RTPATH_IS_SLASH(*pszEnd))84 pszEnd++;85 return pszPath - pszEnd;86 }87 }88 #endif89 return 1;90 }91 92 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)93 /* Drive specifier? */94 if ( pszPath[0] != '\0'95 && pszPath[1] == ':'96 && RT_C_IS_ALPHA(pszPath[0]))97 {98 if (RTPATH_IS_SLASH(pszPath[2]))99 return 3;100 return 2;101 }102 #endif103 return 0;104 }105 35 106 36 107 37 RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend) 108 38 { 109 char *pszPathEnd = RTStrEnd(pszPath, cbPathDst); 110 AssertReturn(pszPathEnd, VERR_INVALID_PARAMETER); 111 112 /* 113 * Special cases. 114 */ 115 if (!pszAppend) 116 return VINF_SUCCESS; 117 size_t cchAppend = strlen(pszAppend); 118 if (!cchAppend) 119 return VINF_SUCCESS; 120 if (pszPathEnd == pszPath) 121 { 122 if (cchAppend >= cbPathDst) 123 return VERR_BUFFER_OVERFLOW; 124 memcpy(pszPath, pszAppend, cchAppend + 1); 125 return VINF_SUCCESS; 126 } 127 128 /* 129 * Balance slashes and check for buffer overflow. 130 */ 131 bool fAddSlash = false; 132 if (!RTPATH_IS_SLASH(pszPathEnd[-1])) 133 { 134 if (!RTPATH_IS_SLASH(pszAppend[0])) 135 { 136 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) 137 if ( (size_t)(pszPathEnd - pszPath) == 2 138 && pszPath[1] == ':' 139 && RT_C_IS_ALPHA(pszPath[0])) 140 { 141 if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cbPathDst) 142 return VERR_BUFFER_OVERFLOW; 143 } 144 else 145 #endif 146 { 147 if ((size_t)(pszPathEnd - pszPath) + 1 + cchAppend >= cbPathDst) 148 return VERR_BUFFER_OVERFLOW; 149 *pszPathEnd++ = '/'; 150 } 151 } 152 else 153 { 154 /* One slash is sufficient at this point. */ 155 while (RTPATH_IS_SLASH(pszAppend[1])) 156 pszAppend++, cchAppend--; 157 158 if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cbPathDst) 159 return VERR_BUFFER_OVERFLOW; 160 } 161 } 162 else 163 { 164 /* No slashes needed in the appended bit. */ 165 while (RTPATH_IS_SLASH(*pszAppend)) 166 pszAppend++, cchAppend--; 167 168 /* In the leading path we can skip unnecessary trailing slashes, but 169 be sure to leave one. */ 170 size_t const cchRoot = rtPathRootSpecLen2(pszPath); 171 while ( (size_t)(pszPathEnd - pszPath) > RT_MAX(1, cchRoot) 172 && RTPATH_IS_SLASH(pszPathEnd[-2])) 173 pszPathEnd--; 174 175 if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cbPathDst) 176 return VERR_BUFFER_OVERFLOW; 177 } 178 179 /* 180 * What remains now is the just the copying. 181 */ 182 memcpy(pszPathEnd, pszAppend, cchAppend + 1); 183 return VINF_SUCCESS; 39 return RTPathAppendEx(pszPath, cbPathDst, pszAppend, RTSTR_MAX); 184 40 } 185 41 -
trunk/src/VBox/Runtime/common/path/RTPathAppendEx.cpp
r34201 r34214 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - RTPathAppend 3 * IPRT - RTPathAppendEx 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2009 Oracle Corporation7 * Copyright (C) 2009-2010 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 105 105 106 106 107 RTDECL(int) RTPathAppend (char *pszPath, size_t cbPathDst, const char *pszAppend)107 RTDECL(int) RTPathAppendEx(char *pszPath, size_t cbPathDst, const char *pszAppend, size_t cchAppendMax) 108 108 { 109 109 char *pszPathEnd = RTStrEnd(pszPath, cbPathDst); … … 115 115 if (!pszAppend) 116 116 return VINF_SUCCESS; 117 size_t cchAppend = strlen(pszAppend);117 size_t cchAppend = RTStrNLen(pszAppend, cchAppendMax); 118 118 if (!cchAppend) 119 119 return VINF_SUCCESS; … … 122 122 if (cchAppend >= cbPathDst) 123 123 return VERR_BUFFER_OVERFLOW; 124 memcpy(pszPath, pszAppend, cchAppend + 1); 124 memcpy(pszPath, pszAppend, cchAppend); 125 pszPath[cchAppend] = '\0'; 125 126 return VINF_SUCCESS; 126 127 } … … 153 154 { 154 155 /* One slash is sufficient at this point. */ 155 while ( RTPATH_IS_SLASH(pszAppend[1]))156 while (cchAppend > 1 && RTPATH_IS_SLASH(pszAppend[1])) 156 157 pszAppend++, cchAppend--; 157 158 … … 163 164 { 164 165 /* No slashes needed in the appended bit. */ 165 while ( RTPATH_IS_SLASH(*pszAppend))166 while (cchAppend && RTPATH_IS_SLASH(*pszAppend)) 166 167 pszAppend++, cchAppend--; 167 168 … … 180 181 * What remains now is the just the copying. 181 182 */ 182 memcpy(pszPathEnd, pszAppend, cchAppend + 1); 183 memcpy(pszPathEnd, pszAppend, cchAppend); 184 pszPathEnd[cchAppend] = '\0'; 183 185 return VINF_SUCCESS; 184 186 } -
trunk/src/VBox/Runtime/common/path/RTPathJoinEx.cpp
r34201 r34214 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - RTPathJoin .3 * IPRT - RTPathJoinEx. 4 4 */ 5 5 … … 38 38 39 39 40 RTDECL(int) RTPathJoin(char *pszPathDst, size_t cbPathDst, const char *pszPathSrc, 41 const char *pszAppend) 40 RTDECL(int) RTPathJoinEx(char *pszPathDst, size_t cbPathDst, 41 const char *pszPathSrc, size_t cchPathSrcMax, 42 const char *pszAppend, size_t cchAppendMax) 42 43 { 43 44 AssertPtr(pszPathDst); … … 48 49 * The easy way: Copy the path into the buffer and call RTPathAppend. 49 50 */ 50 size_t cchPathSrc = strlen(pszPathSrc);51 size_t cchPathSrc = RTStrNLen(pszPathSrc, cchPathSrcMax); 51 52 if (cchPathSrc >= cbPathDst) 52 53 return VERR_BUFFER_OVERFLOW; 53 memcpy(pszPathDst, pszPathSrc, cchPathSrc + 1); 54 memcpy(pszPathDst, pszPathSrc, cchPathSrc); 55 pszPathDst[cchPathSrc] = '\0'; 54 56 55 return RTPathAppend (pszPathDst, cbPathDst, pszAppend);57 return RTPathAppendEx(pszPathDst, cbPathDst, pszAppend, cchAppendMax); 56 58 } 57 59
Note:
See TracChangeset
for help on using the changeset viewer.