@@ -573,6 +573,59 @@ 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 )
603+ || (i == 14 && end == 16 )) {
604+ memcpy (dest + written , _UT (":" ), 1 * sizeof (URI_CHAR ));
605+ written ++ ;
606+ }
607+
608+ if (i >= start && i < end ) {
609+ continue ;
610+ }
611+
612+ const uint16_t value = (ip6 -> data [i ] << 8 ) + ip6 -> data [i + 1 ];
613+ if (value > 0xfff ) {
614+ dest [written ++ ] = URI_FUNC (HexToLetterEx )((value >> 12 ) & 0xf , URI_FALSE );
615+ }
616+ if (value > 0xff ) {
617+ dest [written ++ ] = URI_FUNC (HexToLetterEx )((value >> 8 ) & 0xf , URI_FALSE );
618+ }
619+ if (value > 0xf ) {
620+ dest [written ++ ] = URI_FUNC (HexToLetterEx )((value >> 4 ) & 0xf , URI_FALSE );
621+ }
622+ dest [written ++ ] = URI_FUNC (HexToLetterEx )((value >> 0 ) & 0xf , URI_FALSE );
623+ }
624+ dest [written ] = _UT ('\0' );
625+
626+ return written ;
627+ }
628+
576629static URI_INLINE int URI_FUNC (NormalizeSyntaxEngine )(URI_TYPE (Uri ) * uri ,
577630 unsigned int inMask , unsigned int * outMask , UriMemoryManager * memory ) {
578631 unsigned int revertMask = URI_NORMALIZED ;
@@ -609,7 +662,14 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri,
609662 * outMask |= URI_NORMALIZE_SCHEME ;
610663 }
611664
612- if (normalizeHostCase ) {
665+ if (uri -> hostData .ip6 != NULL ) {
666+ URI_CHAR out [46 ];
667+ int length = URI_FUNC (NormalizeIpv6 )(out , uri -> hostData .ip6 );
668+ if ((uri -> hostText .afterLast - uri -> hostText .first ) != length
669+ || URI_STRNCMP (out , uri -> hostText .first , length ) != 0 ) {
670+ * outMask |= URI_NORMALIZE_HOST ;
671+ }
672+ } else if (normalizeHostCase ) {
613673 * outMask |= URI_NORMALIZE_HOST ;
614674 } else {
615675 const UriBool normalizeHostPrecent = URI_FUNC (ContainsUglyPercentEncoding )(
@@ -635,7 +695,25 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri,
635695
636696 /* Host */
637697 if (inMask & URI_NORMALIZE_HOST ) {
638- if (uri -> hostData .ipFuture .first != NULL ) {
698+ if (uri -> hostData .ip6 != NULL ) {
699+ URI_CHAR out [46 ];
700+ int lenInChars = URI_FUNC (NormalizeIpv6 )(out , uri -> hostData .ip6 );
701+ if (uri -> owner ) {
702+ memory -> free (memory , (URI_CHAR * )uri -> hostText .first );
703+ uri -> hostText .first = NULL ;
704+ uri -> hostText .afterLast = NULL ;
705+ }
706+ URI_CHAR * buffer = memory -> malloc (memory , lenInChars * sizeof (URI_CHAR ));
707+ if (buffer == NULL ) {
708+ URI_FUNC (PreventLeakage )(uri , revertMask , memory );
709+ return URI_ERROR_MALLOC ;
710+ }
711+ memcpy (buffer , out , lenInChars * sizeof (URI_CHAR ));
712+ uri -> hostText .first = buffer ;
713+ uri -> hostText .afterLast = buffer + lenInChars ;
714+
715+ revertMask |= URI_NORMALIZE_HOST ;
716+ } else if (uri -> hostData .ipFuture .first != NULL ) {
639717 /* IPvFuture */
640718 if (uri -> owner ) {
641719 URI_FUNC (LowercaseInplace )(uri -> hostData .ipFuture .first ,
0 commit comments