@@ -573,6 +573,64 @@ static void URI_FUNC(AdvancePastLeadingZeros)(
573573 * first = remainderFirst ;
574574}
575575
576+ static int URI_FUNC (NormalizeIpv6 )(URI_CHAR * dest , const UriIp6 * ip6 ) {
577+ int start = -1 ;
578+ int end = -1 ;
579+ for (int i = 0 ; i < 16 ; i += 2 ) {
580+ if (ip6 -> data [i ] > 0 ) {
581+ continue ;
582+ }
583+ int j = i ;
584+ for (; j < 16 ; j ++ ) {
585+ if (ip6 -> data [j ] > 0 ) {
586+ break ;
587+ }
588+ }
589+ if ((j % 2 ) == 1 ) {
590+ j -- ;
591+ }
592+
593+ if (start == -1 || (j - i ) > (end - start )) {
594+ start = i ;
595+ end = j ;
596+ }
597+ i = j ;
598+ }
599+
600+ int written = 0 ;
601+ for (int i = 0 ; i < 16 ; i += 2 ) {
602+ if ((i > 0 && !(i > start && i < end )) || (i == 0 && start == 0 ) || (i == 14 && end == 16 )) {
603+ memcpy (dest + written , _UT (":" ), 1 * sizeof (URI_CHAR ));
604+ written ++ ;
605+ }
606+
607+ if (i >= start && i < end ) {
608+ continue ;
609+ }
610+
611+ const uint16_t value = (ip6 -> data [i ] << 8 ) + ip6 -> data [i + 1 ];
612+ size_t length = 1 + (value > 0xf ) + (value > 0xff ) + (value > 0xfff );
613+
614+ if (value > 0xfff ) {
615+ dest [written ++ ] = URI_FUNC (HexToLetterEx )(
616+ (value >> 12 ) & 0xf , URI_FALSE );
617+ }
618+ if (value > 0xff ) {
619+ dest [written ++ ] = URI_FUNC (HexToLetterEx )(
620+ (value >> 8 ) & 0xf , URI_FALSE );
621+ }
622+ if (value > 0xf ) {
623+ dest [written ++ ] = URI_FUNC (HexToLetterEx )(
624+ (value >> 4 ) & 0xf , URI_FALSE );
625+ }
626+ dest [written ++ ] = URI_FUNC (HexToLetterEx )(
627+ (value >> 0 ) & 0xf , URI_FALSE );
628+ }
629+ dest [written ] = _UT ('\0' );
630+
631+ return written ;
632+ }
633+
576634static URI_INLINE int URI_FUNC (NormalizeSyntaxEngine )(URI_TYPE (Uri ) * uri ,
577635 unsigned int inMask , unsigned int * outMask , UriMemoryManager * memory ) {
578636 unsigned int revertMask = URI_NORMALIZED ;
@@ -609,7 +667,16 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri,
609667 * outMask |= URI_NORMALIZE_SCHEME ;
610668 }
611669
612- if (normalizeHostCase ) {
670+ if (uri -> hostData .ip6 != NULL ) {
671+ URI_CHAR out [46 ];
672+ int length = URI_FUNC (NormalizeIpv6 )(out , uri -> hostData .ip6 );
673+ if (
674+ (uri -> hostText .afterLast - uri -> hostText .first ) != length
675+ || URI_STRNCMP (out , uri -> hostText .first , length ) != 0
676+ ) {
677+ * outMask |= URI_NORMALIZE_HOST ;
678+ }
679+ } else if (normalizeHostCase ) {
613680 * outMask |= URI_NORMALIZE_HOST ;
614681 } else {
615682 const UriBool normalizeHostPrecent = URI_FUNC (ContainsUglyPercentEncoding )(
@@ -635,7 +702,25 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri,
635702
636703 /* Host */
637704 if (inMask & URI_NORMALIZE_HOST ) {
638- if (uri -> hostData .ipFuture .first != NULL ) {
705+ if (uri -> hostData .ip6 != NULL ) {
706+ URI_CHAR out [46 ];
707+ int lenInChars = URI_FUNC (NormalizeIpv6 )(out , uri -> hostData .ip6 );
708+ if (uri -> owner ) {
709+ memory -> free (memory , (URI_CHAR * )uri -> hostText .first );
710+ uri -> hostText .first = NULL ;
711+ uri -> hostText .afterLast = NULL ;
712+ }
713+ URI_CHAR * buffer = memory -> malloc (memory , lenInChars * sizeof (URI_CHAR ));
714+ if (buffer == NULL ) {
715+ URI_FUNC (PreventLeakage )(uri , revertMask , memory );
716+ return URI_ERROR_MALLOC ;
717+ }
718+ memcpy (buffer , out , lenInChars * sizeof (URI_CHAR ));
719+ uri -> hostText .first = buffer ;
720+ uri -> hostText .afterLast = buffer + lenInChars ;
721+
722+ revertMask |= URI_NORMALIZE_HOST ;
723+ } else if (uri -> hostData .ipFuture .first != NULL ) {
639724 /* IPvFuture */
640725 if (uri -> owner ) {
641726 URI_FUNC (LowercaseInplace )(uri -> hostData .ipFuture .first ,
0 commit comments