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-2018, PostgreSQL Global Development Group
2641
2742#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
2843
44+ /* Mask off any bits that should be zero in the last byte of a bitstring */
45+ #define VARBIT_PAD (vb ) \
46+ do { \
47+ int32pad_ = VARBITPAD(vb); \
48+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
49+ if (pad_ > 0) \
50+ *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \
51+ } while (0)
52+
53+ /*
54+ * Many functions work byte-by-byte, so they have a pointer handy to the
55+ * last-plus-one byte, which saves a cycle or two.
56+ */
57+ #define VARBIT_PAD_LAST (vb ,ptr ) \
58+ do { \
59+ int32pad_ = VARBITPAD(vb); \
60+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
61+ if (pad_ > 0) \
62+ *((ptr) - 1) &= BITMASK << pad_; \
63+ } while (0)
64+
65+ /* Assert proper padding of a bitstring */
66+ #ifdef USE_ASSERT_CHECKING
67+ #define VARBIT_CORRECTLY_PADDED (vb ) \
68+ do { \
69+ int32pad_ = VARBITPAD(vb); \
70+ Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \
71+ Assert(pad_ == 0 || \
72+ (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \
73+ } while (0)
74+ #else
75+ #define VARBIT_CORRECTLY_PADDED (vb ) ((void) 0)
76+ #endif
77+
2978static VarBit * bit_catenate (VarBit * arg1 ,VarBit * arg2 );
3079static VarBit * bitsubstring (VarBit * arg ,int32 s ,int32 l ,
3180bool length_not_specified );
@@ -86,24 +135,6 @@ anybit_typmodout(int32 typmod)
86135}
87136
88137
89- /*----------
90- *attypmod -- contains the length of the bit string in bits, or for
91- * varying bits the maximum length.
92- *
93- *The data structure contains the following elements:
94- * header -- length of the whole data structure (incl header)
95- * in bytes. (as with all varying length datatypes)
96- * data section -- private data section for the bits data structures
97- *bitlength -- length of the bit string in bits
98- *bitdata -- bit string, most significant byte first
99- *
100- *The length of the bitdata vector should always be exactly as many
101- *bytes as are needed for the given bitlength. If the bitlength is
102- *not a multiple of 8, the extra low-order padding bits of the last
103- *byte must be zeroes.
104- *----------
105- */
106-
107138/*
108139 * bit_in -
109140 * converts a char string to the internal representation of a bitstring.
@@ -263,6 +294,9 @@ bit_out(PG_FUNCTION_ARGS)
263294len ,
264295bitlen ;
265296
297+ /* Assertion to help catch any bit functions that don't pad correctly */
298+ VARBIT_CORRECTLY_PADDED (s );
299+
266300bitlen = VARBITLEN (s );
267301len = (bitlen + 3 ) /4 ;
268302result = (char * )palloc (len + 2 );
@@ -303,8 +337,6 @@ bit_recv(PG_FUNCTION_ARGS)
303337VarBit * result ;
304338int len ,
305339bitlen ;
306- int ipad ;
307- bits8 mask ;
308340
309341bitlen = pq_getmsgint (buf ,sizeof (int32 ));
310342if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -329,13 +361,8 @@ bit_recv(PG_FUNCTION_ARGS)
329361
330362pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
331363
332- /* Make sure last byte is zero-padded if needed */
333- ipad = VARBITPAD (result );
334- if (ipad > 0 )
335- {
336- mask = BITMASK <<ipad ;
337- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
338- }
364+ /* Make sure last byte is correctly zero-padded */
365+ VARBIT_PAD (result );
339366
340367PG_RETURN_VARBIT_P (result );
341368}
@@ -366,8 +393,6 @@ bit(PG_FUNCTION_ARGS)
366393bool isExplicit = PG_GETARG_BOOL (2 );
367394VarBit * result ;
368395int rlen ;
369- int ipad ;
370- bits8 mask ;
371396
372397/* No work if typmod is invalid or supplied data matches it already */
373398if (len <=0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -393,12 +418,7 @@ bit(PG_FUNCTION_ARGS)
393418 * if source data was shorter than target length (we assume the last byte
394419 * of the source data was itself correctly zero-padded).
395420 */
396- ipad = VARBITPAD (result );
397- if (ipad > 0 )
398- {
399- mask = BITMASK <<ipad ;
400- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
401- }
421+ VARBIT_PAD (result );
402422
403423PG_RETURN_VARBIT_P (result );
404424}
@@ -573,6 +593,9 @@ varbit_out(PG_FUNCTION_ARGS)
573593k ,
574594len ;
575595
596+ /* Assertion to help catch any bit functions that don't pad correctly */
597+ VARBIT_CORRECTLY_PADDED (s );
598+
576599len = VARBITLEN (s );
577600result = (char * )palloc (len + 1 );
578601sp = VARBITS (s );
@@ -619,8 +642,6 @@ varbit_recv(PG_FUNCTION_ARGS)
619642VarBit * result ;
620643int len ,
621644bitlen ;
622- int ipad ;
623- bits8 mask ;
624645
625646bitlen = pq_getmsgint (buf ,sizeof (int32 ));
626647if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -645,13 +666,8 @@ varbit_recv(PG_FUNCTION_ARGS)
645666
646667pq_copymsgbytes (buf , (char * )VARBITS (result ),VARBITBYTES (result ));
647668
648- /* Make sure last byte is zero-padded if needed */
649- ipad = VARBITPAD (result );
650- if (ipad > 0 )
651- {
652- mask = BITMASK <<ipad ;
653- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
654- }
669+ /* Make sure last byte is correctly zero-padded */
670+ VARBIT_PAD (result );
655671
656672PG_RETURN_VARBIT_P (result );
657673}
@@ -719,8 +735,6 @@ varbit(PG_FUNCTION_ARGS)
719735bool isExplicit = PG_GETARG_BOOL (2 );
720736VarBit * result ;
721737int rlen ;
722- int ipad ;
723- bits8 mask ;
724738
725739/* No work if typmod is invalid or supplied data matches it already */
726740if (len <=0 || len >=VARBITLEN (arg ))
@@ -739,13 +753,8 @@ varbit(PG_FUNCTION_ARGS)
739753
740754memcpy (VARBITS (result ),VARBITS (arg ),VARBITBYTES (result ));
741755
742- /* Make sure last byte is zero-padded if needed */
743- ipad = VARBITPAD (result );
744- if (ipad > 0 )
745- {
746- mask = BITMASK <<ipad ;
747- * (VARBITS (result )+ VARBITBYTES (result )- 1 ) &=mask ;
748- }
756+ /* Make sure last byte is correctly zero-padded */
757+ VARBIT_PAD (result );
749758
750759PG_RETURN_VARBIT_P (result );
751760}
@@ -1003,6 +1012,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
10031012}
10041013}
10051014
1015+ /* The pad bits should be already zero at this point */
1016+
10061017return result ;
10071018}
10081019
@@ -1036,14 +1047,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
10361047int bitlen ,
10371048rbitlen ,
10381049len ,
1039- ipad = 0 ,
10401050ishift ,
10411051i ;
10421052int e ,
10431053s1 ,
10441054e1 ;
1045- bits8 mask ,
1046- * r ,
1055+ bits8 * r ,
10471056* ps ;
10481057
10491058bitlen = VARBITLEN (arg );
@@ -1108,13 +1117,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
11081117r ++ ;
11091118}
11101119}
1111- /* Do we need to pad at the end? */
1112- ipad = VARBITPAD (result );
1113- if (ipad > 0 )
1114- {
1115- mask = BITMASK <<ipad ;
1116- * (VARBITS (result )+ len - 1 ) &=mask ;
1117- }
1120+
1121+ /* Make sure last byte is correctly zero-padded */
1122+ VARBIT_PAD (result );
11181123}
11191124
11201125return result ;
@@ -1236,7 +1241,7 @@ bit_and(PG_FUNCTION_ARGS)
12361241for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
12371242* r ++ = * p1 ++ & * p2 ++ ;
12381243
1239- /* Padding is not needed as & of 0pad is 0 */
1244+ /* Padding is not needed as & of 0pads is 0 */
12401245
12411246PG_RETURN_VARBIT_P (result );
12421247}
@@ -1258,7 +1263,6 @@ bit_or(PG_FUNCTION_ARGS)
12581263bits8 * p1 ,
12591264* p2 ,
12601265* r ;
1261- bits8 mask ;
12621266
12631267bitlen1 = VARBITLEN (arg1 );
12641268bitlen2 = VARBITLEN (arg2 );
@@ -1277,13 +1281,7 @@ bit_or(PG_FUNCTION_ARGS)
12771281for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
12781282* r ++ = * p1 ++ |* p2 ++ ;
12791283
1280- /* Pad the result */
1281- mask = BITMASK <<VARBITPAD (result );
1282- if (mask )
1283- {
1284- r -- ;
1285- * r &=mask ;
1286- }
1284+ /* Padding is not needed as | of 0 pads is 0 */
12871285
12881286PG_RETURN_VARBIT_P (result );
12891287}
@@ -1305,7 +1303,6 @@ bitxor(PG_FUNCTION_ARGS)
13051303bits8 * p1 ,
13061304* p2 ,
13071305* r ;
1308- bits8 mask ;
13091306
13101307bitlen1 = VARBITLEN (arg1 );
13111308bitlen2 = VARBITLEN (arg2 );
@@ -1325,13 +1322,7 @@ bitxor(PG_FUNCTION_ARGS)
13251322for (i = 0 ;i < VARBITBYTES (arg1 );i ++ )
13261323* r ++ = * p1 ++ ^* p2 ++ ;
13271324
1328- /* Pad the result */
1329- mask = BITMASK <<VARBITPAD (result );
1330- if (mask )
1331- {
1332- r -- ;
1333- * r &=mask ;
1334- }
1325+ /* Padding is not needed as ^ of 0 pads is 0 */
13351326
13361327PG_RETURN_VARBIT_P (result );
13371328}
@@ -1347,7 +1338,6 @@ bitnot(PG_FUNCTION_ARGS)
13471338VarBit * result ;
13481339bits8 * p ,
13491340* r ;
1350- bits8 mask ;
13511341
13521342result = (VarBit * )palloc (VARSIZE (arg ));
13531343SET_VARSIZE (result ,VARSIZE (arg ));
@@ -1358,13 +1348,8 @@ bitnot(PG_FUNCTION_ARGS)
13581348for (;p < VARBITEND (arg );p ++ )
13591349* r ++ = ~* p ;
13601350
1361- /* Pad the result */
1362- mask = BITMASK <<VARBITPAD (result );
1363- if (mask )
1364- {
1365- r -- ;
1366- * r &=mask ;
1367- }
1351+ /* Must zero-pad the result, because extra bits are surely 1's here */
1352+ VARBIT_PAD_LAST (result ,r );
13681353
13691354PG_RETURN_VARBIT_P (result );
13701355}
@@ -1431,6 +1416,8 @@ bitshiftleft(PG_FUNCTION_ARGS)
14311416* r = 0 ;
14321417}
14331418
1419+ /* The pad bits should be already zero at this point */
1420+
14341421PG_RETURN_VARBIT_P (result );
14351422}
14361423
@@ -1497,6 +1484,8 @@ bitshiftright(PG_FUNCTION_ARGS)
14971484if ((++ r )< VARBITEND (result ))
14981485* r = (* p << (BITS_PER_BYTE - ishift ))& BITMASK ;
14991486}
1487+ /* We may have shifted 1's into the pad bits, so fix that */
1488+ VARBIT_PAD_LAST (result ,r );
15001489}
15011490
15021491PG_RETURN_VARBIT_P (result );