3
3
* varbit.c
4
4
* Functions for the SQL datatypes BIT() and BIT VARYING().
5
5
*
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
+ *
6
21
* Code originally contributed by Adriaan Joubert.
7
22
*
8
23
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
27
42
28
43
#define HEXDIG (z ) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
29
44
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
+
30
79
static VarBit * bit_catenate (VarBit * arg1 , VarBit * arg2 );
31
80
static VarBit * bitsubstring (VarBit * arg , int32 s , int32 l ,
32
81
bool length_not_specified );
@@ -87,24 +136,6 @@ anybit_typmodout(int32 typmod)
87
136
}
88
137
89
138
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
-
108
139
/*
109
140
* bit_in -
110
141
* converts a char string to the internal representation of a bitstring.
@@ -264,6 +295,9 @@ bit_out(PG_FUNCTION_ARGS)
264
295
len ,
265
296
bitlen ;
266
297
298
+ /* Assertion to help catch any bit functions that don't pad correctly */
299
+ VARBIT_CORRECTLY_PADDED (s );
300
+
267
301
bitlen = VARBITLEN (s );
268
302
len = (bitlen + 3 ) / 4 ;
269
303
result = (char * ) palloc (len + 2 );
@@ -304,8 +338,6 @@ bit_recv(PG_FUNCTION_ARGS)
304
338
VarBit * result ;
305
339
int len ,
306
340
bitlen ;
307
- int ipad ;
308
- bits8 mask ;
309
341
310
342
bitlen = pq_getmsgint (buf , sizeof (int32 ));
311
343
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -330,13 +362,8 @@ bit_recv(PG_FUNCTION_ARGS)
330
362
331
363
pq_copymsgbytes (buf , (char * ) VARBITS (result ), VARBITBYTES (result ));
332
364
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 );
340
367
341
368
PG_RETURN_VARBIT_P (result );
342
369
}
@@ -367,8 +394,6 @@ bit(PG_FUNCTION_ARGS)
367
394
bool isExplicit = PG_GETARG_BOOL (2 );
368
395
VarBit * result ;
369
396
int rlen ;
370
- int ipad ;
371
- bits8 mask ;
372
397
373
398
/* No work if typmod is invalid or supplied data matches it already */
374
399
if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN (arg ))
@@ -394,12 +419,7 @@ bit(PG_FUNCTION_ARGS)
394
419
* if source data was shorter than target length (we assume the last byte
395
420
* of the source data was itself correctly zero-padded).
396
421
*/
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 );
403
423
404
424
PG_RETURN_VARBIT_P (result );
405
425
}
@@ -574,6 +594,9 @@ varbit_out(PG_FUNCTION_ARGS)
574
594
k ,
575
595
len ;
576
596
597
+ /* Assertion to help catch any bit functions that don't pad correctly */
598
+ VARBIT_CORRECTLY_PADDED (s );
599
+
577
600
len = VARBITLEN (s );
578
601
result = (char * ) palloc (len + 1 );
579
602
sp = VARBITS (s );
@@ -620,8 +643,6 @@ varbit_recv(PG_FUNCTION_ARGS)
620
643
VarBit * result ;
621
644
int len ,
622
645
bitlen ;
623
- int ipad ;
624
- bits8 mask ;
625
646
626
647
bitlen = pq_getmsgint (buf , sizeof (int32 ));
627
648
if (bitlen < 0 || bitlen > VARBITMAXLEN )
@@ -646,13 +667,8 @@ varbit_recv(PG_FUNCTION_ARGS)
646
667
647
668
pq_copymsgbytes (buf , (char * ) VARBITS (result ), VARBITBYTES (result ));
648
669
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 );
656
672
657
673
PG_RETURN_VARBIT_P (result );
658
674
}
@@ -729,8 +745,6 @@ varbit(PG_FUNCTION_ARGS)
729
745
bool isExplicit = PG_GETARG_BOOL (2 );
730
746
VarBit * result ;
731
747
int rlen ;
732
- int ipad ;
733
- bits8 mask ;
734
748
735
749
/* No work if typmod is invalid or supplied data matches it already */
736
750
if (len <= 0 || len >= VARBITLEN (arg ))
@@ -749,13 +763,8 @@ varbit(PG_FUNCTION_ARGS)
749
763
750
764
memcpy (VARBITS (result ), VARBITS (arg ), VARBITBYTES (result ));
751
765
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 );
759
768
760
769
PG_RETURN_VARBIT_P (result );
761
770
}
@@ -1013,6 +1022,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
1013
1022
}
1014
1023
}
1015
1024
1025
+ /* The pad bits should be already zero at this point */
1026
+
1016
1027
return result ;
1017
1028
}
1018
1029
@@ -1046,14 +1057,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1046
1057
int bitlen ,
1047
1058
rbitlen ,
1048
1059
len ,
1049
- ipad = 0 ,
1050
1060
ishift ,
1051
1061
i ;
1052
1062
int e ,
1053
1063
s1 ,
1054
1064
e1 ;
1055
- bits8 mask ,
1056
- * r ,
1065
+ bits8 * r ,
1057
1066
* ps ;
1058
1067
1059
1068
bitlen = VARBITLEN (arg );
@@ -1118,13 +1127,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
1118
1127
r ++ ;
1119
1128
}
1120
1129
}
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 );
1128
1133
}
1129
1134
1130
1135
return result ;
@@ -1246,7 +1251,7 @@ bit_and(PG_FUNCTION_ARGS)
1246
1251
for (i = 0 ; i < VARBITBYTES (arg1 ); i ++ )
1247
1252
* r ++ = * p1 ++ & * p2 ++ ;
1248
1253
1249
- /* Padding is not needed as & of 0 pad is 0 */
1254
+ /* Padding is not needed as & of 0 pads is 0 */
1250
1255
1251
1256
PG_RETURN_VARBIT_P (result );
1252
1257
}
@@ -1268,7 +1273,6 @@ bit_or(PG_FUNCTION_ARGS)
1268
1273
bits8 * p1 ,
1269
1274
* p2 ,
1270
1275
* r ;
1271
- bits8 mask ;
1272
1276
1273
1277
bitlen1 = VARBITLEN (arg1 );
1274
1278
bitlen2 = VARBITLEN (arg2 );
@@ -1287,13 +1291,7 @@ bit_or(PG_FUNCTION_ARGS)
1287
1291
for (i = 0 ; i < VARBITBYTES (arg1 ); i ++ )
1288
1292
* r ++ = * p1 ++ | * p2 ++ ;
1289
1293
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 */
1297
1295
1298
1296
PG_RETURN_VARBIT_P (result );
1299
1297
}
@@ -1315,7 +1313,6 @@ bitxor(PG_FUNCTION_ARGS)
1315
1313
bits8 * p1 ,
1316
1314
* p2 ,
1317
1315
* r ;
1318
- bits8 mask ;
1319
1316
1320
1317
bitlen1 = VARBITLEN (arg1 );
1321
1318
bitlen2 = VARBITLEN (arg2 );
@@ -1335,13 +1332,7 @@ bitxor(PG_FUNCTION_ARGS)
1335
1332
for (i = 0 ; i < VARBITBYTES (arg1 ); i ++ )
1336
1333
* r ++ = * p1 ++ ^ * p2 ++ ;
1337
1334
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 */
1345
1336
1346
1337
PG_RETURN_VARBIT_P (result );
1347
1338
}
@@ -1357,7 +1348,6 @@ bitnot(PG_FUNCTION_ARGS)
1357
1348
VarBit * result ;
1358
1349
bits8 * p ,
1359
1350
* r ;
1360
- bits8 mask ;
1361
1351
1362
1352
result = (VarBit * ) palloc (VARSIZE (arg ));
1363
1353
SET_VARSIZE (result , VARSIZE (arg ));
@@ -1368,13 +1358,8 @@ bitnot(PG_FUNCTION_ARGS)
1368
1358
for (; p < VARBITEND (arg ); p ++ )
1369
1359
* r ++ = ~* p ;
1370
1360
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 );
1378
1363
1379
1364
PG_RETURN_VARBIT_P (result );
1380
1365
}
@@ -1441,6 +1426,8 @@ bitshiftleft(PG_FUNCTION_ARGS)
1441
1426
* r = 0 ;
1442
1427
}
1443
1428
1429
+ /* The pad bits should be already zero at this point */
1430
+
1444
1431
PG_RETURN_VARBIT_P (result );
1445
1432
}
1446
1433
@@ -1507,6 +1494,8 @@ bitshiftright(PG_FUNCTION_ARGS)
1507
1494
if ((++ r ) < VARBITEND (result ))
1508
1495
* r = (* p << (BITS_PER_BYTE - ishift )) & BITMASK ;
1509
1496
}
1497
+ /* We may have shifted 1's into the pad bits, so fix that */
1498
+ VARBIT_PAD_LAST (result , r );
1510
1499
}
1511
1500
1512
1501
PG_RETURN_VARBIT_P (result );
0 commit comments