@@ -268,41 +268,15 @@ Datum
268268inet_to_cidr (PG_FUNCTION_ARGS )
269269{
270270 inet * src = PG_GETARG_INET_PP (0 );
271- inet * dst ;
272271 int bits ;
273- int byte ;
274- int nbits ;
275- int maxbytes ;
276272
277273 bits = ip_bits (src );
278274
279275 /* safety check */
280276 if ((bits < 0 ) || (bits > ip_maxbits (src )))
281277 elog (ERROR , "invalid inet bit length: %d" , bits );
282278
283- /* clone the original data */
284- dst = (inet * ) palloc (VARSIZE_ANY (src ));
285- memcpy (dst , src , VARSIZE_ANY (src ));
286-
287- /* zero out any bits to the right of the netmask */
288- byte = bits / 8 ;
289-
290- nbits = bits % 8 ;
291- /* clear the first byte, this might be a partial byte */
292- if (nbits != 0 )
293- {
294- ip_addr (dst )[byte ] &= ~(0xFF >> nbits );
295- byte ++ ;
296- }
297- /* clear remaining bytes */
298- maxbytes = ip_addrsize (dst );
299- while (byte < maxbytes )
300- {
301- ip_addr (dst )[byte ] = 0 ;
302- byte ++ ;
303- }
304-
305- PG_RETURN_INET_P (dst );
279+ PG_RETURN_INET_P (cidr_set_masklen_internal (src , bits ));
306280}
307281
308282Datum
@@ -334,10 +308,6 @@ cidr_set_masklen(PG_FUNCTION_ARGS)
334308{
335309 inet * src = PG_GETARG_INET_PP (0 );
336310 int bits = PG_GETARG_INT32 (1 );
337- inet * dst ;
338- int byte ;
339- int nbits ;
340- int maxbytes ;
341311
342312 if (bits == -1 )
343313 bits = ip_maxbits (src );
@@ -347,31 +317,36 @@ cidr_set_masklen(PG_FUNCTION_ARGS)
347317 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
348318 errmsg ("invalid mask length: %d" , bits )));
349319
350- /* clone the original data */
351- dst = (inet * ) palloc (VARSIZE_ANY (src ));
352- memcpy (dst , src , VARSIZE_ANY (src ));
320+ PG_RETURN_INET_P (cidr_set_masklen_internal (src , bits ));
321+ }
353322
354- ip_bits (dst ) = bits ;
323+ /*
324+ * Copy src and set mask length to 'bits' (which must be valid for the family)
325+ */
326+ inet *
327+ cidr_set_masklen_internal (const inet * src , int bits )
328+ {
329+ inet * dst = (inet * ) palloc0 (sizeof (inet ));
355330
356- /* zero out any bits to the right of the new netmask */
357- byte = bits / 8 ;
331+ ip_family ( dst ) = ip_family ( src );
332+ ip_bits ( dst ) = bits ;
358333
359- nbits = bits % 8 ;
360- /* clear the first byte, this might be a partial byte */
361- if (nbits != 0 )
334+ if (bits > 0 )
362335 {
363- ip_addr (dst )[byte ] &= ~(0xFF >> nbits );
364- byte ++ ;
365- }
366- /* clear remaining bytes */
367- maxbytes = ip_addrsize (dst );
368- while (byte < maxbytes )
369- {
370- ip_addr (dst )[byte ] = 0 ;
371- byte ++ ;
336+ Assert (bits <= ip_maxbits (dst ));
337+
338+ /* Clone appropriate bytes of the address, leaving the rest 0 */
339+ memcpy (ip_addr (dst ), ip_addr (src ), (bits + 7 ) / 8 );
340+
341+ /* Clear any unwanted bits in the last partial byte */
342+ if (bits % 8 )
343+ ip_addr (dst )[bits / 8 ] &= ~(0xFF >> (bits % 8 ));
372344 }
373345
374- PG_RETURN_INET_P (dst );
346+ /* Set varlena header correctly */
347+ SET_INET_VARSIZE (dst );
348+
349+ return dst ;
375350}
376351
377352/*
@@ -719,11 +694,7 @@ network_broadcast(PG_FUNCTION_ARGS)
719694 /* make sure any unused bits are zeroed */
720695 dst = (inet * ) palloc0 (sizeof (inet ));
721696
722- if (ip_family (ip ) == PGSQL_AF_INET )
723- maxbytes = 4 ;
724- else
725- maxbytes = 16 ;
726-
697+ maxbytes = ip_addrsize (ip );
727698 bits = ip_bits (ip );
728699 a = ip_addr (ip );
729700 b = ip_addr (dst );
@@ -853,11 +824,7 @@ network_hostmask(PG_FUNCTION_ARGS)
853824 /* make sure any unused bits are zeroed */
854825 dst = (inet * ) palloc0 (sizeof (inet ));
855826
856- if (ip_family (ip ) == PGSQL_AF_INET )
857- maxbytes = 4 ;
858- else
859- maxbytes = 16 ;
860-
827+ maxbytes = ip_addrsize (ip );
861828 bits = ip_maxbits (ip ) - ip_bits (ip );
862829 b = ip_addr (dst );
863830
@@ -907,8 +874,7 @@ Datum
907874inet_merge (PG_FUNCTION_ARGS )
908875{
909876 inet * a1 = PG_GETARG_INET_PP (0 ),
910- * a2 = PG_GETARG_INET_PP (1 ),
911- * result ;
877+ * a2 = PG_GETARG_INET_PP (1 );
912878 int commonbits ;
913879
914880 if (ip_family (a1 ) != ip_family (a2 ))
@@ -919,24 +885,7 @@ inet_merge(PG_FUNCTION_ARGS)
919885 commonbits = bitncommon (ip_addr (a1 ), ip_addr (a2 ),
920886 Min (ip_bits (a1 ), ip_bits (a2 )));
921887
922- /* Make sure any unused bits are zeroed. */
923- result = (inet * ) palloc0 (sizeof (inet ));
924-
925- ip_family (result ) = ip_family (a1 );
926- ip_bits (result ) = commonbits ;
927-
928- /* Clone appropriate bytes of the address. */
929- if (commonbits > 0 )
930- memcpy (ip_addr (result ), ip_addr (a1 ), (commonbits + 7 ) / 8 );
931-
932- /* Clean any unwanted bits in the last partial byte. */
933- if (commonbits % 8 != 0 )
934- ip_addr (result )[commonbits / 8 ] &= ~(0xFF >> (commonbits % 8 ));
935-
936- /* Set varlena header correctly. */
937- SET_INET_VARSIZE (result );
938-
939- PG_RETURN_INET_P (result );
888+ PG_RETURN_INET_P (cidr_set_masklen_internal (a1 , commonbits ));
940889}
941890
942891/*
0 commit comments