@@ -727,23 +727,29 @@ bool IPV6_API_DEF(ipv6_from_str_diag) (
727727 // Treat the end of input as whitespace to simplify state transitions
728728 ipv6_state_transition (& state , EC_WHITESPACE );
729729
730- // Early out if there was an error processing the string
731- if ((state .flags & READER_FLAG_ERROR ) != 0 ) {
732- return false;
733- }
734-
735- // If an IPv4 compatible address was specified the rest of the IPv6 collapsing
736- // rules can be skipped
737- if ((state .flags & READER_FLAG_IPV4_COMPAT ) != 0 ) {
738- state .address_full -> flags |= IPV6_FLAG_IPV4_COMPAT ;
739- return true;
740- }
730+ // Early out if there was an error processing the string
731+ if ((state .flags & READER_FLAG_ERROR ) != 0 ) {
732+ return false;
733+ }
734+
735+ // If an IPv4 compatible address was specified the rest of the IPv6 collapsing
736+ // rules can be skipped
737+ if ((state .flags & READER_FLAG_IPV4_COMPAT ) != 0 ) {
738+ if (state .v4_octets != 4 ) {
739+ ipv6_error (& state , IPV6_DIAG_V4_BAD_COMPONENT_COUNT ,
740+ "IPv4 compatible address was used but required 4 octets" );
741+ return false;
742+ }
743+ state .address_full -> flags |= IPV6_FLAG_IPV4_COMPAT ;
744+ return true;
745+ }
741746
742747 // Mark the presence of embedded IPv4 addresses
743748 if (state .flags & READER_FLAG_IPV4_EMBEDDING ) {
744749 if (state .v4_octets != 4 ) {
745750 ipv6_error (& state , IPV6_DIAG_V4_BAD_COMPONENT_COUNT ,
746751 "IPv4 address embedding was used but required 4 octets" );
752+ return false;
747753 } else {
748754 state .address_full -> flags |= IPV6_FLAG_IPV4_EMBED ;
749755 }
@@ -808,29 +814,32 @@ bool IPV6_API_DEF(ipv6_from_str) (
808814
809815#define OUTPUT_TRUNCATED () \
810816 IPV6_TRACE(" ! buffer truncated at position %u\n", (uint32_t)(wp - out)); \
811- *out = '\0';
817+ output_bytes = 0; \
818+ *output = '\0';
812819
813820//--------------------------------------------------------------------------------
814- char * IPV6_API_DEF (ipv6_to_str ) (
821+ size_t IPV6_API_DEF (ipv6_to_str ) (
815822 const ipv6_address_full_t * in ,
816- char * out ,
817- size_t size )
823+ char * output ,
824+ size_t output_bytes )
818825{
819- if (size < 4 ) {
820- return NULL ;
826+ if (! in || ! output ) {
827+ return 0 ;
821828 }
822829
823- if (! in ) {
824- return NULL ;
830+ if (output_bytes < 4 ) {
831+ return 0 ;
825832 }
826833
834+ * output = '\0' ;
835+
827836 const uint16_t * components = in -> address .components ;
828- char * wp = out ; // write pointer
829- const char * ep = out + size - 1 ; // end pointer with one octet for nul
837+ char * wp = output ; // write pointer
838+ const char * ep = output + output_bytes - 1 ; // end pointer with one octet for nul
830839 char token [16 ] = {0 , };
831840
832-
833- // If the address is an IPv4 compat address shortcut the IPv6 rules and print an address or address:port
841+ // If the address is an IPv4 compatible address shortcut the IPv6 rules and
842+ // print an address or address:port
834843 if (in -> flags & IPV6_FLAG_IPV4_COMPAT ) {
835844 const uint32_t host_ipv4 = components [0 ] << 16 | components [1 ];
836845 if (in -> flags & IPV6_FLAG_HAS_PORT ) {
@@ -851,8 +860,10 @@ char* IPV6_API_DEF(ipv6_to_str) (
851860 while (wp < ep && * cp ) {
852861 * wp ++ = * cp ++ ;
853862 }
863+
864+ output_bytes = (size_t )(ptrdiff_t )(wp - output );
854865 * wp ++ = '\0' ;
855- return out ;
866+ return output_bytes ;
856867 }
857868
858869 // For each component find the length of 0 digits that it covers (including
@@ -915,7 +926,7 @@ char* IPV6_API_DEF(ipv6_to_str) (
915926 if (i == longest_position && longest_span > 1 ) {
916927 if (wp + 2 >= ep ) {
917928 OUTPUT_TRUNCATED ();
918- return NULL ;
929+ return output_bytes ;
919930 }
920931
921932 // The previous component already emitted a separator, or this is the
@@ -942,7 +953,7 @@ char* IPV6_API_DEF(ipv6_to_str) (
942953 if (wp == ep ) {
943954 // Truncated, return a deterministic result
944955 OUTPUT_TRUNCATED ();
945- return NULL ;
956+ return output_bytes ;
946957 }
947958 }
948959
@@ -962,9 +973,15 @@ char* IPV6_API_DEF(ipv6_to_str) (
962973 }
963974 }
964975
965- * wp = '\0' ;
966-
967- return out ;
976+ // Output truncated
977+ if (wp == ep ) {
978+ OUTPUT_TRUNCATED ();
979+ }
980+ else {
981+ output_bytes = (size_t )(ptrdiff_t )(wp - output );
982+ * wp = '\0' ;
983+ }
984+ return output_bytes ;
968985}
969986
970987//--------------------------------------------------------------------------------
0 commit comments