33 * varbit.c
44 * Functions for the SQL datatypes BIT() and BIT VARYING().
55 *
6+ * The data structure contains the following elements:
7+ * header -- length of the whole data structure (incl header)
8+ * in bytes (as with all varying length datatypes)
9+ * data section -- private data section for the bits data structures
10+ * bitlength -- length of the bit string in bits
11+ * bitdata -- bit string, most significant byte first
12+ *
13+ * The length of the bitdata vector should always be exactly as many
14+ * bytes as are needed for the given bitlength. If the bitlength is
15+ * not a multiple of 8, the extra low-order padding bits of the last
16+ * byte must be zeroes.
17+ *
18+ * attypmod is defined as the length of the bit string in bits, or for
19+ * varying bits the maximum length.
20+ *
621 * Code originally contributed by Adriaan Joubert.
722 *
823 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
2742
2843#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
2944
45+ /* Mask off any bits that should be zero in the last byte of a bitstring */
46+ #define VARBIT_PAD (vb ) \
47+ do { \
48+ int32 pad_ = VARBITPAD(vb); \
49+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
50+ if (pad_ > 0) \
51+ *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
52+ } while (0)
53+
54+ /*
55+ * Many functions work byte-by-byte, so they have a pointer handy to the
56+ * last-plus-one byte, which saves a cycle or two.
57+ */
58+ #define VARBIT_PAD_LAST (vb , ptr ) \
59+ do { \
60+ int32 pad_ = VARBITPAD(vb); \
61+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
62+ if (pad_ > 0) \
63+ *((ptr) - 1) &= BITMASK << pad_; \
64+ } while (0)
65+
66+ /* Assert proper padding of a bitstring */
67+ #ifdef USE_ASSERT_CHECKING
68+ #define VARBIT_CORRECTLY_PADDED (vb ) \
69+ do { \
70+ int32 pad_ = VARBITPAD(vb); \
71+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
72+ Assert(pad_ == 0 || \
73+ (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
74+ } while (0)
75+ #else
76+ #define VARBIT_CORRECTLY_PADDED (vb ) ((void) 0)
77+ #endif
78+
3079static VarBit * bit_catenate (VarBit * arg1 , VarBit * arg2 );
3180static VarBit * bitsubstring (VarBit * arg , int32 s , int32 l ,
3281 bool length_not_specified );
@@ -87,24 +136,6 @@ anybit_typmodout(int32 typmod)
87136}
88137
89138
90- /*----------
91- * attypmod -- contains the length of the bit string in bits, or for
92- * varying bits the maximum length.
93- *
94- * The data structure contains the following elements:
95- * header -- length of the whole data structure (incl header)
96- * in bytes. (as with all varying length datatypes)
97- * data section -- private data section for the bits data structures
98- * bitlength -- length of the bit string in bits
99- * bitdata -- bit string, most significant byte first
100- *
101- * The length of the bitdata vector should always be exactly as many
102- * bytes as are needed for the given bitlength. If the bitlength is
103- * not a multiple of 8, the extra low-order padding bits of the last
104- * byte must be zeroes.
105- *----------
106- */
107-
108139/*
109140 * bit_in -
110141 * converts a char string to the internal representation of a bitstring.
@@ -264,6 +295,9 @@ bit_out(PG_FUNCTION_ARGS)
264295 len ,
265296 bitlen ;
266297
298+ /* Assertion to help catch any bit functions that don't pad correctly */
299+ VARBIT_CORRECTLY_PADDED (s );
300+
267301 bitlen = VARBITLEN (s );
268302 len = (bitlen + 3 ) / 4 ;
269303 result = (char * ) palloc (len + 2 );
@@ -304,8 +338,6 @@ bit_recv(PG_FUNCTION_ARGS)
304338 VarBit * result ;
305339 int len ,
306340 bitlen ;
307- int ipad ;
308- bits8 mask ;
309341
310342 bitlen = pq_getmsgint (buf , sizeof (int32 ));
311343 if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -330,13 +362,8 @@ bit_recv(PG_FUNCTION_ARGS)
330362
331363 pq_copymsgbytes (buf , (char * ) VARBITS (result ), VARBITBYTES (result ));
332364
333- /* Make sure last byte is zero-padded if needed */
334- ipad = VARBITPAD (result );
335- if (ipad > 0 )
336- {
337- mask = BITMASK << ipad ;
338- * (VARBITS (result ) + VARBITBYTES (result ) - 1 ) &= mask ;
339- }
365+ /* Make sure last byte is correctly zero-padded */
366+ VARBIT_PAD (result );
340367
341368 PG_RETURN_VARBIT_P (result );
342369}
@@ -367,8 +394,6 @@ bit(PG_FUNCTION_ARGS)
367394 bool isExplicit = PG_GETARG_BOOL (2 );
368395 VarBit * result ;
369396 int rlen ;
370- int ipad ;
371- bits8 mask ;
372397
373398 /* No work if typmod is invalid or supplied data matches it already */
374399 if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -394,12 +419,7 @@ bit(PG_FUNCTION_ARGS)
394419 * if source data was shorter than target length (we assume the last byte
395420 * of the source data was itself correctly zero-padded).
396421 */
397- ipad = VARBITPAD (result );
398- if (ipad > 0 )
399- {
400- mask = BITMASK << ipad ;
401- * (VARBITS (result ) + VARBITBYTES (result ) - 1 ) &= mask ;
402- }
422+ VARBIT_PAD (result );
403423
404424 PG_RETURN_VARBIT_P (result );
405425}
@@ -574,6 +594,9 @@ varbit_out(PG_FUNCTION_ARGS)
574594 k ,
575595 len ;
576596
597+ /* Assertion to help catch any bit functions that don't pad correctly */
598+ VARBIT_CORRECTLY_PADDED (s );
599+
577600 len = VARBITLEN (s );
578601 result = (char * ) palloc (len + 1 );
579602 sp = VARBITS (s );
@@ -620,8 +643,6 @@ varbit_recv(PG_FUNCTION_ARGS)
620643 VarBit * result ;
621644 int len ,
622645 bitlen ;
623- int ipad ;
624- bits8 mask ;
625646
626647 bitlen = pq_getmsgint (buf , sizeof (int32 ));
627648 if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -646,13 +667,8 @@ varbit_recv(PG_FUNCTION_ARGS)
646667
647668 pq_copymsgbytes (buf , (char * ) VARBITS (result ), VARBITBYTES (result ));
648669
649- /* Make sure last byte is zero-padded if needed */
650- ipad = VARBITPAD (result );
651- if (ipad > 0 )
652- {
653- mask = BITMASK << ipad ;
654- * (VARBITS (result ) + VARBITBYTES (result ) - 1 ) &= mask ;
655- }
670+ /* Make sure last byte is correctly zero-padded */
671+ VARBIT_PAD (result );
656672
657673 PG_RETURN_VARBIT_P (result );
658674}
@@ -729,8 +745,6 @@ varbit(PG_FUNCTION_ARGS)
729745 bool isExplicit = PG_GETARG_BOOL (2 );
730746 VarBit * result ;
731747 int rlen ;
732- int ipad ;
733- bits8 mask ;
734748
735749 /* No work if typmod is invalid or supplied data matches it already */
736750 if (len <= 0 || len >= VARBITLEN (arg ))
@@ -749,13 +763,8 @@ varbit(PG_FUNCTION_ARGS)
749763
750764 memcpy (VARBITS (result ), VARBITS (arg ), VARBITBYTES (result ));
751765
752- /* Make sure last byte is zero-padded if needed */
753- ipad = VARBITPAD (result );
754- if (ipad > 0 )
755- {
756- mask = BITMASK << ipad ;
757- * (VARBITS (result ) + VARBITBYTES (result ) - 1 ) &= mask ;
758- }
766+ /* Make sure last byte is correctly zero-padded */
767+ VARBIT_PAD (result );
759768
760769 PG_RETURN_VARBIT_P (result );
761770}
@@ -1013,6 +1022,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
10131022 }
10141023 }
10151024
1025+ /* The pad bits should be already zero at this point */
1026+
10161027 return result ;
10171028}
10181029
@@ -1046,14 +1057,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
10461057 int bitlen ,
10471058 rbitlen ,
10481059 len ,
1049- ipad = 0 ,
10501060 ishift ,
10511061 i ;
10521062 int e ,
10531063 s1 ,
10541064 e1 ;
1055- bits8 mask ,
1056- * r ,
1065+ bits8 * r ,
10571066 * ps ;
10581067
10591068 bitlen = VARBITLEN (arg );
@@ -1118,13 +1127,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
11181127 r ++ ;
11191128 }
11201129 }
1121- /* Do we need to pad at the end? */
1122- ipad = VARBITPAD (result );
1123- if (ipad > 0 )
1124- {
1125- mask = BITMASK << ipad ;
1126- * (VARBITS (result ) + len - 1 ) &= mask ;
1127- }
1130+
1131+ /* Make sure last byte is correctly zero-padded */
1132+ VARBIT_PAD (result );
11281133 }
11291134
11301135 return result ;
@@ -1246,7 +1251,7 @@ bit_and(PG_FUNCTION_ARGS)
12461251 for (i = 0 ; i < VARBITBYTES (arg1 ); i ++ )
12471252 * r ++ = * p1 ++ & * p2 ++ ;
12481253
1249- /* Padding is not needed as & of 0 pad is 0 */
1254+ /* Padding is not needed as & of 0 pads is 0 */
12501255
12511256 PG_RETURN_VARBIT_P (result );
12521257}
@@ -1268,7 +1273,6 @@ bit_or(PG_FUNCTION_ARGS)
12681273 bits8 * p1 ,
12691274 * p2 ,
12701275 * r ;
1271- bits8 mask ;
12721276
12731277 bitlen1 = VARBITLEN (arg1 );
12741278 bitlen2 = VARBITLEN (arg2 );
@@ -1287,13 +1291,7 @@ bit_or(PG_FUNCTION_ARGS)
12871291 for (i = 0 ; i < VARBITBYTES (arg1 ); i ++ )
12881292 * r ++ = * p1 ++ | * p2 ++ ;
12891293
1290- /* Pad the result */
1291- mask = BITMASK << VARBITPAD (result );
1292- if (mask )
1293- {
1294- r -- ;
1295- * r &= mask ;
1296- }
1294+ /* Padding is not needed as | of 0 pads is 0 */
12971295
12981296 PG_RETURN_VARBIT_P (result );
12991297}
@@ -1315,7 +1313,6 @@ bitxor(PG_FUNCTION_ARGS)
13151313 bits8 * p1 ,
13161314 * p2 ,
13171315 * r ;
1318- bits8 mask ;
13191316
13201317 bitlen1 = VARBITLEN (arg1 );
13211318 bitlen2 = VARBITLEN (arg2 );
@@ -1335,13 +1332,7 @@ bitxor(PG_FUNCTION_ARGS)
13351332 for (i = 0 ; i < VARBITBYTES (arg1 ); i ++ )
13361333 * r ++ = * p1 ++ ^ * p2 ++ ;
13371334
1338- /* Pad the result */
1339- mask = BITMASK << VARBITPAD (result );
1340- if (mask )
1341- {
1342- r -- ;
1343- * r &= mask ;
1344- }
1335+ /* Padding is not needed as ^ of 0 pads is 0 */
13451336
13461337 PG_RETURN_VARBIT_P (result );
13471338}
@@ -1357,7 +1348,6 @@ bitnot(PG_FUNCTION_ARGS)
13571348 VarBit * result ;
13581349 bits8 * p ,
13591350 * r ;
1360- bits8 mask ;
13611351
13621352 result = (VarBit * ) palloc (VARSIZE (arg ));
13631353 SET_VARSIZE (result , VARSIZE (arg ));
@@ -1368,13 +1358,8 @@ bitnot(PG_FUNCTION_ARGS)
13681358 for (; p < VARBITEND (arg ); p ++ )
13691359 * r ++ = ~* p ;
13701360
1371- /* Pad the result */
1372- mask = BITMASK << VARBITPAD (result );
1373- if (mask )
1374- {
1375- r -- ;
1376- * r &= mask ;
1377- }
1361+ /* Must zero-pad the result, because extra bits are surely 1's here */
1362+ VARBIT_PAD_LAST (result , r );
13781363
13791364 PG_RETURN_VARBIT_P (result );
13801365}
@@ -1441,6 +1426,8 @@ bitshiftleft(PG_FUNCTION_ARGS)
14411426 * r = 0 ;
14421427 }
14431428
1429+ /* The pad bits should be already zero at this point */
1430+
14441431 PG_RETURN_VARBIT_P (result );
14451432}
14461433
@@ -1507,6 +1494,8 @@ bitshiftright(PG_FUNCTION_ARGS)
15071494 if ((++ r ) < VARBITEND (result ))
15081495 * r = (* p << (BITS_PER_BYTE - ishift )) & BITMASK ;
15091496 }
1497+ /* We may have shifted 1's into the pad bits, so fix that */
1498+ VARBIT_PAD_LAST (result , r );
15101499 }
15111500
15121501 PG_RETURN_VARBIT_P (result );
0 commit comments