Changeset 57723 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Sep 11, 2015 8:02:15 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 102638
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/misc/uri.cpp
r57720 r57723 36 36 #include <iprt/string.h> 37 37 38 39 /********************************************************************************************************************************* 40 * Defined Constants And Macros * 41 *********************************************************************************************************************************/ 42 /** Internal magic value we use to check if a RTURIPARSED structure has made it thru RTUriParse. */ 43 #define RTURIPARSED_MAGIC UINT32_C(0x439e0745) 44 45 38 46 /* General URI format: 39 47 … … 47 55 */ 48 56 49 /**50 * Parsed URI.51 */52 typedef struct RTURIPARSED53 {54 /** RTURIPARSED_F_XXX. */55 uint32_t fFlags;56 57 /** The length of the scheme. */58 size_t cchScheme;59 60 /** The offset into the string of the authority. */61 size_t offAuthority;62 /** The authority length.63 * @remarks The authority component can be zero length, so to check whether64 * it's there or not consult RTURIPARSED_F_HAVE_AUTHORITY. */65 size_t cchAuthority;66 67 /** The offset into the string of the path. */68 size_t offPath;69 /** The length of the path. */70 size_t cchPath;71 72 /** The offset into the string of the query. */73 size_t offQuery;74 /** The length of the query. */75 size_t cchQuery;76 77 /** The offset into the string of the fragment. */78 size_t offFragment;79 /** The length of the fragment. */80 size_t cchFragment;81 82 /** @name Authority subdivisions83 * @{ */84 /** If there is a userinfo part, this is the start of it. Otherwise it's the85 * same as offAuthorityHost. */86 size_t offAuthorityUsername;87 /** The length of the username (zero if not present). */88 size_t cchAuthorityUsername;89 /** If there is a userinfo part containing a password, this is the start of it.90 * Otherwise it's the same as offAuthorityHost. */91 size_t offAuthorityPassword;92 /** The length of the password (zero if not present). */93 size_t cchAuthorityPassword;94 /** The offset of the host part of the authority. */95 size_t offAuthorityHost;96 /** The length of the host part of the authority. */97 size_t cchAuthorityHost;98 /** The authority port number, UINT32_MAX if not present. */99 uint32_t uAuthorityPort;100 /** @} */101 } RTURIPARSED;102 /** Pointer to a parsed URI. */103 typedef RTURIPARSED *PRTURIPARSED;104 /** Set if the URI contains escaped characters. */105 #define RTURIPARSED_F_CONTAINS_ESCAPED_CHARS UINT32_C(0x00000001)106 /** Set if the URI have an authority component. Necessary since the authority107 * component can have a zero length. */108 #define RTURIPARSED_F_HAVE_AUTHORITY UINT32_C(0x00000002)109 110 111 112 /*********************************************************************************************************************************113 * Internal Functions *114 *********************************************************************************************************************************/115 57 116 58 /** … … 176 118 } 177 119 178 static char *rtUriPercentDecodeN(const char *pszString, size_t cchMax) 179 { 180 if (!pszString) 181 return NULL; 182 183 /* The new string can only get smaller. */ 184 size_t cchLen = strlen(pszString); 185 cchLen = RT_MIN(cchLen, cchMax); 186 char *pszNew = RTStrAlloc(cchLen + 1); 187 if (!pszNew) 188 return NULL; 189 190 int rc = VINF_SUCCESS; 191 char *pszRes = NULL; 192 size_t iIn = 0; 193 size_t iOut = 0; 194 while (iIn < cchLen) 195 { 196 if (pszString[iIn] == '%') 197 { 198 /* % encoding means the percent sign and exactly 2 hexadecimal 199 * digits describing the ASCII number of the character. */ 200 ++iIn; 201 char szNum[3]; 202 szNum[0] = pszString[iIn++]; 203 szNum[1] = pszString[iIn++]; 204 szNum[2] = '\0'; 205 206 uint8_t u8; 207 rc = RTStrToUInt8Ex(szNum, NULL, 16, &u8); 208 if (RT_FAILURE(rc)) 120 121 static char *rtUriPercentDecodeN(const char *pszString, size_t cchString) 122 { 123 AssertPtr(pszString); 124 Assert(strlen(pszString) >= cchString); 125 126 /* 127 * The new string can only get smaller, so use the input length as a 128 * staring buffer size. 129 */ 130 char *pszDecoded = RTStrAlloc(cchString + 1); 131 if (pszDecoded) 132 { 133 /* 134 * Knowing that the pszString itself is valid UTF-8, we only have to 135 * validate the escape sequences. 136 */ 137 size_t cchLeft = cchString; 138 char const *pchSrc = pszString; 139 char *pchDst = pszDecoded; 140 while (cchLeft > 0) 141 { 142 const char *pchPct = (const char *)memchr(pchSrc, '%', cchLeft); 143 if (pchPct) 144 { 145 size_t cchBefore = pchPct - pchSrc; 146 if (cchBefore) 147 { 148 memcpy(pchDst, pchSrc, cchBefore); 149 pchDst += cchBefore; 150 pchSrc += cchBefore; 151 cchLeft -= cchBefore; 152 } 153 154 char chHigh, chLow; 155 if ( cchLeft >= 3 156 && RT_C_IS_XDIGIT(chHigh = pchSrc[1]) 157 && RT_C_IS_XDIGIT(chLow = pchSrc[2])) 158 { 159 uint8_t b = RT_C_IS_DIGIT(chHigh) ? chHigh - '0' : (chHigh & ~0x20) - 'A' + 10; 160 b <<= 4; 161 b |= RT_C_IS_DIGIT(chLow) ? chLow - '0' : (chLow & ~0x20) - 'A' + 10; 162 *pchDst++ = (char)b; 163 pchSrc += 3; 164 cchLeft -= 3; 165 } 166 else 167 { 168 AssertFailed(); 169 *pchDst++ = *pchSrc++; 170 cchLeft--; 171 } 172 } 173 else 174 { 175 memcpy(pchDst, pchSrc, cchLeft); 176 pchDst += cchLeft; 177 pchSrc += cchLeft; 178 cchLeft = 0; 209 179 break; 210 pszNew[iOut] = u8; 211 } 212 else 213 pszNew[iOut] = pszString[iIn++]; 214 ++iOut; 215 } 216 if (RT_SUCCESS(rc)) 217 { 218 pszNew[iOut] = '\0'; 219 if (iOut != iIn) 220 { 221 /* If the source and target strings have different size, recreate 222 * the target string with the correct size. */ 223 pszRes = RTStrDupN(pszNew, iOut); 224 RTStrFree(pszNew); 225 } 226 else 227 pszRes = pszNew; 228 } 229 else 230 RTStrFree(pszNew); 231 232 return pszRes; 233 } 234 235 static bool rtUriFindSchemeEnd(const char *pszUri, size_t iStart, size_t cbLen, size_t *piEnd) 236 { 237 /* The scheme has to end with ':'. */ 238 size_t i = iStart; 239 while (i < iStart + cbLen) 240 { 241 if (pszUri[i] == ':') 242 { 243 *piEnd = i; 244 return true; 245 } 246 ++i; 247 } 248 return false; 249 } 250 251 static bool rtUriCheckAuthorityStart(const char *pszUri, size_t iStart, size_t cbLen, size_t *piStart) 252 { 253 /* The authority have to start with '//' */ 254 if ( cbLen >= 2 255 && pszUri[iStart ] == '/' 256 && pszUri[iStart + 1] == '/') 257 { 258 *piStart = iStart + 2; 259 return true; 260 } 261 262 return false; 263 } 264 265 static bool rtUriFindAuthorityEnd(const char *pszUri, size_t iStart, size_t cbLen, size_t *piEnd) 266 { 267 /* The authority can end with '/' || '?' || '#'. */ 268 size_t i = iStart; 269 while (i < iStart + cbLen) 270 { 271 if ( pszUri[i] == '/' 272 || pszUri[i] == '?' 273 || pszUri[i] == '#') 274 { 275 *piEnd = i; 276 return true; 277 } 278 ++i; 279 } 280 return false; 281 } 282 283 static bool rtUriCheckPathStart(const char *pszUri, size_t iStart, size_t cbLen, size_t *piStart) 284 { 285 /* The path could start with a '/'. */ 286 if ( cbLen >= 1 287 && pszUri[iStart] == '/') 288 { 289 *piStart = iStart; /* Including '/' */ 290 return true; 291 } 292 293 /* '?' || '#' means there is no path. */ 294 if ( cbLen >= 1 295 && ( pszUri[iStart] == '?' 296 || pszUri[iStart] == '#')) 297 return false; 298 299 /* All other values are allowed. */ 300 *piStart = iStart; 301 return true; 302 } 303 304 static bool rtUriFindPathEnd(const char *pszUri, size_t iStart, size_t cbLen, size_t *piEnd) 305 { 306 /* The path can end with '?' || '#'. */ 307 size_t i = iStart; 308 while (i < iStart + cbLen) 309 { 310 if ( pszUri[i] == '?' 311 || pszUri[i] == '#') 312 { 313 *piEnd = i; 314 return true; 315 } 316 ++i; 317 } 318 return false; 319 } 180 } 181 } 182 183 *pchDst = '\0'; 184 185 /* 186 * If we've got lof space room in the result string, reallocate it. 187 */ 188 size_t cchDecoded = pchDst - pszDecoded; 189 Assert(cchDecoded <= cchString); 190 // if (cchString - cchDecoded > 64) - enable later! 191 RTStrRealloc(&pszDecoded, cchDecoded + 1); 192 } 193 return pszDecoded; 194 } 195 320 196 321 197 static int rtUriParse(const char *pszUri, PRTURIPARSED pParsed) … … 329 205 330 206 AssertPtrReturn(pszUri, VERR_INVALID_POINTER); 207 331 208 size_t const cchUri = strlen(pszUri); 332 209 if (RT_LIKELY(cchUri >= 3)) { /* likely */ } 333 210 else return cchUri ? VERR_URI_TOO_SHORT : VERR_URI_EMPTY; 211 212 /* 213 * Validating escaped text sequences is much simpler if we know that 214 * that the base URI string is valid. Also, we don't necessarily trust 215 * the developer calling us to remember to do this. 216 */ 217 int rc = RTStrValidateEncoding(pszUri); 218 AssertRCReturn(rc, rc); 334 219 335 220 /* … … 500 385 } 501 386 387 /* 388 * If there are any escape sequences, validate them. 389 * 390 * This is reasonably simple as we already know that the string is valid UTF-8 391 * before they get decoded. Thus we only have to validate the escaped sequences. 392 */ 393 if (pParsed->fFlags & RTURIPARSED_F_CONTAINS_ESCAPED_CHARS) 394 { 395 const char *pchSrc = (const char *)memchr(pszUri, '%', cchUri); 396 AssertReturn(pchSrc, VERR_INTERNAL_ERROR); 397 do 398 { 399 char szUtf8Seq[8]; 400 unsigned cchUtf8Seq = 0; 401 unsigned cchNeeded = 0; 402 size_t cchLeft = &pszUri[cchUri] - pchSrc; 403 do 404 { 405 if (cchLeft >= 3) 406 { 407 char chHigh = pchSrc[1]; 408 char chLow = pchSrc[2]; 409 if ( RT_C_IS_XDIGIT(chHigh) 410 && RT_C_IS_XDIGIT(chLow)) 411 { 412 uint8_t b = RT_C_IS_DIGIT(chHigh) ? chHigh - '0' : (chHigh & ~0x20) - 'A' + 10; 413 b <<= 4; 414 b |= RT_C_IS_DIGIT(chLow) ? chLow - '0' : (chLow & ~0x20) - 'A' + 10; 415 416 if (!(b & 0x80)) 417 { 418 /* We don't want the string to be terminated prematurely. */ 419 if (RT_LIKELY(b != 0)) { /* likely */ } 420 else return VERR_URI_ESCAPED_ZERO; 421 422 /* Check that we're not expecting more UTF-8 bytes. */ 423 if (RT_LIKELY(cchNeeded == 0)) { /* likely */ } 424 else return VERR_URI_MISSING_UTF8_CONTINUATION_BYTE; 425 } 426 /* Are we waiting UTF-8 bytes? */ 427 else if (cchNeeded > 0) 428 { 429 if (RT_LIKELY(!(b & 0x40))) { /* likely */ } 430 else return VERR_URI_INVALID_ESCAPED_UTF8_CONTINUATION_BYTE; 431 432 szUtf8Seq[cchUtf8Seq++] = (char)b; 433 if (--cchNeeded == 0) 434 { 435 szUtf8Seq[cchUtf8Seq] = '\0'; 436 int rc = RTStrValidateEncoding(szUtf8Seq); 437 if (RT_FAILURE(rc)) 438 return VERR_URI_ESCAPED_CHARS_NOT_VALID_UTF8; 439 cchUtf8Seq = 0; 440 } 441 } 442 /* Start a new UTF-8 sequence. */ 443 else 444 { 445 if ((b & 0xf8) == 0xf0) 446 cchNeeded = 3; 447 else if ((b & 0xf0) == 0xe0) 448 cchNeeded = 2; 449 else if ((b & 0xe0) == 0xc0) 450 cchNeeded = 1; 451 else 452 return VERR_URI_INVALID_ESCAPED_UTF8_LEAD_BYTE; 453 szUtf8Seq[0] = (char)b; 454 cchUtf8Seq = 1; 455 } 456 pchSrc += 3; 457 cchLeft -= 3; 458 } 459 else 460 return VERR_URI_INVALID_ESCAPE_SEQ; 461 } 462 else 463 return VERR_URI_INVALID_ESCAPE_SEQ; 464 } while (cchLeft > 0 && pchSrc[0] == '%'); 465 466 /* Check that we're not expecting more UTF-8 bytes. */ 467 if (RT_LIKELY(cchNeeded == 0)) { /* likely */ } 468 else return VERR_URI_MISSING_UTF8_CONTINUATION_BYTE; 469 470 /* next */ 471 pchSrc = (const char *)memchr(pchSrc, '%', cchLeft); 472 } while (pchSrc); 473 } 474 475 pParsed->u32Magic = RTURIPARSED_MAGIC; 502 476 return VINF_SUCCESS; 503 477 } 504 478 505 479 506 /********************************************************************************************************************************* 507 * Generic URI APIs * 508 *********************************************************************************************************************************/ 509 510 RTR3DECL(char *) RTUriCreate(const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery, 511 const char *pszFragment) 480 481 RTDECL(int) RTUriParse(const char *pszUri, PRTURIPARSED pParsed) 482 { 483 return rtUriParse(pszUri, pParsed); 484 } 485 486 487 RTDECL(char *) RTUriParsedScheme(const char *pszUri, PCRTURIPARSED pParsed) 488 { 489 AssertPtrReturn(pszUri, NULL); 490 AssertPtrReturn(pParsed, NULL); 491 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 492 return RTStrDupN(pszUri, pParsed->cchScheme); 493 } 494 495 496 RTDECL(char *) RTUriParsedAuthority(const char *pszUri, PCRTURIPARSED pParsed) 497 { 498 AssertPtrReturn(pszUri, NULL); 499 AssertPtrReturn(pParsed, NULL); 500 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 501 if (pParsed->cchAuthority || (pParsed->fFlags & RTURIPARSED_F_HAVE_AUTHORITY)) 502 return rtUriPercentDecodeN(&pszUri[pParsed->offAuthority], pParsed->cchAuthority); 503 return NULL; 504 } 505 506 507 RTDECL(char *) RTUriParsedAuthorityUsername(const char *pszUri, PCRTURIPARSED pParsed) 508 { 509 AssertPtrReturn(pszUri, NULL); 510 AssertPtrReturn(pParsed, NULL); 511 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 512 if (pParsed->cchAuthorityUsername) 513 return rtUriPercentDecodeN(&pszUri[pParsed->offAuthorityUsername], pParsed->cchAuthorityUsername); 514 return NULL; 515 } 516 517 518 RTDECL(char *) RTUriParsedAuthorityPassword(const char *pszUri, PCRTURIPARSED pParsed) 519 { 520 AssertPtrReturn(pszUri, NULL); 521 AssertPtrReturn(pParsed, NULL); 522 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 523 if (pParsed->cchAuthorityPassword) 524 return rtUriPercentDecodeN(&pszUri[pParsed->offAuthorityPassword], pParsed->cchAuthorityPassword); 525 return NULL; 526 } 527 528 529 RTDECL(char *) RTUriParsedAuthorityHost(const char *pszUri, PCRTURIPARSED pParsed) 530 { 531 AssertPtrReturn(pszUri, NULL); 532 AssertPtrReturn(pParsed, NULL); 533 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 534 if (pParsed->cchAuthorityHost) 535 return rtUriPercentDecodeN(&pszUri[pParsed->offAuthorityHost], pParsed->cchAuthorityHost); 536 return NULL; 537 } 538 539 540 RTDECL(uint32_t) RTUriParsedAuthorityPort(const char *pszUri, PCRTURIPARSED pParsed) 541 { 542 AssertPtrReturn(pszUri, UINT32_MAX); 543 AssertPtrReturn(pParsed, UINT32_MAX); 544 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, UINT32_MAX); 545 return pParsed->uAuthorityPort; 546 } 547 548 549 RTDECL(char *) RTUriParsedPath(const char *pszUri, PCRTURIPARSED pParsed) 550 { 551 AssertPtrReturn(pszUri, NULL); 552 AssertPtrReturn(pParsed, NULL); 553 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 554 if (pParsed->cchPath) 555 return rtUriPercentDecodeN(&pszUri[pParsed->offPath], pParsed->cchPath); 556 return NULL; 557 } 558 559 560 RTDECL(char *) RTUriParsedQuery(const char *pszUri, PCRTURIPARSED pParsed) 561 { 562 AssertPtrReturn(pszUri, NULL); 563 AssertPtrReturn(pParsed, NULL); 564 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 565 if (pParsed->cchQuery) 566 return rtUriPercentDecodeN(&pszUri[pParsed->offQuery], pParsed->cchQuery); 567 return NULL; 568 } 569 570 571 RTDECL(char *) RTUriParsedFragment(const char *pszUri, PCRTURIPARSED pParsed) 572 { 573 AssertPtrReturn(pszUri, NULL); 574 AssertPtrReturn(pParsed, NULL); 575 AssertReturn(pParsed->u32Magic == RTURIPARSED_MAGIC, NULL); 576 if (pParsed->cchFragment) 577 return rtUriPercentDecodeN(&pszUri[pParsed->offFragment], pParsed->cchFragment); 578 return NULL; 579 } 580 581 582 RTDECL(char *) RTUriCreate(const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery, 583 const char *pszFragment) 512 584 { 513 585 if (!pszScheme) /* Scheme is minimum requirement */ … … 596 668 } 597 669 598 RTR3DECL(bool) RTUriHasScheme(const char *pszUri, const char *pszScheme) 599 { 600 bool fRes = false; 601 char *pszTmp = RTUriScheme(pszUri); 602 if (pszTmp) 603 { 604 fRes = RTStrNICmp(pszScheme, pszTmp, strlen(pszTmp)) == 0; 605 RTStrFree(pszTmp); 606 } 607 return fRes; 608 } 609 610 RTR3DECL(char *) RTUriScheme(const char *pszUri) 611 { 612 AssertPtrReturn(pszUri, NULL); 613 614 size_t iPos1; 615 size_t cbLen = strlen(pszUri); 616 if (rtUriFindSchemeEnd(pszUri, 0, cbLen, &iPos1)) 617 return rtUriPercentDecodeN(pszUri, iPos1); 618 return NULL; 619 } 620 621 RTR3DECL(char *) RTUriAuthority(const char *pszUri) 622 { 623 RTURIPARSED Parsed; 624 int rc = rtUriParse(pszUri, &Parsed); 625 if (RT_SUCCESS(rc)) 626 if (Parsed.cchAuthority || (Parsed.fFlags & RTURIPARSED_F_HAVE_AUTHORITY)) 627 return rtUriPercentDecodeN(&pszUri[Parsed.offAuthority], Parsed.cchAuthority); 628 return NULL; 629 } 630 631 RTR3DECL(char *) RTUriAuthorityUsername(const char *pszUri) 632 { 633 RTURIPARSED Parsed; 634 int rc = rtUriParse(pszUri, &Parsed); 635 if (RT_SUCCESS(rc)) 636 if (Parsed.cchAuthorityUsername) 637 return rtUriPercentDecodeN(&pszUri[Parsed.offAuthorityUsername], Parsed.cchAuthorityUsername); 638 return NULL; 639 } 640 641 RTR3DECL(char *) RTUriAuthorityPassword(const char *pszUri) 642 { 643 RTURIPARSED Parsed; 644 int rc = rtUriParse(pszUri, &Parsed); 645 if (RT_SUCCESS(rc)) 646 if (Parsed.cchAuthorityPassword) 647 return rtUriPercentDecodeN(&pszUri[Parsed.offAuthorityPassword], Parsed.cchAuthorityPassword); 648 return NULL; 649 } 650 651 RTR3DECL(uint32_t) RTUriAuthorityPort(const char *pszUri) 652 { 653 RTURIPARSED Parsed; 654 int rc = rtUriParse(pszUri, &Parsed); 655 if (RT_SUCCESS(rc)) 656 return Parsed.uAuthorityPort; 657 return UINT32_MAX; 658 } 659 660 RTR3DECL(char *) RTUriPath(const char *pszUri) 670 671 RTDECL(bool) RTUriIsSchemeMatch(const char *pszUri, const char *pszScheme) 672 { 673 AssertPtrReturn(pszUri, false); 674 size_t const cchScheme = strlen(pszScheme); 675 return RTStrNICmp(pszUri, pszScheme, cchScheme) == 0 676 && pszScheme[cchScheme] == ':'; 677 } 678 679 680 /* temporarily kept around till Andy stops using it. */ 681 RTDECL(char *) RTUriPath(const char *pszUri) 661 682 { 662 683 RTURIPARSED Parsed; … … 668 689 } 669 690 670 RTR3DECL(char *) RTUriQuery(const char *pszUri) 671 { 672 RTURIPARSED Parsed; 673 int rc = rtUriParse(pszUri, &Parsed); 674 if (RT_SUCCESS(rc)) 675 if (Parsed.cchQuery) 676 return rtUriPercentDecodeN(&pszUri[Parsed.offQuery], Parsed.cchQuery); 677 return NULL; 678 } 679 680 RTR3DECL(char *) RTUriFragment(const char *pszUri) 681 { 682 RTURIPARSED Parsed; 683 int rc = rtUriParse(pszUri, &Parsed); 684 if (RT_SUCCESS(rc)) 685 if (Parsed.cchFragment) 686 return rtUriPercentDecodeN(&pszUri[Parsed.offFragment], Parsed.cchFragment); 687 return NULL; 688 } 689 690 691 /********************************************************************************************************************************* 692 * File URI APIs * 693 *********************************************************************************************************************************/ 694 695 RTR3DECL(char *) RTUriFileCreate(const char *pszPath) 691 692 RTDECL(char *) RTUriFileCreate(const char *pszPath) 696 693 { 697 694 char *pszResult = NULL; … … 721 718 } 722 719 723 RTR3DECL(char *) RTUriFilePath(const char *pszUri, uint32_t uFormat) 720 721 RTDECL(char *) RTUriFilePath(const char *pszUri, uint32_t uFormat) 724 722 { 725 723 return RTUriFileNPath(pszUri, uFormat, RTSTR_MAX); 726 724 } 727 725 728 RTR3DECL(char *) RTUriFileNPath(const char *pszUri, uint32_t uFormat, size_t cchMax) 726 727 RTDECL(char *) RTUriFileNPath(const char *pszUri, uint32_t uFormat, size_t cchMax) 729 728 { 730 729 AssertPtrReturn(pszUri, NULL); -
trunk/src/VBox/Runtime/testcase/tstRTUri.cpp
r57720 r57723 52 52 const char *pszUsername; 53 53 const char *pszPassword; 54 const char *pszHost; 54 55 uint32_t uPort; 55 56 } g_aTests[] = 56 57 { 57 58 { /* #0 */ 58 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", 59 /*.pszScheme =*/ "foo", 60 /*.pszAuthority =*/ "tt:[email protected]:8042", 61 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there", 62 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret", 63 /*.pszFragment =*/ "nose <>#%\"{}|^[]`", 64 /*.pszUsername =*/ "tt", 65 /*.pszPassword =*/ "tt", 59 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", 60 /*.pszScheme =*/ "foo", 61 /*.pszAuthority =*/ "tt:[email protected]:8042", 62 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there", 63 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret", 64 /*.pszFragment =*/ "nose <>#%\"{}|^[]`", 65 /*.pszUsername =*/ "tt", 66 /*.pszPassword =*/ "yt", 67 /*.pszHost =*/ "example.com", 66 68 /*.uPort =*/ 8042, 67 69 }, 68 70 { /* #1 */ 69 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret", 70 /*.pszScheme =*/ "foo", 71 /*.pszAuthority =*/ "tt:[email protected]:8042", 72 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there", 73 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret", 74 /*.pszFragment =*/ NULL, 75 /*.pszUsername =*/ "tt", 76 /*.pszPassword =*/ "tt", 71 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret", 72 /*.pszScheme =*/ "foo", 73 /*.pszAuthority =*/ "tt:[email protected]:8042", 74 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there", 75 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret", 76 /*.pszFragment =*/ NULL, 77 /*.pszUsername =*/ "tt", 78 /*.pszPassword =*/ "yt", 79 /*.pszHost =*/ "example.com", 77 80 /*.uPort =*/ 8042, 78 81 }, 79 82 { /* #2 */ 80 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there", 81 /*.pszScheme =*/ "foo", 82 /*.pszAuthority =*/ "tt:[email protected]:8042", 83 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there", 84 /*.pszQuery =*/ NULL, 85 /*.pszFragment =*/ NULL, 86 /*.pszUsername =*/ "tt", 87 /*.pszPassword =*/ "tt", 83 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there", 84 /*.pszScheme =*/ "foo", 85 /*.pszAuthority =*/ "tt:[email protected]:8042", 86 /*.pszPath =*/ "/over/ <>#%\"{}|^[]`/there", 87 /*.pszQuery =*/ NULL, 88 /*.pszFragment =*/ NULL, 89 /*.pszUsername =*/ "tt", 90 /*.pszPassword =*/ "yt", 91 /*.pszHost =*/ "example.com", 88 92 /*.uPort =*/ 8042, 89 93 }, … … 97 101 /*.pszUsername =*/ NULL, 98 102 /*.pszPassword =*/ NULL, 103 /*.pszHost =*/ NULL, 99 104 /*.uPort =*/ UINT32_MAX, 100 105 }, … … 108 113 /*.pszUsername =*/ NULL, 109 114 /*.pszPassword =*/ NULL, 115 /*.pszHost =*/ NULL, 110 116 /*.uPort =*/ UINT32_MAX, 111 117 }, … … 119 125 /*.pszUsername =*/ NULL, 120 126 /*.pszPassword =*/ NULL, 127 /*.pszHost =*/ NULL, 121 128 /*.uPort =*/ UINT32_MAX, 122 129 }, … … 130 137 /*.pszUsername =*/ NULL, 131 138 /*.pszPassword =*/ NULL, 139 /*.pszHost =*/ NULL, 132 140 /*.uPort =*/ UINT32_MAX, 133 141 }, … … 141 149 /*.pszUsername =*/ NULL, 142 150 /*.pszPassword =*/ NULL, 151 /*.pszHost =*/ NULL, 143 152 /*.uPort =*/ UINT32_MAX, 144 153 }, … … 152 161 /*.pszUsername =*/ NULL, 153 162 /*.pszPassword =*/ NULL, 163 /*.pszHost =*/ NULL, 154 164 /*.uPort =*/ UINT32_MAX, 155 165 }, 156 166 { /* #9 */ 157 "foo://tt: t[email protected]:8042/?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",158 /*.pszScheme =*/ "foo", 159 /*.pszAuthority =*/ "tt: t[email protected]:8042",167 "foo://tt:y[email protected]:8042/?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", 168 /*.pszScheme =*/ "foo", 169 /*.pszAuthority =*/ "tt:y[email protected]:8042", 160 170 /*.pszPath =*/ "/", 161 171 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret", 162 172 /*.pszFragment =*/ "nose <>#%\"{}|^[]`", 163 173 /*.pszUsername =*/ "tt", 164 /*.pszPassword =*/ "tt", 174 /*.pszPassword =*/ "yt", 175 /*.pszHost =*/ "example.com", 165 176 /*.uPort =*/ 8042, 166 177 }, 167 178 { /* #10 */ 168 "foo://tt: t[email protected]:8042/",169 /*.pszScheme =*/ "foo", 170 /*.pszAuthority =*/ "tt: t[email protected]:8042",179 "foo://tt:y[email protected]:8042/", 180 /*.pszScheme =*/ "foo", 181 /*.pszAuthority =*/ "tt:y[email protected]:8042", 171 182 /*.pszPath =*/ "/", 172 183 /*.pszQuery =*/ NULL, 173 184 /*.pszFragment =*/ NULL, 174 185 /*.pszUsername =*/ "tt", 175 /*.pszPassword =*/ "tt", 186 /*.pszPassword =*/ "yt", 187 /*.pszHost =*/ "example.com", 176 188 /*.uPort =*/ 8042, 177 189 }, 178 190 { /* #11 */ 179 "foo://tt:[email protected]:8042?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", 180 /*.pszScheme =*/ "foo", 181 /*.pszAuthority =*/ "tt:[email protected]:8042", 182 /*.pszPath =*/ NULL, 183 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret", 184 /*.pszFragment =*/ "nose <>#%\"{}|^[]`", 185 /*.pszUsername =*/ "tt", 186 /*.pszPassword =*/ "tt", 191 "foo://tt:[email protected]:8042?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", 192 /*.pszScheme =*/ "foo", 193 /*.pszAuthority =*/ "tt:[email protected]:8042", 194 /*.pszPath =*/ NULL, 195 /*.pszQuery =*/ "name= <>#%\"{}|^[]`ferret", 196 /*.pszFragment =*/ "nose <>#%\"{}|^[]`", 197 /*.pszUsername =*/ "tt", 198 /*.pszPassword =*/ "yt", 199 /*.pszHost =*/ "example.com", 187 200 /*.uPort =*/ 8042, 188 201 }, 189 202 { /* #12 */ 190 "foo://tt:[email protected]:8042#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", 191 /*.pszScheme =*/ "foo", 192 /*.pszAuthority =*/ "tt:[email protected]:8042", 193 /*.pszPath =*/ NULL, 194 /*.pszQuery =*/ NULL, 195 /*.pszFragment =*/ "nose <>#%\"{}|^[]`", 196 /*.pszUsername =*/ "tt", 197 /*.pszPassword =*/ "tt", 203 "foo://tt:[email protected]:8042#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", 204 /*.pszScheme =*/ "foo", 205 /*.pszAuthority =*/ "tt:[email protected]:8042", 206 /*.pszPath =*/ NULL, 207 /*.pszQuery =*/ NULL, 208 /*.pszFragment =*/ "nose <>#%\"{}|^[]`", 209 /*.pszUsername =*/ "tt", 210 /*.pszPassword =*/ "yt", 211 /*.pszHost =*/ "example.com", 198 212 /*.uPort =*/ 8042, 199 213 }, 200 214 { /* #13 */ 201 "foo://tt:[email protected]:8042", 202 /*.pszScheme =*/ "foo", 203 /*.pszAuthority =*/ "tt:[email protected]:8042", 204 /*.pszPath =*/ NULL, 205 /*.pszQuery =*/ NULL, 206 /*.pszFragment =*/ NULL, 207 /*.pszUsername =*/ "tt", 208 /*.pszPassword =*/ "tt", 215 "foo://tt:[email protected]:8042", 216 /*.pszScheme =*/ "foo", 217 /*.pszAuthority =*/ "tt:[email protected]:8042", 218 /*.pszPath =*/ NULL, 219 /*.pszQuery =*/ NULL, 220 /*.pszFragment =*/ NULL, 221 /*.pszUsername =*/ "tt", 222 /*.pszPassword =*/ "yt", 223 /*.pszHost =*/ "example.com", 209 224 /*.uPort =*/ 8042, 210 225 }, … … 218 233 /*.pszUsername =*/ NULL, 219 234 /*.pszPassword =*/ NULL, 235 /*.pszHost =*/ NULL, 220 236 /*.uPort =*/ UINT32_MAX, 221 237 }, … … 229 245 /*.pszUsername =*/ NULL, 230 246 /*.pszPassword =*/ NULL, 247 /*.pszHost =*/ NULL, 231 248 /*.uPort =*/ UINT32_MAX, 232 249 }, 233 250 }; 234 251 235 236 static const char *g_apcszTestURIs[] =237 {238 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",239 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret",240 "foo://tt:[email protected]:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there",241 "foo:[email protected]",242 "foo:/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",243 "foo:/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",244 "urn:example:animal:ferret:nose",245 "foo:?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",246 "foo:#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",247 "foo://tt:[email protected]:8042/?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",248 "foo://tt:[email protected]:8042/",249 "foo://tt:[email protected]:8042?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",250 "foo://tt:[email protected]:8042#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60",251 "foo://tt:[email protected]:8042",252 "foo:///",253 "foo://"254 };255 256 static const char *g_apcszCreateURIs[][5] =257 {258 { "foo", "tt:[email protected]:8042", "/over/ <>#%\"{}|^[]`/there", "name= <>#%\"{}|^[]`ferret", "nose <>#%\"{}|^[]`" },259 { "foo", "tt:[email protected]:8042", "/over/ <>#%\"{}|^[]`/there", "name= <>#%\"{}|^[]`ferret", NULL },260 { "foo", "tt:[email protected]:8042", "/over/ <>#%\"{}|^[]`/there", NULL, NULL },261 { "foo", NULL, "[email protected]", NULL, NULL },262 { "foo", NULL, "/over/ <>#%\"{}|^[]`/there", "name= <>#%\"{}|^[]`ferret", "nose <>#%\"{}|^[]`" },263 { "foo", NULL, "/over/ <>#%\"{}|^[]`/there", NULL, "nose <>#%\"{}|^[]`" },264 { "urn", NULL, "example:animal:ferret:nose", NULL, NULL },265 { "foo", NULL, NULL, "name= <>#%\"{}|^[]`ferret", "nose <>#%\"{}|^[]`" },266 { "foo", NULL, NULL, NULL, "nose <>#%\"{}|^[]`" },267 { "foo", "tt:[email protected]:8042", "/", "name= <>#%\"{}|^[]`ferret", "nose <>#%\"{}|^[]`" },268 { "foo", "tt:[email protected]:8042", "/", NULL, NULL },269 { "foo", "tt:[email protected]:8042", NULL, "name= <>#%\"{}|^[]`ferret", "nose <>#%\"{}|^[]`" },270 { "foo", "tt:[email protected]:8042", NULL, NULL, "nose <>#%\"{}|^[]`" },271 { "foo", "tt:[email protected]:8042", NULL, NULL, NULL },272 { "foo", "", "/", NULL, NULL },273 { "foo", "", NULL, NULL, NULL }274 };275 252 276 253 struct URIFILETEST … … 289 266 }; 290 267 291 /** 292 * Basic API checks. 293 */ 294 static void tstScheme(size_t idxTest, const char *pszUri, const char *pszTest) 295 { 296 char *pszResult = RTUriScheme(pszUri); 297 if (pszTest) 298 { 299 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 300 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 301 } 302 else 303 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 304 305 if (pszResult) 306 RTStrFree(pszResult); 307 } 308 309 static void tstAuthority(size_t idxTest, const char *pszUri, const char *pszTest) 310 { 311 char *pszResult = RTUriAuthority(pszUri); 312 if (pszTest) 313 { 314 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 315 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 316 } 317 else 318 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 319 320 if (pszResult) 321 RTStrFree(pszResult); 322 } 323 324 static void tstAuthorityUsername(size_t idxTest, const char *pszUri, const char *pszTest) 325 { 326 char *pszResult = RTUriAuthorityUsername(pszUri); 327 if (pszTest) 328 { 329 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 330 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 331 } 332 else 333 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 334 RTStrFree(pszResult); 335 } 336 337 static void tstAuthorityPassword(size_t idxTest, const char *pszUri, const char *pszTest) 338 { 339 char *pszResult = RTUriAuthorityPassword(pszUri); 340 if (pszTest) 341 { 342 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 343 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 344 } 345 else 346 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 347 RTStrFree(pszResult); 348 } 349 350 static void tstAuthorityPort(size_t idxTest, const char *pszUri, uint32_t uTest) 351 { 352 uint32_t uResult = RTUriAuthorityPort(pszUri); 353 RTTESTI_CHECK_MSG_RETV(uResult == uTest, ("#%u: Result %#x != %#x (%s)", idxTest, uResult, uTest, pszUri)); 354 } 355 356 static void tstPath(size_t idxTest, const char *pszUri, const char *pszTest) 357 { 358 char *pszResult = RTUriPath(pszUri); 359 if (pszTest) 360 { 361 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 362 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 363 } 364 else 365 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 366 367 if (pszResult) 368 RTStrFree(pszResult); 369 } 370 371 static void tstQuery(size_t idxTest, const char *pszUri, const char *pszTest) 372 { 373 char *pszResult = RTUriQuery(pszUri); 374 if (pszTest) 375 { 376 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 377 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 378 } 379 else 380 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 381 382 if (pszResult) 383 RTStrFree(pszResult); 384 } 385 386 static void tstFragment(size_t idxTest, const char *pszUri, const char *pszTest) 387 { 388 char *pszResult = RTUriFragment(pszUri); 389 if (pszTest) 390 { 391 RTTESTI_CHECK_MSG_RETV(pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 392 RTTESTI_CHECK_MSG(RTStrCmp(pszResult, pszTest) == 0, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 393 } 394 else 395 RTTESTI_CHECK_MSG(!pszResult, ("#%u: Result '%s' != '%s'", idxTest, pszResult, pszTest)); 396 397 if (pszResult) 398 RTStrFree(pszResult); 399 } 268 400 269 401 270 static void tstCreate(size_t idxTest, const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery, const char *pszFragment, const char *pszTest) … … 455 324 RTTestBanner(hTest); 456 325 457 /* Scheme */ 458 RTTestISub("RTUriScheme"); 459 for (uint32_t i = 0; i < RT_ELEMENTS(g_aTests); i++) 460 tstScheme(i, g_aTests[i].pszUri, g_aTests[i].pszScheme); 461 462 /* Authority */ 463 RTTestISub("RTUriAuthority"); 326 RTTestISub("RTUriParse & RTUriParsed*"); 464 327 for (uint32_t i = 0; i < RT_ELEMENTS(g_aTests); i++) 465 328 { 466 tstAuthority(i, g_aTests[i].pszUri, g_aTests[i].pszAuthority); 467 tstAuthorityUsername(i, g_aTests[i].pszUri, g_aTests[i].pszUsername); 468 tstAuthorityPassword(i, g_aTests[i].pszUri, g_aTests[i].pszPassword); 469 tstAuthorityPort(i, g_aTests[i].pszUri, g_aTests[i].uPort); 329 RTURIPARSED Parsed; 330 RTTESTI_CHECK_RC(rc = RTUriParse(g_aTests[i].pszUri, &Parsed), VINF_SUCCESS); 331 if (RT_SUCCESS(rc)) 332 { 333 #define CHECK_STR_API(a_Call, a_pszExpected) \ 334 do { \ 335 char *pszTmp = a_Call; \ 336 if (a_pszExpected) \ 337 { \ 338 if (!pszTmp) \ 339 RTTestIFailed("#%u: %s returns NULL, expected '%s'", i, #a_Call, a_pszExpected); \ 340 else if (strcmp(pszTmp, a_pszExpected)) \ 341 RTTestIFailed("#%u: %s returns '%s', expected '%s'", i, #a_Call, pszTmp, a_pszExpected); \ 342 } \ 343 else if (pszTmp) \ 344 RTTestIFailed("#%u: %s returns '%s', expected NULL", i, #a_Call, pszTmp); \ 345 RTStrFree(pszTmp); \ 346 } while (0) 347 CHECK_STR_API(RTUriParsedScheme(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszScheme); 348 CHECK_STR_API(RTUriParsedAuthority(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszAuthority); 349 CHECK_STR_API(RTUriParsedAuthorityUsername(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszUsername); 350 CHECK_STR_API(RTUriParsedAuthorityPassword(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszPassword); 351 CHECK_STR_API(RTUriParsedAuthorityHost(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszHost); 352 CHECK_STR_API(RTUriParsedPath(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszPath); 353 CHECK_STR_API(RTUriParsedQuery(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszQuery); 354 CHECK_STR_API(RTUriParsedFragment(g_aTests[i].pszUri, &Parsed), g_aTests[i].pszFragment); 355 uint32_t uPort = RTUriParsedAuthorityPort(g_aTests[i].pszUri, &Parsed); 356 if (uPort != g_aTests[i].uPort) 357 RTTestIFailed("#%u: RTUriParsedAuthorityPort returns %#x, expected %#x", i, uPort, g_aTests[i].uPort); 358 } 470 359 } 471 472 /* Path */473 RTTestISub("RTUriPath");474 for (uint32_t i = 0; i < RT_ELEMENTS(g_aTests); i++)475 tstPath(i, g_aTests[i].pszUri, g_aTests[i].pszPath);476 477 /* Query */478 RTTestISub("RTUriQuery");479 for (uint32_t i = 0; i < RT_ELEMENTS(g_aTests); i++)480 tstQuery(i, g_aTests[i].pszUri, g_aTests[i].pszQuery);481 482 /* Fragment */483 RTTestISub("RTUriFragment");484 for (uint32_t i = 0; i < RT_ELEMENTS(g_aTests); i++)485 tstFragment(i, g_aTests[i].pszUri, g_aTests[i].pszFragment);486 360 487 361 /* Creation */
Note:
See TracChangeset
for help on using the changeset viewer.