Page MenuHomePhabricator (Chris)

No OneTemporary

Size
5 MB
Referenced Files
None
Subscribers
None
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/mongodb-1.13.0/src/LIBMONGOCRYPT_VERSION_CURRENT b/mongodb-1.13.0/src/LIBMONGOCRYPT_VERSION_CURRENT
deleted file mode 100644
index 1892b926..00000000
--- a/mongodb-1.13.0/src/LIBMONGOCRYPT_VERSION_CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-1.3.2
diff --git a/mongodb-1.13.0/src/LIBMONGOC_VERSION_CURRENT b/mongodb-1.13.0/src/LIBMONGOC_VERSION_CURRENT
deleted file mode 100644
index 28449774..00000000
--- a/mongodb-1.13.0/src/LIBMONGOC_VERSION_CURRENT
+++ /dev/null
@@ -1 +0,0 @@
-1.21.1
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/crc32.c b/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/crc32.c
deleted file mode 100644
index 9580440c..00000000
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/crc32.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
- * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
- * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors. This results in about a
- * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
- */
-
-/* @(#) $Id$ */
-
-/*
- Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
- protection on the static variables used to control the first-use generation
- of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
- first call get_crc_table() to initialize the tables before allowing more than
- one thread to use crc32().
-
- DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
- */
-
-#ifdef MAKECRCH
-# include <stdio.h>
-# ifndef DYNAMIC_CRC_TABLE
-# define DYNAMIC_CRC_TABLE
-# endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
-
-#include "zutil.h" /* for STDC and FAR definitions */
-
-/* Definitions for doing the crc four data bytes at a time. */
-#if !defined(NOBYFOUR) && defined(Z_U4)
-# define BYFOUR
-#endif
-#ifdef BYFOUR
- local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, z_size_t));
- local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, z_size_t));
-# define TBLS 8
-#else
-# define TBLS 1
-#endif /* BYFOUR */
-
-/* Local functions for crc concatenation */
-local unsigned long gf2_matrix_times OF((unsigned long *mat,
- unsigned long vec));
-local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
-
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local volatile int crc_table_empty = 1;
-local z_crc_t FAR crc_table[TBLS][256];
-local void make_crc_table OF((void));
-#ifdef MAKECRCH
- local void write_table OF((FILE *, const z_crc_t FAR *));
-#endif /* MAKECRCH */
-/*
- Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The first table is simply the CRC of all possible eight bit values. This is
- all the information needed to generate CRCs on data a byte at a time for all
- combinations of CRC register values and incoming bytes. The remaining tables
- allow for word-at-a-time CRC calculation for both big-endian and little-
- endian machines, where a word is four bytes.
-*/
-local void make_crc_table()
-{
- z_crc_t c;
- int n, k;
- z_crc_t poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static volatile int first = 1; /* flag to limit concurrent making */
- static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* See if another task is already doing this (not thread-safe, but better
- than nothing -- significantly reduces duration of vulnerability in
- case the advice about DYNAMIC_CRC_TABLE is ignored) */
- if (first) {
- first = 0;
-
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0;
- for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
- poly |= (z_crc_t)1 << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (z_crc_t)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
-
-#ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros,
- and then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = ZSWAP32(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = ZSWAP32(c);
- }
- }
-#endif /* BYFOUR */
-
- crc_table_empty = 0;
- }
- else { /* not first */
- /* wait for the other guy to finish (not efficient, but rare) */
- while (crc_table_empty)
- ;
- }
-
-#ifdef MAKECRCH
- /* write out CRC tables to crc32.h */
- {
- FILE *out;
-
- out = fopen("crc32.h", "w");
- if (out == NULL) return;
- fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
- fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const z_crc_t FAR ");
- fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
- write_table(out, crc_table[0]);
-# ifdef BYFOUR
- fprintf(out, "#ifdef BYFOUR\n");
- for (k = 1; k < 8; k++) {
- fprintf(out, " },\n {\n");
- write_table(out, crc_table[k]);
- }
- fprintf(out, "#endif\n");
-# endif /* BYFOUR */
- fprintf(out, " }\n};\n");
- fclose(out);
- }
-#endif /* MAKECRCH */
-}
-
-#ifdef MAKECRCH
-local void write_table(out, table)
- FILE *out;
- const z_crc_t FAR *table;
-{
- int n;
-
- for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
- (unsigned long)(table[n]),
- n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
-}
-#endif /* MAKECRCH */
-
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-#include "crc32.h"
-#endif /* DYNAMIC_CRC_TABLE */
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const z_crc_t FAR * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
- return (const z_crc_t FAR *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32_z(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- z_size_t len;
-{
- if (buf == Z_NULL) return 0UL;
-
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-#ifdef BYFOUR
- if (sizeof(void *) == sizeof(ptrdiff_t)) {
- z_crc_t endian;
-
- endian = 1;
- if (*((unsigned char *)(&endian)))
- return crc32_little(crc, buf, len);
- else
- return crc32_big(crc, buf, len);
- }
-#endif /* BYFOUR */
- crc = crc ^ 0xffffffffUL;
- while (len >= 8) {
- DO8;
- len -= 8;
- }
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffffUL;
-}
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- uInt len;
-{
- return crc32_z(crc, buf, len);
-}
-
-#ifdef BYFOUR
-
-/*
- This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
- integer pointer type. This violates the strict aliasing rule, where a
- compiler can assume, for optimization purposes, that two pointers to
- fundamentally different types won't ever point to the same memory. This can
- manifest as a problem only if one of the pointers is written to. This code
- only reads from those pointers. So long as this code remains isolated in
- this compilation unit, there won't be a problem. For this reason, this code
- should not be copied and pasted into a compilation unit in which other code
- writes to the buffer that is passed to these routines.
- */
-
-/* ========================================================================= */
-#define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-local unsigned long crc32_little(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- z_size_t len;
-{
- register z_crc_t c;
- register const z_crc_t FAR *buf4;
-
- c = (z_crc_t)crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return (unsigned long)c;
-}
-
-/* ========================================================================= */
-#define DOBIG4 c ^= *buf4++; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
-/* ========================================================================= */
-local unsigned long crc32_big(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- z_size_t len;
-{
- register z_crc_t c;
- register const z_crc_t FAR *buf4;
-
- c = ZSWAP32((z_crc_t)crc);
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- len--;
- }
-
- buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOBIG32;
- len -= 32;
- }
- while (len >= 4) {
- DOBIG4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- } while (--len);
- c = ~c;
- return (unsigned long)(ZSWAP32(c));
-}
-
-#endif /* BYFOUR */
-
-#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
-
-/* ========================================================================= */
-local unsigned long gf2_matrix_times(mat, vec)
- unsigned long *mat;
- unsigned long vec;
-{
- unsigned long sum;
-
- sum = 0;
- while (vec) {
- if (vec & 1)
- sum ^= *mat;
- vec >>= 1;
- mat++;
- }
- return sum;
-}
-
-/* ========================================================================= */
-local void gf2_matrix_square(square, mat)
- unsigned long *square;
- unsigned long *mat;
-{
- int n;
-
- for (n = 0; n < GF2_DIM; n++)
- square[n] = gf2_matrix_times(mat, mat[n]);
-}
-
-/* ========================================================================= */
-local uLong crc32_combine_(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off64_t len2;
-{
- int n;
- unsigned long row;
- unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
- unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
-
- /* degenerate case (also disallow negative lengths) */
- if (len2 <= 0)
- return crc1;
-
- /* put operator for one zero bit in odd */
- odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
- row = 1;
- for (n = 1; n < GF2_DIM; n++) {
- odd[n] = row;
- row <<= 1;
- }
-
- /* put operator for two zero bits in even */
- gf2_matrix_square(even, odd);
-
- /* put operator for four zero bits in odd */
- gf2_matrix_square(odd, even);
-
- /* apply len2 zeros to crc1 (first square will put the operator for one
- zero byte, eight zero bits, in even) */
- do {
- /* apply zeros operator for this bit of len2 */
- gf2_matrix_square(even, odd);
- if (len2 & 1)
- crc1 = gf2_matrix_times(even, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- if (len2 == 0)
- break;
-
- /* another iteration of the loop with odd and even swapped */
- gf2_matrix_square(odd, even);
- if (len2 & 1)
- crc1 = gf2_matrix_times(odd, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- } while (len2 != 0);
-
- /* return combined crc */
- crc1 ^= crc2;
- return crc1;
-}
-
-/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off_t len2;
-{
- return crc32_combine_(crc1, crc2, len2);
-}
-
-uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off64_t len2;
-{
- return crc32_combine_(crc1, crc2, len2);
-}
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/crc32.h b/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/crc32.h
deleted file mode 100644
index 9e0c7781..00000000
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/crc32.h
+++ /dev/null
@@ -1,441 +0,0 @@
-/* crc32.h -- tables for rapid CRC calculation
- * Generated automatically by crc32.c
- */
-
-local const z_crc_t FAR crc_table[TBLS][256] =
-{
- {
- 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
- 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
- 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
- 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
- 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
- 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
- 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
- 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
- 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
- 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
- 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
- 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
- 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
- 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
- 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
- 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
- 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
- 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
- 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
- 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
- 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
- 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
- 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
- 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
- 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
- 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
- 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
- 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
- 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
- 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
- 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
- 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
- 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
- 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
- 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
- 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
- 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
- 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
- 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
- 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
- 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
- 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
- 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
- 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
- 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
- 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
- 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
- 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
- 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
- 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
- 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
- 0x2d02ef8dUL
-#ifdef BYFOUR
- },
- {
- 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
- 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
- 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
- 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
- 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
- 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
- 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
- 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
- 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
- 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
- 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
- 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
- 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
- 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
- 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
- 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
- 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
- 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
- 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
- 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
- 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
- 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
- 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
- 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
- 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
- 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
- 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
- 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
- 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
- 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
- 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
- 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
- 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
- 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
- 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
- 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
- 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
- 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
- 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
- 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
- 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
- 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
- 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
- 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
- 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
- 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
- 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
- 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
- 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
- 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
- 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
- 0x9324fd72UL
- },
- {
- 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
- 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
- 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
- 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
- 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
- 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
- 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
- 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
- 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
- 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
- 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
- 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
- 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
- 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
- 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
- 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
- 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
- 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
- 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
- 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
- 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
- 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
- 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
- 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
- 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
- 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
- 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
- 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
- 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
- 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
- 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
- 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
- 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
- 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
- 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
- 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
- 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
- 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
- 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
- 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
- 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
- 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
- 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
- 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
- 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
- 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
- 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
- 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
- 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
- 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
- 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
- 0xbe9834edUL
- },
- {
- 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
- 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
- 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
- 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
- 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
- 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
- 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
- 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
- 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
- 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
- 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
- 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
- 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
- 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
- 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
- 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
- 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
- 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
- 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
- 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
- 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
- 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
- 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
- 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
- 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
- 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
- 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
- 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
- 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
- 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
- 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
- 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
- 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
- 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
- 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
- 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
- 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
- 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
- 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
- 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
- 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
- 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
- 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
- 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
- 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
- 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
- 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
- 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
- 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
- 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
- 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
- 0xde0506f1UL
- },
- {
- 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
- 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
- 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
- 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
- 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
- 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
- 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
- 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
- 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
- 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
- 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
- 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
- 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
- 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
- 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
- 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
- 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
- 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
- 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
- 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
- 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
- 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
- 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
- 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
- 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
- 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
- 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
- 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
- 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
- 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
- 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
- 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
- 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
- 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
- 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
- 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
- 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
- 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
- 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
- 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
- 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
- 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
- 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
- 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
- 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
- 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
- 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
- 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
- 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
- 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
- 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
- 0x8def022dUL
- },
- {
- 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
- 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
- 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
- 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
- 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
- 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
- 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
- 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
- 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
- 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
- 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
- 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
- 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
- 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
- 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
- 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
- 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
- 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
- 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
- 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
- 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
- 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
- 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
- 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
- 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
- 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
- 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
- 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
- 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
- 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
- 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
- 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
- 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
- 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
- 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
- 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
- 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
- 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
- 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
- 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
- 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
- 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
- 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
- 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
- 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
- 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
- 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
- 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
- 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
- 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
- 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
- 0x72fd2493UL
- },
- {
- 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
- 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
- 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
- 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
- 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
- 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
- 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
- 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
- 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
- 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
- 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
- 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
- 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
- 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
- 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
- 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
- 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
- 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
- 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
- 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
- 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
- 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
- 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
- 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
- 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
- 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
- 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
- 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
- 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
- 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
- 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
- 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
- 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
- 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
- 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
- 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
- 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
- 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
- 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
- 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
- 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
- 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
- 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
- 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
- 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
- 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
- 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
- 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
- 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
- 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
- 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
- 0xed3498beUL
- },
- {
- 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
- 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
- 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
- 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
- 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
- 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
- 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
- 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
- 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
- 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
- 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
- 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
- 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
- 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
- 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
- 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
- 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
- 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
- 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
- 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
- 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
- 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
- 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
- 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
- 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
- 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
- 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
- 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
- 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
- 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
- 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
- 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
- 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
- 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
- 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
- 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
- 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
- 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
- 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
- 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
- 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
- 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
- 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
- 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
- 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
- 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
- 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
- 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
- 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
- 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
- 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
- 0xf10605deUL
-#endif
- }
-};
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zconf.h b/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zconf.h
deleted file mode 100644
index 5e1d68a0..00000000
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zconf.h
+++ /dev/null
@@ -1,534 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- * Even better than compiling with -DZ_PREFIX would be to use configure to set
- * this permanently in zconf.h using "./configure --zprefix".
- */
-#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
-# define Z_PREFIX_SET
-
-/* all linked symbols and init macros */
-# define _dist_code z__dist_code
-# define _length_code z__length_code
-# define _tr_align z__tr_align
-# define _tr_flush_bits z__tr_flush_bits
-# define _tr_flush_block z__tr_flush_block
-# define _tr_init z__tr_init
-# define _tr_stored_block z__tr_stored_block
-# define _tr_tally z__tr_tally
-# define adler32 z_adler32
-# define adler32_combine z_adler32_combine
-# define adler32_combine64 z_adler32_combine64
-# define adler32_z z_adler32_z
-# ifndef Z_SOLO
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# endif
-# define crc32 z_crc32
-# define crc32_combine z_crc32_combine
-# define crc32_combine64 z_crc32_combine64
-# define crc32_z z_crc32_z
-# define deflate z_deflate
-# define deflateBound z_deflateBound
-# define deflateCopy z_deflateCopy
-# define deflateEnd z_deflateEnd
-# define deflateGetDictionary z_deflateGetDictionary
-# define deflateInit z_deflateInit
-# define deflateInit2 z_deflateInit2
-# define deflateInit2_ z_deflateInit2_
-# define deflateInit_ z_deflateInit_
-# define deflateParams z_deflateParams
-# define deflatePending z_deflatePending
-# define deflatePrime z_deflatePrime
-# define deflateReset z_deflateReset
-# define deflateResetKeep z_deflateResetKeep
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateSetHeader z_deflateSetHeader
-# define deflateTune z_deflateTune
-# define deflate_copyright z_deflate_copyright
-# define get_crc_table z_get_crc_table
-# ifndef Z_SOLO
-# define gz_error z_gz_error
-# define gz_intmax z_gz_intmax
-# define gz_strwinerror z_gz_strwinerror
-# define gzbuffer z_gzbuffer
-# define gzclearerr z_gzclearerr
-# define gzclose z_gzclose
-# define gzclose_r z_gzclose_r
-# define gzclose_w z_gzclose_w
-# define gzdirect z_gzdirect
-# define gzdopen z_gzdopen
-# define gzeof z_gzeof
-# define gzerror z_gzerror
-# define gzflush z_gzflush
-# define gzfread z_gzfread
-# define gzfwrite z_gzfwrite
-# define gzgetc z_gzgetc
-# define gzgetc_ z_gzgetc_
-# define gzgets z_gzgets
-# define gzoffset z_gzoffset
-# define gzoffset64 z_gzoffset64
-# define gzopen z_gzopen
-# define gzopen64 z_gzopen64
-# ifdef _WIN32
-# define gzopen_w z_gzopen_w
-# endif
-# define gzprintf z_gzprintf
-# define gzputc z_gzputc
-# define gzputs z_gzputs
-# define gzread z_gzread
-# define gzrewind z_gzrewind
-# define gzseek z_gzseek
-# define gzseek64 z_gzseek64
-# define gzsetparams z_gzsetparams
-# define gztell z_gztell
-# define gztell64 z_gztell64
-# define gzungetc z_gzungetc
-# define gzvprintf z_gzvprintf
-# define gzwrite z_gzwrite
-# endif
-# define inflate z_inflate
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define inflateBackInit z_inflateBackInit
-# define inflateBackInit_ z_inflateBackInit_
-# define inflateCodesUsed z_inflateCodesUsed
-# define inflateCopy z_inflateCopy
-# define inflateEnd z_inflateEnd
-# define inflateGetDictionary z_inflateGetDictionary
-# define inflateGetHeader z_inflateGetHeader
-# define inflateInit z_inflateInit
-# define inflateInit2 z_inflateInit2
-# define inflateInit2_ z_inflateInit2_
-# define inflateInit_ z_inflateInit_
-# define inflateMark z_inflateMark
-# define inflatePrime z_inflatePrime
-# define inflateReset z_inflateReset
-# define inflateReset2 z_inflateReset2
-# define inflateResetKeep z_inflateResetKeep
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateUndermine z_inflateUndermine
-# define inflateValidate z_inflateValidate
-# define inflate_copyright z_inflate_copyright
-# define inflate_fast z_inflate_fast
-# define inflate_table z_inflate_table
-# ifndef Z_SOLO
-# define uncompress z_uncompress
-# define uncompress2 z_uncompress2
-# endif
-# define zError z_zError
-# ifndef Z_SOLO
-# define zcalloc z_zcalloc
-# define zcfree z_zcfree
-# endif
-# define zlibCompileFlags z_zlibCompileFlags
-# define zlibVersion z_zlibVersion
-
-/* all zlib typedefs in zlib.h and zconf.h */
-# define Byte z_Byte
-# define Bytef z_Bytef
-# define alloc_func z_alloc_func
-# define charf z_charf
-# define free_func z_free_func
-# ifndef Z_SOLO
-# define gzFile z_gzFile
-# endif
-# define gz_header z_gz_header
-# define gz_headerp z_gz_headerp
-# define in_func z_in_func
-# define intf z_intf
-# define out_func z_out_func
-# define uInt z_uInt
-# define uIntf z_uIntf
-# define uLong z_uLong
-# define uLongf z_uLongf
-# define voidp z_voidp
-# define voidpc z_voidpc
-# define voidpf z_voidpf
-
-/* all zlib structs in zlib.h and zconf.h */
-# define gz_header_s z_gz_header_s
-# define internal_state z_internal_state
-
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-#if defined(ZLIB_CONST) && !defined(z_const)
-# define z_const const
-#else
-# define z_const
-#endif
-
-#ifdef Z_SOLO
- typedef unsigned long z_size_t;
-#else
-# define z_longlong long long
-# if defined(NO_SIZE_T)
- typedef unsigned NO_SIZE_T z_size_t;
-# elif defined(STDC)
-# include <stddef.h>
- typedef size_t z_size_t;
-# else
- typedef unsigned long z_size_t;
-# endif
-# undef z_longlong
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-#ifndef Z_ARG /* function prototypes for stdarg */
-# if defined(STDC) || defined(Z_HAVE_STDARG_H)
-# define Z_ARG(args) args
-# else
-# define Z_ARG(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
-# include <limits.h>
-# if (UINT_MAX == 0xffffffffUL)
-# define Z_U4 unsigned
-# elif (ULONG_MAX == 0xffffffffUL)
-# define Z_U4 unsigned long
-# elif (USHRT_MAX == 0xffffffffUL)
-# define Z_U4 unsigned short
-# endif
-#endif
-
-#ifdef Z_U4
- typedef Z_U4 z_crc_t;
-#else
- typedef unsigned long z_crc_t;
-#endif
-
-#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
-# define Z_HAVE_UNISTD_H
-#endif
-
-#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
-# define Z_HAVE_STDARG_H
-#endif
-
-#ifdef STDC
-# ifndef Z_SOLO
-# include <sys/types.h> /* for off_t */
-# endif
-#endif
-
-#if defined(STDC) || defined(Z_HAVE_STDARG_H)
-# ifndef Z_SOLO
-# include <stdarg.h> /* for va_list */
-# endif
-#endif
-
-#ifdef _WIN32
-# ifndef Z_SOLO
-# include <stddef.h> /* for wchar_t */
-# endif
-#endif
-
-/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
- * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
- * though the former does not conform to the LFS document), but considering
- * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
- * equivalently requesting no 64-bit operations
- */
-#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
-# undef _LARGEFILE64_SOURCE
-#endif
-
-#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
-# define Z_HAVE_UNISTD_H
-#endif
-#ifndef Z_SOLO
-# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
-# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# ifndef z_off_t
-# define z_off_t off_t
-# endif
-# endif
-#endif
-
-#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
-# define Z_LFS64
-#endif
-
-#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
-# define Z_LARGE64
-#endif
-
-#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
-# define Z_WANT64
-#endif
-
-#if !defined(SEEK_SET) && !defined(Z_SOLO)
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if !defined(_WIN32) && defined(Z_LARGE64)
-# define z_off64_t off64_t
-#else
-# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
-# define z_off64_t __int64
-# else
-# define z_off64_t z_off_t
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
- #pragma map(deflateInit_,"DEIN")
- #pragma map(deflateInit2_,"DEIN2")
- #pragma map(deflateEnd,"DEEND")
- #pragma map(deflateBound,"DEBND")
- #pragma map(inflateInit_,"ININ")
- #pragma map(inflateInit2_,"ININ2")
- #pragma map(inflateEnd,"INEND")
- #pragma map(inflateSync,"INSY")
- #pragma map(inflateSetDictionary,"INSEDI")
- #pragma map(compressBound,"CMBND")
- #pragma map(inflate_table,"INTABL")
- #pragma map(inflate_fast,"INFA")
- #pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt-compat/mongocrypt-export.h b/mongodb-1.13.0/src/libmongocrypt-compat/mongocrypt-export.h
deleted file mode 100644
index 9fc272a8..00000000
--- a/mongodb-1.13.0/src/libmongocrypt-compat/mongocrypt-export.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef MONGOCRYPT_EXPORT_H
-#define MONGOCRYPT_EXPORT_H
-
-#define MONGOCRYPT_EXPORT
-#define MONGOCRYPT_NO_EXPORT
-
-#endif /* MONGOCRYPT_EXPORT_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/crypto/cng.c b/mongodb-1.13.0/src/libmongocrypt/src/crypto/cng.c
deleted file mode 100644
index 901fe087..00000000
--- a/mongodb-1.13.0/src/libmongocrypt/src/crypto/cng.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright 2019-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "../mongocrypt-crypto-private.h"
-#include "../mongocrypt-private.h"
-
-#ifdef MONGOCRYPT_ENABLE_CRYPTO_CNG
-
-#include <bcrypt.h>
-
-static BCRYPT_ALG_HANDLE _algo_sha512_hmac = 0;
-static BCRYPT_ALG_HANDLE _algo_aes256 = 0;
-static DWORD _aes256_key_blob_length;
-
-static BCRYPT_ALG_HANDLE _random;
-
-#define STATUS_SUCCESS 0
-
-bool _native_crypto_initialized = false;
-
-void
-_native_crypto_init ()
-{
- DWORD cbOutput;
- NTSTATUS nt_status;
-
- /* Note, there is no mechanism for libmongocrypt to close these providers,
- * If we ever add such a mechanism, call BCryptCloseAlgorithmProvider.
- */
- nt_status = BCryptOpenAlgorithmProvider (&_algo_sha512_hmac,
- BCRYPT_SHA512_ALGORITHM,
- MS_PRIMITIVE_PROVIDER,
- BCRYPT_ALG_HANDLE_HMAC_FLAG);
- if (nt_status != STATUS_SUCCESS) {
- return;
- }
-
- nt_status = BCryptOpenAlgorithmProvider (
- &_algo_aes256, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
- if (nt_status != STATUS_SUCCESS) {
- return;
- }
-
- nt_status = BCryptSetProperty (
- _algo_aes256,
- BCRYPT_CHAINING_MODE,
- (PUCHAR) (BCRYPT_CHAIN_MODE_CBC),
- (ULONG) (sizeof (wchar_t) * wcslen (BCRYPT_CHAIN_MODE_CBC)),
- 0);
- if (nt_status != STATUS_SUCCESS) {
- return;
- }
-
- cbOutput = sizeof (_aes256_key_blob_length);
- nt_status = BCryptGetProperty (_algo_aes256,
- BCRYPT_OBJECT_LENGTH,
- (PUCHAR) (&_aes256_key_blob_length),
- cbOutput,
- &cbOutput,
- 0);
- if (nt_status != STATUS_SUCCESS) {
- return;
- }
-
- nt_status = BCryptOpenAlgorithmProvider (
- &_random, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
- if (nt_status != STATUS_SUCCESS) {
- return;
- }
-
- _native_crypto_initialized = true;
-}
-
-typedef struct {
- unsigned char *key_object;
- uint32_t key_object_length;
-
- BCRYPT_KEY_HANDLE key_handle;
-
- unsigned char *iv;
- uint32_t iv_len;
-} cng_encrypt_state;
-
-static void
-_crypto_state_destroy (cng_encrypt_state *state);
-
-static cng_encrypt_state *
-_crypto_state_init (const _mongocrypt_buffer_t *key,
- const _mongocrypt_buffer_t *iv,
- mongocrypt_status_t *status)
-{
- cng_encrypt_state *state;
- uint32_t keyBlobLength;
- unsigned char *keyBlob;
- BCRYPT_KEY_DATA_BLOB_HEADER blobHeader;
- NTSTATUS nt_status;
-
- keyBlob = NULL;
-
- state = bson_malloc0 (sizeof (*state));
- BSON_ASSERT (state);
-
- state->key_handle = INVALID_HANDLE_VALUE;
-
- /* Initialize key storage buffer */
- state->key_object = bson_malloc0 (_aes256_key_blob_length);
- BSON_ASSERT (state->key_object);
-
- state->key_object_length = _aes256_key_blob_length;
-
- /* Allocate temporary buffer for key import */
- keyBlobLength = sizeof (BCRYPT_KEY_DATA_BLOB_HEADER) + key->len;
- keyBlob = bson_malloc0 (keyBlobLength);
- BSON_ASSERT (keyBlob);
-
-
- blobHeader.dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
- blobHeader.dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
- blobHeader.cbKeyData = key->len;
-
- memcpy (keyBlob, &blobHeader, sizeof (BCRYPT_KEY_DATA_BLOB_HEADER));
-
- memcpy (keyBlob + sizeof (BCRYPT_KEY_DATA_BLOB_HEADER), key->data, key->len);
-
- nt_status = BCryptImportKey (_algo_aes256,
- NULL,
- BCRYPT_KEY_DATA_BLOB,
- &(state->key_handle),
- state->key_object,
- state->key_object_length,
- keyBlob,
- keyBlobLength,
- 0);
- if (nt_status != STATUS_SUCCESS) {
- CLIENT_ERR ("Import Key Failed: 0x%x", (int) nt_status);
- goto fail;
- }
-
- bson_free (keyBlob);
-
- state->iv = bson_malloc0 (iv->len);
- BSON_ASSERT (state->iv);
-
- state->iv_len = iv->len;
- memcpy (state->iv, iv->data, iv->len);
-
- return state;
-fail:
- _crypto_state_destroy (state);
- bson_free (keyBlob);
-
- return NULL;
-}
-
-
-static void
-_crypto_state_destroy (cng_encrypt_state *state)
-{
- if (state) {
- /* Free the key handle before the key_object that contains it */
- if (state->key_handle != INVALID_HANDLE_VALUE) {
- BCryptDestroyKey (state->key_handle);
- }
-
- bson_free (state->key_object);
- bson_free (state->iv);
- bson_free (state);
- }
-}
-
-
-bool
-_native_crypto_aes_256_cbc_encrypt (aes_256_args_t args)
-{
- bool ret = false;
- mongocrypt_status_t *status = args.status;
- cng_encrypt_state *state = _crypto_state_init (args.key, args.iv, status);
-
- NTSTATUS nt_status;
-
- nt_status = BCryptEncrypt (state->key_handle,
- (PUCHAR) (args.in->data),
- args.in->len,
- NULL,
- state->iv,
- state->iv_len,
- args.out->data,
- args.out->len,
- args.bytes_written,
- 0);
-
- if (nt_status != STATUS_SUCCESS) {
- CLIENT_ERR ("error initializing cipher: 0x%x", (int) nt_status);
- goto done;
- }
-
- ret = true;
-done:
- _crypto_state_destroy (state);
- return ret;
-}
-
-
-bool
-_native_crypto_aes_256_cbc_decrypt (aes_256_args_t args)
-{
- bool ret = false;
- mongocrypt_status_t *status = args.status;
- cng_encrypt_state *state = _crypto_state_init (args.key, args.iv, status);
-
- NTSTATUS nt_status;
-
- nt_status = BCryptDecrypt (state->key_handle,
- (PUCHAR) (args.in->data),
- args.in->len,
- NULL,
- state->iv,
- state->iv_len,
- args.out->data,
- args.out->len,
- args.bytes_written,
- 0);
-
-
- if (nt_status != STATUS_SUCCESS) {
- CLIENT_ERR ("error initializing cipher: 0x%x", (int) nt_status);
- goto done;
- }
-
- ret = true;
-done:
- _crypto_state_destroy (state);
- return ret;
-}
-
-
-bool
-_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
- const _mongocrypt_buffer_t *in,
- _mongocrypt_buffer_t *out,
- mongocrypt_status_t *status)
-{
- bool ret = false;
- BCRYPT_HASH_HANDLE hHash;
- NTSTATUS nt_status;
-
- if (out->len != 64) {
- CLIENT_ERR ("out does not contain 64 bytes");
- return false;
- }
-
- nt_status = BCryptCreateHash (_algo_sha512_hmac,
- &hHash,
- NULL,
- 0,
- (PUCHAR) key->data,
- (ULONG) key->len,
- 0);
- if (nt_status != STATUS_SUCCESS) {
- CLIENT_ERR ("error initializing hmac: 0x%x", (int) nt_status);
- goto done;
- }
-
- nt_status = BCryptHashData (hHash, (PUCHAR) in->data, (ULONG) in->len, 0);
- if (nt_status != STATUS_SUCCESS) {
- CLIENT_ERR ("error hashing data: 0x%x", (int) nt_status);
- goto done;
- }
-
- nt_status = BCryptFinishHash (hHash, out->data, out->len, 0);
- if (nt_status != STATUS_SUCCESS) {
- CLIENT_ERR ("error finishing hmac: 0x%x", (int) nt_status);
- goto done;
- }
-
- ret = true;
-done:
- (void) BCryptDestroyHash (hHash);
- return ret;
-}
-
-
-bool
-_native_crypto_random (_mongocrypt_buffer_t *out,
- uint32_t count,
- mongocrypt_status_t *status)
-{
- NTSTATUS nt_status = BCryptGenRandom (_random, out->data, count, 0);
- if (nt_status != STATUS_SUCCESS) {
- CLIENT_ERR ("BCryptGenRandom Failed: 0x%x", (int) nt_status);
- return false;
- }
-
- return true;
-}
-
-bool
-_native_crypto_aes_256_ctr_encrypt (aes_256_args_t args)
-{
- mongocrypt_status_t *status = args.status;
- CLIENT_ERR ("_native_crypto_aes_256_ctr_encrypt not implemented for CNG");
- return false;
-}
-
-bool
-_native_crypto_aes_256_ctr_decrypt (aes_256_args_t args)
-{
- mongocrypt_status_t *status = args.status;
- CLIENT_ERR ("_native_crypto_aes_256_ctr_decrypt not implemented for CNG");
- return false;
-}
-
-#endif /* MONGOCRYPT_ENABLE_CRYPTO_CNG */
\ No newline at end of file
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/crypto/commoncrypto.c b/mongodb-1.13.0/src/libmongocrypt/src/crypto/commoncrypto.c
deleted file mode 100644
index 04f56563..00000000
--- a/mongodb-1.13.0/src/libmongocrypt/src/crypto/commoncrypto.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2019-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "../mongocrypt-crypto-private.h"
-#include "../mongocrypt-private.h"
-
-#ifdef MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO
-
-#include <CommonCrypto/CommonCryptor.h>
-#include <CommonCrypto/CommonHMAC.h>
-#include <CommonCrypto/CommonRandom.h>
-
-bool _native_crypto_initialized = false;
-
-void
-_native_crypto_init ()
-{
- _native_crypto_initialized = true;
-}
-
-
-bool
-_native_crypto_aes_256_cbc_encrypt (aes_256_args_t args)
-{
- bool ret = false;
- CCCryptorRef ctx = NULL;
- CCCryptorStatus cc_status;
- size_t intermediate_bytes_written;
- mongocrypt_status_t *status = args.status;
-
- cc_status = CCCryptorCreate (kCCEncrypt,
- kCCAlgorithmAES,
- 0 /* defaults to CBC w/ no padding */,
- args.key->data,
- kCCKeySizeAES256,
- args.iv->data,
- &ctx);
-
- if (cc_status != kCCSuccess) {
- CLIENT_ERR ("error initializing cipher: %d", (int) cc_status);
- goto done;
- }
-
- *args.bytes_written = 0;
-
- cc_status = CCCryptorUpdate (ctx,
- args.in->data,
- args.in->len,
- args.out->data,
- args.out->len,
- &intermediate_bytes_written);
- if (cc_status != kCCSuccess) {
- CLIENT_ERR ("error encrypting: %d", (int) cc_status);
- goto done;
- }
- *args.bytes_written = intermediate_bytes_written;
-
-
- cc_status = CCCryptorFinal (ctx,
- args.out->data + *args.bytes_written,
- args.out->len - *args.bytes_written,
- &intermediate_bytes_written);
- *args.bytes_written += intermediate_bytes_written;
-
- if (cc_status != kCCSuccess) {
- CLIENT_ERR ("error finalizing: %d", (int) cc_status);
- goto done;
- }
-
- ret = true;
-done:
- CCCryptorRelease (ctx);
- return ret;
-}
-
-
-/* Note, the decrypt function is almost exactly the same as the encrypt
- * functions except for the kCCDecrypt and the error message. */
-bool
-_native_crypto_aes_256_cbc_decrypt (aes_256_args_t args)
-{
- bool ret = false;
- CCCryptorRef ctx = NULL;
- CCCryptorStatus cc_status;
- size_t intermediate_bytes_written;
- mongocrypt_status_t *status = args.status;
-
- cc_status = CCCryptorCreate (kCCDecrypt,
- kCCAlgorithmAES,
- 0 /* defaults to CBC w/ no padding */,
- args.key->data,
- kCCKeySizeAES256,
- args.iv->data,
- &ctx);
-
- if (cc_status != kCCSuccess) {
- CLIENT_ERR ("error initializing cipher: %d", (int) cc_status);
- goto done;
- }
-
- *args.bytes_written = 0;
- cc_status = CCCryptorUpdate (ctx,
- args.in->data,
- args.in->len,
- args.out->data,
- args.out->len,
- &intermediate_bytes_written);
- if (cc_status != kCCSuccess) {
- CLIENT_ERR ("error decrypting: %d", (int) cc_status);
- goto done;
- }
- *args.bytes_written = intermediate_bytes_written;
-
- cc_status = CCCryptorFinal (ctx,
- args.out->data + *args.bytes_written,
- args.out->len - *args.bytes_written,
- &intermediate_bytes_written);
- *args.bytes_written += intermediate_bytes_written;
-
- if (cc_status != kCCSuccess) {
- CLIENT_ERR ("error finalizing: %d", (int) cc_status);
- goto done;
- }
-
- ret = true;
-done:
- CCCryptorRelease (ctx);
- return ret;
-}
-
-
-/* CCHmac functions don't return errors. */
-bool
-_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
- const _mongocrypt_buffer_t *in,
- _mongocrypt_buffer_t *out,
- mongocrypt_status_t *status)
-{
- CCHmacContext *ctx;
-
- if (out->len != MONGOCRYPT_HMAC_SHA512_LEN) {
- CLIENT_ERR ("out does not contain %d bytes", MONGOCRYPT_HMAC_SHA512_LEN);
- return false;
- }
-
- ctx = bson_malloc0 (sizeof (*ctx));
- BSON_ASSERT (ctx);
-
-
- CCHmacInit (ctx, kCCHmacAlgSHA512, key->data, key->len);
- CCHmacUpdate (ctx, in->data, in->len);
- CCHmacFinal (ctx, out->data);
- bson_free (ctx);
- return true;
-}
-
-
-bool
-_native_crypto_random (_mongocrypt_buffer_t *out,
- uint32_t count,
- mongocrypt_status_t *status)
-{
- CCRNGStatus ret = CCRandomGenerateBytes (out->data, (size_t) count);
- if (ret != kCCSuccess) {
- CLIENT_ERR ("failed to generate random iv: %d", (int) ret);
- return false;
- }
- return true;
-}
-
-bool
-_native_crypto_aes_256_ctr_encrypt (aes_256_args_t args)
-{
- mongocrypt_status_t *status = args.status;
- CLIENT_ERR (
- "_native_crypto_aes_256_ctr_encrypt not implemented for CommonCrypto");
- return false;
-}
-
-bool
-_native_crypto_aes_256_ctr_decrypt (aes_256_args_t args)
-{
- mongocrypt_status_t *status = args.status;
- CLIENT_ERR (
- "_native_crypto_aes_256_ctr_decrypt not implemented for CommonCrypto");
- return false;
-}
-
-#endif /* MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c b/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c
deleted file mode 100644
index 001f3135..00000000
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright 2019-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mongocrypt-ciphertext-private.h"
-#include "mongocrypt-crypto-private.h"
-#include "mongocrypt-ctx-private.h"
-#include "mongocrypt-traverse-util-private.h"
-
-static bool
-_replace_ciphertext_with_plaintext (void *ctx,
- _mongocrypt_buffer_t *in,
- bson_value_t *out,
- mongocrypt_status_t *status)
-{
- _mongocrypt_key_broker_t *kb;
- _mongocrypt_ciphertext_t ciphertext;
- _mongocrypt_buffer_t plaintext;
- _mongocrypt_buffer_t key_material;
- _mongocrypt_buffer_t associated_data;
- uint32_t bytes_written;
- bool ret = false;
-
- BSON_ASSERT (ctx);
- BSON_ASSERT (in);
- BSON_ASSERT (out);
-
- _mongocrypt_buffer_init (&plaintext);
- _mongocrypt_buffer_init (&associated_data);
- _mongocrypt_buffer_init (&key_material);
- kb = (_mongocrypt_key_broker_t *) ctx;
-
- if (!_mongocrypt_ciphertext_parse_unowned (in, &ciphertext, status)) {
- goto fail;
- }
-
- /* look up the key */
- if (!_mongocrypt_key_broker_decrypted_key_by_id (
- kb, &ciphertext.key_id, &key_material)) {
- CLIENT_ERR ("key not found");
- goto fail;
- }
-
- plaintext.len = _mongocrypt_calculate_plaintext_len (ciphertext.data.len);
- plaintext.data = bson_malloc0 (plaintext.len);
- BSON_ASSERT (plaintext.data);
-
- plaintext.owned = true;
-
- if (!_mongocrypt_ciphertext_serialize_associated_data (&ciphertext,
- &associated_data)) {
- CLIENT_ERR ("could not serialize associated data");
- goto fail;
- }
-
- if (!_mongocrypt_do_decryption (kb->crypt->crypto,
- &associated_data,
- &key_material,
- &ciphertext.data,
- &plaintext,
- &bytes_written,
- status)) {
- goto fail;
- }
-
- plaintext.len = bytes_written;
-
- if (!_mongocrypt_buffer_to_bson_value (
- &plaintext, ciphertext.original_bson_type, out)) {
- CLIENT_ERR ("malformed encrypted bson");
- goto fail;
- }
- ret = true;
-
-fail:
- _mongocrypt_buffer_cleanup (&plaintext);
- _mongocrypt_buffer_cleanup (&associated_data);
- _mongocrypt_buffer_cleanup (&key_material);
- return ret;
-}
-
-
-static bool
-_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
-{
- bson_t as_bson, final_bson;
- bson_iter_t iter;
- _mongocrypt_ctx_decrypt_t *dctx;
- bool res;
-
- if (!ctx) {
- return false;
- }
-
- if (!out) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "null out parameter");
- }
-
- dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
-
- if (!dctx->explicit) {
- if (ctx->nothing_to_do) {
- _mongocrypt_buffer_to_binary (&dctx->original_doc, out);
- ctx->state = MONGOCRYPT_CTX_DONE;
- return true;
- }
-
- if (!_mongocrypt_buffer_to_bson (&dctx->original_doc, &as_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
- }
-
- bson_iter_init (&iter, &as_bson);
- bson_init (&final_bson);
- res = _mongocrypt_transform_binary_in_bson (
- _replace_ciphertext_with_plaintext,
- &ctx->kb,
- TRAVERSE_MATCH_CIPHERTEXT,
- &iter,
- &final_bson,
- ctx->status);
- if (!res) {
- return _mongocrypt_ctx_fail (ctx);
- }
- } else {
- /* For explicit decryption, we just have a single value */
- bson_value_t value;
-
- if (!_replace_ciphertext_with_plaintext (
- &ctx->kb, &dctx->unwrapped_doc, &value, ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
-
- bson_init (&final_bson);
- bson_append_value (&final_bson, MONGOCRYPT_STR_AND_LEN ("v"), &value);
- bson_value_destroy (&value);
- }
-
- _mongocrypt_buffer_steal_from_bson (&dctx->decrypted_doc, &final_bson);
- out->data = dctx->decrypted_doc.data;
- out->len = dctx->decrypted_doc.len;
- ctx->state = MONGOCRYPT_CTX_DONE;
- return true;
-}
-
-
-static bool
-_collect_key_from_ciphertext (void *ctx,
- _mongocrypt_buffer_t *in,
- mongocrypt_status_t *status)
-{
- _mongocrypt_ciphertext_t ciphertext;
- _mongocrypt_key_broker_t *kb;
-
- BSON_ASSERT (ctx);
- BSON_ASSERT (in);
-
- kb = (_mongocrypt_key_broker_t *) ctx;
-
- if (!_mongocrypt_ciphertext_parse_unowned (in, &ciphertext, status)) {
- return false;
- }
-
- if (!_mongocrypt_key_broker_request_id (kb, &ciphertext.key_id)) {
- return _mongocrypt_key_broker_status (kb, status);
- }
-
- return true;
-}
-
-
-static void
-_cleanup (mongocrypt_ctx_t *ctx)
-{
- _mongocrypt_ctx_decrypt_t *dctx;
-
- dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
- _mongocrypt_buffer_cleanup (&dctx->original_doc);
- _mongocrypt_buffer_cleanup (&dctx->decrypted_doc);
-}
-
-
-bool
-mongocrypt_ctx_explicit_decrypt_init (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *msg)
-{
- _mongocrypt_ctx_decrypt_t *dctx;
- bson_iter_t iter;
- bson_t as_bson;
- _mongocrypt_ctx_opts_spec_t opts_spec;
-
- if (!ctx) {
- return false;
- }
- memset (&opts_spec, 0, sizeof (opts_spec));
- if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
- return false;
- }
-
- if (!msg || !msg->data) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid msg");
- }
-
- if (ctx->crypt->log.trace_enabled) {
- char *msg_val;
- msg_val = _mongocrypt_new_json_string_from_binary (msg);
- _mongocrypt_log (&ctx->crypt->log,
- MONGOCRYPT_LOG_LEVEL_TRACE,
- "%s (%s=\"%s\")",
- BSON_FUNC,
- "msg",
- msg_val);
-
- bson_free (msg_val);
- }
-
- dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
- dctx->explicit = true;
- ctx->type = _MONGOCRYPT_TYPE_DECRYPT;
- ctx->vtable.finalize = _finalize;
- ctx->vtable.cleanup = _cleanup;
-
-
- /* We expect these to be round-tripped from explicit encrypt,
- so they must be wrapped like { "v" : "encrypted thing" } */
- _mongocrypt_buffer_copy_from_binary (&dctx->original_doc, msg);
- if (!_mongocrypt_buffer_to_bson (&dctx->original_doc, &as_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
- }
-
- if (!bson_iter_init_find (&iter, &as_bson, "v")) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid msg, must contain 'v'");
- }
-
- if (!_mongocrypt_buffer_from_binary_iter (&dctx->unwrapped_doc, &iter)) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "invalid msg, 'v' must contain a binary");
- }
-
- /* Parse out our one key id */
- if (!_collect_key_from_ciphertext (
- &ctx->kb, &dctx->unwrapped_doc, ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
-
- (void) _mongocrypt_key_broker_requests_done (&ctx->kb);
- return _mongocrypt_ctx_state_from_key_broker (ctx);
-}
-
-
-bool
-mongocrypt_ctx_decrypt_init (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *doc)
-{
- _mongocrypt_ctx_decrypt_t *dctx;
- bson_t as_bson;
- bson_iter_t iter;
- _mongocrypt_ctx_opts_spec_t opts_spec;
-
- memset (&opts_spec, 0, sizeof (opts_spec));
- if (!ctx) {
- return false;
- }
-
- if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
- return false;
- }
-
- if (!doc || !doc->data) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid doc");
- }
-
- if (ctx->crypt->log.trace_enabled) {
- char *doc_val;
- doc_val = _mongocrypt_new_json_string_from_binary (doc);
- _mongocrypt_log (&ctx->crypt->log,
- MONGOCRYPT_LOG_LEVEL_TRACE,
- "%s (%s=\"%s\")",
- BSON_FUNC,
- "doc",
- doc_val);
- bson_free (doc_val);
- }
- dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
- ctx->type = _MONGOCRYPT_TYPE_DECRYPT;
- ctx->vtable.finalize = _finalize;
- ctx->vtable.cleanup = _cleanup;
-
- _mongocrypt_buffer_copy_from_binary (&dctx->original_doc, doc);
- /* get keys. */
- if (!_mongocrypt_buffer_to_bson (&dctx->original_doc, &as_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
- }
-
- bson_iter_init (&iter, &as_bson);
- if (!_mongocrypt_traverse_binary_in_bson (_collect_key_from_ciphertext,
- &ctx->kb,
- TRAVERSE_MATCH_CIPHERTEXT,
- &iter,
- ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
-
- (void) _mongocrypt_key_broker_requests_done (&ctx->kb);
- return _mongocrypt_ctx_state_from_key_broker (ctx);
-}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c b/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c
deleted file mode 100644
index 7cba8113..00000000
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * Copyright 2019-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mongocrypt-ciphertext-private.h"
-#include "mongocrypt-crypto-private.h"
-#include "mongocrypt-ctx-private.h"
-#include "mongocrypt-key-broker-private.h"
-#include "mongocrypt-marking-private.h"
-#include "mongocrypt-traverse-util-private.h"
-
-/* Construct the list collections command to send. */
-static bool
-_mongo_op_collinfo (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
-{
- _mongocrypt_ctx_encrypt_t *ectx;
- bson_t *cmd;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- cmd = BCON_NEW ("name", BCON_UTF8 (ectx->coll_name));
- CRYPT_TRACEF (&ectx->parent.crypt->log, "constructed: %s\n", tmp_json (cmd));
- _mongocrypt_buffer_steal_from_bson (&ectx->list_collections_filter, cmd);
- out->data = ectx->list_collections_filter.data;
- out->len = ectx->list_collections_filter.len;
- return true;
-}
-
-static bool
-_set_schema_from_collinfo (mongocrypt_ctx_t *ctx, bson_t *collinfo)
-{
- bson_iter_t iter;
- _mongocrypt_ctx_encrypt_t *ectx;
- bool found_jsonschema = false;
-
- /* Parse out the schema. */
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
-
- /* Disallow views. */
- if (bson_iter_init_find (&iter, collinfo, "type") &&
- BSON_ITER_HOLDS_UTF8 (&iter) && bson_iter_utf8 (&iter, NULL) &&
- 0 == strcmp ("view", bson_iter_utf8 (&iter, NULL))) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "cannot auto encrypt a view");
- }
-
- if (!bson_iter_init (&iter, collinfo)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "BSON malformed");
- }
-
- if (bson_iter_find_descendant (&iter, "options.validator", &iter) &&
- BSON_ITER_HOLDS_DOCUMENT (&iter)) {
- if (!bson_iter_recurse (&iter, &iter)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "BSON malformed");
- }
- while (bson_iter_next (&iter)) {
- const char *key;
-
- key = bson_iter_key (&iter);
- BSON_ASSERT (key);
- if (0 == strcmp ("$jsonSchema", key)) {
- if (found_jsonschema) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "duplicate $jsonSchema fields found");
- }
- if (!_mongocrypt_buffer_copy_from_document_iter (&ectx->schema,
- &iter)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed $jsonSchema");
- }
- found_jsonschema = true;
- } else {
- ectx->collinfo_has_siblings = true;
- }
- }
- }
-
- if (!found_jsonschema) {
- bson_t empty = BSON_INITIALIZER;
-
- _mongocrypt_buffer_steal_from_bson (&ectx->schema, &empty);
- }
-
-
- return true;
-}
-
-static bool
-_mongo_feed_collinfo (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
-{
- bson_t as_bson;
-
- _mongocrypt_ctx_encrypt_t *ectx;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- if (!bson_init_static (&as_bson, in->data, in->len)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "BSON malformed");
- }
-
- /* Cache the received collinfo. */
- if (!_mongocrypt_cache_add_copy (
- &ctx->crypt->cache_collinfo, ectx->ns, &as_bson, ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
-
- if (!_set_schema_from_collinfo (ctx, &as_bson)) {
- return false;
- }
-
- return true;
-}
-
-
-static bool
-_mongo_done_collinfo (mongocrypt_ctx_t *ctx)
-{
- _mongocrypt_ctx_encrypt_t *ectx;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- if (_mongocrypt_buffer_empty (&ectx->schema)) {
- bson_t empty_collinfo = BSON_INITIALIZER;
-
- /* If no collinfo was fed, cache an empty collinfo. */
- if (!_mongocrypt_cache_add_copy (&ctx->crypt->cache_collinfo,
- ectx->ns,
- &empty_collinfo,
- ctx->status)) {
- bson_destroy (&empty_collinfo);
- return _mongocrypt_ctx_fail (ctx);
- }
- bson_destroy (&empty_collinfo);
- }
-
- ectx->parent.state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
- return true;
-}
-
-
-static bool
-_mongo_op_markings (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
-{
- _mongocrypt_ctx_encrypt_t *ectx;
- bson_t cmd_bson, schema_bson, mongocryptd_cmd_bson;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- if (_mongocrypt_buffer_empty (&ectx->mongocryptd_cmd)) {
- /* first, get the original command. */
- if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &cmd_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid BSON cmd");
- }
-
- if (_mongocrypt_buffer_empty (&ectx->schema)) {
- bson_init (&schema_bson);
- } else if (!_mongocrypt_buffer_to_bson (&ectx->schema, &schema_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid BSON schema");
- }
-
- bson_copy_to (&cmd_bson, &mongocryptd_cmd_bson);
- BSON_APPEND_DOCUMENT (&mongocryptd_cmd_bson, "jsonSchema", &schema_bson);
-
- /* if a local schema was not set, set isRemoteSchema=true */
- BSON_APPEND_BOOL (
- &mongocryptd_cmd_bson, "isRemoteSchema", !ectx->used_local_schema);
- _mongocrypt_buffer_steal_from_bson (&ectx->mongocryptd_cmd,
- &mongocryptd_cmd_bson);
-
- bson_destroy (&cmd_bson);
- bson_destroy (&schema_bson);
- }
- out->data = ectx->mongocryptd_cmd.data;
- out->len = ectx->mongocryptd_cmd.len;
- return true;
-}
-
-
-static bool
-_collect_key_from_marking (void *ctx,
- _mongocrypt_buffer_t *in,
- mongocrypt_status_t *status)
-{
- _mongocrypt_marking_t marking;
- _mongocrypt_key_broker_t *kb;
- bool res;
-
- kb = (_mongocrypt_key_broker_t *) ctx;
-
- if (!_mongocrypt_marking_parse_unowned (in, &marking, status)) {
- _mongocrypt_marking_cleanup (&marking);
- return false;
- }
-
- if (marking.has_alt_name) {
- res = _mongocrypt_key_broker_request_name (kb, &marking.key_alt_name);
- } else {
- res = _mongocrypt_key_broker_request_id (kb, &marking.key_id);
- }
-
- if (!res) {
- _mongocrypt_key_broker_status (kb, status);
- _mongocrypt_marking_cleanup (&marking);
- return false;
- }
-
- _mongocrypt_marking_cleanup (&marking);
-
- return true;
-}
-
-
-static bool
-_mongo_feed_markings (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
-{
- /* Find keys. */
- bson_t as_bson;
- bson_iter_t iter;
- _mongocrypt_ctx_encrypt_t *ectx;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- if (!_mongocrypt_binary_to_bson (in, &as_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed BSON");
- }
-
- if (bson_iter_init_find (&iter, &as_bson, "schemaRequiresEncryption") &&
- !bson_iter_as_bool (&iter)) {
- /* TODO: update cache: this schema does not require encryption. */
-
- /* If using a local schema, warn if there are no encrypted fields. */
- if (ectx->used_local_schema) {
- _mongocrypt_log (
- &ctx->crypt->log,
- MONGOCRYPT_LOG_LEVEL_WARNING,
- "local schema used but does not have encryption specifiers");
- }
- return true;
- } else {
- /* if the schema requires encryption, but has sibling validators, error.
- */
- if (ectx->collinfo_has_siblings) {
- return _mongocrypt_ctx_fail_w_msg (ctx,
- "schema requires encryption, "
- "but collection JSON schema "
- "validator has siblings");
- }
- }
-
- if (bson_iter_init_find (&iter, &as_bson, "hasEncryptedPlaceholders") &&
- !bson_iter_as_bool (&iter)) {
- return true;
- }
-
- if (!bson_iter_init_find (&iter, &as_bson, "result")) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed marking, no 'result'");
- }
-
- if (!_mongocrypt_buffer_copy_from_document_iter (&ectx->marked_cmd, &iter)) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "malformed marking, 'result' must be a document");
- }
-
- if (!bson_iter_recurse (&iter, &iter)) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "malformed marking, could not recurse into 'result'");
- }
- if (!_mongocrypt_traverse_binary_in_bson (_collect_key_from_marking,
- (void *) &ctx->kb,
- TRAVERSE_MATCH_MARKING,
- &iter,
- ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
-
- return true;
-}
-
-
-static bool
-_mongo_done_markings (mongocrypt_ctx_t *ctx)
-{
- (void) _mongocrypt_key_broker_requests_done (&ctx->kb);
- return _mongocrypt_ctx_state_from_key_broker (ctx);
-}
-
-
-static bool
-_marking_to_bson_value (void *ctx,
- _mongocrypt_marking_t *marking,
- bson_value_t *out,
- mongocrypt_status_t *status)
-{
- _mongocrypt_ciphertext_t ciphertext;
- _mongocrypt_buffer_t serialized_ciphertext = {0};
- bool ret = false;
-
- BSON_ASSERT (out);
-
- _mongocrypt_ciphertext_init (&ciphertext);
-
- if (!_mongocrypt_marking_to_ciphertext (ctx, marking, &ciphertext, status)) {
- goto fail;
- }
-
- if (!_mongocrypt_serialize_ciphertext (&ciphertext,
- &serialized_ciphertext)) {
- CLIENT_ERR ("malformed ciphertext");
- goto fail;
- };
-
- /* ownership of serialized_ciphertext is transferred to caller. */
- out->value_type = BSON_TYPE_BINARY;
- out->value.v_binary.data = serialized_ciphertext.data;
- out->value.v_binary.data_len = serialized_ciphertext.len;
- out->value.v_binary.subtype = (bson_subtype_t) 6;
-
- ret = true;
-
-fail:
- _mongocrypt_ciphertext_cleanup (&ciphertext);
- return ret;
-}
-
-
-static bool
-_replace_marking_with_ciphertext (void *ctx,
- _mongocrypt_buffer_t *in,
- bson_value_t *out,
- mongocrypt_status_t *status)
-{
- _mongocrypt_marking_t marking;
- bool ret;
-
- BSON_ASSERT (in);
-
- memset (&marking, 0, sizeof (marking));
-
- if (!_mongocrypt_marking_parse_unowned (in, &marking, status)) {
- _mongocrypt_marking_cleanup (&marking);
- return false;
- }
-
- ret = _marking_to_bson_value (ctx, &marking, out, status);
- _mongocrypt_marking_cleanup (&marking);
- return ret;
-}
-
-static bool
-_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
-{
- bson_t as_bson, converted;
- bson_iter_t iter;
- _mongocrypt_ctx_encrypt_t *ectx;
- bool res;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
-
- if (!ectx->explicit) {
- if (ctx->nothing_to_do) {
- _mongocrypt_buffer_to_binary (&ectx->original_cmd, out);
- ctx->state = MONGOCRYPT_CTX_DONE;
- return true;
- }
- if (!_mongocrypt_buffer_to_bson (&ectx->marked_cmd, &as_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
- }
-
- bson_iter_init (&iter, &as_bson);
- bson_init (&converted);
- if (!_mongocrypt_transform_binary_in_bson (
- _replace_marking_with_ciphertext,
- &ctx->kb,
- TRAVERSE_MATCH_MARKING,
- &iter,
- &converted,
- ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
- } else {
- /* For explicit encryption, we have no marking, but we can fake one */
- _mongocrypt_marking_t marking;
- bson_value_t value;
-
- memset (&value, 0, sizeof (value));
-
- _mongocrypt_marking_init (&marking);
-
- if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &as_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
- }
-
- if (!bson_iter_init_find (&iter, &as_bson, "v")) {
- return _mongocrypt_ctx_fail_w_msg (ctx,
- "invalid msg, must contain 'v'");
- }
-
-
- memcpy (&marking.v_iter, &iter, sizeof (bson_iter_t));
- marking.algorithm = ctx->opts.algorithm;
- _mongocrypt_buffer_set_to (&ctx->opts.key_id, &marking.key_id);
- if (ctx->opts.key_alt_names) {
- bson_value_copy (&ctx->opts.key_alt_names->value,
- &marking.key_alt_name);
- marking.has_alt_name = true;
- }
-
- bson_init (&converted);
- res = _marking_to_bson_value (&ctx->kb, &marking, &value, ctx->status);
- if (res) {
- bson_append_value (&converted, MONGOCRYPT_STR_AND_LEN ("v"), &value);
- }
-
- bson_value_destroy (&value);
- _mongocrypt_marking_cleanup (&marking);
-
- if (!res) {
- bson_destroy (&converted);
- return _mongocrypt_ctx_fail (ctx);
- }
- }
-
- _mongocrypt_buffer_steal_from_bson (&ectx->encrypted_cmd, &converted);
- _mongocrypt_buffer_to_binary (&ectx->encrypted_cmd, out);
- ctx->state = MONGOCRYPT_CTX_DONE;
-
- return true;
-}
-
-
-static void
-_cleanup (mongocrypt_ctx_t *ctx)
-{
- _mongocrypt_ctx_encrypt_t *ectx;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- bson_free (ectx->ns);
- bson_free (ectx->db_name);
- bson_free (ectx->coll_name);
- _mongocrypt_buffer_cleanup (&ectx->list_collections_filter);
- _mongocrypt_buffer_cleanup (&ectx->schema);
- _mongocrypt_buffer_cleanup (&ectx->original_cmd);
- _mongocrypt_buffer_cleanup (&ectx->mongocryptd_cmd);
- _mongocrypt_buffer_cleanup (&ectx->marked_cmd);
- _mongocrypt_buffer_cleanup (&ectx->encrypted_cmd);
-}
-
-
-static bool
-_try_schema_from_schema_map (mongocrypt_ctx_t *ctx)
-{
- mongocrypt_t *crypt;
- _mongocrypt_ctx_encrypt_t *ectx;
- bson_t schema_map;
- bson_iter_t iter;
-
- crypt = ctx->crypt;
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
-
- if (_mongocrypt_buffer_empty (&crypt->opts.schema_map)) {
- /* No schema map set. */
- return true;
- }
-
- if (!_mongocrypt_buffer_to_bson (&crypt->opts.schema_map, &schema_map)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed schema map");
- }
-
- if (bson_iter_init_find (&iter, &schema_map, ectx->ns)) {
- if (!_mongocrypt_buffer_copy_from_document_iter (&ectx->schema, &iter)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "malformed schema map");
- }
- ectx->used_local_schema = true;
- ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
- }
-
- /* No schema found in map. */
- return true;
-}
-
-
-static bool
-_try_schema_from_cache (mongocrypt_ctx_t *ctx)
-{
- _mongocrypt_ctx_encrypt_t *ectx;
- bson_t *collinfo = NULL;
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
-
- /* Otherwise, we need a remote schema. Check if we have a response to
- * listCollections cached. */
- if (!_mongocrypt_cache_get (&ctx->crypt->cache_collinfo,
- ectx->ns /* null terminated */,
- (void **) &collinfo)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "failed to retrieve from cache");
- }
-
- if (collinfo) {
- if (!_set_schema_from_collinfo (ctx, collinfo)) {
- return _mongocrypt_ctx_fail (ctx);
- }
- ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
- } else {
- /* we need to get it. */
- ctx->state = MONGOCRYPT_CTX_NEED_MONGO_COLLINFO;
- }
-
- bson_destroy (collinfo);
- return true;
-}
-
-static bool
-_permitted_for_encryption (bson_iter_t *iter,
- mongocrypt_encryption_algorithm_t algo,
- mongocrypt_status_t *status)
-{
- bson_type_t bson_type;
- const bson_value_t *bson_value = bson_iter_value (iter);
- bool ret = false;
-
- if (!bson_value) {
- CLIENT_ERR ("Unknown BSON type");
- goto fail;
- }
- bson_type = bson_value->value_type;
- switch (bson_type) {
- case BSON_TYPE_NULL:
- case BSON_TYPE_MINKEY:
- case BSON_TYPE_MAXKEY:
- case BSON_TYPE_UNDEFINED:
- CLIENT_ERR ("BSON type invalid for encryption");
- goto fail;
- case BSON_TYPE_BINARY:
- if (bson_value->value.v_binary.subtype == 6) {
- CLIENT_ERR ("BSON binary subtype 6 is invalid for encryption");
- goto fail;
- }
- /* ok */
- break;
- case BSON_TYPE_DOUBLE:
- case BSON_TYPE_DOCUMENT:
- case BSON_TYPE_ARRAY:
- case BSON_TYPE_CODEWSCOPE:
- case BSON_TYPE_BOOL:
- case BSON_TYPE_DECIMAL128:
- if (algo == MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC) {
- CLIENT_ERR ("BSON type invalid for deterministic encryption");
- goto fail;
- }
- break;
- case BSON_TYPE_UTF8:
- case BSON_TYPE_OID:
- case BSON_TYPE_DATE_TIME:
- case BSON_TYPE_REGEX:
- case BSON_TYPE_DBPOINTER:
- case BSON_TYPE_CODE:
- case BSON_TYPE_SYMBOL:
- case BSON_TYPE_INT32:
- case BSON_TYPE_TIMESTAMP:
- case BSON_TYPE_INT64:
- /* ok */
- break;
- case BSON_TYPE_EOD:
- default:
- CLIENT_ERR ("invalid BSON value type 00");
- goto fail;
- }
-
- ret = true;
-fail:
- return ret;
-}
-
-bool
-mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *msg)
-{
- _mongocrypt_ctx_encrypt_t *ectx;
- bson_t as_bson;
- bson_iter_t iter;
- _mongocrypt_ctx_opts_spec_t opts_spec;
-
- if (!ctx) {
- return false;
- }
- memset (&opts_spec, 0, sizeof (opts_spec));
- opts_spec.key_descriptor = OPT_REQUIRED;
- opts_spec.algorithm = OPT_REQUIRED;
-
- if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
- return false;
- }
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- ctx->type = _MONGOCRYPT_TYPE_ENCRYPT;
- ectx->explicit = true;
- ctx->vtable.finalize = _finalize;
- ctx->vtable.cleanup = _cleanup;
-
- if (!msg || !msg->data) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "msg required for explicit encryption");
- }
-
- if (ctx->opts.key_alt_names) {
- if (!_mongocrypt_key_broker_request_name (
- &ctx->kb, &ctx->opts.key_alt_names->value)) {
- return _mongocrypt_ctx_fail (ctx);
- }
- } else {
- if (!_mongocrypt_key_broker_request_id (&ctx->kb, &ctx->opts.key_id)) {
- return _mongocrypt_ctx_fail (ctx);
- }
- }
-
- _mongocrypt_buffer_init (&ectx->original_cmd);
-
- _mongocrypt_buffer_copy_from_binary (&ectx->original_cmd, msg);
- if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &as_bson)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "msg must be bson");
- }
-
- if (ctx->crypt->log.trace_enabled) {
- char *cmd_val;
- cmd_val = _mongocrypt_new_json_string_from_binary (msg);
- _mongocrypt_log (&ctx->crypt->log,
- MONGOCRYPT_LOG_LEVEL_TRACE,
- "%s (%s=\"%s\")",
- BSON_FUNC,
- "msg",
- cmd_val);
- bson_free (cmd_val);
- }
-
- if (!bson_iter_init_find (&iter, &as_bson, "v")) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid msg, must contain 'v'");
- }
-
- if (!_permitted_for_encryption (&iter, ctx->opts.algorithm, ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
-
- (void) _mongocrypt_key_broker_requests_done (&ctx->kb);
- return _mongocrypt_ctx_state_from_key_broker (ctx);
-}
-
-static bool
-_check_cmd_for_auto_encrypt (mongocrypt_binary_t *cmd,
- bool *bypass,
- char **collname,
- mongocrypt_status_t *status)
-{
- bson_t as_bson;
- bson_iter_t iter, ns_iter;
- const char *cmd_name;
- bool eligible = false;
-
- *bypass = false;
-
- if (!_mongocrypt_binary_to_bson (cmd, &as_bson) ||
- !bson_iter_init (&iter, &as_bson)) {
- CLIENT_ERR ("invalid BSON");
- return false;
- }
-
- /* The command name is the first key. */
- if (!bson_iter_next (&iter)) {
- CLIENT_ERR ("invalid empty BSON");
- return false;
- }
-
- cmd_name = bson_iter_key (&iter);
- BSON_ASSERT (cmd_name);
-
- /* get the collection name (or NULL if database/client command). */
- if (0 == strcmp (cmd_name, "explain")) {
- if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
- CLIENT_ERR ("explain value is not a document");
- return false;
- }
- if (!bson_iter_recurse (&iter, &ns_iter)) {
- CLIENT_ERR ("malformed BSON for encrypt command");
- return false;
- }
- if (!bson_iter_next (&ns_iter)) {
- CLIENT_ERR ("invalid empty BSON");
- return false;
- }
- } else {
- memcpy (&ns_iter, &iter, sizeof (iter));
- }
-
- if (BSON_ITER_HOLDS_UTF8 (&ns_iter)) {
- *collname = bson_strdup (bson_iter_utf8 (&ns_iter, NULL));
- } else {
- *collname = NULL;
- }
-
- /* check if command is eligible for auto encryption, bypassed, or ineligible.
- */
- if (0 == strcmp (cmd_name, "aggregate")) {
- /* collection level aggregate ok, database/client is not. */
- eligible = true;
- } else if (0 == strcmp (cmd_name, "count")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "distinct")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "delete")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "find")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "findAndModify")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "getMore")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "insert")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "update")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "authenticate")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "getnonce")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "logout")) {
- *bypass = true;
- } else if (0 == bson_strcasecmp (cmd_name, "isMaster")) {
- /* use case insensitive compare for ismaster, since some drivers send
- * "ismaster" and others send "isMaster" */
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "abortTransaction")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "commitTransaction")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "endSessions")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "startSession")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "create")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "createIndexes")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "drop")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "dropDatabase")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "dropIndexes")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "killCursors")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "listCollections")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "listDatabases")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "listIndexes")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "renameCollection")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "explain")) {
- eligible = true;
- } else if (0 == strcmp (cmd_name, "ping")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "saslStart")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "saslContinue")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "killAllSessions")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "killSessions")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "killAllSessionsByPattern")) {
- *bypass = true;
- } else if (0 == strcmp (cmd_name, "refreshSessions")) {
- *bypass = true;
- }
-
- /* database/client commands are ineligible. */
- if (eligible) {
- if (!*collname) {
- CLIENT_ERR (
- "non-collection command not supported for auto encryption: %s",
- cmd_name);
- return false;
- }
- if (0 == strlen (*collname)) {
- CLIENT_ERR ("empty collection name on command: %s", cmd_name);
- return false;
- }
- }
-
- if (eligible || *bypass) {
- return true;
- }
-
- CLIENT_ERR ("command not supported for auto encryption: %s", cmd_name);
- return false;
-}
-
-bool
-mongocrypt_ctx_encrypt_init (mongocrypt_ctx_t *ctx,
- const char *db,
- int32_t db_len,
- mongocrypt_binary_t *cmd)
-{
- _mongocrypt_ctx_encrypt_t *ectx;
- _mongocrypt_ctx_opts_spec_t opts_spec;
- bool bypass;
-
- if (!ctx) {
- return false;
- }
- memset (&opts_spec, 0, sizeof (opts_spec));
- opts_spec.schema = OPT_OPTIONAL;
- if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
- return false;
- }
-
- ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
- ctx->type = _MONGOCRYPT_TYPE_ENCRYPT;
- ectx->explicit = false;
- ctx->vtable.mongo_op_collinfo = _mongo_op_collinfo;
- ctx->vtable.mongo_feed_collinfo = _mongo_feed_collinfo;
- ctx->vtable.mongo_done_collinfo = _mongo_done_collinfo;
- ctx->vtable.mongo_op_collinfo = _mongo_op_collinfo;
- ctx->vtable.mongo_op_markings = _mongo_op_markings;
- ctx->vtable.mongo_feed_markings = _mongo_feed_markings;
- ctx->vtable.mongo_done_markings = _mongo_done_markings;
- ctx->vtable.finalize = _finalize;
- ctx->vtable.cleanup = _cleanup;
- ctx->vtable.mongo_op_collinfo = _mongo_op_collinfo;
- ctx->vtable.mongo_feed_collinfo = _mongo_feed_collinfo;
- ctx->vtable.mongo_done_collinfo = _mongo_done_collinfo;
-
-
- if (!cmd || !cmd->data) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid command");
- }
-
- _mongocrypt_buffer_copy_from_binary (&ectx->original_cmd, cmd);
-
- if (!_check_cmd_for_auto_encrypt (
- cmd, &bypass, &ectx->coll_name, ctx->status)) {
- return _mongocrypt_ctx_fail (ctx);
- }
-
- if (bypass) {
- ctx->nothing_to_do = true;
- ctx->state = MONGOCRYPT_CTX_READY;
- return true;
- }
-
- /* if _check_cmd_for_auto_encrypt did not bypass or error, a collection name
- * must have been set. */
- if (!ectx->coll_name) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx,
- "unexpected error: did not bypass or error but no collection name");
- }
-
- if (!_mongocrypt_validate_and_copy_string (db, db_len, &ectx->db_name) ||
- 0 == strlen (ectx->db_name)) {
- return _mongocrypt_ctx_fail_w_msg (ctx, "invalid db");
- }
-
- ectx->ns = bson_strdup_printf ("%s.%s", ectx->db_name, ectx->coll_name);
-
- if (ctx->opts.kek.provider.aws.region || ctx->opts.kek.provider.aws.cmk) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "aws masterkey options must not be set");
- }
-
- if (!_mongocrypt_buffer_empty (&ctx->opts.key_id)) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "key_id must not be set for auto encryption");
- }
-
- if (ctx->opts.algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE) {
- return _mongocrypt_ctx_fail_w_msg (
- ctx, "algorithm must not be set for auto encryption");
- }
-
- if (ctx->crypt->log.trace_enabled) {
- char *cmd_val;
- cmd_val = _mongocrypt_new_json_string_from_binary (cmd);
- _mongocrypt_log (&ctx->crypt->log,
- MONGOCRYPT_LOG_LEVEL_TRACE,
- "%s (%s=\"%s\", %s=%d, %s=\"%s\")",
- BSON_FUNC,
- "db",
- ectx->db_name,
- "db_len",
- db_len,
- "cmd",
- cmd_val);
- bson_free (cmd_val);
- }
-
- /* Check if we have a local schema from schema_map */
- if (!_try_schema_from_schema_map (ctx)) {
- return false;
- }
-
- /* If we didn't have a local schema, try the cache. */
- if (_mongocrypt_buffer_empty (&ectx->schema)) {
- if (!_try_schema_from_cache (ctx)) {
- return false;
- }
- }
-
- /* Otherwise, we need the the driver to fetch the schema. */
- if (_mongocrypt_buffer_empty (&ectx->schema)) {
- ctx->state = MONGOCRYPT_CTX_NEED_MONGO_COLLINFO;
- }
- return true;
-}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-marking.c b/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-marking.c
deleted file mode 100644
index c38aee7e..00000000
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-marking.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2019-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mongocrypt.h"
-#include "mongocrypt-buffer-private.h"
-#include "mongocrypt-ciphertext-private.h"
-#include "mongocrypt-crypto-private.h"
-#include "mongocrypt-key-broker-private.h"
-#include "mongocrypt-marking-private.h"
-
-bool
-_mongocrypt_marking_parse_unowned (const _mongocrypt_buffer_t *in,
- _mongocrypt_marking_t *out,
- mongocrypt_status_t *status)
-{
- bson_t bson;
- bson_iter_t iter;
- bool has_ki = false, has_ka = false, has_a = false, has_v = false;
-
- _mongocrypt_marking_init (out);
-
- if (in->len < 5) {
- CLIENT_ERR ("invalid marking, length < 5");
- return false;
- }
-
- if (in->data[0] != 0) {
- CLIENT_ERR ("invalid marking, first byte must be 0");
- return false;
- }
-
- if (!bson_init_static (&bson, in->data + 1, in->len - 1)) {
- CLIENT_ERR ("invalid BSON");
- return false;
- }
-
- if (!bson_validate (&bson, BSON_VALIDATE_NONE, NULL) ||
- !bson_iter_init (&iter, &bson)) {
- CLIENT_ERR ("invalid BSON");
- return false;
- }
-
- while (bson_iter_next (&iter)) {
- const char *field;
-
- field = bson_iter_key (&iter);
- BSON_ASSERT (field);
- if (0 == strcmp ("ki", field)) {
- has_ki = true;
- if (!_mongocrypt_buffer_from_uuid_iter (&out->key_id, &iter)) {
- CLIENT_ERR ("key id must be a UUID");
- return false;
- }
- continue;
- }
-
- if (0 == strcmp ("ka", field)) {
- has_ka = true;
- /* Some bson_value types are not allowed to be key alt names */
- const bson_value_t *value;
-
- value = bson_iter_value (&iter);
-
- if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
- CLIENT_ERR ("key alt name must be a UTF8");
- return false;
- }
- /* CDRIVER-3100 We must make a copy of this value; the result of
- * bson_iter_value is ephemeral. */
- bson_value_copy (value, &out->key_alt_name);
- out->has_alt_name = true;
- continue;
- }
-
- if (0 == strcmp ("v", field)) {
- has_v = true;
- memcpy (&out->v_iter, &iter, sizeof (bson_iter_t));
- continue;
- }
-
-
- if (0 == strcmp ("a", field)) {
- int32_t algorithm;
-
- has_a = true;
- if (!BSON_ITER_HOLDS_INT32 (&iter)) {
- CLIENT_ERR ("invalid marking, 'a' must be an int32");
- return false;
- }
- algorithm = bson_iter_int32 (&iter);
- if (algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC &&
- algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM) {
- CLIENT_ERR ("invalid algorithm value: %d", algorithm);
- return false;
- }
- out->algorithm = (mongocrypt_encryption_algorithm_t) algorithm;
- continue;
- }
-
- CLIENT_ERR ("unrecognized field '%s'", field);
- return false;
- }
-
- if (!has_v) {
- CLIENT_ERR ("no 'v' specified");
- return false;
- }
-
- if (!has_ki && !has_ka) {
- CLIENT_ERR ("neither 'ki' nor 'ka' specified");
- return false;
- }
-
- if (has_ki && has_ka) {
- CLIENT_ERR ("both 'ki' and 'ka' specified");
- return false;
- }
-
- if (!has_a) {
- CLIENT_ERR ("no 'a' specified");
- return false;
- }
-
- return true;
-}
-
-
-void
-_mongocrypt_marking_init (_mongocrypt_marking_t *marking)
-{
- memset (marking, 0, sizeof (*marking));
-}
-
-
-void
-_mongocrypt_marking_cleanup (_mongocrypt_marking_t *marking)
-{
- bson_value_destroy (&marking->key_alt_name);
- _mongocrypt_buffer_cleanup (&marking->key_id);
-}
-
-
-bool
-_mongocrypt_marking_to_ciphertext (void *ctx,
- _mongocrypt_marking_t *marking,
- _mongocrypt_ciphertext_t *ciphertext,
- mongocrypt_status_t *status)
-{
- _mongocrypt_buffer_t plaintext;
- _mongocrypt_buffer_t iv;
- _mongocrypt_key_broker_t *kb;
- _mongocrypt_buffer_t associated_data;
- _mongocrypt_buffer_t key_material;
- _mongocrypt_buffer_t key_id;
- bool ret = false;
- bool key_found;
- uint32_t bytes_written;
-
- BSON_ASSERT (marking);
- BSON_ASSERT (ciphertext);
- BSON_ASSERT (status);
- BSON_ASSERT (ctx);
-
- _mongocrypt_buffer_init (&plaintext);
- _mongocrypt_buffer_init (&associated_data);
- _mongocrypt_buffer_init (&iv);
- _mongocrypt_buffer_init (&key_id);
- _mongocrypt_buffer_init (&key_material);
-
- kb = (_mongocrypt_key_broker_t *) ctx;
-
- /* Get the decrypted key for this marking. */
- if (marking->has_alt_name) {
- key_found = _mongocrypt_key_broker_decrypted_key_by_name (
- kb, &marking->key_alt_name, &key_material, &key_id);
- } else if (!_mongocrypt_buffer_empty (&marking->key_id)) {
- key_found = _mongocrypt_key_broker_decrypted_key_by_id (
- kb, &marking->key_id, &key_material);
- _mongocrypt_buffer_copy_to (&marking->key_id, &key_id);
- } else {
- CLIENT_ERR ("marking must have either key_id or key_alt_name");
- goto fail;
- }
-
- if (!key_found) {
- _mongocrypt_status_copy_to (kb->status, status);
- goto fail;
- }
-
- _mongocrypt_ciphertext_init (ciphertext);
- ciphertext->original_bson_type = (uint8_t) bson_iter_type (&marking->v_iter);
- ciphertext->blob_subtype = marking->algorithm;
- _mongocrypt_buffer_copy_to (&key_id, &ciphertext->key_id);
- if (!_mongocrypt_ciphertext_serialize_associated_data (ciphertext,
- &associated_data)) {
- CLIENT_ERR ("could not serialize associated data");
- goto fail;
- }
-
- _mongocrypt_buffer_from_iter (&plaintext, &marking->v_iter);
- ciphertext->data.len = _mongocrypt_calculate_ciphertext_len (plaintext.len);
- ciphertext->data.data = bson_malloc (ciphertext->data.len);
- BSON_ASSERT (ciphertext->data.data);
-
- ciphertext->data.owned = true;
-
- switch (marking->algorithm) {
- case MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC:
- /* Use deterministic encryption. */
- _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
- ret = _mongocrypt_calculate_deterministic_iv (kb->crypt->crypto,
- &key_material,
- &plaintext,
- &associated_data,
- &iv,
- status);
- if (!ret) {
- goto fail;
- }
-
- ret = _mongocrypt_do_encryption (kb->crypt->crypto,
- &iv,
- &associated_data,
- &key_material,
- &plaintext,
- &ciphertext->data,
- &bytes_written,
- status);
- break;
- case MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM:
- /* Use randomized encryption.
- * In this case, we must generate a new, random iv. */
- _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
- if (!_mongocrypt_random (
- kb->crypt->crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
- goto fail;
- }
- ret = _mongocrypt_do_encryption (kb->crypt->crypto,
- &iv,
- &associated_data,
- &key_material,
- &plaintext,
- &ciphertext->data,
- &bytes_written,
- status);
- break;
- default:
- /* Error. */
- CLIENT_ERR ("Unsupported value for encryption algorithm");
- goto fail;
- }
-
- if (!ret) {
- goto fail;
- }
-
- BSON_ASSERT (bytes_written == ciphertext->data.len);
-
- ret = true;
-
-fail:
- _mongocrypt_buffer_cleanup (&iv);
- _mongocrypt_buffer_cleanup (&key_id);
- _mongocrypt_buffer_cleanup (&plaintext);
- _mongocrypt_buffer_cleanup (&associated_data);
- _mongocrypt_buffer_cleanup (&key_material);
- return ret;
-}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.h.in b/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.h.in
deleted file mode 100644
index 6e2b8f04..00000000
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.h.in
+++ /dev/null
@@ -1,1255 +0,0 @@
-/*
- * Copyright 2019-present MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef MONGOCRYPT_H
-#define MONGOCRYPT_H
-
-/** @file mongocrypt.h The top-level handle to libmongocrypt. */
-
-/**
- * @mainpage libmongocrypt
- * See all public API documentation in: @ref mongocrypt.h
- */
-
-#include "mongocrypt-export.h"
-#include "mongocrypt-compat.h"
-#include "mongocrypt-config.h"
-
-/**
- * @def MONGOCRYPT_VERSION
- * The version string describing libmongocrypt.
- * Has the form x.y.z-<pre>+<date>+git<sha>.
- */
-#define MONGOCRYPT_VERSION "@MONGOCRYPT_BUILD_VERSION@"
-
-/**
- * Returns the version string for libmongocrypt.
- *
- * @param[out] len An optional length of the returned string. May be NULL.
- * @returns a NULL terminated version string for libmongocrypt.
- */
-MONGOCRYPT_EXPORT
-const char *
-mongocrypt_version (uint32_t *len);
-
-
-/**
- * A non-owning view of a byte buffer.
- *
- * When constructing a mongocrypt_binary_t it is the responsibility of the
- * caller to maintain the lifetime of the viewed data. However, all public
- * functions that take a mongocrypt_binary_t as an argument will make a copy of
- * the viewed data. For example, the following is valid:
- *
- * @code{.c}
- * mongocrypt_binary_t bin = mongocrypt_binary_new_from_data(mydata, mylen);
- * assert (mongocrypt_setopt_kms_provider_local (crypt), bin);
- * // The viewed data of bin has been copied. Ok to free the view and the data.
- * mongocrypt_binary_destroy (bin);
- * my_free_fn (mydata);
- * @endcode
- *
- * Functions with a mongocrypt_binary_t* out guarantee the lifetime of the
- * viewed data to live as long as the parent object. For example, @ref
- * mongocrypt_ctx_mongo_op guarantees that the viewed data of
- * mongocrypt_binary_t is valid until the parent ctx is destroyed with @ref
- * mongocrypt_ctx_destroy.
- */
-typedef struct _mongocrypt_binary_t mongocrypt_binary_t;
-
-
-/**
- * Create a new non-owning view of a buffer (data + length).
- *
- * Use this to create a mongocrypt_binary_t used for output parameters.
- *
- * @returns A new mongocrypt_binary_t.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_binary_t *
-mongocrypt_binary_new (void);
-
-
-/**
- * Create a new non-owning view of a buffer (data + length).
- *
- * @param[in] data A pointer to an array of bytes. This data is not copied. @p
- * data must outlive the binary object.
- * @param[in] len The length of the @p data byte array.
- *
- * @returns A new @ref mongocrypt_binary_t.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_binary_t *
-mongocrypt_binary_new_from_data (uint8_t *data, uint32_t len);
-
-
-/**
- * Get a pointer to the viewed data.
- *
- * @param[in] binary The @ref mongocrypt_binary_t.
- *
- * @returns A pointer to the viewed data.
- */
-MONGOCRYPT_EXPORT
-uint8_t *
-mongocrypt_binary_data (const mongocrypt_binary_t *binary);
-
-
-/**
- * Get the length of the viewed data.
- *
- * @param[in] binary The @ref mongocrypt_binary_t.
- *
- * @returns The length of the viewed data.
- */
-MONGOCRYPT_EXPORT
-uint32_t
-mongocrypt_binary_len (const mongocrypt_binary_t *binary);
-
-
-/**
- * Free the @ref mongocrypt_binary_t.
- *
- * This does not free the viewed data.
- *
- * @param[in] binary The mongocrypt_binary_t destroy.
- */
-MONGOCRYPT_EXPORT
-void
-mongocrypt_binary_destroy (mongocrypt_binary_t *binary);
-
-
-/**
- * Indicates success or contains error information.
- *
- * Functions like @ref mongocrypt_ctx_encrypt_init follow a pattern to expose a
- * status. A boolean is returned. True indicates success, and false indicates
- * failure. On failure a status on the handle is set, and is accessible with a
- * corresponding (handle)_status function. E.g. @ref mongocrypt_ctx_status.
- */
-typedef struct _mongocrypt_status_t mongocrypt_status_t;
-
-/**
- * Indicates the type of error.
- */
-typedef enum {
- MONGOCRYPT_STATUS_OK = 0,
- MONGOCRYPT_STATUS_ERROR_CLIENT = 1,
- MONGOCRYPT_STATUS_ERROR_KMS = 2
-} mongocrypt_status_type_t;
-
-
-/**
- * Create a new status object.
- *
- * Use a new status object to retrieve the status from a handle by passing
- * this as an out-parameter to functions like @ref mongocrypt_ctx_status.
- * When done, destroy it with @ref mongocrypt_status_destroy.
- *
- * @returns A new status object.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_status_t *
-mongocrypt_status_new (void);
-
-
-/**
- * Set a status object with message, type, and code.
- *
- * Use this to set the @ref mongocrypt_status_t given in the crypto hooks.
- *
- * @param[in] type The status type.
- * @param[in] code The status code.
- * @param[in] message The message.
- * @param[in] message_len Due to historical behavior, pass 1 + the string length
- * of @p message (which differs from other functions accepting string
- * arguments).
- * Alternatively, if message is NULL terminated this may be -1 to tell
- * mongocrypt
- * to determine the string's length with strlen.
- *
- */
-MONGOCRYPT_EXPORT
-void
-mongocrypt_status_set (mongocrypt_status_t *status,
- mongocrypt_status_type_t type,
- uint32_t code,
- const char *message,
- int32_t message_len);
-
-
-/**
- * Indicates success or the type of error.
- *
- * @param[in] status The status object.
- *
- * @returns A @ref mongocrypt_status_type_t.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_status_type_t
-mongocrypt_status_type (mongocrypt_status_t *status);
-
-
-/**
- * Get an error code or 0.
- *
- * @param[in] status The status object.
- *
- * @returns An error code.
- */
-MONGOCRYPT_EXPORT
-uint32_t
-mongocrypt_status_code (mongocrypt_status_t *status);
-
-
-/**
- * Get the error message associated with a status or NULL.
- *
- * @param[in] status The status object.
- * @param[out] len An optional length of the returned string (excluding the
- * trailing NULL byte). May be NULL.
- *
- * @returns A NULL terminated error message or NULL.
- */
-MONGOCRYPT_EXPORT
-const char *
-mongocrypt_status_message (mongocrypt_status_t *status, uint32_t *len);
-
-
-/**
- * Returns true if the status indicates success.
- *
- * @param[in] status The status to check.
- *
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_status_ok (mongocrypt_status_t *status);
-
-
-/**
- * Free the memory for a status object.
- *
- * @param[in] status The status to destroy.
- */
-MONGOCRYPT_EXPORT
-void
-mongocrypt_status_destroy (mongocrypt_status_t *status);
-
-/**
- * Indicates the type of log message.
- */
-typedef enum {
- MONGOCRYPT_LOG_LEVEL_FATAL = 0,
- MONGOCRYPT_LOG_LEVEL_ERROR = 1,
- MONGOCRYPT_LOG_LEVEL_WARNING = 2,
- MONGOCRYPT_LOG_LEVEL_INFO = 3,
- MONGOCRYPT_LOG_LEVEL_TRACE = 4
-} mongocrypt_log_level_t;
-
-
-/**
- * A log callback function. Set a custom log callback with @ref
- * mongocrypt_setopt_log_handler.
- *
- * @param[in] message A NULL terminated message.
- * @param[in] message_len The length of message.
- * @param[in] ctx A context provided by the caller of @ref
- * mongocrypt_setopt_log_handler.
- */
-typedef void (*mongocrypt_log_fn_t) (mongocrypt_log_level_t level,
- const char *message,
- uint32_t message_len,
- void *ctx);
-
-
-/**
- * The top-level handle to libmongocrypt.
- *
- * Create a mongocrypt_t handle to perform operations within libmongocrypt:
- * encryption, decryption, registering log callbacks, etc.
- *
- * Functions on a mongocrypt_t are thread safe, though functions on derived
- * handles (e.g. mongocrypt_ctx_t) are not and must be owned by a single
- * thread. See each handle's documentation for thread-safety considerations.
- *
- * Multiple mongocrypt_t handles may be created.
- */
-typedef struct _mongocrypt_t mongocrypt_t;
-
-
-/**
- * Allocate a new @ref mongocrypt_t object.
- *
- * Set options using mongocrypt_setopt_* functions, then initialize with @ref
- * mongocrypt_init. When done with the @ref mongocrypt_t, free with @ref
- * mongocrypt_destroy.
- *
- * @returns A new @ref mongocrypt_t object.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_t *
-mongocrypt_new (void);
-
-
-/**
- * Set a handler on the @ref mongocrypt_t object to get called on every log
- * message.
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @param[in] log_fn The log callback.
- * @param[in] log_ctx A context passed as an argument to the log callback every
- * invocation.
- * @pre @ref mongocrypt_init has not been called on @p crypt.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_setopt_log_handler (mongocrypt_t *crypt,
- mongocrypt_log_fn_t log_fn,
- void *log_ctx);
-
-
-/**
- * Configure an AWS KMS provider on the @ref mongocrypt_t object.
- *
- * This has been superseded by the more flexible:
- * @ref mongocrypt_setopt_kms_providers
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @param[in] aws_access_key_id The AWS access key ID used to generate KMS
- * messages.
- * @param[in] aws_access_key_id_len The string length (in bytes) of @p
- * aws_access_key_id. Pass -1 to determine the string length with strlen (must
- * be NULL terminated).
- * @param[in] aws_secret_access_key The AWS secret access key used to generate
- * KMS messages.
- * @param[in] aws_secret_access_key_len The string length (in bytes) of @p
- * aws_secret_access_key. Pass -1 to determine the string length with strlen
- * (must be NULL terminated).
- * @pre @ref mongocrypt_init has not been called on @p crypt.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_setopt_kms_provider_aws (mongocrypt_t *crypt,
- const char *aws_access_key_id,
- int32_t aws_access_key_id_len,
- const char *aws_secret_access_key,
- int32_t aws_secret_access_key_len);
-
-
-/**
- * Configure a local KMS provider on the @ref mongocrypt_t object.
- *
- * This has been superseded by the more flexible:
- * @ref mongocrypt_setopt_kms_providers
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @param[in] key A 96 byte master key used to encrypt and decrypt key vault
- * keys. The viewed data is copied. It is valid to destroy @p key with @ref
- * mongocrypt_binary_destroy immediately after.
- * @pre @ref mongocrypt_init has not been called on @p crypt.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_setopt_kms_provider_local (mongocrypt_t *crypt,
- mongocrypt_binary_t *key);
-
-/**
- * Configure KMS providers with a BSON document.
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @param[in] kms_providers A BSON document mapping the KMS provider names
- * to credentials.
- * @pre @ref mongocrypt_init has not been called on @p crypt.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_setopt_kms_providers (mongocrypt_t *crypt,
- mongocrypt_binary_t *kms_providers);
-
-/**
- * Set a local schema map for encryption.
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @param[in] schema_map A BSON document representing the schema map supplied by
- * the user. The keys are collection namespaces and values are JSON schemas. The
- * viewed data copied. It is valid to destroy @p schema_map with @ref
- * mongocrypt_binary_destroy immediately after.
- * @pre @p crypt has not been initialized.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_setopt_schema_map (mongocrypt_t *crypt,
- mongocrypt_binary_t *schema_map);
-
-
-/**
- * @brief Append an additional search directory to the search path for loading
- * the CSFLE dynamic library.
- *
- * @param[in] crypt The @ref mongocrypt_t object to update
- * @param[in] path A null-terminated sequence of bytes for the search path. On
- * some filesystems, this may be arbitrary bytes. On other filesystems, this may
- * be required to be a valid UTF-8 code unit sequence. If the leading element of
- * the path is the literal string "$ORIGIN", that substring will be replaced
- * with the directory path containing the executable libmongocrypt module. If
- * the path string is literal "$SYSTEM", then libmongocrypt will defer to the
- * system's library resolution mechanism to find the CSFLE library.
- *
- * @note If no CSFLE dynamic library is found in any of the directories
- * specified by the search paths loaded here, @ref mongocrypt_init() will still
- * succeed and continue to operate without CSFLE.
- *
- * @note The search paths are searched in the order that they are appended. This
- * allows one to provide a precedence in how the library will be discovered. For
- * example, appending known directories before appending "$SYSTEM" will allow
- * one to supersede the system's installed library, but still fall-back to it if
- * the library wasn't found otherwise. If one does not ever append "$SYSTEM",
- * then the system's library-search mechanism will never be consulted.
- *
- * @note If an absolute path to the library is specified using
- * @ref mongocrypt_setopt_set_csfle_lib_path_override, then paths appended here
- * will have no effect.
- */
-MONGOCRYPT_EXPORT
-void
-mongocrypt_setopt_append_csfle_search_path (mongocrypt_t *crypt,
- const char *path);
-
-
-/**
- * @brief Set a single override path for loading the CSFLE dynamic library.
- *
- * @param[in] crypt The @ref mongocrypt_t object to update
- * @param[in] path A null-terminated sequence of bytes for a path to the CSFLE
- * dynamic library. On some filesystems, this may be arbitrary bytes. On other
- * filesystems, this may be required to be a valid UTF-8 code unit sequence. If
- * the leading element of the path is the literal string `$ORIGIN`, that
- * substring will be replaced with the directory path containing the executable
- * libmongocrypt module.
- *
- * @note This function will do no IO nor path validation. All validation will
- * occur during the call to @ref mongocrypt_init.
- *
- * @note If a CSFLE library path override is specified here, then no paths given
- * to @ref mongocrypt_setopt_append_csfle_search_path will be consulted when
- * opening the CSFLE library.
- *
- * @note If a path is provided via this API and @ref mongocrypt_init fails to
- * initialize a valid CSFLE library instance for the path specified, then
- * the initialization of mongocrypt_t will fail with an error.
- */
-MONGOCRYPT_EXPORT
-void
-mongocrypt_setopt_set_csfle_lib_path_override (mongocrypt_t *crypt,
- const char *path);
-
-
-/**
- * Initialize new @ref mongocrypt_t object.
- *
- * Set options before using @ref mongocrypt_setopt_kms_provider_local, @ref
- * mongocrypt_setopt_kms_provider_aws, or @ref mongocrypt_setopt_log_handler.
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- *
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status Failure may occur if previously
- * set
- * options are invalid.
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_init (mongocrypt_t *crypt);
-
-
-/**
- * Get the status associated with a @ref mongocrypt_t object.
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @param[out] status Receives the status.
- *
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_status (mongocrypt_t *crypt, mongocrypt_status_t *status);
-
-
-/**
- * Destroy the @ref mongocrypt_t object.
- *
- * @param[in] crypt The @ref mongocrypt_t object to destroy.
- */
-MONGOCRYPT_EXPORT
-void
-mongocrypt_destroy (mongocrypt_t *crypt);
-
-
-/**
- * Manages the state machine for encryption or decryption.
- */
-typedef struct _mongocrypt_ctx_t mongocrypt_ctx_t;
-
-
-/**
- * Create a new uninitialized @ref mongocrypt_ctx_t.
- *
- * Initialize the context with functions like @ref mongocrypt_ctx_encrypt_init.
- * When done, destroy it with @ref mongocrypt_ctx_destroy.
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @returns A new context.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_ctx_t *
-mongocrypt_ctx_new (mongocrypt_t *crypt);
-
-
-/**
- * Get the status associated with a @ref mongocrypt_ctx_t object.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[out] status Receives the status.
- *
- * @returns True if the output is an ok status, false if it is an error
- * status.
- *
- * @see mongocrypt_status_ok
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_status (mongocrypt_ctx_t *ctx, mongocrypt_status_t *status);
-
-
-/**
- * Set the key id to use for explicit encryption.
- *
- * It is an error to set both this and the key alt name.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] key_id The binary corresponding to the _id (a UUID) of the data
- * key to use from the key vault collection. Note, the UUID must be encoded with
- * RFC-4122 byte order. The viewed data is copied. It is valid to destroy
- * @p key_id with @ref mongocrypt_binary_destroy immediately after.
- * @pre @p ctx has not been initialized.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_key_id (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *key_id);
-
-/**
- * Set the keyAltName to use for explicit encryption or
- * data key creation.
- *
- * Pass the binary encoding a BSON document like the following:
- *
- * { "keyAltName" : (BSON UTF8 value) }
- *
- * For explicit encryption, it is an error to set both the keyAltName
- * and the key id.
- *
- * For creating data keys, call this function repeatedly to set
- * multiple keyAltNames.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] key_alt_name The name to use. The viewed data is copied. It is
- * valid to destroy @p key_alt_name with @ref mongocrypt_binary_destroy
- * immediately after.
- * @pre @p ctx has not been initialized.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_key_alt_name (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *key_alt_name);
-
-/**
- * Set the keyMaterial to use for encrypting data.
- *
- * Pass the binary encoding of a BSON document like the following:
- *
- * { "keyMaterial" : (BSON BINARY value) }
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] key_material The data encryption key to use. The viewed data is
- * copied. It is valid to destroy @p key_material with @ref
- * mongocrypt_binary_destroy immediately after.
- * @pre @p ctx has not been initialized.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_key_material (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *key_material);
-
-/**
- * Set the algorithm used for encryption to either
- * deterministic or random encryption. This value
- * should only be set when using explicit encryption.
- *
- * If -1 is passed in for "len", then "algorithm" is
- * assumed to be a null-terminated string.
- *
- * Valid values for algorithm are:
- * "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
- * "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] algorithm A string specifying the algorithm to
- * use for encryption.
- * @param[in] len The length of the algorithm string.
- * @pre @p ctx has not been initialized.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_algorithm (mongocrypt_ctx_t *ctx,
- const char *algorithm,
- int len);
-
-
-/**
- * Identify the AWS KMS master key to use for creating a data key.
- *
- * This has been superseded by the more flexible:
- * @ref mongocrypt_ctx_setopt_key_encryption_key
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] region The AWS region.
- * @param[in] region_len The string length of @p region. Pass -1 to determine
- * the string length with strlen (must be NULL terminated).
- * @param[in] cmk The Amazon Resource Name (ARN) of the customer master key
- * (CMK).
- * @param[in] cmk_len The string length of @p cmk_len. Pass -1 to determine the
- * string length with strlen (must be NULL terminated).
- * @pre @p ctx has not been initialized.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_masterkey_aws (mongocrypt_ctx_t *ctx,
- const char *region,
- int32_t region_len,
- const char *cmk,
- int32_t cmk_len);
-
-
-/**
- * Identify a custom AWS endpoint when creating a data key.
- * This is used internally to construct the correct HTTP request
- * (with the Host header set to this endpoint). This endpoint
- * is persisted in the new data key, and will be returned via
- * @ref mongocrypt_kms_ctx_endpoint.
- *
- * This has been superseded by the more flexible:
- * @ref mongocrypt_ctx_setopt_key_encryption_key
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] endpoint The endpoint.
- * @param[in] endpoint_len The string length of @p endpoint. Pass -1 to
- * determine the string length with strlen (must be NULL terminated).
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_masterkey_aws_endpoint (mongocrypt_ctx_t *ctx,
- const char *endpoint,
- int32_t endpoint_len);
-
-/**
- * Set the master key to "local" for creating a data key.
- * This has been superseded by the more flexible:
- * @ref mongocrypt_ctx_setopt_key_encryption_key
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @pre @p ctx has not been initialized.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_masterkey_local (mongocrypt_ctx_t *ctx);
-
-/**
- * Set key encryption key document for creating a data key.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] bin BSON representing the key encryption key document with
- * an additional "provider" field. The following forms are accepted:
- *
- * AWS
- * {
- * provider: "aws",
- * region: <string>,
- * key: <string>,
- * endpoint: <optional string>
- * }
- *
- * Azure
- * {
- * provider: "azure",
- * keyVaultEndpoint: <string>,
- * keyName: <string>,
- * keyVersion: <optional string>
- * }
- *
- * GCP
- * {
- * provider: "gcp",
- * projectId: <string>,
- * location: <string>,
- * keyRing: <string>,
- * keyName: <string>,
- * keyVersion: <string>,
- * endpoint: <optional string>
- * }
- *
- * Local
- * {
- * provider: "local"
- * }
- *
- * KMIP
- * {
- * provider: "kmip",
- * keyId: <optional string>
- * endpoint: <string>
- * }
- *
- * @pre @p ctx has not been initialized.
- * @returns A boolean indicating success. If false, and error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status.
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_setopt_key_encryption_key (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *bin);
-
-
-/**
- * Initialize a context to create a data key.
- *
- * Associated options:
- * - @ref mongocrypt_ctx_setopt_masterkey_aws
- * - @ref mongocrypt_ctx_setopt_masterkey_aws_endpoint
- * - @ref mongocrypt_ctx_setopt_masterkey_local
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- * @pre A master key option has been set, and an associated KMS provider
- * has been set on the parent @ref mongocrypt_t.
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_datakey_init (mongocrypt_ctx_t *ctx);
-
-/**
- * Initialize a context for encryption.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] db The database name.
- * @param[in] db_len The byte length of @p db. Pass -1 to determine the string
- * length with strlen (must
- * be NULL terminated).
- * @param[in] cmd The BSON command to be encrypted. The viewed data is copied.
- * It is valid to destroy @p cmd with @ref mongocrypt_binary_destroy immediately
- * after.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_encrypt_init (mongocrypt_ctx_t *ctx,
- const char *db,
- int32_t db_len,
- mongocrypt_binary_t *cmd);
-
-/**
- * Explicit helper method to encrypt a single BSON object. Contexts
- * created for explicit encryption will not go through mongocryptd.
- *
- * To specify a key_id, algorithm, or iv to use, please use the
- * corresponding mongocrypt_setopt methods before calling this.
- *
- * This method expects the passed-in BSON to be of the form:
- * { "v" : BSON value to encrypt }
- *
- * Associated options:
- * - @ref mongocrypt_ctx_setopt_key_id
- * - @ref mongocrypt_ctx_setopt_key_alt_name
- * - @ref mongocrypt_ctx_setopt_algorithm
- *
- * @param[in] ctx A @ref mongocrypt_ctx_t.
- * @param[in] msg A @ref mongocrypt_binary_t the plaintext BSON value. The
- * viewed data is copied. It is valid to destroy @p msg with @ref
- * mongocrypt_binary_destroy immediately after.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *msg);
-
-
-/**
- * Initialize a context for decryption.
- *
- * This method expects the passed-in BSON to be of the form:
- * { "v" : BSON value to encrypt }
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] doc The document to be decrypted. The viewed data is copied. It is
- * valid to destroy @p doc with @ref mongocrypt_binary_destroy immediately
- * after.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_decrypt_init (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *doc);
-
-
-/**
- * Explicit helper method to decrypt a single BSON object.
- *
- *
- * @param[in] ctx A @ref mongocrypt_ctx_t.
- * @param[in] msg A @ref mongocrypt_binary_t the encrypted BSON. The viewed data
- * is copied. It is valid to destroy @p msg with @ref mongocrypt_binary_destroy
- * immediately after.
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_explicit_decrypt_init (mongocrypt_ctx_t *ctx,
- mongocrypt_binary_t *msg);
-
-
-/**
- * Indicates the state of the @ref mongocrypt_ctx_t. Each state requires
- * different handling. See [the integration
- * guide](https://github.com/mongodb/libmongocrypt/blob/master/integrating.md#state-machine)
- * for information on what to do for each state.
- */
-typedef enum {
- MONGOCRYPT_CTX_ERROR = 0,
- MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1, /* run on main MongoClient */
- MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2, /* run on mongocryptd. */
- MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3, /* run on key vault */
- MONGOCRYPT_CTX_NEED_KMS = 4,
- MONGOCRYPT_CTX_READY = 5, /* ready for encryption/decryption */
- MONGOCRYPT_CTX_DONE = 6
-} mongocrypt_ctx_state_t;
-
-
-/**
- * Get the current state of a context.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @returns A @ref mongocrypt_ctx_state_t.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_ctx_state_t
-mongocrypt_ctx_state (mongocrypt_ctx_t *ctx);
-
-
-/**
- * Get BSON necessary to run the mongo operation when mongocrypt_ctx_t
- * is in MONGOCRYPT_CTX_NEED_MONGO_* states.
- *
- * @p op_bson is a BSON document to be used for the operation.
- * - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a listCollections filter.
- * - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a find filter.
- * - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a command to send to
- * mongocryptd.
- *
- * The lifetime of @p op_bson is tied to the lifetime of @p ctx. It is valid
- * until @ref mongocrypt_ctx_destroy is called.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[out] op_bson A BSON document for the MongoDB operation. The data
- * viewed by @p op_bson is guaranteed to be valid until @p ctx is destroyed with
- * @ref mongocrypt_ctx_destroy.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_mongo_op (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *op_bson);
-
-
-/**
- * Feed a BSON reply or result when mongocrypt_ctx_t is in
- * MONGOCRYPT_CTX_NEED_MONGO_* states. This may be called multiple times
- * depending on the operation.
- *
- * reply is a BSON document result being fed back for this operation.
- * - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a doc from a listCollections
- * cursor. (Note, if listCollections returned no result, do not call this
- * function.)
- * - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a doc from a find cursor.
- * (Note, if find returned no results, do not call this function. reply must
- * not
- * be NULL.)
- * - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a reply from mongocryptd.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @param[in] reply A BSON document for the MongoDB operation. The viewed data
- * is copied. It is valid to destroy @p reply with @ref
- * mongocrypt_binary_destroy immediately after.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_mongo_feed (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *reply);
-
-
-/**
- * Call when done feeding the reply (or replies) back to the context.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_mongo_done (mongocrypt_ctx_t *ctx);
-
-
-/**
- * Manages a single KMS HTTP request/response.
- */
-typedef struct _mongocrypt_kms_ctx_t mongocrypt_kms_ctx_t;
-
-
-/**
- * Get the next KMS handle.
- *
- * Multiple KMS handles may be retrieved at once. Drivers may do this to fan
- * out multiple concurrent KMS HTTP requests. Feeding multiple KMS requests
- * is thread-safe.
- *
- * If KMS handles are being handled synchronously, the driver can reuse the same
- * TLS socket to send HTTP requests and receive responses.
- *
- * @param[in] ctx A @ref mongocrypt_ctx_t.
- * @returns a new @ref mongocrypt_kms_ctx_t or NULL.
- */
-MONGOCRYPT_EXPORT
-mongocrypt_kms_ctx_t *
-mongocrypt_ctx_next_kms_ctx (mongocrypt_ctx_t *ctx);
-
-
-/**
- * Get the HTTP request message for a KMS handle.
- *
- * The lifetime of @p msg is tied to the lifetime of @p kms. It is valid
- * until @ref mongocrypt_ctx_kms_done is called.
- *
- * @param[in] kms A @ref mongocrypt_kms_ctx_t.
- * @param[out] msg The HTTP request to send to KMS. The data viewed by @p msg is
- * guaranteed to be valid until the call of @ref mongocrypt_ctx_kms_done of the
- * parent @ref mongocrypt_ctx_t.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_kms_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_kms_ctx_message (mongocrypt_kms_ctx_t *kms,
- mongocrypt_binary_t *msg);
-
-
-/**
- * Get the hostname from which to connect over TLS.
- *
- * The storage for @p endpoint is not owned by the caller, but
- * is valid until calling @ref mongocrypt_ctx_kms_done.
- *
- * @param[in] kms A @ref mongocrypt_kms_ctx_t.
- * @param[out] endpoint The output endpoint as a NULL terminated string.
- * The endpoint consists of a hostname and port separated by a colon.
- * E.g. "example.com:123". A port is always present.
- *
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_kms_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_kms_ctx_endpoint (mongocrypt_kms_ctx_t *kms, const char **endpoint);
-
-
-/**
- * Indicates how many bytes to feed into @ref mongocrypt_kms_ctx_feed.
- *
- * @param[in] kms The @ref mongocrypt_kms_ctx_t.
- * @returns The number of requested bytes.
- */
-MONGOCRYPT_EXPORT
-uint32_t
-mongocrypt_kms_ctx_bytes_needed (mongocrypt_kms_ctx_t *kms);
-
-
-/**
- * Feed bytes from the HTTP response.
- *
- * Feeding more bytes than what has been returned in @ref
- * mongocrypt_kms_ctx_bytes_needed is an error.
- *
- * @param[in] kms The @ref mongocrypt_kms_ctx_t.
- * @param[in] bytes The bytes to feed. The viewed data is copied. It is valid to
- * destroy @p bytes with @ref mongocrypt_binary_destroy immediately after.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_kms_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_kms_ctx_feed (mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes);
-
-
-/**
- * Get the status associated with a @ref mongocrypt_kms_ctx_t object.
- *
- * @param[in] kms The @ref mongocrypt_kms_ctx_t object.
- * @param[out] status Receives the status.
- *
- * @returns A boolean indicating success. If false, an error status is set.
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_kms_ctx_status (mongocrypt_kms_ctx_t *kms,
- mongocrypt_status_t *status);
-
-/**
- * Get the KMS provider identifier associated with this KMS request.
- *
- * This is used to conditionally configure TLS connections based on the KMS
- * request. It is useful for KMIP, which authenticates with a client
- * certificate.
- *
- * @param[in] kms The @ref mongocrypt_kms_ctx_t object.
- * @param[out] len Receives the length of the returned string. It may be NULL.
- * If it is not NULL, it is set to the length of the returned string without
- * the NULL terminator.
- *
- * @returns One of the NULL terminated static strings: "aws", "azure", "gcp", or
- * "kmip".
- */
-MONGOCRYPT_EXPORT
-const char *
-mongocrypt_kms_ctx_get_kms_provider (mongocrypt_kms_ctx_t *kms, uint32_t *len);
-
-
-/**
- * Call when done handling all KMS contexts.
- *
- * @param[in] ctx The @ref mongocrypt_ctx_t object.
- *
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_kms_done (mongocrypt_ctx_t *ctx);
-
-
-/**
- * Perform the final encryption or decryption.
- *
- * @param[in] ctx A @ref mongocrypt_ctx_t.
- * @param[out] out The final BSON. The data viewed by @p out is guaranteed
- * to be valid until @p ctx is destroyed with @ref mongocrypt_ctx_destroy.
- * The meaning of this BSON depends on the type of @p ctx.
- *
- * If @p ctx was initialized with @ref mongocrypt_ctx_encrypt_init, then
- * this BSON is the (possibly) encrypted command to send to the server.
- *
- * If @p ctx was initialized with @ref mongocrypt_ctx_decrypt_init, then
- * this BSON is the decrypted result to return to the user.
- *
- * If @p ctx was initialized with @ref mongocrypt_ctx_explicit_encrypt_init,
- * then this BSON has the form { "v": (BSON binary) } where the BSON binary
- * is the resulting encrypted value.
- *
- * If @p ctx was initialized with @ref mongocrypt_ctx_explicit_decrypt_init,
- * then this BSON has the form { "v": (BSON value) } where the BSON value
- * is the resulting decrypted value.
- *
- * If @p ctx was initialized with @ref mongocrypt_ctx_datakey_init, then
- * this BSON is the document containing the new data key to be inserted into
- * the key vault collection.
- *
- * @returns a bool indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_ctx_status
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_ctx_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);
-
-
-/**
- * Destroy and free all memory associated with a @ref mongocrypt_ctx_t.
- *
- * @param[in] ctx A @ref mongocrypt_ctx_t.
- */
-MONGOCRYPT_EXPORT
-void
-mongocrypt_ctx_destroy (mongocrypt_ctx_t *ctx);
-
-/**
- * An crypto AES-256-CBC encrypt or decrypt function.
- *
- * Note, @p in is already padded. Encrypt with padding disabled.
- * @param[in] ctx An optional context object that may have been set when hooks
- * were enabled.
- * @param[in] key An encryption key (32 bytes for AES_256).
- * @param[in] iv An initialization vector (16 bytes for AES_256);
- * @param[in] in The input.
- * @param[out] out A preallocated byte array for the output. See @ref
- * mongocrypt_binary_data.
- * @param[out] bytes_written Set this to the number of bytes written to @p out.
- * @param[out] status An optional status to pass error messages. See @ref
- * mongocrypt_status_set.
- * @returns A boolean indicating success. If returning false, set @p status
- * with a message indiciating the error using @ref mongocrypt_status_set.
- */
-typedef bool (*mongocrypt_crypto_fn) (void *ctx,
- mongocrypt_binary_t *key,
- mongocrypt_binary_t *iv,
- mongocrypt_binary_t *in,
- mongocrypt_binary_t *out,
- uint32_t *bytes_written,
- mongocrypt_status_t *status);
-
-/**
- * A crypto signature or HMAC function.
- *
- * Currently used in callbacks for HMAC SHA-512, HMAC SHA-256, and RSA SHA-256
- * signature.
- *
- * @param[in] ctx An optional context object that may have been set when hooks
- * were enabled.
- * @param[in] key An encryption key (32 bytes for HMAC_SHA512).
- * @param[in] in The input.
- * @param[out] out A preallocated byte array for the output. See @ref
- * mongocrypt_binary_data.
- * @param[out] status An optional status to pass error messages. See @ref
- * mongocrypt_status_set.
- * @returns A boolean indicating success. If returning false, set @p status
- * with a message indiciating the error using @ref mongocrypt_status_set.
- */
-typedef bool (*mongocrypt_hmac_fn) (void *ctx,
- mongocrypt_binary_t *key,
- mongocrypt_binary_t *in,
- mongocrypt_binary_t *out,
- mongocrypt_status_t *status);
-
-
-/**
- * A crypto hash (SHA-256) function.
- *
- * @param[in] ctx An optional context object that may have been set when hooks
- * were enabled.
- * @param[in] in The input.
- * @param[out] out A preallocated byte array for the output. See @ref
- * mongocrypt_binary_data.
- * @param[out] status An optional status to pass error messages. See @ref
- * mongocrypt_status_set.
- * @returns A boolean indicating success. If returning false, set @p status
- * with a message indiciating the error using @ref mongocrypt_status_set.
- */
-typedef bool (*mongocrypt_hash_fn) (void *ctx,
- mongocrypt_binary_t *in,
- mongocrypt_binary_t *out,
- mongocrypt_status_t *status);
-
-/**
- * A crypto secure random function.
- *
- * @param[in] ctx An optional context object that may have been set when hooks
- * were enabled.
- * @param[out] out A preallocated byte array for the output. See @ref
- * mongocrypt_binary_data.
- * @param[in] count The number of random bytes requested.
- * @param[out] status An optional status to pass error messages. See @ref
- * mongocrypt_status_set.
- * @returns A boolean indicating success. If returning false, set @p status
- * with a message indiciating the error using @ref mongocrypt_status_set.
- */
-typedef bool (*mongocrypt_random_fn) (void *ctx,
- mongocrypt_binary_t *out,
- uint32_t count,
- mongocrypt_status_t *status);
-
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_setopt_crypto_hooks (mongocrypt_t *crypt,
- mongocrypt_crypto_fn aes_256_cbc_encrypt,
- mongocrypt_crypto_fn aes_256_cbc_decrypt,
- mongocrypt_random_fn random,
- mongocrypt_hmac_fn hmac_sha_512,
- mongocrypt_hmac_fn hmac_sha_256,
- mongocrypt_hash_fn sha_256,
- void *ctx);
-
-/**
- * Set a crypto hook for the RSASSA-PKCS1-v1_5 algorithm with a SHA-256 hash.
- *
- * See: https://tools.ietf.org/html/rfc3447#section-8.2
- *
- * Note: this function has the wrong name. It should be:
- * mongocrypt_setopt_crypto_hook_sign_rsassa_pkcs1_v1_5
- *
- * @param[in] crypt The @ref mongocrypt_t object.
- * @param[in] sign_rsaes_pkcs1_v1_5 The crypto callback function.
- * @param[in] sign_ctx A context passed as an argument to the crypto callback
- * every invocation.
- * @pre @ref mongocrypt_init has not been called on @p crypt.
- * @returns A boolean indicating success. If false, an error status is set.
- * Retrieve it with @ref mongocrypt_status
- *
- */
-MONGOCRYPT_EXPORT
-bool
-mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 (
- mongocrypt_t *crypt,
- mongocrypt_hmac_fn sign_rsaes_pkcs1_v1_5,
- void *sign_ctx);
-
-#endif /* MONGOCRYPT_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/os_posix/os_dll.c b/mongodb-1.13.0/src/libmongocrypt/src/os_posix/os_dll.c
deleted file mode 100644
index 1c896a96..00000000
--- a/mongodb-1.13.0/src/libmongocrypt/src/os_posix/os_dll.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "../mongocrypt-dll-private.h"
-
-#ifndef _WIN32
-
-#include <string.h>
-#include <stdio.h>
-
-#include <dlfcn.h>
-
-mcr_dll
-mcr_dll_open (const char *filepath)
-{
- void *handle = dlopen (filepath, RTLD_LAZY | RTLD_LOCAL);
- if (handle == NULL) {
- // Failed to open. Return NULL and copy the error message
- return (mcr_dll){
- ._native_handle = NULL,
- .error_string = mstr_copy_cstr (dlerror ()),
- };
- } else {
- // Okay
- return (mcr_dll){
- ._native_handle = handle,
- .error_string = MSTR_NULL,
- };
- }
-}
-
-void
-mcr_dll_close_handle (mcr_dll dll)
-{
- if (dll._native_handle) {
- dlclose (dll._native_handle);
- }
-}
-
-void *
-mcr_dll_sym (mcr_dll dll, const char *sym)
-{
- return dlsym (dll._native_handle, sym);
-}
-
-#endif
diff --git a/mongodb-1.13.0/tests/ini/ini-mock_service_id-ini_get-001.phpt b/mongodb-1.13.0/tests/ini/ini-mock_service_id-ini_get-001.phpt
deleted file mode 100644
index 39384cc0..00000000
--- a/mongodb-1.13.0/tests/ini/ini-mock_service_id-ini_get-001.phpt
+++ /dev/null
@@ -1,13 +0,0 @@
---TEST--
-ini_get() reports mongodb.mock_service_id (default)
---FILE--
-<?php
-
-var_dump(ini_get('mongodb.mock_service_id'));
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECT--
-string(1) "0"
-===DONE===
diff --git a/mongodb-1.13.0/tests/ini/ini-mock_service_id-ini_get-002.phpt b/mongodb-1.13.0/tests/ini/ini-mock_service_id-ini_get-002.phpt
deleted file mode 100644
index 10823fc2..00000000
--- a/mongodb-1.13.0/tests/ini/ini-mock_service_id-ini_get-002.phpt
+++ /dev/null
@@ -1,18 +0,0 @@
---TEST--
-ini_get() reports mongodb.mock_service_id (master and local)
---INI--
-mongodb.mock_service_id=1
---FILE--
-<?php
-
-var_dump(ini_get('mongodb.mock_service_id'));
-ini_set('mongodb.mock_service_id', '0');
-var_dump(ini_get('mongodb.mock_service_id'));
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECT--
-string(1) "1"
-string(1) "0"
-===DONE===
diff --git a/mongodb-1.13.0/tests/ini/ini-mock_service_id-phpinfo-001.phpt b/mongodb-1.13.0/tests/ini/ini-mock_service_id-phpinfo-001.phpt
deleted file mode 100644
index 41452ec6..00000000
--- a/mongodb-1.13.0/tests/ini/ini-mock_service_id-phpinfo-001.phpt
+++ /dev/null
@@ -1,15 +0,0 @@
---TEST--
-phpinfo() reports mongodb.mock_service_id (default)
---FILE--
-<?php
-
-phpinfo();
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECTF--
-%a
-mongodb.mock_service_id => Off => Off
-%a
-===DONE===
diff --git a/mongodb-1.13.0/tests/ini/ini-mock_service_id-phpinfo-002.phpt b/mongodb-1.13.0/tests/ini/ini-mock_service_id-phpinfo-002.phpt
deleted file mode 100644
index 0c2275cf..00000000
--- a/mongodb-1.13.0/tests/ini/ini-mock_service_id-phpinfo-002.phpt
+++ /dev/null
@@ -1,21 +0,0 @@
---TEST--
-phpinfo() reports mongodb.mock_service_id (master and local)
---INI--
-mongodb.mock_service_id=1
---FILE--
-<?php
-
-/* Note: the master and local values for mongodb.mock_service_id are not
- * differentiated in phpinfo() output, since its value is only tracked by
- * mongoc_global_mock_service_id (DisplayMockServiceId). */
-ini_set('mongodb.mock_service_id', '0');
-phpinfo();
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECTF--
-%a
-mongodb.mock_service_id => Off => Off
-%a
-===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-createClientEncryption-001.phpt b/mongodb-1.13.0/tests/manager/manager-createClientEncryption-001.phpt
deleted file mode 100644
index 5321f70c..00000000
--- a/mongodb-1.13.0/tests/manager/manager-createClientEncryption-001.phpt
+++ /dev/null
@@ -1,18 +0,0 @@
---TEST--
-MongoDB\Driver\Manager::createClientEncryption()
---SKIPIF--
-<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
-<?php skip_if_not_libmongocrypt(); ?>
---FILE--
-<?php
-
-$key = base64_decode('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk');
-
-$manager = new MongoDB\Driver\Manager();
-$clientEncryption = $manager->createClientEncryption(['keyVaultNamespace' => 'default.keys', 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary($key, 0)]]]);
-
-?>
-===DONE===
-<?php exit(0); ?>
---EXPECT--
-===DONE===
diff --git a/mongodb-1.13.0/CONTRIBUTING.md b/mongodb-1.14.0/CONTRIBUTING.md
similarity index 98%
rename from mongodb-1.13.0/CONTRIBUTING.md
rename to mongodb-1.14.0/CONTRIBUTING.md
index 9063a665..9d16610e 100644
--- a/mongodb-1.13.0/CONTRIBUTING.md
+++ b/mongodb-1.14.0/CONTRIBUTING.md
@@ -1,467 +1,471 @@
# Contributing to the PHP Driver for MongoDB
## Building from Source
Developers who would like to contribute to the driver will need to build it from
source. The repository may be initialized with:
```
$ git clone https://github.com/mongodb/mongo-php-driver.git
$ cd mongo-php-driver
$ git submodule update --init
```
The following script may be used to build the driver:
```
#!/bin/sh
phpize > /dev/null && \
./configure --enable-mongodb-developer-flags > /dev/null && \
make clean > /dev/null && make all > /dev/null && make install
```
## Testing
The extension's test use the PHPT format from PHP internals. This format is
documented in the following links:
* [Introduction to PHPT Files](https://qa.php.net/write-test.php)
* [PHPT - Test File Layout](https://qa.php.net/phpt_details.php)
Generally, most tests will be based on the following template:
```
--TEST--
Description of API or JIRA issue being tested
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php /* One or more skip functions */ ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
// Test code
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
===DONE===
```
The `basic-skipif.inc` and `basic.inc` files contain utility functions for the
`SKIPIF` and `FILE` sections, respectively. If those functions are not needed
(e.g. skip logic only depends on checking the `PHP_INT_SIZE` constant), the test
should not include the file. When it doubt, keep it simple.
### Best Practices for `SKIPIF`
The [`skipif.php`](tests/utils/skipif.php) file defines various helper functions
for use within a test's [`SKIPIF`](https://qa.php.net/phpt_details.php#skipif_section)
section. When multiple functions are used in a single `SKIPIF` section, they
should be logically ordered:
* Any PHP environment requirements should be checked first. For example, if a
test requires a 64-bit architecture, start by checking `PHP_INT_SIZE` before
anything else.
* Any extension build requirements (e.g. `skip_if_not_libmongoc_crypto()`) or
test environment requirements (e.g. `skip_if_auth()`) should then be checked.
These functions only examine local information, such as `phpinfo()` output or
the structure of the `URI` constant, and do not interact with a remote
MongoDB server.
* Any remote server requirements should then be checked. A general integration
test that requires any type of remote server to be accessible might use
`skip_if_not_live()` while a test requiring a replica set would prefer
`skip_if_not_replica_set()`.
* After requiring a remote server to be accessible (optionally with a specific
type), you can enforce requirements about that server. This includes checking
its server version, storage engine, availability of test commands, etc.
* Finally, use `skip_if_not_clean()` if needed to ensure that the collection(s)
under test are dropped before the test runs.
As a rule of thumb, your `SKIPIF` logic should be written to allow the test to
run in as many environments as possible. To paraphrase the
[robustness principal](https://en.wikipedia.org/wiki/Robustness_principle):
> Be conservative in what/how you test, and liberal in what environment you require
Consider that a well-crafted `EXPECTF` section may allow a `SKIPIF` section to
be less restrictive.
### Environment Variables
The test suite references the following environment variables:
* `MONGODB_URI`: Connection string. Defaults to `mongodb://127.0.0.1/`, which
assumes a MongoDB server is listening localhost port 27017.
* `MONGO_ORCHESTRATION_URI`: API endpoint for Mongo Orchestration. Defaults to
`http://localhost:8889/v1`. This is only used by a few tests that start
temporary servers, and those tests will be skipped if Mongo Orchestration is
inaccessible.
* `MONGODB_DATABASE`: Default database to use in tests. Defaults to `phongo`.
* `SSL_DIR`: Path to directory containing certificate files. On Evergreen, this
will be set to the
[.evergreen/x509gen](https://github.com/mongodb-labs/drivers-evergreen-tools/tree/master/.evergreen/x509gen)
directory within
[drivers-evergreen-tools](https://github.com/mongodb-labs/drivers-evergreen-tools).
If undefined or inaccessible, tests requiring certificates will be skipped.
* `API_VERSION`: If defined, this value will be used to construct a
[`MongoDB\Driver\ServerApi`](https://www.php.net/manual/en/mongodb-driver-serverapi.construct.php),
which will then be specified as the `serverApi` driver option for
[`MongoDB\Driver\Manager`](https://www.php.net/manual/en/class.mongodb-driver-manager.php)
objects created by the test suite.
+ * `CRYPT_SHARED_LIB_PATH`: If defined, this value will be used to set the
+ `cryptSharedLibPath` autoEncryption driver option for
+ [`MongoDB\Driver\Manager`](https://www.php.net/manual/en/class.mongodb-driver-manager.php)
+ objects created by the test suite.
### Mongo Orchestration
[Mongo Orchestration](https://github.com/10gen/mongo-orchestration) is an HTTP
server that provides a REST API for managing MongoDB servers and clusters.
Evergreen CI and GitHub Actions use configurations provided by the
[drivers-evergreen-tools](https://github.com/mongodb-labs/drivers-evergreen-tools)
repository. These configurations are loaded by Mongo Orchestration, which then
provides a connection string to assign to `MONGODB_URI` and run the test suite.
Additionally, some tests start temporary servers and interact directly with
Mongo Orchestration (via `MONGO_ORCHESTRATION_URI`).
For local development, running Mongo Orchestration is not required and it is
generally sufficient to test against a single-node replica set.
## Updating libmongoc, libbson, and libmongocrypt
The PHP driver can use either system libraries or bundled versions of
libmongoc, libbson, and libmongocrypt. If a new version of either library is
available, the submodule and build configuration will need to be updated to
reflect the new sources and/or package version.
### Updating libmongoc and libbson
#### Update libmongoc submodule
```
$ cd src/libmongoc
$ git fetch
$ git checkout 1.20.0
```
During development, it may be necessary to temporarily point the libmongoc
submodule to a commit on the developer's fork of libmongoc. For instance, the
developer may be working on a PHP driver feature that depends on an unmerged
pull request to libmongoc. In this case, `git remote add` can be used to add
the fork before fetching and checking out the target commit. Additionally, the
submodule path in
[`.gitmodules`](https://github.com/mongodb/mongo-php-driver/blob/master/.gitmodules)
must also be updated to refer to the fork.
#### Ensure libmongoc version information is correct
The build process for Autotools and Windows rely on
`src/LIBMONGOC_VERSION_CURRENT` to infer version information for libmongoc and
libbson. This file can be regenerated using the following Makefile target:
```
$ make libmongoc-version-current
```
Alternatively, the `build/calc_release_version.py` script in libmongoc can be
executed directly.
Note: If the libmongoc submodule points to a non-release, non-master branch, the
script may fail to correctly detect the version. This issue is being tracked in
[CDRIVER-3315](https://jira.mongodb.org/browse/CDRIVER-3315) and can be safely
ignored since this should only happen during development (any PHP driver release
should point to a tagged libmongoc release).
#### Update sources in build configurations
The Autotools and Windows build configurations (`config.m4` and `config.w32`,
respectively) define several variables (e.g. `PHP_MONGODB_MONGOC_SOURCES`) that
collectively enumerate all of the the sources within the libmongoc submodule to
include in a bundled build.
These variables should each have a shell command in a preceding comment, which
should be run to regenerate that particular list of source files. Each command
may be run manually or `scripts/update-submodule-sources.php` may be used to
update all variables. In the event that either libmongoc or libbson introduce a
new source directory, that will need to be manually added (follow prior art).
#### Update package dependencies
The Autotools configuration additionally includes some `pkg-config` commands for
using libmongoc and libbson as system libraries (in lieu of a bundled build).
When bumping the libmongoc version, be sure to update the version check _and_
error message in the `pkg-config` blocks for both libmongoc and libbson.
For example, the following lines might be updated for libmongoc:
```
if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.20.0; then
...
AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.20.0)
```
#### Update tested versions in Evergreen configuration
Evergreen tests against multiple versions of libmongoc. When updating to a newer
libmongoc version, make sure to update the `libmongoc-version` build axis in
`.evergreen/config.yml`. In general, we test against two additional versions of
libmongoc:
- The upcoming patch release of the current libmongoc minor version (e.g. the
`r1.x` branch)
- The upcoming minor release of libmongoc (e.g. the `master` branch)
#### Update sources in PECL package generation script
If either libmongoc or libbson introduce a new source directory, that may also
require updating the glob patterns in the `bin/prep-release.php` script to
ensure new source files will be included in any generated PECL package.
#### Test and commit your changes
Verify that the upgrade was successful by ensuring that the driver can compile
using both the bundled sources and system libraries for libmongoc and libbson,
and by ensuring that the test suite passes. Once done, commit the changes to all
of the above files/paths. For example:
```
$ git commit -m "Bump libmongoc to 1.20.0" config.m4 config.w32 src/libmongoc src/LIBMONGOC_VERSION_CURRENT
```
### Updating libmongocrypt
To update libmongocrypt, the steps are similar to the above:
```
$ cd src/libmongocrypt
$ git fetch
$ git checkout 1.3.0
$ make libmongocrypt-version-current
```
Package dependencies in `config.m4` must also be updated (either manually or
with `scripts/update-submodule-sources.php`), as do the sources in the PECL
generation script.
## Releasing
The follow steps outline the release process for a maintenance branch (e.g.
releasing the `vX.Y` branch as X.Y.Z).
### Ensure PHP version compatibility
Ensure that the library test suite completes on supported versions of PHP.
### Ensure Windows compatibility
PECL will create Windows DLLs for new releases; however, you must ensure that
the extension successfully builds on Windows before releasing. Windows builds
are tested by [AppVeyor](.appveyor.yml).
See the [internals wiki](https://wiki.php.net/internals/windows/stepbystepbuild)
for more information.
### Transition JIRA issues and version
All issues associated with the release version should be in the "Closed" state
and have a resolution of "Fixed". Issues with other resolutions (e.g.
"Duplicate", "Works as Designed") should be removed from the release version so
that they do not appear in the release notes.
Check the corresponding ".x" fix version to see if it contains any issues that
are resolved as "Fixed" and should be included in this release version.
Update the version's release date and status from the
[Manage Versions](https://jira.mongodb.org/plugins/servlet/project-config/PHPC/versions)
page.
### Update version info
The PHP driver uses [semantic versioning](http://semver.org/). Do not break
backwards compatibility in a non-major release or your users will kill you.
Before proceeding, ensure that the `master` branch is up-to-date with all code
changes in this maintenance branch. This is important because we will later
merge the ensuing release commits up to master with `--strategy=ours`, which
will ignore changes from the merged commits.
Update the version and stability constants in `phongo_version.h`. This should
entail removing the version's "-dev" suffix, changing the stability to
"stable", and increasing the last digit for `PHP_MONGO_VERSION_DESC`:
```
#define PHP_MONGODB_VERSION "1.1.8-dev"
#define PHP_MONGODB_STABILITY "devel"
#define PHP_MONGODB_VERSION_DESC 1,1,8,0
```
The above would be changed to:
```
#define PHP_MONGODB_VERSION "1.1.8"
#define PHP_MONGODB_STABILITY "stable"
#define PHP_MONGODB_VERSION_DESC 1,1,8,1
```
The Makefile targets for creating the PECL package depend on these constants, so
you must rebuild the extension after updating `phongo_version.h`.
> **Note:** If this is an alpha or beta release, the version string should
> include the X.Y.Z version followed by the stability and an increment. For
> instance, the first beta release in the 1.4.0 series would be "1.4.0beta1".
> Alpha and beta releases use "alpha" and "beta" stability strings,
> respectively. Release candidates (e.g. "1.4.0RC1") also use "beta" stability.
> See [Documenting release stability and API stability](https://pear.php.net/manual/en/guide.developers.package2.stability.php)
> for more information. For each change to the suffixes of
> `PHP_MONGODB_VERSION`, increment the last digit of
> `PHP_MONGODB_VERSION_DESC`.
### Build PECL package
Create the PECL package description file with `make package.xml`. This creates
a `package.xml` file from a template. Version, author, and file information will
be filled in, but release notes must be copied manually from JIRA.
After copying release notes, use `make package` to create the package file (e.g.
`mongodb-X.Y.Z.tgz`) and ensure that it can be successfully installed:
```
$ pecl install -f mongodb-X.Y.Z.tgz
```
### Commit version update and release notes
Commit the modified `phongo_version.h` file as "Package X.Y.Z"
```
$ git add phongo_version.h
$ git commit -m "Package X.Y.Z"
```
### Tag release
The previous commit will be the target for our release tag:
```
$ git tag -a -m "Release X.Y.Z" X.Y.Z
```
### Update version info back to dev
After tagging, the version and stability constants in `phongo_version.h` should be
updated back to development status.
```
#define PHP_MONGODB_VERSION "1.1.8"
#define PHP_MONGODB_STABILITY "stable"
#define PHP_MONGODB_VERSION_DESC 1,1,8,1
```
The above would be changed to:
```
#define PHP_MONGODB_VERSION "1.1.9-dev"
#define PHP_MONGODB_STABILITY "devel"
#define PHP_MONGODB_VERSION_DESC 1,1,9,0
```
Commit this change:
```
$ git commit -m "Back to -dev" phongo_version.h
```
> **Note:** If this is an alpha, beta, or RC release, the version string should
> increment the stability sequence instead of the patch version. For example,
> if the constants were originally "1.4.0-dev" and "devel" and then changed to
> "1.4.0beta1" and "beta" for the first beta release, this step would see them
> ultimately changed to "1.4.0beta2-dev" and "devel".
### Push commits and tags
```
$ git push
$ git push --tags
```
### Release PECL package
The PECL package may be published via the
[Release Upload](https://pecl.php.net/release-upload.php) form. You will have
one chance to confirm the package information after uploading.
### Merge the maintenance branch up to master
```
$ git checkout master
$ git merge vX.Y --strategy=ours
$ git push
```
The `--strategy=ours` option ensures that all changes from the merged commits
will be ignored.
### Publish release notes
The following template should be used for creating GitHub release notes via
[this form](https://github.com/mongodb/mongo-php-driver/releases/new). The PECL
package may also be attached to the release notes.
```
The PHP team is happy to announce that version X.Y.Z of the [mongodb](https://pecl.php.net/package/mongodb) PHP extension is now available on PECL.
**Release Highlights**
<one or more paragraphs describing important changes in this release>
A complete list of resolved issues in this release may be found at:
$JIRA_URL
**Documentation**
Documentation is available on PHP.net:
https://www.php.net/set.mongodb
**Installation**
You can either download and install the source manually, or you can install the extension with:
pecl install mongodb-X.Y.Z
or update with:
pecl upgrade mongodb-X.Y.Z
Windows binaries are available on PECL:
https://pecl.php.net/package/mongodb
```
> **Note:** If this is an alpha or beta release, the installation examples
> should refer to the exact version (e.g. "mongodb-1.8.0beta2"). This is necessary
> because PECL prioritizes recent, stable releases over any stability preferences
> (e.g. "mongodb-beta").
The URL for the list of resolved JIRA issues will need to be updated with each
release. You may obtain the list from
[this form](https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=12484).
If commits from community contributors were included in this release, append the
following section:
```
**Thanks**
Thanks for our community contributors for X.Y.Z:
* [$CONTRIBUTOR_NAME](https://github.com/$GITHUB_USERNAME)
```
Release announcements should also be posted in the [MongoDB Product & Driver Announcements: Driver Releases](https://www.mongodb.com/community/forums/tags/c/announcements/driver-releases/110/php) forum and shared on Twitter.
### Update compatibility tables in MongoDB docs
For minor releases, create a DOCSP ticket indicating whether there are changes to MongoDB Server or PHP version
compatibility. The [compatibility tables](https://docs.mongodb.com/drivers/driver-compatibility-reference#php-driver-compatibility)
in the MongoDB documentation must be updated to account for new releases. Make sure to update both MongoDB and Language
compatibility tables, as shown in [this pull request](https://github.com/mongodb/docs-ecosystem/pull/642).
diff --git a/mongodb-1.13.0/CREDITS b/mongodb-1.14.0/CREDITS
similarity index 100%
rename from mongodb-1.13.0/CREDITS
rename to mongodb-1.14.0/CREDITS
diff --git a/mongodb-1.13.0/LICENSE b/mongodb-1.14.0/LICENSE
similarity index 100%
rename from mongodb-1.13.0/LICENSE
rename to mongodb-1.14.0/LICENSE
diff --git a/mongodb-1.13.0/Makefile.frag b/mongodb-1.14.0/Makefile.frag
similarity index 100%
rename from mongodb-1.13.0/Makefile.frag
rename to mongodb-1.14.0/Makefile.frag
diff --git a/mongodb-1.13.0/README.md b/mongodb-1.14.0/README.md
similarity index 100%
rename from mongodb-1.13.0/README.md
rename to mongodb-1.14.0/README.md
diff --git a/mongodb-1.13.0/THIRD_PARTY_NOTICES b/mongodb-1.14.0/THIRD_PARTY_NOTICES
similarity index 100%
rename from mongodb-1.13.0/THIRD_PARTY_NOTICES
rename to mongodb-1.14.0/THIRD_PARTY_NOTICES
diff --git a/mongodb-1.13.0/Vagrantfile b/mongodb-1.14.0/Vagrantfile
similarity index 100%
rename from mongodb-1.13.0/Vagrantfile
rename to mongodb-1.14.0/Vagrantfile
diff --git a/mongodb-1.13.0/config.m4 b/mongodb-1.14.0/config.m4
similarity index 96%
rename from mongodb-1.13.0/config.m4
rename to mongodb-1.14.0/config.m4
index 2a0e97a5..454f57c0 100644
--- a/mongodb-1.13.0/config.m4
+++ b/mongodb-1.14.0/config.m4
@@ -1,560 +1,559 @@
dnl config.m4 for extension mongodb
PHP_ARG_ENABLE([mongodb],
[whether to enable MongoDB support],
[AS_HELP_STRING([--enable-mongodb],
[Enable MongoDB support])])
if test "$PHP_MONGODB" != "no"; then
dnl Check PHP version is compatible with this extension
AC_MSG_CHECKING([PHP version])
PHP_MONGODB_PHP_VERSION=$PHP_VERSION
PHP_MONGODB_PHP_VERSION_ID=$PHP_VERSION_ID
if test -z "$PHP_MONGODB_PHP_VERSION"; then
if test -z "$PHP_CONFIG"; then
AC_MSG_ERROR([php-config not found])
fi
PHP_MONGODB_PHP_VERSION=`${PHP_CONFIG} --version`
PHP_MONGODB_PHP_VERSION_ID=`echo "${PHP_MONGODB_PHP_VERSION}" | $AWK 'BEGIN { FS = "."; } { printf "%d", ([$]1 * 100 + [$]2) * 100 + [$]3;}'`
fi
AC_MSG_RESULT($PHP_MONGODB_PHP_VERSION)
if test "$PHP_MONGODB_PHP_VERSION_ID" -lt "70200"; then
AC_MSG_ERROR([not supported. Need a PHP version >= 7.2.0 (found $PHP_MONGODB_PHP_VERSION)])
fi
PHP_ARG_ENABLE([mongodb-developer-flags],
[whether to enable developer build flags],
[AS_HELP_STRING([--enable-mongodb-developer-flags],
[MongoDB: Enable developer flags [default=no]])],
[no],
[no])
if test "$PHP_MONGODB_DEVELOPER_FLAGS" = "yes"; then
dnl Warn about functions which might be candidates for format attributes
AX_CHECK_COMPILE_FLAG(-Wmissing-format-attribute, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wmissing-format-attribute" ,, -Werror)
dnl Avoid duplicating values for an enum
AX_CHECK_COMPILE_FLAG(-Wduplicate-enum, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wduplicate-enum" ,, -Werror)
dnl Warns on mismatches between #ifndef and #define header guards
AX_CHECK_COMPILE_FLAG(-Wheader-guard, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wheader-guard" ,, -Werror)
dnl logical not of a non-boolean expression
AX_CHECK_COMPILE_FLAG(-Wlogical-not-parentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-not-parentheses" ,, -Werror)
dnl Warn about suspicious uses of logical operators in expressions
AX_CHECK_COMPILE_FLAG(-Wlogical-op, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-op" ,, -Werror)
dnl memory error detector.
dnl FIXME: -fsanitize=address,undefined for clang. The AX_CHECK_COMPILE_FLAG macro isn't happy about that string :(
AX_CHECK_COMPILE_FLAG(-fsanitize-address, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fsanitize-address" ,, -Werror)
dnl Enable frame debugging
AX_CHECK_COMPILE_FLAG(-fno-omit-frame-pointer, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-omit-frame-pointer" ,, -Werror)
dnl Make sure we don't optimize calls
AX_CHECK_COMPILE_FLAG(-fno-optimize-sibling-calls, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-optimize-sibling-calls" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wlogical-op-parentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-op-parentheses" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wpointer-bool-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wpointer-bool-conversion" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wbool-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wbool-conversion" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wloop-analysis, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wloop-analysis" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wsizeof-array-argument, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wsizeof-array-argument" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wstring-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wstring-conversion" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wno-variadic-macros, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-variadic-macros" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wno-sign-compare, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-sign-compare" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-fstack-protector, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fstack-protector" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-fno-exceptions, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-exceptions" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wformat-security, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wformat-security" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wformat-nonliteral, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wformat-nonliteral" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Winit-self, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Winit-self" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wwrite-strings, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wwrite-strings" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wenum-compare, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wenum-compare" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wempty-body, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wempty-body" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wparentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wparentheses" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wdeclaration-after-statement, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wdeclaration-after-statement" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wmaybe-uninitialized, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wmaybe-uninitialized" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wimplicit-fallthrough, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wimplicit-fallthrough" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Werror, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Werror" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wextra, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wextra" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wno-unused-parameter, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-unused-parameter" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wno-unused-but-set-variable, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-unused-but-set-variable" ,, -Werror)
AX_CHECK_COMPILE_FLAG(-Wno-missing-field-initializers, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-missing-field-initializers",, -Werror)
MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS"
STD_CFLAGS="-g -O0 -Wall"
fi
PHP_ARG_ENABLE([mongodb-coverage],
[whether to enable code coverage],
[AS_HELP_STRING([--enable-mongodb-coverage],
[MongoDB: Enable developer code coverage information [default=no]])],
[no],
[no])
if test "$PHP_MONGODB_COVERAGE" = "yes"; then
if test "$ext_shared" != "yes"; then
AC_MSG_ERROR(code coverage is not supported for static builds)
fi
COVERAGE_CFLAGS="--coverage -g"
COVERAGE_LDFLAGS="--coverage"
MONGODB_SHARED_LIBADD="$MONGODB_SHARED_LIBADD $COVERAGE_LDFLAGS"
fi
PHP_MONGODB_CFLAGS="$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS"
PHP_MONGODB_SOURCES="\
php_phongo.c \
src/phongo_apm.c \
src/phongo_bson.c \
src/phongo_bson_encode.c \
src/phongo_client.c \
src/phongo_compat.c \
src/phongo_error.c \
src/phongo_execute.c \
src/phongo_ini.c \
src/phongo_util.c \
src/BSON/Binary.c \
src/BSON/BinaryInterface.c \
src/BSON/DBPointer.c \
src/BSON/Decimal128.c \
src/BSON/Decimal128Interface.c \
src/BSON/Int64.c \
src/BSON/Javascript.c \
src/BSON/JavascriptInterface.c \
src/BSON/MaxKey.c \
src/BSON/MaxKeyInterface.c \
src/BSON/MinKey.c \
src/BSON/MinKeyInterface.c \
src/BSON/ObjectId.c \
src/BSON/ObjectIdInterface.c \
src/BSON/Persistable.c \
src/BSON/Regex.c \
src/BSON/RegexInterface.c \
src/BSON/Serializable.c \
src/BSON/Symbol.c \
src/BSON/Timestamp.c \
src/BSON/TimestampInterface.c \
src/BSON/Type.c \
src/BSON/Undefined.c \
src/BSON/Unserializable.c \
src/BSON/UTCDateTime.c \
src/BSON/UTCDateTimeInterface.c \
src/BSON/functions.c \
src/MongoDB/BulkWrite.c \
src/MongoDB/ClientEncryption.c \
src/MongoDB/Command.c \
src/MongoDB/Cursor.c \
src/MongoDB/CursorId.c \
src/MongoDB/CursorInterface.c \
src/MongoDB/Manager.c \
src/MongoDB/Query.c \
src/MongoDB/ReadConcern.c \
src/MongoDB/ReadPreference.c \
src/MongoDB/Server.c \
src/MongoDB/ServerApi.c \
src/MongoDB/ServerDescription.c \
src/MongoDB/Session.c \
src/MongoDB/TopologyDescription.c \
src/MongoDB/WriteConcern.c \
src/MongoDB/WriteConcernError.c \
src/MongoDB/WriteError.c \
src/MongoDB/WriteResult.c \
src/MongoDB/Exception/AuthenticationException.c \
src/MongoDB/Exception/BulkWriteException.c \
src/MongoDB/Exception/CommandException.c \
src/MongoDB/Exception/ConnectionException.c \
src/MongoDB/Exception/ConnectionTimeoutException.c \
src/MongoDB/Exception/EncryptionException.c \
src/MongoDB/Exception/Exception.c \
src/MongoDB/Exception/ExecutionTimeoutException.c \
src/MongoDB/Exception/InvalidArgumentException.c \
src/MongoDB/Exception/LogicException.c \
src/MongoDB/Exception/RuntimeException.c \
src/MongoDB/Exception/ServerException.c \
src/MongoDB/Exception/SSLConnectionException.c \
src/MongoDB/Exception/UnexpectedValueException.c \
src/MongoDB/Exception/WriteException.c \
src/MongoDB/Monitoring/CommandFailedEvent.c \
src/MongoDB/Monitoring/CommandStartedEvent.c \
src/MongoDB/Monitoring/CommandSubscriber.c \
src/MongoDB/Monitoring/CommandSucceededEvent.c \
src/MongoDB/Monitoring/SDAMSubscriber.c \
src/MongoDB/Monitoring/Subscriber.c \
src/MongoDB/Monitoring/ServerChangedEvent.c \
src/MongoDB/Monitoring/ServerClosedEvent.c \
src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.c \
src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.c \
src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.c \
src/MongoDB/Monitoring/ServerOpeningEvent.c \
src/MongoDB/Monitoring/TopologyChangedEvent.c \
src/MongoDB/Monitoring/TopologyClosedEvent.c \
src/MongoDB/Monitoring/TopologyOpeningEvent.c \
src/MongoDB/Monitoring/functions.c \
"
PHP_ARG_WITH([mongodb-system-libs],
[whether to compile against system libraries instead of bundled],
[AS_HELP_STRING([--with-mongodb-system-libs=@<:@yes/no@:>@],
[MongoDB: Use system libraries for libbson, libmongoc, and libmongocrypt [default=no]])],
[no],
[no])
PHP_ARG_WITH([libbson],
[whether to use system libbson],
[AS_HELP_STRING([--with-libbson=@<:@yes/no@:>@],
[MongoDB: Use system libbson [default=no]])],
[no],
[no])
PHP_ARG_WITH([libmongoc],
[whether to use system libmongoc],
[AS_HELP_STRING([--with-libmongoc=@<:@yes/no@:>@],
[MongoDB: Use system libmongoc [default=no]])],
[no],
[no])
PHP_ARG_WITH([mongodb-client-side-encryption],
[whether to enable client-side encryption],
[AS_HELP_STRING([--with-mongodb-client-side-encryption=@<:@auto/yes/no@:>@],
[MongoDB: Enable client-side encryption [default=auto]])],
[auto],
[no])
if test "$PHP_LIBBSON" != "no"; then
AC_MSG_WARN(Using --with-libbson is deprecated and will be removed in a future version. Please use --with-system-libs instead)
if test "$PHP_LIBMONGOC" = "no"; then
AC_MSG_ERROR(Cannot use system libbson and bundled libmongoc)
fi
PHP_MONGODB_SYSTEM_LIBS="yes"
fi
if test "$PHP_LIBMONGOC" != "no"; then
AC_MSG_WARN(Using --with-libmongoc is deprecated and will be removed in a future version. Please use --with-system-libs instead)
if test "$PHP_LIBBSON" = "no"; then
AC_MSG_ERROR(Cannot use system libmongoc and bundled libbson)
fi
PHP_MONGODB_SYSTEM_LIBS="yes"
fi
PHP_MONGODB_BSON_VERSION_STRING="None"
PHP_MONGODB_MONGOC_VERSION_STRING="None"
PHP_MONGODB_MONGOCRYPT_VERSION_STRING="None"
if test "$PHP_MONGODB_SYSTEM_LIBS" != "no"; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
AC_MSG_CHECKING(for libbson)
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libbson-1.0; then
- if $PKG_CONFIG libbson-1.0 --atleast-version 1.21.1; then
+ if $PKG_CONFIG libbson-1.0 --atleast-version 1.22.0; then
PHP_MONGODB_BSON_CFLAGS=`$PKG_CONFIG libbson-1.0 --cflags`
PHP_MONGODB_BSON_LIBS=`$PKG_CONFIG libbson-1.0 --libs`
PHP_MONGODB_BSON_VERSION=`$PKG_CONFIG libbson-1.0 --modversion`
PHP_MONGODB_BSON_VERSION_STRING="System ($PHP_MONGODB_BSON_VERSION)"
AC_MSG_RESULT(version $PHP_MONGODB_BSON_VERSION found)
else
- AC_MSG_ERROR(system libbson must be upgraded to version >= 1.21.1)
+ AC_MSG_ERROR(system libbson must be upgraded to version >= 1.22.0)
fi
else
AC_MSG_ERROR(pkgconfig and libbson must be installed)
fi
PHP_MONGODB_CFLAGS="$PHP_MONGODB_CFLAGS $PHP_MONGODB_BSON_CFLAGS"
PHP_EVAL_LIBLINE($PHP_MONGODB_BSON_LIBS, MONGODB_SHARED_LIBADD)
AC_DEFINE(HAVE_SYSTEM_LIBBSON, 1, [Use system libbson])
AC_MSG_CHECKING(for libmongoc)
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmongoc-1.0; then
- if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.21.1; then
+ if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.22.0; then
PHP_MONGODB_MONGOC_CFLAGS=`$PKG_CONFIG libmongoc-1.0 --cflags`
PHP_MONGODB_MONGOC_LIBS=`$PKG_CONFIG libmongoc-1.0 --libs`
PHP_MONGODB_MONGOC_VERSION=`$PKG_CONFIG libmongoc-1.0 --modversion`
PHP_MONGODB_MONGOC_VERSION_STRING="System ($PHP_MONGODB_MONGOC_VERSION)"
AC_MSG_RESULT(version $PHP_MONGODB_MONGOC_VERSION found)
else
- AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.21.1)
+ AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.22.0)
fi
else
AC_MSG_ERROR(pkgconfig and libmongoc must be installed)
fi
PHP_MONGODB_CFLAGS="$PHP_MONGODB_CFLAGS $PHP_MONGODB_MONGOC_CFLAGS"
PHP_EVAL_LIBLINE($PHP_MONGODB_MONGOC_LIBS, MONGODB_SHARED_LIBADD)
AC_DEFINE(HAVE_SYSTEM_LIBMONGOC, 1, [Use system libmongoc])
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" != "no"; then
AC_MSG_CHECKING(for libmongocrypt)
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmongocrypt; then
- if $PKG_CONFIG libmongocrypt --atleast-version 1.3.2; then
+ if $PKG_CONFIG libmongocrypt --atleast-version 1.5.0; then
PHP_MONGODB_MONGOCRYPT_CFLAGS=`$PKG_CONFIG libmongocrypt --cflags`
PHP_MONGODB_MONGOCRYPT_LIBS=`$PKG_CONFIG libmongocrypt --libs`
PHP_MONGODB_MONGOCRYPT_VERSION=`$PKG_CONFIG libmongocrypt --modversion`
PHP_MONGODB_MONGOCRYPT_VERSION_STRING="System ($PHP_MONGODB_MONGOCRYPT_VERSION)"
AC_MSG_RESULT(version $PHP_MONGODB_MONGOCRYPT_VERSION found)
PHP_MONGODB_CFLAGS="$PHP_MONGODB_CFLAGS $PHP_MONGODB_MONGOCRYPT_CFLAGS"
PHP_EVAL_LIBLINE($PHP_MONGODB_MONGOCRYPT_LIBS, MONGODB_SHARED_LIBADD)
AC_DEFINE(HAVE_SYSTEM_LIBMONGOCRYPT, 1, [Use system libmongocrypt])
elif test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
- AC_MSG_ERROR(system libmongocrypt must be upgraded to version >= 1.3.2)
+ AC_MSG_ERROR(system libmongocrypt must be upgraded to version >= 1.5.0)
else
AC_MSG_RESULT(found an older version, compiling without client-side encryption)
fi
else
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
AC_MSG_ERROR(pkgconfig and libmongocrypt must be installed)
else
AC_MSG_RESULT(not found, compiling without client-side encryption)
fi
fi
fi
fi
if test "$PHP_MONGODB_SYSTEM_LIBS" = "no"; then
PHP_MONGODB_BUNDLED_CFLAGS="$STD_CFLAGS -DBSON_COMPILATION -DMONGOC_COMPILATION"
dnl TODO: MONGOCRYPT-219 makes the -std argument obsolete
PHP_MONGODB_LIBMONGOCRYPT_CFLAGS="-DKMS_MSG_STATIC -DMLIB_USER -std=gnu99"
PHP_MONGODB_ZLIB_CFLAGS=""
dnl M4 doesn't know if we're building statically or as a shared module, so
dnl attempt to include both paths while ignoring errors. If neither path
dnl exists, report an error during configure (this is later than M4 parsing
dnl during phpize but better than nothing).
m4_pushdef([_include],[
dnl TODO: Fix this for PECL install (PHPC-1218)
dnl if test ! \( -f "$1" -o -f "ext/mongodb/$1" \); then
dnl AC_MSG_ERROR([m4 could not include $1: No such file or directory])
dnl fi
m4_builtin([sinclude],[$1])
m4_builtin([sinclude],[ext/mongodb/][$1])
])
dnl Avoid using AC_CONFIG_MACRO_DIR, which might conflict with PHP
_include([scripts/autotools/m4/as_var_copy.m4])
_include([scripts/autotools/m4/ax_check_compile_flag.m4])
_include([scripts/autotools/m4/ax_prototype.m4])
_include([scripts/autotools/m4/ax_pthread.m4])
_include([scripts/autotools/m4/php_mongodb.m4])
_include([scripts/autotools/m4/pkg.m4])
_include([scripts/autotools/CheckCompiler.m4])
_include([scripts/autotools/CheckHost.m4])
_include([scripts/autotools/libbson/CheckAtomics.m4])
_include([scripts/autotools/libbson/CheckHeaders.m4])
_include([scripts/autotools/libbson/Endian.m4])
_include([scripts/autotools/libbson/FindDependencies.m4])
_include([scripts/autotools/libbson/Versions.m4])
_include([scripts/autotools/libmongoc/CheckCompression.m4])
_include([scripts/autotools/libmongoc/CheckResolv.m4])
_include([scripts/autotools/libmongoc/CheckSasl.m4])
_include([scripts/autotools/libmongoc/CheckSSL.m4])
_include([scripts/autotools/libmongoc/CheckICU.m4])
_include([scripts/autotools/libmongoc/FindDependencies.m4])
_include([scripts/autotools/libmongoc/PlatformFlags.m4])
_include([scripts/autotools/libmongoc/Versions.m4])
_include([scripts/autotools/libmongoc/WeakSymbols.m4])
dnl This include modifies the value of $PHP_MONGODB_CLIENT_SIDE_ENCRYPTION to "yes"
dnl or "no" depending on whether dependencies for libmongocrypt are fulfilled
_include([scripts/autotools/libmongocrypt/CheckSSL.m4])
_include([scripts/autotools/libmongocrypt/Endian.m4])
_include([scripts/autotools/libmongocrypt/Version.m4])
PHP_MONGODB_BSON_VERSION_STRING="Bundled ($BSON_VERSION)"
PHP_MONGODB_MONGOC_VERSION_STRING="Bundled ($MONGOC_VERSION)"
PHP_MONGODB_MONGOCRYPT_VERSION_STRING="Bundled ($MONGOCRYPT_BUILD_VERSION)"
m4_popdef([_include])
AC_SUBST(BSON_EXTRA_ALIGN, 0)
AC_SUBST(BSON_OS, 1)
AC_SUBST(MONGOC_NO_AUTOMATIC_GLOBALS, 1)
AC_SUBST(MONGOC_ENABLE_MONGODB_AWS_AUTH, 0)
AC_SUBST(MONGOC_ENABLE_RDTSCP, 0)
AC_SUBST(MONGOC_ENABLE_SHM_COUNTERS, 0)
AC_SUBST(MONGOC_TRACE, 1)
dnl Assignments for metadata handshake. Leave CFLAGS/LDFLAGS empty as they
dnl would likely cause platform info (PHP version) to be truncated. We can
dnl consider restoring CFLAGS/LDFLAGS once CDRIVER-3134 is resolved.
AC_SUBST(MONGOC_CC, [$CC])
AC_SUBST(MONGOC_USER_SET_CFLAGS, [])
AC_SUBST(MONGOC_USER_SET_LDFLAGS, [])
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
AC_SUBST(MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION, 1)
else
AC_SUBST(MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION, 0)
fi
if test "$PHP_MONGODB_DEVELOPER_FLAGS" = "yes"; then
AC_SUBST(MONGOC_ENABLE_DEBUG_ASSERTIONS, 1)
else
AC_SUBST(MONGOC_ENABLE_DEBUG_ASSERTIONS, 0)
fi
dnl On MacOS, use gcut from the coreutils brew package instead of cut
dnl Generated with: find src/libmongoc/src/common -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_COMMON_SOURCES="common-b64.c common-md5.c common-thread.c"
dnl Generated with: find src/libmongoc/src/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 6- | sort -dz | tr '\000' ' '
PHP_MONGODB_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c"
dnl Generated with: find src/libmongoc/src/libbson/src/bson -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
PHP_MONGODB_BSON_SOURCES="bcon.c bson-atomic.c bson.c bson-clock.c bson-context.c bson-decimal128.c bson-error.c bson-iso8601.c bson-iter.c bson-json.c bson-keys.c bson-md5.c bson-memory.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-version-functions.c bson-writer.c"
dnl Generated with: find src/libmongoc/src/libbson/src/jsonsl -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
PHP_MONGODB_JSONSL_SOURCES="jsonsl.c"
dnl Generated with: find src/libmongoc/src/libmongoc/src/mongoc -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOC_SOURCES="mongoc-aggregate.c mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-change-stream.c mongoc-client.c mongoc-client-pool.c mongoc-client-session.c mongoc-client-side-encryption.c mongoc-cluster-aws.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypt.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-change-stream.c mongoc-cursor-cmd.c mongoc-cursor-cmd-deprecated.c mongoc-cursor-find.c mongoc-cursor-find-cmd.c mongoc-cursor-find-opquery.c mongoc-cursor-legacy.c mongoc-cyrus.c mongoc-database.c mongoc-error.c mongoc-find-and-modify.c mongoc-generation-map.c mongoc-gridfs-bucket.c mongoc-gridfs-bucket-file.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-handshake.c mongoc-host-list.c mongoc-http.c mongoc-index.c mongoc-init.c mongoc-interrupt.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-ocsp-cache.c mongoc-openssl.c mongoc-optional.c mongoc-opts.c mongoc-opts-helpers.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-api.c mongoc-server-description.c mongoc-server-monitor.c mongoc-server-stream.c mongoc-set.c mongoc-shared.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-gridfs-download.c mongoc-stream-gridfs-upload.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-timeout.c mongoc-topology-background-monitoring.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-ts-pool.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-command-legacy.c mongoc-write-concern.c"
- dnl Generated with: find src/libmongoc/src/zlib-1.2.11 -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
+ dnl Generated with: find src/libmongoc/src/zlib-1.2.12 -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_ZLIB_SOURCES="adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c"
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/common/], $PHP_MONGODB_COMMON_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/libbson/src/bson/], $PHP_MONGODB_BSON_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/libbson/src/jsonsl/], $PHP_MONGODB_JSONSL_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/libmongoc/src/mongoc/], $PHP_MONGODB_MONGOC_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/common/])
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/libbson/src/])
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/libbson/src/jsonsl/])
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/libmongoc/src/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/common/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/libbson/src/bson/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/libbson/src/jsonsl/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/libmongoc/src/mongoc/])
dnl If compiling without libmongocrypt, use kms_message sources bundled with libmongoc.
dnl If compiling with libmongocrypt, kms_message bundled with libmongocrypt is used as it is most likely newer.
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" != "yes" && test "$PHP_MONGODB_SSL" != "no"; then
AC_SUBST(MONGOC_ENABLE_MONGODB_AWS_AUTH, 1)
PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/kms-message/src/], $PHP_MONGODB_KMS_MESSAGE_SOURCES, $PHP_MONGODB_BUNDLED_CFLAGS)
PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/kms-message/src/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/kms-message/src/])
fi
dnl TODO: Use $ext_srcdir if we can move this after PHP_NEW_EXTENSION
ac_config_dir=PHP_EXT_SRCDIR(mongodb)
AC_CONFIG_FILES([
${ac_config_dir}/src/libmongoc/src/common/common-config.h
${ac_config_dir}/src/libmongoc/src/libbson/src/bson/bson-config.h
${ac_config_dir}/src/libmongoc/src/libbson/src/bson/bson-version.h
${ac_config_dir}/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
${ac_config_dir}/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
])
if test "x$bundled_zlib" = "xyes"; then
PHP_MONGODB_ZLIB_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_ZLIB_CFLAGS"
- PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/zlib-1.2.11/], $PHP_MONGODB_ZLIB_SOURCES, $PHP_MONGODB_ZLIB_CFLAGS)
- PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/zlib-1.2.11/])
- PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/zlib-1.2.11/])
- AC_CONFIG_FILES([${ac_config_dir}/src/libmongoc/src/zlib-1.2.11/zconf.h])
+ PHP_MONGODB_ADD_SOURCES([src/libmongoc/src/zlib-1.2.12/], $PHP_MONGODB_ZLIB_SOURCES, $PHP_MONGODB_ZLIB_CFLAGS)
+ PHP_MONGODB_ADD_INCLUDE([src/libmongoc/src/zlib-1.2.12/])
+ PHP_MONGODB_ADD_BUILD_DIR([src/libmongoc/src/zlib-1.2.12/])
+ AC_CONFIG_FILES([${ac_config_dir}/src/libmongoc/src/zlib-1.2.12/zconf.h])
fi
if test "$PHP_MONGODB_CLIENT_SIDE_ENCRYPTION" = "yes"; then
dnl Since libmongocrypt adds kms-message, we can enable AWS auth in this case
AC_SUBST(MONGOC_ENABLE_MONGODB_AWS_AUTH, 1)
AC_SUBST(MONGOCRYPT_ENABLE_TRACE, 1)
dnl Generated with: find src/libmongocrypt/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 4- | sort -dz | tr '\000' ' '
- PHP_MONGODB_MONGOCRYPT_SOURCES="mongocrypt-binary.c mongocrypt-buffer.c mongocrypt.c mongocrypt-cache.c mongocrypt-cache-collinfo.c mongocrypt-cache-key.c mongocrypt-cache-oauth.c mongocrypt-ciphertext.c mongocrypt-crypto.c mongocrypt-ctx.c mongocrypt-ctx-datakey.c mongocrypt-ctx-decrypt.c mongocrypt-ctx-encrypt.c mongocrypt-endpoint.c mongocrypt-kek.c mongocrypt-key-broker.c mongocrypt-key.c mongocrypt-kms-ctx.c mongocrypt-log.c mongocrypt-marking.c mongocrypt-opts.c mongocrypt-status.c mongocrypt-traverse-util.c mongocrypt-util.c"
+ PHP_MONGODB_MONGOCRYPT_SOURCES="mc-efc.c mc-fle2-encryption-placeholder.c mc-fle2-find-equality-payload.c mc-fle2-insert-update-payload.c mc-fle2-payload-ieev.c mc-fle2-payload-uev.c mc-tokens.c mongocrypt-binary.c mongocrypt-buffer.c mongocrypt.c mongocrypt-cache.c mongocrypt-cache-collinfo.c mongocrypt-cache-key.c mongocrypt-cache-oauth.c mongocrypt-ciphertext.c mongocrypt-crypto.c mongocrypt-ctx.c mongocrypt-ctx-datakey.c mongocrypt-ctx-decrypt.c mongocrypt-ctx-encrypt.c mongocrypt-ctx-rewrap-many-datakey.c mongocrypt-endpoint.c mongocrypt-kek.c mongocrypt-key-broker.c mongocrypt-key.c mongocrypt-kms-ctx.c mongocrypt-log.c mongocrypt-marking.c mongocrypt-opts.c mongocrypt-status.c mongocrypt-traverse-util.c mongocrypt-util.c"
dnl Generated with: find src/libmongocrypt/src/crypto -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES="cng.c commoncrypto.c libcrypto.c none.c"
dnl Note: src/libmongocrypt/src/mlib/ does not contain source files (as of libmongocrypt 1.3.2)
dnl Generated with: find src/libmongocrypt/src/os_posix -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES="os_dll.c os_mutex.c"
dnl Generated with: find src/libmongocrypt/src/os_win -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES="os_dll.c os_mutex.c"
dnl Generated with: find src/libmongocrypt/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES="hexlify.c kms_azure_request.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_gcp_request.c kms_kmip_reader_writer.c kms_kmip_request.c kms_kmip_response.c kms_kmip_response_parser.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c"
PHP_MONGODB_LIBMONGOCRYPT_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS"
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/], $PHP_MONGODB_MONGOCRYPT_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/crypto/], $PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/os_posix/], $PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/src/os_win/], $PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_SOURCES([src/libmongocrypt/kms-message/src/], $PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES, $PHP_MONGODB_LIBMONGOCRYPT_CFLAGS)
PHP_MONGODB_ADD_INCLUDE([src/libmongocrypt/src/])
PHP_MONGODB_ADD_INCLUDE([src/libmongocrypt/kms-message/src/])
PHP_MONGODB_ADD_INCLUDE([src/libmongocrypt-compat/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/crypto/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/os_posix/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/src/os_win/])
PHP_MONGODB_ADD_BUILD_DIR([src/libmongocrypt/kms-message/src/])
AC_CONFIG_FILES([
${ac_config_dir}/src/libmongocrypt/src/mongocrypt-config.h
- ${ac_config_dir}/src/libmongocrypt/src/mongocrypt.h
])
fi
fi
PHP_NEW_EXTENSION(mongodb, $PHP_MONGODB_SOURCES, $ext_shared,, $PHP_MONGODB_CFLAGS)
PHP_SUBST(MONGODB_SHARED_LIBADD)
PHP_ADD_EXTENSION_DEP(mongodb, date)
PHP_ADD_EXTENSION_DEP(mongodb, json)
PHP_ADD_EXTENSION_DEP(mongodb, spl)
PHP_ADD_EXTENSION_DEP(mongodb, standard)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/BSON/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/MongoDB/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/MongoDB/Exception/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/MongoDB/Monitoring/])
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR(mongodb)[/src/contrib/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/BSON/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/MongoDB/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/MongoDB/Exception/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/MongoDB/Monitoring/])
PHP_ADD_BUILD_DIR(PHP_EXT_BUILDDIR(mongodb)[/src/contrib/])
dnl Necessary to ensure that static builds include "-pthread" when linking
if test "$ext_shared" != "yes"; then
EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM $EXTRA_LDFLAGS"
fi
dnl This must come after PHP_NEW_EXTENSION, otherwise the srcdir won't be set
PHP_ADD_MAKEFILE_FRAGMENT
dnl The libmongocrypt line intentionally uses the PHP_LIBBSON flag as that decides whether to build against bundled or system libraries.
AC_CONFIG_COMMANDS_POST([
if test "$enable_static" = "no"; then
echo "
mongodb was configured with the following options:
Build configuration:
CFLAGS : $CFLAGS
Extra CFLAGS : $STD_CFLAGS $EXTRA_CFLAGS
Developers flags (slow) : $MAINTAINER_CFLAGS
Code Coverage flags (extra slow) : $COVERAGE_CFLAGS
libmongoc : $PHP_MONGODB_BSON_VERSION_STRING
libbson : $PHP_MONGODB_MONGOC_VERSION_STRING
libmongocrypt : $PHP_MONGODB_MONGOCRYPT_VERSION_STRING
LDFLAGS : $LDFLAGS
EXTRA_LDFLAGS : $EXTRA_LDFLAGS
MONGODB_SHARED_LIBADD : $MONGODB_SHARED_LIBADD
Please submit bugreports at:
https://jira.mongodb.org/browse/PHPC
"
fi
])
fi
dnl: vim: et sw=2
diff --git a/mongodb-1.13.0/config.w32 b/mongodb-1.14.0/config.w32
similarity index 96%
rename from mongodb-1.13.0/config.w32
rename to mongodb-1.14.0/config.w32
index ba0d68b0..fa6b20da 100644
--- a/mongodb-1.13.0/config.w32
+++ b/mongodb-1.14.0/config.w32
@@ -1,383 +1,377 @@
// vim:ft=javascript
function mongodb_generate_header(inpath, outpath, replacements)
{
STDOUT.WriteLine("Generating " + outpath);
var infile = FSO.OpenTextFile(inpath, 1);
var outdata = infile.ReadAll();
infile.Close();
for (var key in replacements) {
var replacement = replacements[key];
if (typeof replacement === 'string') {
replacement = replacement.replace(/"/g, '\\"');
}
outdata = outdata.replace(new RegExp('@' + key + '@', 'g'), replacement);
}
var outfile = FSO.CreateTextFile(outpath, true);
outfile.Write(outdata);
outfile.Close();
}
function mongodb_parse_version_file(inpath, prefix)
{
var infile = FSO.OpenTextFile(inpath, 1);
var version = infile.ReadLine();
infile.Close();
var xyz_pre = version.split("-");
var xyz = xyz_pre[0].split(".");
var pre = xyz_pre.length > 1 ? xyz_pre[1] : "";
var replacements = {};
replacements[prefix + "VERSION"] = version;
replacements[prefix + "MAJOR_VERSION"] = xyz[0];
replacements[prefix + "MINOR_VERSION"] = xyz[1];
replacements[prefix + "MICRO_VERSION"] = xyz[2];
replacements[prefix + "PRERELEASE_VERSION"] = pre;
return replacements;
}
function create_folder_recursive(path)
{
if (FSO.FolderExists(path)) {
return;
}
create_folder_recursive(FSO.GetParentFolderName(path));
FSO.CreateFolder(path);
}
function MONGODB_ADD_SOURCES(dir, file_list)
{
// Ensure obj_dir and all parent directories exist
create_folder_recursive(FSO.BuildPath(get_define('BUILD_DIR'), dir));
ADD_SOURCES(configure_module_dirname + dir, file_list, "mongodb", dir);
}
ARG_ENABLE("mongodb", "MongoDB support", "no");
ARG_WITH("mongodb-sasl", "MongoDB: Build against Cyrus-SASL", "yes");
ARG_WITH("mongodb-client-side-encryption", "MongoDB: Enable client-side encryption", "yes");
if (PHP_MONGODB != "no") {
/* Note: ADD_EXTENSION_DEP() only reports the date and standard extensions as
* installed in PHP 7.3.25+, 7.4.13+, and 8.0.0+). On other versions, assume
* that they're always enabled. */
if (
PHP_VERSION >= 8 ||
(PHP_VERSION == 7 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION >= 25) ||
(PHP_VERSION == 7 && PHP_MINOR_VERSION == 4 && PHP_RELEASE_VERSION >= 13)
) {
ADD_EXTENSION_DEP("mongodb", "date", false);
ADD_EXTENSION_DEP("mongodb", "standard", false);
}
ADD_EXTENSION_DEP("mongodb", "json", false);
ADD_EXTENSION_DEP("mongodb", "spl", false);
/* MongoDB does not actually depend on PHP's OpenSSL extension, but this is in
* place to ensure that later SSL library checks succeed. This can be removed
* once we support building with Secure Channel. */
ADD_EXTENSION_DEP("mongodb", "openssl", false);
var PHP_MONGODB_CFLAGS="\
/D BSON_COMPILATION /D MONGOC_COMPILATION \
/I" + configure_module_dirname + " \
/I" + configure_module_dirname + "/src \
/I" + configure_module_dirname + "/src/BSON \
/I" + configure_module_dirname + "/src/MongoDB \
/I" + configure_module_dirname + "/src/MongoDB/Exception \
/I" + configure_module_dirname + "/src/MongoDB/Monitoring \
/I" + configure_module_dirname + "/src/contrib \
/I" + configure_module_dirname + "/src/libmongoc/src/common \
/I" + configure_module_dirname + "/src/libmongoc/src/libbson/src \
/I" + configure_module_dirname + "/src/libmongoc/src/libbson/src/jsonsl \
/I" + configure_module_dirname + "/src/libmongoc/src/libmongoc/src \
";
// Condense whitespace in CFLAGS
PHP_MONGODB_CFLAGS = PHP_MONGODB_CFLAGS.replace(/\s+/g, ' ');
// On MacOS, use gcut from the coreutils brew package instead of cut
// Generated with: find src/libmongoc/src/common -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_COMMON_SOURCES="common-b64.c common-md5.c common-thread.c"
// Generated with: find src/libmongoc/src/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 6- | sort -dz | tr '\000' ' '
var PHP_MONGODB_KMS_MESSAGE_SOURCES="hexlify.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c";
// Generated with: find src/libmongoc/src/libbson/src/bson -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
var PHP_MONGODB_BSON_SOURCES="bcon.c bson-atomic.c bson.c bson-clock.c bson-context.c bson-decimal128.c bson-error.c bson-iso8601.c bson-iter.c bson-json.c bson-keys.c bson-md5.c bson-memory.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-version-functions.c bson-writer.c";
// Generated with: find src/libmongoc/src/libbson/src/jsonsl -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
var PHP_MONGODB_JSONSL_SOURCES="jsonsl.c";
// Generated with: find src/libmongoc/src/libmongoc/src/mongoc -name '*.c' -print0 | cut -sz -d / -f 7- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOC_SOURCES="mongoc-aggregate.c mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-change-stream.c mongoc-client.c mongoc-client-pool.c mongoc-client-session.c mongoc-client-side-encryption.c mongoc-cluster-aws.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypt.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-change-stream.c mongoc-cursor-cmd.c mongoc-cursor-cmd-deprecated.c mongoc-cursor-find.c mongoc-cursor-find-cmd.c mongoc-cursor-find-opquery.c mongoc-cursor-legacy.c mongoc-cyrus.c mongoc-database.c mongoc-error.c mongoc-find-and-modify.c mongoc-generation-map.c mongoc-gridfs-bucket.c mongoc-gridfs-bucket-file.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-handshake.c mongoc-host-list.c mongoc-http.c mongoc-index.c mongoc-init.c mongoc-interrupt.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-ocsp-cache.c mongoc-openssl.c mongoc-optional.c mongoc-opts.c mongoc-opts-helpers.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-api.c mongoc-server-description.c mongoc-server-monitor.c mongoc-server-stream.c mongoc-set.c mongoc-shared.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-gridfs-download.c mongoc-stream-gridfs-upload.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-timeout.c mongoc-topology-background-monitoring.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-ts-pool.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-command-legacy.c mongoc-write-concern.c";
EXTENSION("mongodb", "php_phongo.c", null, PHP_MONGODB_CFLAGS);
MONGODB_ADD_SOURCES("/src", "phongo_apm.c phongo_bson.c phongo_bson_encode.c phongo_client.c phongo_compat.c phongo_error.c phongo_execute.c phongo_ini.c phongo_util.c");
MONGODB_ADD_SOURCES("/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c");
MONGODB_ADD_SOURCES("/src/MongoDB", "BulkWrite.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c ServerApi.c ServerDescription.c Session.c TopologyDescription.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c");
MONGODB_ADD_SOURCES("/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c EncryptionException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c");
MONGODB_ADD_SOURCES("/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c SDAMSubscriber.c Subscriber.c ServerChangedEvent.c ServerClosedEvent.c ServerHeartbeatFailedEvent.c ServerHeartbeatStartedEvent.c ServerHeartbeatSucceededEvent.c ServerOpeningEvent.c TopologyChangedEvent.c TopologyClosedEvent.c TopologyOpeningEvent.c functions.c");
MONGODB_ADD_SOURCES("/src/libmongoc/src/common", PHP_MONGODB_COMMON_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/bson", PHP_MONGODB_BSON_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/jsonsl", PHP_MONGODB_JSONSL_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongoc/src/libmongoc/src/mongoc", PHP_MONGODB_MONGOC_SOURCES);
var bson_opts = {
BSON_BYTE_ORDER: 1234,
BSON_OS: 2,
BSON_HAVE_STDBOOL_H: 0,
BSON_HAVE_STRINGS_H: 0,
BSON_HAVE_ATOMIC_32_ADD_AND_FETCH: 0,
BSON_HAVE_ATOMIC_64_ADD_AND_FETCH: 0,
BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES: 0,
BSON_HAVE_CLOCK_GETTIME: 0,
BSON_HAVE_STRNLEN: 0,
BSON_HAVE_SNPRINTF: 0,
BSON_HAVE_STRLCPY: 0,
BSON_HAVE_REALLOCF: 0,
BSON_NEEDS_SET_OUTPUT_FORMAT: 0,
BSON_HAVE_TIMESPEC: 0,
BSON_EXTRA_ALIGN: 0,
BSON_HAVE_SYSCALL_TID: 0,
BSON_HAVE_DECIMAL128: 0,
BSON_HAVE_GMTIME_R: 0,
BSON_HAVE_RAND_R: 0,
BSON_HAVE_ARC4RANDOM_BUF: 0
};
if (CHECK_FUNC_IN_HEADER("stdio.h", "_set_output_format")) {
bson_opts.BSON_NEEDS_SET_OUTPUT_FORMAT = 1;
}
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-config.h.in",
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-config.h",
bson_opts
);
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-version.h.in",
configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/bson-version.h",
mongodb_parse_version_file(configure_module_dirname + "/src/LIBMONGOC_VERSION_CURRENT", "BSON_")
);
var mongoc_opts = {
// TODO: Support building with Secure Channel on Windows
MONGOC_ENABLE_SSL_SECURE_CHANNEL: 0,
MONGOC_ENABLE_CRYPTO_CNG: 0,
// Secure Transport does not apply to Windows
MONGOC_ENABLE_SSL_SECURE_TRANSPORT: 0,
MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO: 0,
MONGOC_ENABLE_SSL_LIBRESSL: 0,
MONGOC_ENABLE_SSL_OPENSSL: 0,
MONGOC_ENABLE_CRYPTO_LIBCRYPTO: 0,
MONGOC_ENABLE_SSL: 0,
MONGOC_ENABLE_CRYPTO: 0,
MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE: 0,
MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION: 0,
MONGOC_ENABLE_COMPRESSION_SNAPPY: 0,
MONGOC_ENABLE_COMPRESSION_ZLIB: 0,
MONGOC_ENABLE_COMPRESSION_ZSTD: 0,
MONGOC_ENABLE_COMPRESSION: 0,
MONGOC_ENABLE_DEBUG_ASSERTIONS: 0,
MONGOC_ENABLE_MONGODB_AWS_AUTH: 0,
MONGOC_ENABLE_SASL: 0,
MONGOC_ENABLE_SASL_CYRUS: 0,
MONGOC_ENABLE_SASL_GSSAPI: 0,
MONGOC_ENABLE_SASL_SSPI: 0,
MONGOC_ENABLE_ICU: 0,
MONGOC_ENABLE_RDTSCP: 0,
MONGOC_ENABLE_SHM_COUNTERS: 0,
MONGOC_HAVE_ASN1_STRING_GET0_DATA: 0,
MONGOC_HAVE_SASL_CLIENT_DONE: 0,
MONGOC_HAVE_SCHED_GETCPU: 0,
MONGOC_HAVE_SOCKLEN: 1,
MONGOC_HAVE_WEAK_SYMBOLS: 0,
MONGOC_NO_AUTOMATIC_GLOBALS: 1,
MONGOC_SOCKET_ARG2: "struct sockaddr",
MONGOC_SOCKET_ARG3: "socklen_t",
MONGOC_TRACE: 1,
MONGOC_HAVE_DNSAPI: 0,
MONGOC_HAVE_RES_NSEARCH: 0,
MONGOC_HAVE_RES_NDESTROY: 0,
MONGOC_HAVE_RES_NCLOSE: 0,
MONGOC_HAVE_RES_SEARCH: 0,
MONGOC_HAVE_SS_FAMILY: 0,
MONGOC_CC: "",
MONGOC_USER_SET_CFLAGS: "",
MONGOC_USER_SET_LDFLAGS: ""
};
var mongoc_ssl_path_to_check = PHP_MONGODB;
if (typeof PHP_OPENSSL === 'string') {
mongoc_ssl_path_to_check += ";" + PHP_OPENSSL;
}
var mongoc_ssl_found = false;
/* PHP 7.1.2 introduced SETUP_OPENSSL(), which supports OpenSSL 1.1.x. Earlier
* versions will use the legacy check for OpenSSL 1.0.x and lower. */
if (typeof SETUP_OPENSSL === 'function') {
openssl_type = SETUP_OPENSSL("mongodb", mongoc_ssl_path_to_check);
mongoc_ssl_found = openssl_type > 0;
if (openssl_type >= 2) {
mongoc_opts.MONGOC_HAVE_ASN1_STRING_GET0_DATA = 1;
}
} else if (CHECK_LIB("ssleay32.lib", "mongodb", mongoc_ssl_path_to_check) &&
CHECK_LIB("libeay32.lib", "mongodb", mongoc_ssl_path_to_check) &&
CHECK_LIB("crypt32.lib", "mongodb", mongoc_ssl_path_to_check) &&
CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", "CFLAGS_MONGODB")) {
mongoc_ssl_found = true;
}
if (mongoc_ssl_found) {
mongoc_opts.MONGOC_ENABLE_SSL_OPENSSL = 1;
mongoc_opts.MONGOC_ENABLE_CRYPTO_LIBCRYPTO = 1;
mongoc_opts.MONGOC_ENABLE_SSL = 1;
mongoc_opts.MONGOC_ENABLE_CRYPTO = 1;
mongoc_opts.MONGOC_ENABLE_MONGODB_AWS_AUTH = 1;
ADD_FLAG("CFLAGS_MONGODB", "/D KMS_MSG_STATIC=1 /D KMS_MESSAGE_ENABLE_CRYPTO=1 /D KMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO=1");
} else {
WARNING("mongodb libopenssl support not enabled, libs not found");
}
// TODO: Support building with native GSSAPI (SSPI) on Windows
if (PHP_MONGODB_SASL != "no" &&
CHECK_LIB("libsasl.lib", "mongodb", PHP_MONGODB) &&
CHECK_HEADER_ADD_INCLUDE("sasl/sasl.h", "CFLAGS_MONGODB")) {
mongoc_opts.MONGOC_ENABLE_SASL = 1;
mongoc_opts.MONGOC_ENABLE_SASL_CYRUS = 1;
if (CHECK_FUNC_IN_HEADER("sasl/sasl.h", "sasl_client_done")) {
mongoc_opts.MONGOC_HAVE_SASL_CLIENT_DONE = 1;
}
} else if (PHP_MONGODB_SASL != "no") {
WARNING("mongodb libsasl support not enabled, libs not found");
}
if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION != "no" && mongoc_ssl_found) {
mongoc_opts.MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION = 1;
- ADD_FLAG("CFLAGS_MONGODB", "/D KMS_MESSAGE_LITTLE_ENDIAN=1 /D MLIB_USER=1");
+ ADD_FLAG("CFLAGS_MONGODB", "/D KMS_MESSAGE_LITTLE_ENDIAN=1 /D MONGOCRYPT_LITTLE_ENDIAN=1 /D MLIB_USER=1");
ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt/src");
ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt/kms-message/src");
ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt-compat");
var mongocrypt_opts = {
MONGOCRYPT_ENABLE_TRACE: 1,
MONGOCRYPT_ENABLE_CRYPTO: 1,
MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO: 1,
// TODO: Support building with Secure Channel on Windows
MONGOCRYPT_ENABLE_CRYPTO_CNG: 0,
// Secure Transport does not apply to Windows
MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO: 0
};
// Generated with: find src/libmongocrypt/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 4- | sort -dz | tr '\000' ' '
- var PHP_MONGODB_MONGOCRYPT_SOURCES="mongocrypt-binary.c mongocrypt-buffer.c mongocrypt.c mongocrypt-cache.c mongocrypt-cache-collinfo.c mongocrypt-cache-key.c mongocrypt-cache-oauth.c mongocrypt-ciphertext.c mongocrypt-crypto.c mongocrypt-ctx.c mongocrypt-ctx-datakey.c mongocrypt-ctx-decrypt.c mongocrypt-ctx-encrypt.c mongocrypt-endpoint.c mongocrypt-kek.c mongocrypt-key-broker.c mongocrypt-key.c mongocrypt-kms-ctx.c mongocrypt-log.c mongocrypt-marking.c mongocrypt-opts.c mongocrypt-status.c mongocrypt-traverse-util.c mongocrypt-util.c";
+ var PHP_MONGODB_MONGOCRYPT_SOURCES="mc-efc.c mc-fle2-encryption-placeholder.c mc-fle2-find-equality-payload.c mc-fle2-insert-update-payload.c mc-fle2-payload-ieev.c mc-fle2-payload-uev.c mc-tokens.c mongocrypt-binary.c mongocrypt-buffer.c mongocrypt.c mongocrypt-cache.c mongocrypt-cache-collinfo.c mongocrypt-cache-key.c mongocrypt-cache-oauth.c mongocrypt-ciphertext.c mongocrypt-crypto.c mongocrypt-ctx.c mongocrypt-ctx-datakey.c mongocrypt-ctx-decrypt.c mongocrypt-ctx-encrypt.c mongocrypt-ctx-rewrap-many-datakey.c mongocrypt-endpoint.c mongocrypt-kek.c mongocrypt-key-broker.c mongocrypt-key.c mongocrypt-kms-ctx.c mongocrypt-log.c mongocrypt-marking.c mongocrypt-opts.c mongocrypt-status.c mongocrypt-traverse-util.c mongocrypt-util.c";
// Generated with: find src/libmongocrypt/src/crypto -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES="cng.c commoncrypto.c libcrypto.c none.c";
// Note: src/libmongocrypt/src/mlib/ does not contain source files (as of libmongocrypt 1.3.2)
// Generated with: find src/libmongocrypt/src/os_posix -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES="os_dll.c os_mutex.c";
// Generated with: find src/libmongocrypt/src/os_win -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES="os_dll.c os_mutex.c";
// Generated with: find src/libmongocrypt/kms-message/src -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f 5- | sort -dz | tr '\000' ' '
var PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES="hexlify.c kms_azure_request.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_gcp_request.c kms_kmip_reader_writer.c kms_kmip_request.c kms_kmip_response.c kms_kmip_response_parser.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c";
MONGODB_ADD_SOURCES("/src/libmongocrypt/src", PHP_MONGODB_MONGOCRYPT_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongocrypt/src/crypto", PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongocrypt/src/os_posix", PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongocrypt/src/os_win", PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongocrypt/kms-message/src", PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES);
var mongocrypt_version = mongodb_parse_version_file(configure_module_dirname + "/src/LIBMONGOCRYPT_VERSION_CURRENT", "")
mongocrypt_opts.MONGOCRYPT_BUILD_VERSION = mongocrypt_version.VERSION;
mongodb_generate_header(
configure_module_dirname + "/src/libmongocrypt/src/mongocrypt-config.h.in",
configure_module_dirname + "/src/libmongocrypt/src/mongocrypt-config.h",
mongocrypt_opts
);
-
- mongodb_generate_header(
- configure_module_dirname + "/src/libmongocrypt/src/mongocrypt.h.in",
- configure_module_dirname + "/src/libmongocrypt/src/mongocrypt.h",
- mongocrypt_opts
- );
} else if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION != "no") {
// No SSL library found, we can't enable libmongocrypt
WARNING("mongodb libmongocrypt support not enabled, crypto libs not found");
}
if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION == "no" && mongoc_ssl_found) {
// Add kms-message sources bundled with libmongoc
MONGODB_ADD_SOURCES("/src/libmongoc/src/kms-message/src", PHP_MONGODB_KMS_MESSAGE_SOURCES);
ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongoc/src/kms-message/src");
}
if (CHECK_LIB("dnsapi.lib", "mongodb", PHP_MONGODB) &&
CHECK_HEADER_ADD_INCLUDE("windns.h", "CFLAGS_MONGODB")) {
mongoc_opts.MONGOC_HAVE_DNSAPI = 1;
}
if (CHECK_LIB("icuuc.lib", "mongodb", PHP_MONGODB) &&
CHECK_HEADER_ADD_INCLUDE("unicode/utf.h", "CFLAGS_MONGODB")) {
mongoc_opts.MONGODB_ENABLE_ICU = 1;
ADD_FLAG("LIBS_MONGODB", "icudt.lib icuin.lib icuio.lib");
/* Compat for ICU before 58.1.*/
if (CHECK_LIB("icule.lib", "mongodb", PHP_MONGODB)) {
ADD_FLAG("LIBS_MONGODB", "icule.lib");
}
if (CHECK_LIB("iculx.lib", "mongodb", PHP_MONGODB)) {
ADD_FLAG("LIBS_MONGODB", "iculx.lib");
}
ADD_FLAG("CFLAGS_MONGODB", "/EHsc /D U_USING_ICU_NAMESPACE=1");
}
if (typeof COMPILER_NAME === 'string') {
mongoc_opts.MONGOC_CC = COMPILER_NAME;
} else if (typeof VC_VERSIONS === 'array' && typeof VC_VERSIONS[VCVERS] === 'string') {
mongoc_opts.MONGOC_CC = VC_VERSIONS[VCVERS];
} else if (typeof COMPILER_NAME_LONG === 'string') {
mongoc_opts.MONGOC_CC = COMPILER_NAME_LONG;
}
/* MONGOC_USER_SET_CFLAGS and MONGOC_USER_SET_LDFLAGS can be left blank, as we
* do not expect CFLAGS or LDFLAGS to be customized at build time. */
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in",
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h",
mongoc_opts
);
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/common/common-config.h.in",
configure_module_dirname + "/src/libmongoc/src/common/common-config.h",
mongoc_opts
);
mongodb_generate_header(
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in",
configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h",
mongodb_parse_version_file(configure_module_dirname + "/src/LIBMONGOC_VERSION_CURRENT", "MONGOC_")
);
}
diff --git a/mongodb-1.13.0/src/phongo_version.h b/mongodb-1.14.0/phongo_version.h
similarity index 74%
rename from mongodb-1.13.0/src/phongo_version.h
rename to mongodb-1.14.0/phongo_version.h
index db15d176..88fdbf82 100644
--- a/mongodb-1.13.0/src/phongo_version.h
+++ b/mongodb-1.14.0/phongo_version.h
@@ -1,26 +1,30 @@
/*
* Copyright 2014-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PHONGO_VERSION_H
#define PHONGO_VERSION_H
+/* Note: this file should remain in the repository's root directory so that
+ * PECL's release-upload.php script can verify the version information when
+ * publishing a release. */
+
/* clang-format off */
-#define PHP_MONGODB_VERSION "1.13.0"
+#define PHP_MONGODB_VERSION "1.14.0"
#define PHP_MONGODB_STABILITY "stable"
-#define PHP_MONGODB_VERSION_DESC 1,13,0,1
+#define PHP_MONGODB_VERSION_DESC 1,14,0,3
/* clang-format on */
#endif /* PHONGO_VERSION_H */
diff --git a/mongodb-1.13.0/php_phongo.c b/mongodb-1.14.0/php_phongo.c
similarity index 100%
rename from mongodb-1.13.0/php_phongo.c
rename to mongodb-1.14.0/php_phongo.c
diff --git a/mongodb-1.13.0/php_phongo.h b/mongodb-1.14.0/php_phongo.h
similarity index 99%
rename from mongodb-1.13.0/php_phongo.h
rename to mongodb-1.14.0/php_phongo.h
index ca54b4c2..29dceef4 100644
--- a/mongodb-1.13.0/php_phongo.h
+++ b/mongodb-1.14.0/php_phongo.h
@@ -1,117 +1,116 @@
/*
* Copyright 2014-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PHONGO_H
#define PHONGO_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* Include headers for getpid(), which is used by PHONGO_SET_CREATED_BY_PID.
* This is based on PHP's ext/standard/pageinfo.c includes for getmypid. */
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef PHP_WIN32
#include <process.h>
#endif
#include "phongo_version.h"
#include "phongo_compat.h"
#include "phongo_classes.h"
#include "phongo_structs.h"
/* Define a common logging domain for the extension. Individual files may
* override the domain after including this header (e.g. phongo_bson.c). */
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "PHONGO"
#define phpext_mongodb_ptr &mongodb_module_entry
extern zend_module_entry mongodb_module_entry;
ZEND_BEGIN_MODULE_GLOBALS(mongodb)
char* debug;
FILE* debug_fd;
- bool mock_service_id;
HashTable persistent_clients;
HashTable* request_clients;
HashTable* subscribers;
HashTable* managers;
ZEND_END_MODULE_GLOBALS(mongodb)
#define MONGODB_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mongodb, v)
#if defined(ZTS) && defined(COMPILE_DL_MONGODB)
ZEND_TSRMLS_CACHE_EXTERN()
#endif
zend_object_handlers* phongo_get_std_object_handlers(void);
#define PHONGO_CE_FINAL(ce) \
do { \
ce->ce_flags |= ZEND_ACC_FINAL; \
} while (0)
#if PHP_VERSION_ID < 80100
#define PHONGO_CE_DISABLE_SERIALIZATION(ce) \
do { \
ce->serialize = zend_class_serialize_deny; \
ce->unserialize = zend_class_unserialize_deny; \
} while (0)
#else
#define PHONGO_CE_DISABLE_SERIALIZATION(ce) \
do { \
ce->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; \
} while (0)
#endif
#define PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_temp, intern, props, size) \
do { \
if (is_temp) { \
ALLOC_HASHTABLE(props); \
zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \
} else if ((intern)->properties) { \
(props) = (intern)->properties; \
} else { \
ALLOC_HASHTABLE(props); \
zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \
(intern)->properties = (props); \
} \
} while (0)
#define PHONGO_GET_PROPERTY_HASH_FREE_PROPS(is_temp, props) \
do { \
if (is_temp) { \
zend_hash_destroy((props)); \
FREE_HASHTABLE(props); \
} \
} while (0)
#define PHONGO_ZVAL_CLASS_OR_TYPE_NAME(zv) (Z_TYPE(zv) == IS_OBJECT ? ZSTR_VAL(Z_OBJCE(zv)->name) : zend_get_type_by_const(Z_TYPE(zv)))
#define PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zvp) PHONGO_ZVAL_CLASS_OR_TYPE_NAME(*(zvp))
#define PHONGO_ZVAL_EXCEPTION_NAME(e) (ZSTR_VAL(e->ce->name))
#define PHONGO_SET_CREATED_BY_PID(intern) \
do { \
(intern)->created_by_pid = (int) getpid(); \
} while (0)
/* Shared function entries for disabling constructors and unserialize() */
PHP_FUNCTION(MongoDB_disabled___construct);
PHP_FUNCTION(MongoDB_disabled___wakeup);
#endif /* PHONGO_H */
diff --git a/mongodb-1.13.0/scripts/autotools/CheckCompiler.m4 b/mongodb-1.14.0/scripts/autotools/CheckCompiler.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/CheckCompiler.m4
rename to mongodb-1.14.0/scripts/autotools/CheckCompiler.m4
diff --git a/mongodb-1.13.0/scripts/autotools/CheckHost.m4 b/mongodb-1.14.0/scripts/autotools/CheckHost.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/CheckHost.m4
rename to mongodb-1.14.0/scripts/autotools/CheckHost.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libbson/CheckAtomics.m4 b/mongodb-1.14.0/scripts/autotools/libbson/CheckAtomics.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libbson/CheckAtomics.m4
rename to mongodb-1.14.0/scripts/autotools/libbson/CheckAtomics.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libbson/CheckHeaders.m4 b/mongodb-1.14.0/scripts/autotools/libbson/CheckHeaders.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libbson/CheckHeaders.m4
rename to mongodb-1.14.0/scripts/autotools/libbson/CheckHeaders.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libbson/Endian.m4 b/mongodb-1.14.0/scripts/autotools/libbson/Endian.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libbson/Endian.m4
rename to mongodb-1.14.0/scripts/autotools/libbson/Endian.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libbson/FindDependencies.m4 b/mongodb-1.14.0/scripts/autotools/libbson/FindDependencies.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libbson/FindDependencies.m4
rename to mongodb-1.14.0/scripts/autotools/libbson/FindDependencies.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libbson/Versions.m4 b/mongodb-1.14.0/scripts/autotools/libbson/Versions.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libbson/Versions.m4
rename to mongodb-1.14.0/scripts/autotools/libbson/Versions.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/CheckCompression.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/CheckCompression.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/CheckCompression.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/CheckCompression.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/CheckICU.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/CheckICU.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/CheckICU.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/CheckICU.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/CheckResolv.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/CheckResolv.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/CheckResolv.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/CheckResolv.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/CheckSSL.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/CheckSSL.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/CheckSSL.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/CheckSSL.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/CheckSasl.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/CheckSasl.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/CheckSasl.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/CheckSasl.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/FindDependencies.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/FindDependencies.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/FindDependencies.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/FindDependencies.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/PlatformFlags.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/PlatformFlags.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/PlatformFlags.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/PlatformFlags.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/Versions.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/Versions.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/Versions.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/Versions.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongoc/WeakSymbols.m4 b/mongodb-1.14.0/scripts/autotools/libmongoc/WeakSymbols.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongoc/WeakSymbols.m4
rename to mongodb-1.14.0/scripts/autotools/libmongoc/WeakSymbols.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongocrypt/CheckSSL.m4 b/mongodb-1.14.0/scripts/autotools/libmongocrypt/CheckSSL.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongocrypt/CheckSSL.m4
rename to mongodb-1.14.0/scripts/autotools/libmongocrypt/CheckSSL.m4
diff --git a/mongodb-1.13.0/scripts/autotools/libmongocrypt/Endian.m4 b/mongodb-1.14.0/scripts/autotools/libmongocrypt/Endian.m4
similarity index 64%
rename from mongodb-1.13.0/scripts/autotools/libmongocrypt/Endian.m4
rename to mongodb-1.14.0/scripts/autotools/libmongocrypt/Endian.m4
index aac4a5b6..c1964f9e 100644
--- a/mongodb-1.13.0/scripts/autotools/libmongocrypt/Endian.m4
+++ b/mongodb-1.14.0/scripts/autotools/libmongocrypt/Endian.m4
@@ -1,6 +1,6 @@
AC_C_BIGENDIAN
if test "x$ac_cv_c_bigendian" = "xyes"; then
- PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS -DKMS_MESSAGE_BIG_ENDIAN=1"
+ PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS -DKMS_MESSAGE_BIG_ENDIAN=1 -DMONGOCRYPT_BIG_ENDIAN=1"
else
- PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS -DKMS_MESSAGE_LITTLE_ENDIAN=1"
+ PHP_MONGODB_BUNDLED_CFLAGS="$PHP_MONGODB_BUNDLED_CFLAGS -DKMS_MESSAGE_LITTLE_ENDIAN=1 -DMONGOCRYPT_LITTLE_ENDIAN=1"
fi
diff --git a/mongodb-1.13.0/scripts/autotools/libmongocrypt/Version.m4 b/mongodb-1.14.0/scripts/autotools/libmongocrypt/Version.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/libmongocrypt/Version.m4
rename to mongodb-1.14.0/scripts/autotools/libmongocrypt/Version.m4
diff --git a/mongodb-1.13.0/scripts/autotools/m4/as_var_copy.m4 b/mongodb-1.14.0/scripts/autotools/m4/as_var_copy.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/m4/as_var_copy.m4
rename to mongodb-1.14.0/scripts/autotools/m4/as_var_copy.m4
diff --git a/mongodb-1.13.0/scripts/autotools/m4/ax_check_compile_flag.m4 b/mongodb-1.14.0/scripts/autotools/m4/ax_check_compile_flag.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/m4/ax_check_compile_flag.m4
rename to mongodb-1.14.0/scripts/autotools/m4/ax_check_compile_flag.m4
diff --git a/mongodb-1.13.0/scripts/autotools/m4/ax_prototype.m4 b/mongodb-1.14.0/scripts/autotools/m4/ax_prototype.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/m4/ax_prototype.m4
rename to mongodb-1.14.0/scripts/autotools/m4/ax_prototype.m4
diff --git a/mongodb-1.13.0/scripts/autotools/m4/ax_pthread.m4 b/mongodb-1.14.0/scripts/autotools/m4/ax_pthread.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/m4/ax_pthread.m4
rename to mongodb-1.14.0/scripts/autotools/m4/ax_pthread.m4
diff --git a/mongodb-1.13.0/scripts/autotools/m4/php_mongodb.m4 b/mongodb-1.14.0/scripts/autotools/m4/php_mongodb.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/m4/php_mongodb.m4
rename to mongodb-1.14.0/scripts/autotools/m4/php_mongodb.m4
diff --git a/mongodb-1.13.0/scripts/autotools/m4/pkg.m4 b/mongodb-1.14.0/scripts/autotools/m4/pkg.m4
similarity index 100%
rename from mongodb-1.13.0/scripts/autotools/m4/pkg.m4
rename to mongodb-1.14.0/scripts/autotools/m4/pkg.m4
diff --git a/mongodb-1.13.0/scripts/clang-format.sh b/mongodb-1.14.0/scripts/clang-format.sh
similarity index 100%
rename from mongodb-1.13.0/scripts/clang-format.sh
rename to mongodb-1.14.0/scripts/clang-format.sh
diff --git a/mongodb-1.13.0/scripts/convert-bson-corpus-tests.php b/mongodb-1.14.0/scripts/convert-bson-corpus-tests.php
similarity index 100%
rename from mongodb-1.13.0/scripts/convert-bson-corpus-tests.php
rename to mongodb-1.14.0/scripts/convert-bson-corpus-tests.php
diff --git a/mongodb-1.13.0/scripts/mongo-orchestration.php b/mongodb-1.14.0/scripts/mongo-orchestration.php
similarity index 100%
rename from mongodb-1.13.0/scripts/mongo-orchestration.php
rename to mongodb-1.14.0/scripts/mongo-orchestration.php
diff --git a/mongodb-1.13.0/scripts/update-submodule-sources.php b/mongodb-1.14.0/scripts/update-submodule-sources.php
similarity index 96%
rename from mongodb-1.13.0/scripts/update-submodule-sources.php
rename to mongodb-1.14.0/scripts/update-submodule-sources.php
index b526d337..05b76ea0 100644
--- a/mongodb-1.13.0/scripts/update-submodule-sources.php
+++ b/mongodb-1.14.0/scripts/update-submodule-sources.php
@@ -1,47 +1,47 @@
<?php
$cmd = "find %s -maxdepth 1 -name '*.c' -print0 | cut -sz -d / -f %d- | sort -dz | tr '\\000' ' '";
$vars = [
'PHP_MONGODB_COMMON_SOURCES' => 'src/libmongoc/src/common',
'PHP_MONGODB_KMS_MESSAGE_SOURCES' => 'src/libmongoc/src/kms-message/src',
'PHP_MONGODB_BSON_SOURCES' => 'src/libmongoc/src/libbson/src/bson',
'PHP_MONGODB_JSONSL_SOURCES' => 'src/libmongoc/src/libbson/src/jsonsl',
'PHP_MONGODB_MONGOC_SOURCES' => 'src/libmongoc/src/libmongoc/src/mongoc',
- 'PHP_MONGODB_ZLIB_SOURCES' => 'src/libmongoc/src/zlib-1.2.11',
+ 'PHP_MONGODB_ZLIB_SOURCES' => 'src/libmongoc/src/zlib-1.2.12',
'PHP_MONGODB_MONGOCRYPT_SOURCES' => 'src/libmongocrypt/src',
'PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES' => 'src/libmongocrypt/src/crypto',
'PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES' => 'src/libmongocrypt/src/os_posix',
'PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES' => 'src/libmongocrypt/src/os_win',
'PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES' => 'src/libmongocrypt/kms-message/src',
];
$patterns = [];
$replacements = [];
foreach ($vars as $var => $path) {
$cutNth = 2 + substr_count($path, '/');
$files = trim(shell_exec(sprintf($cmd, $path, $cutNth)));
$patterns[] = sprintf('/(%s=")([^"]*)(";?)/', $var);
$replacements[] = '$1' . $files . '$3';
}
$files = [
realpath(__DIR__ . '/../config.m4') => count($patterns),
// config.w32 does not use PHP_MONGODB_ZLIB_SOURCES (PHPC-1111)
realpath(__DIR__ . '/../config.w32') => count($patterns) - 1,
];
foreach ($files as $file => $expectedCount) {
$replaced = preg_replace($patterns, $replacements, file_get_contents($file), 1, $count);
if ($count !== $expectedCount) {
fprintf(STDERR, "Skipping %s: Expected %d replacements but only matched %d\n", basename($file), $expectedCount, $count);
continue;
}
printf("Updated %s\n", basename($file));
file_put_contents($file, $replaced);
}
diff --git a/mongodb-1.13.0/src/BSON/Binary.c b/mongodb-1.14.0/src/BSON/Binary.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Binary.c
rename to mongodb-1.14.0/src/BSON/Binary.c
diff --git a/mongodb-1.13.0/src/BSON/BinaryInterface.c b/mongodb-1.14.0/src/BSON/BinaryInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/BinaryInterface.c
rename to mongodb-1.14.0/src/BSON/BinaryInterface.c
diff --git a/mongodb-1.13.0/src/BSON/DBPointer.c b/mongodb-1.14.0/src/BSON/DBPointer.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/DBPointer.c
rename to mongodb-1.14.0/src/BSON/DBPointer.c
diff --git a/mongodb-1.13.0/src/BSON/Decimal128.c b/mongodb-1.14.0/src/BSON/Decimal128.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Decimal128.c
rename to mongodb-1.14.0/src/BSON/Decimal128.c
diff --git a/mongodb-1.13.0/src/BSON/Decimal128Interface.c b/mongodb-1.14.0/src/BSON/Decimal128Interface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Decimal128Interface.c
rename to mongodb-1.14.0/src/BSON/Decimal128Interface.c
diff --git a/mongodb-1.13.0/src/BSON/Int64.c b/mongodb-1.14.0/src/BSON/Int64.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Int64.c
rename to mongodb-1.14.0/src/BSON/Int64.c
diff --git a/mongodb-1.13.0/src/BSON/Javascript.c b/mongodb-1.14.0/src/BSON/Javascript.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Javascript.c
rename to mongodb-1.14.0/src/BSON/Javascript.c
diff --git a/mongodb-1.13.0/src/BSON/JavascriptInterface.c b/mongodb-1.14.0/src/BSON/JavascriptInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/JavascriptInterface.c
rename to mongodb-1.14.0/src/BSON/JavascriptInterface.c
diff --git a/mongodb-1.13.0/src/BSON/MaxKey.c b/mongodb-1.14.0/src/BSON/MaxKey.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/MaxKey.c
rename to mongodb-1.14.0/src/BSON/MaxKey.c
diff --git a/mongodb-1.13.0/src/BSON/MaxKeyInterface.c b/mongodb-1.14.0/src/BSON/MaxKeyInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/MaxKeyInterface.c
rename to mongodb-1.14.0/src/BSON/MaxKeyInterface.c
diff --git a/mongodb-1.13.0/src/BSON/MinKey.c b/mongodb-1.14.0/src/BSON/MinKey.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/MinKey.c
rename to mongodb-1.14.0/src/BSON/MinKey.c
diff --git a/mongodb-1.13.0/src/BSON/MinKeyInterface.c b/mongodb-1.14.0/src/BSON/MinKeyInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/MinKeyInterface.c
rename to mongodb-1.14.0/src/BSON/MinKeyInterface.c
diff --git a/mongodb-1.13.0/src/BSON/ObjectId.c b/mongodb-1.14.0/src/BSON/ObjectId.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/ObjectId.c
rename to mongodb-1.14.0/src/BSON/ObjectId.c
diff --git a/mongodb-1.13.0/src/BSON/ObjectId.h b/mongodb-1.14.0/src/BSON/ObjectId.h
similarity index 100%
rename from mongodb-1.13.0/src/BSON/ObjectId.h
rename to mongodb-1.14.0/src/BSON/ObjectId.h
diff --git a/mongodb-1.13.0/src/BSON/ObjectIdInterface.c b/mongodb-1.14.0/src/BSON/ObjectIdInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/ObjectIdInterface.c
rename to mongodb-1.14.0/src/BSON/ObjectIdInterface.c
diff --git a/mongodb-1.13.0/src/BSON/Persistable.c b/mongodb-1.14.0/src/BSON/Persistable.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Persistable.c
rename to mongodb-1.14.0/src/BSON/Persistable.c
diff --git a/mongodb-1.13.0/src/BSON/Regex.c b/mongodb-1.14.0/src/BSON/Regex.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Regex.c
rename to mongodb-1.14.0/src/BSON/Regex.c
diff --git a/mongodb-1.13.0/src/BSON/RegexInterface.c b/mongodb-1.14.0/src/BSON/RegexInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/RegexInterface.c
rename to mongodb-1.14.0/src/BSON/RegexInterface.c
diff --git a/mongodb-1.13.0/src/BSON/Serializable.c b/mongodb-1.14.0/src/BSON/Serializable.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Serializable.c
rename to mongodb-1.14.0/src/BSON/Serializable.c
diff --git a/mongodb-1.13.0/src/BSON/Symbol.c b/mongodb-1.14.0/src/BSON/Symbol.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Symbol.c
rename to mongodb-1.14.0/src/BSON/Symbol.c
diff --git a/mongodb-1.13.0/src/BSON/Timestamp.c b/mongodb-1.14.0/src/BSON/Timestamp.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Timestamp.c
rename to mongodb-1.14.0/src/BSON/Timestamp.c
diff --git a/mongodb-1.13.0/src/BSON/TimestampInterface.c b/mongodb-1.14.0/src/BSON/TimestampInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/TimestampInterface.c
rename to mongodb-1.14.0/src/BSON/TimestampInterface.c
diff --git a/mongodb-1.13.0/src/BSON/Type.c b/mongodb-1.14.0/src/BSON/Type.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Type.c
rename to mongodb-1.14.0/src/BSON/Type.c
diff --git a/mongodb-1.13.0/src/BSON/UTCDateTime.c b/mongodb-1.14.0/src/BSON/UTCDateTime.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/UTCDateTime.c
rename to mongodb-1.14.0/src/BSON/UTCDateTime.c
diff --git a/mongodb-1.13.0/src/BSON/UTCDateTimeInterface.c b/mongodb-1.14.0/src/BSON/UTCDateTimeInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/UTCDateTimeInterface.c
rename to mongodb-1.14.0/src/BSON/UTCDateTimeInterface.c
diff --git a/mongodb-1.13.0/src/BSON/Undefined.c b/mongodb-1.14.0/src/BSON/Undefined.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Undefined.c
rename to mongodb-1.14.0/src/BSON/Undefined.c
diff --git a/mongodb-1.13.0/src/BSON/Unserializable.c b/mongodb-1.14.0/src/BSON/Unserializable.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/Unserializable.c
rename to mongodb-1.14.0/src/BSON/Unserializable.c
diff --git a/mongodb-1.13.0/src/BSON/functions.c b/mongodb-1.14.0/src/BSON/functions.c
similarity index 100%
rename from mongodb-1.13.0/src/BSON/functions.c
rename to mongodb-1.14.0/src/BSON/functions.c
diff --git a/mongodb-1.13.0/src/BSON/functions.h b/mongodb-1.14.0/src/BSON/functions.h
similarity index 100%
rename from mongodb-1.13.0/src/BSON/functions.h
rename to mongodb-1.14.0/src/BSON/functions.h
diff --git a/mongodb-1.14.0/src/LIBMONGOCRYPT_VERSION_CURRENT b/mongodb-1.14.0/src/LIBMONGOCRYPT_VERSION_CURRENT
new file mode 100644
index 00000000..bc80560f
--- /dev/null
+++ b/mongodb-1.14.0/src/LIBMONGOCRYPT_VERSION_CURRENT
@@ -0,0 +1 @@
+1.5.0
diff --git a/mongodb-1.14.0/src/LIBMONGOC_VERSION_CURRENT b/mongodb-1.14.0/src/LIBMONGOC_VERSION_CURRENT
new file mode 100644
index 00000000..57807d6d
--- /dev/null
+++ b/mongodb-1.14.0/src/LIBMONGOC_VERSION_CURRENT
@@ -0,0 +1 @@
+1.22.0
diff --git a/mongodb-1.13.0/src/MongoDB/BulkWrite.c b/mongodb-1.14.0/src/MongoDB/BulkWrite.c
similarity index 93%
rename from mongodb-1.13.0/src/MongoDB/BulkWrite.c
rename to mongodb-1.14.0/src/MongoDB/BulkWrite.c
index 7dc20ea8..74c8915e 100644
--- a/mongodb-1.13.0/src/MongoDB/BulkWrite.c
+++ b/mongodb-1.14.0/src/MongoDB/BulkWrite.c
@@ -1,675 +1,740 @@
/*
* Copyright 2015-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "php_array_api.h"
#include "php_phongo.h"
#include "phongo_bson_encode.h"
#include "phongo_error.h"
#include "MongoDB/WriteConcern.h"
#define PHONGO_BULKWRITE_BYPASS_UNSET -1
zend_class_entry* php_phongo_bulkwrite_ce;
/* Extracts the "_id" field of a BSON document into a return value. */
static void php_phongo_bulkwrite_extract_id(bson_t* doc, zval** return_value) /* {{{ */
{
zval* id = NULL;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &state)) {
goto cleanup;
}
id = php_array_fetchc(&state.zchild, "_id");
if (id) {
ZVAL_ZVAL(*return_value, id, 1, 0);
}
cleanup:
zval_ptr_dtor(&state.zchild);
} /* }}} */
/* Returns whether any top-level field names in the document contain a "$". */
static inline bool php_phongo_bulkwrite_update_has_operators(bson_t* bupdate) /* {{{ */
{
bson_iter_t iter;
if (bson_iter_init(&iter, bupdate)) {
while (bson_iter_next(&iter)) {
if (strchr(bson_iter_key(&iter), '$')) {
return true;
}
}
}
return false;
} /* }}} */
/* Returns whether the update document is considered an aggregation pipeline */
static inline bool php_phongo_bulkwrite_update_is_pipeline(bson_t* bupdate) /* {{{ */
{
bson_iter_t iter;
bson_iter_t child;
const char* key;
int i = 0;
char* i_str;
if (!bson_iter_init(&iter, bupdate)) {
return false;
}
while (bson_iter_next(&iter)) {
key = bson_iter_key(&iter);
i_str = bson_strdup_printf("%d", i++);
if (strcmp(key, i_str)) {
bson_free(i_str);
return false;
}
bson_free(i_str);
if (BSON_ITER_HOLDS_DOCUMENT(&iter)) {
if (!bson_iter_recurse(&iter, &child)) {
return false;
}
if (!bson_iter_next(&child)) {
return false;
}
key = bson_iter_key(&child);
if (key[0] != '$') {
return false;
}
} else {
return false;
}
}
/* should return false when the document is empty */
return i != 0;
} /* }}} */
/* Returns whether the BSON array's keys are a sequence of integer strings
* starting with "0". BSON_APPEND_ARRAY considers it the caller's responsibility
* to ensure that the array's keys are properly formatted. */
static inline bool php_phongo_bulkwrite_bson_array_has_valid_keys(bson_t* array) /* {{{ */
{
bson_iter_t iter;
if (bson_empty(array)) {
return true;
}
if (bson_iter_init(&iter, array)) {
char key[12];
int count = 0;
while (bson_iter_next(&iter)) {
bson_snprintf(key, sizeof(key), "%d", count);
if (0 != strcmp(key, bson_iter_key(&iter))) {
return false;
}
count++;
}
}
return true;
} /* }}} */
/* Appends an array field for the given opts document and key. Returns true on
* success; otherwise, false is returned and an exception is thrown. */
static bool php_phongo_bulkwrite_opts_append_array(bson_t* opts, const char* key, zval* zarr) /* {{{ */
{
zval* value = php_array_fetch(zarr, key);
bson_t b = BSON_INITIALIZER;
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to be array or object, %s given", key, zend_get_type_by_const(Z_TYPE_P(value)));
return false;
}
php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL);
if (EG(exception)) {
bson_destroy(&b);
return false;
}
if (!php_phongo_bulkwrite_bson_array_has_valid_keys(&b)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"%s\" option has invalid keys for a BSON array", key);
bson_destroy(&b);
return false;
}
if (!BSON_APPEND_ARRAY(opts, key, &b)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", key);
bson_destroy(&b);
return false;
}
bson_destroy(&b);
return true;
} /* }}} */
/* Appends a document field for the given opts document and key. Returns true on
* success; otherwise, false is returned and an exception is thrown. */
static bool php_phongo_bulkwrite_opts_append_document(bson_t* opts, const char* key, zval* zarr) /* {{{ */
{
zval* value = php_array_fetch(zarr, key);
bson_t b = BSON_INITIALIZER;
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to be array or object, %s given", key, zend_get_type_by_const(Z_TYPE_P(value)));
return false;
}
php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL);
if (EG(exception)) {
bson_destroy(&b);
return false;
}
if (!BSON_APPEND_DOCUMENT(opts, key, &b)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", key);
bson_destroy(&b);
return false;
}
bson_destroy(&b);
return true;
} /* }}} */
#define PHONGO_BULKWRITE_APPEND_BOOL(opt, value) \
if (!BSON_APPEND_BOOL(boptions, (opt), (value))) { \
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
return false; \
}
#define PHONGO_BULKWRITE_APPEND_INT32(opt, value) \
if (!BSON_APPEND_INT32(boptions, (opt), (value))) { \
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
return false; \
}
#define PHONGO_BULKWRITE_OPT_ARRAY(opt) \
if (zoptions && php_array_existsc(zoptions, (opt))) { \
if (!php_phongo_bulkwrite_opts_append_array(boptions, (opt), zoptions)) { \
return false; \
} \
}
#define PHONGO_BULKWRITE_OPT_DOCUMENT(opt) \
if (zoptions && php_array_existsc(zoptions, (opt))) { \
if (!php_phongo_bulkwrite_opts_append_document(boptions, (opt), zoptions)) { \
return false; \
} \
}
/* Initialize the "hint" option. Returns true on success; otherwise, false is
* returned and an exception is thrown.
*
* The "hint" option must be a string or document. Check for both types and
* merge into BSON options accordingly. */
static bool php_phongo_bulkwrite_opt_hint(bson_t* boptions, zval* zoptions) /* {{{ */
{
/* The "hint" option (or "$hint" modifier) must be a string or document.
* Check for both types and merge into BSON options accordingly. */
if (zoptions && php_array_existsc(zoptions, "hint")) {
zend_uchar type = Z_TYPE_P(php_array_fetchc(zoptions, "hint"));
if (type == IS_STRING) {
zval* value = php_array_fetchc(zoptions, "hint");
if (!bson_append_utf8(boptions, "hint", 4, Z_STRVAL_P(value), Z_STRLEN_P(value))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"hint\" option");
return false;
}
} else if (type == IS_OBJECT || type == IS_ARRAY) {
PHONGO_BULKWRITE_OPT_DOCUMENT("hint");
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type));
return false;
}
}
return true;
} /* }}} */
/* Applies options (including defaults) for an update operation. */
static bool php_phongo_bulkwrite_update_apply_options(bson_t* boptions, zval* zoptions) /* {{{ */
{
bool multi = false, upsert = false;
if (zoptions) {
multi = php_array_fetchc_bool(zoptions, "multi");
upsert = php_array_fetchc_bool(zoptions, "upsert");
}
PHONGO_BULKWRITE_APPEND_BOOL("multi", multi);
PHONGO_BULKWRITE_APPEND_BOOL("upsert", upsert);
PHONGO_BULKWRITE_OPT_ARRAY("arrayFilters");
PHONGO_BULKWRITE_OPT_DOCUMENT("collation");
if (!php_phongo_bulkwrite_opt_hint(boptions, zoptions)) {
return false;
}
return true;
} /* }}} */
-/* Applies options (including defaults) for an delete operation. */
+/* Applies options (including defaults) for a delete operation. */
static bool php_phongo_bulkwrite_delete_apply_options(bson_t* boptions, zval* zoptions) /* {{{ */
{
int32_t limit = 0;
if (zoptions) {
limit = php_array_fetchc_bool(zoptions, "limit") ? 1 : 0;
}
PHONGO_BULKWRITE_APPEND_INT32("limit", limit);
PHONGO_BULKWRITE_OPT_DOCUMENT("collation");
if (!php_phongo_bulkwrite_opt_hint(boptions, zoptions)) {
return false;
}
return true;
} /* }}} */
#undef PHONGO_BULKWRITE_APPEND_BOOL
#undef PHONGO_BULKWRITE_APPEND_INT32
#undef PHONGO_BULKWRITE_OPT_DOCUMENT
/* {{{ proto void MongoDB\Driver\BulkWrite::__construct([array $options = array()])
Constructs a new BulkWrite */
static PHP_METHOD(BulkWrite, __construct)
{
zend_error_handling error_handling;
php_phongo_bulkwrite_t* intern;
zval* options = NULL;
zend_bool ordered = 1;
intern = Z_BULKWRITE_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
if (options && php_array_existsc(options, "ordered")) {
ordered = php_array_fetchc_bool(options, "ordered");
}
intern->bulk = mongoc_bulk_operation_new(ordered);
intern->ordered = ordered;
intern->bypass = PHONGO_BULKWRITE_BYPASS_UNSET;
+ intern->let = NULL;
intern->num_ops = 0;
intern->executed = false;
if (options && php_array_existsc(options, "bypassDocumentValidation")) {
zend_bool bypass = php_array_fetchc_bool(options, "bypassDocumentValidation");
mongoc_bulk_operation_set_bypass_document_validation(intern->bulk, bypass);
intern->bypass = bypass;
}
+
+ if (options && php_array_existsc(options, "let")) {
+ zval* value = php_array_fetch(options, "let");
+
+ if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"let\" option to be array or object, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
+ return;
+ }
+
+ intern->let = bson_new();
+ php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, intern->let, NULL);
+
+ if (EG(exception)) {
+ return;
+ }
+
+ mongoc_bulk_operation_set_let(intern->bulk, intern->let);
+ }
+
+ if (options && php_array_existsc(options, "comment")) {
+ zval* value = php_array_fetch(options, "comment");
+
+ intern->comment = ecalloc(1, sizeof(bson_value_t));
+ php_phongo_zval_to_bson_value(value, PHONGO_BSON_NONE, intern->comment);
+
+ if (EG(exception)) {
+ /* Exception should already have been thrown */
+ return;
+ }
+
+ mongoc_bulk_operation_set_comment(intern->bulk, intern->comment);
+ }
} /* }}} */
/* {{{ proto mixed MongoDB\Driver\BulkWrite::insert(array|object $document)
Adds an insert operation to the BulkWrite */
static PHP_METHOD(BulkWrite, insert)
{
zend_error_handling error_handling;
php_phongo_bulkwrite_t* intern;
zval* zdocument;
bson_t bdocument = BSON_INITIALIZER, boptions = BSON_INITIALIZER;
bson_t* bson_out = NULL;
int bson_flags = PHONGO_BSON_ADD_ID;
bson_error_t error = { 0 };
intern = Z_BULKWRITE_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "A", &zdocument) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
bson_flags |= PHONGO_BSON_RETURN_ID;
php_phongo_zval_to_bson(zdocument, bson_flags, &bdocument, &bson_out);
if (EG(exception)) {
goto cleanup;
}
if (!mongoc_bulk_operation_insert_with_opts(intern->bulk, &bdocument, &boptions, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
intern->num_ops++;
if (!bson_out) {
phongo_throw_exception(PHONGO_ERROR_LOGIC, "Did not receive result from bulk write. Please file a bug report.");
goto cleanup;
}
php_phongo_bulkwrite_extract_id(bson_out, &return_value);
cleanup:
bson_destroy(&bdocument);
bson_destroy(&boptions);
bson_clear(&bson_out);
} /* }}} */
/* {{{ proto void MongoDB\Driver\BulkWrite::update(array|object $query, array|object $newObj[, array $updateOptions = array()])
Adds an update operation to the BulkWrite */
static PHP_METHOD(BulkWrite, update)
{
zend_error_handling error_handling;
php_phongo_bulkwrite_t* intern;
zval * zquery, *zupdate, *zoptions = NULL;
bson_t bquery = BSON_INITIALIZER, bupdate = BSON_INITIALIZER, boptions = BSON_INITIALIZER;
bson_error_t error = { 0 };
intern = Z_BULKWRITE_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "AA|a!", &zquery, &zupdate, &zoptions) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL);
if (EG(exception)) {
goto cleanup;
}
php_phongo_zval_to_bson(zupdate, PHONGO_BSON_NONE, &bupdate, NULL);
if (EG(exception)) {
goto cleanup;
}
if (!php_phongo_bulkwrite_update_apply_options(&boptions, zoptions)) {
goto cleanup;
}
if (php_phongo_bulkwrite_update_has_operators(&bupdate) || php_phongo_bulkwrite_update_is_pipeline(&bupdate)) {
if (zoptions && php_array_fetchc_bool(zoptions, "multi")) {
if (!mongoc_bulk_operation_update_many_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
} else {
if (!mongoc_bulk_operation_update_one_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
}
} else {
if (zoptions && php_array_fetchc_bool(zoptions, "multi")) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Replacement document conflicts with true \"multi\" option");
goto cleanup;
}
if (!mongoc_bulk_operation_replace_one_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
}
intern->num_ops++;
cleanup:
bson_destroy(&bquery);
bson_destroy(&bupdate);
bson_destroy(&boptions);
} /* }}} */
/* {{{ proto void MongoDB\Driver\BulkWrite::delete(array|object $query[, array $deleteOptions = array()])
Adds a delete operation to the BulkWrite */
static PHP_METHOD(BulkWrite, delete)
{
zend_error_handling error_handling;
php_phongo_bulkwrite_t* intern;
zval * zquery, *zoptions = NULL;
bson_t bquery = BSON_INITIALIZER, boptions = BSON_INITIALIZER;
bson_error_t error = { 0 };
intern = Z_BULKWRITE_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "A|a!", &zquery, &zoptions) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL);
if (EG(exception)) {
goto cleanup;
}
if (!php_phongo_bulkwrite_delete_apply_options(&boptions, zoptions)) {
goto cleanup;
}
if (zoptions && php_array_fetchc_bool(zoptions, "limit")) {
if (!mongoc_bulk_operation_remove_one_with_opts(intern->bulk, &bquery, &boptions, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
} else {
if (!mongoc_bulk_operation_remove_many_with_opts(intern->bulk, &bquery, &boptions, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
}
intern->num_ops++;
cleanup:
bson_destroy(&bquery);
bson_destroy(&boptions);
} /* }}} */
/* {{{ proto integer MongoDB\Driver\BulkWrite::count()
Returns the number of operations that have been added to the BulkWrite */
static PHP_METHOD(BulkWrite, count)
{
zend_error_handling error_handling;
php_phongo_bulkwrite_t* intern;
intern = Z_BULKWRITE_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETURN_LONG(intern->num_ops);
} /* }}} */
/* {{{ MongoDB\Driver\BulkWrite function entries */
/* clang-format off */
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite___construct, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(ai_BulkWrite_count, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_insert, 0, 0, 1)
ZEND_ARG_INFO(0, document)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_update, 0, 0, 2)
ZEND_ARG_INFO(0, query)
ZEND_ARG_INFO(0, newObj)
ZEND_ARG_ARRAY_INFO(0, updateOptions, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_delete, 0, 0, 1)
ZEND_ARG_INFO(0, query)
ZEND_ARG_ARRAY_INFO(0, deleteOptions, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_bulkwrite_me[] = {
PHP_ME(BulkWrite, __construct, ai_BulkWrite___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, insert, ai_BulkWrite_insert, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, update, ai_BulkWrite_update, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, delete, ai_BulkWrite_delete, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(BulkWrite, count, ai_BulkWrite_count, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_BulkWrite_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
};
/* clang-format on */
/* }}} */
/* {{{ MongoDB\Driver\BulkWrite object handlers */
static zend_object_handlers php_phongo_handler_bulkwrite;
static void php_phongo_bulkwrite_free_object(zend_object* object) /* {{{ */
{
php_phongo_bulkwrite_t* intern = Z_OBJ_BULKWRITE(object);
zend_object_std_dtor(&intern->std);
if (intern->bulk) {
mongoc_bulk_operation_destroy(intern->bulk);
}
+ if (intern->let) {
+ bson_clear(&intern->let);
+ }
+
+ if (intern->comment) {
+ bson_value_destroy(intern->comment);
+ efree(intern->comment);
+ }
+
if (intern->database) {
efree(intern->database);
}
if (intern->collection) {
efree(intern->collection);
}
if (!Z_ISUNDEF(intern->session)) {
zval_ptr_dtor(&intern->session);
}
} /* }}} */
static zend_object* php_phongo_bulkwrite_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_bulkwrite_t* intern = zend_object_alloc(sizeof(php_phongo_bulkwrite_t), class_type);
zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
intern->std.handlers = &php_phongo_handler_bulkwrite;
return &intern->std;
} /* }}} */
static HashTable* php_phongo_bulkwrite_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
zval retval = ZVAL_STATIC_INIT;
php_phongo_bulkwrite_t* intern = NULL;
*is_temp = 1;
intern = Z_OBJ_BULKWRITE(PHONGO_COMPAT_GET_OBJ(object));
array_init(&retval);
if (intern->database) {
ADD_ASSOC_STRING(&retval, "database", intern->database);
} else {
ADD_ASSOC_NULL_EX(&retval, "database");
}
if (intern->collection) {
ADD_ASSOC_STRING(&retval, "collection", intern->collection);
} else {
ADD_ASSOC_NULL_EX(&retval, "collection");
}
ADD_ASSOC_BOOL_EX(&retval, "ordered", intern->ordered);
if (intern->bypass != PHONGO_BULKWRITE_BYPASS_UNSET) {
ADD_ASSOC_BOOL_EX(&retval, "bypassDocumentValidation", intern->bypass);
} else {
ADD_ASSOC_NULL_EX(&retval, "bypassDocumentValidation");
}
+ if (intern->comment) {
+ zval zv;
+
+ if (!php_phongo_bson_value_to_zval(intern->comment, &zv)) {
+ zval_ptr_dtor(&zv);
+ goto done;
+ }
+
+ ADD_ASSOC_ZVAL_EX(&retval, "comment", &zv);
+ }
+
+ if (intern->let) {
+ zval zv;
+
+ if (!php_phongo_bson_to_zval(bson_get_data(intern->let), intern->let->len, &zv)) {
+ zval_ptr_dtor(&zv);
+ goto done;
+ }
+
+ ADD_ASSOC_ZVAL_EX(&retval, "let", &zv);
+ }
+
ADD_ASSOC_BOOL_EX(&retval, "executed", intern->executed);
ADD_ASSOC_LONG_EX(&retval, "server_id", mongoc_bulk_operation_get_hint(intern->bulk));
if (!Z_ISUNDEF(intern->session)) {
ADD_ASSOC_ZVAL_EX(&retval, "session", &intern->session);
Z_ADDREF(intern->session);
} else {
ADD_ASSOC_NULL_EX(&retval, "session");
}
if (mongoc_bulk_operation_get_write_concern(intern->bulk)) {
zval write_concern;
php_phongo_write_concern_to_zval(&write_concern, mongoc_bulk_operation_get_write_concern(intern->bulk));
ADD_ASSOC_ZVAL_EX(&retval, "write_concern", &write_concern);
} else {
ADD_ASSOC_NULL_EX(&retval, "write_concern");
}
+done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "BulkWrite", php_phongo_bulkwrite_me);
php_phongo_bulkwrite_ce = zend_register_internal_class(&ce);
php_phongo_bulkwrite_ce->create_object = php_phongo_bulkwrite_create_object;
PHONGO_CE_FINAL(php_phongo_bulkwrite_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_bulkwrite_ce);
memcpy(&php_phongo_handler_bulkwrite, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_bulkwrite.get_debug_info = php_phongo_bulkwrite_get_debug_info;
php_phongo_handler_bulkwrite.free_obj = php_phongo_bulkwrite_free_object;
php_phongo_handler_bulkwrite.offset = XtOffsetOf(php_phongo_bulkwrite_t, std);
zend_class_implements(php_phongo_bulkwrite_ce, 1, zend_ce_countable);
} /* }}} */
diff --git a/mongodb-1.13.0/src/MongoDB/ClientEncryption.c b/mongodb-1.14.0/src/MongoDB/ClientEncryption.c
similarity index 81%
rename from mongodb-1.13.0/src/MongoDB/ClientEncryption.c
rename to mongodb-1.14.0/src/MongoDB/ClientEncryption.c
index 792dead2..f9811e6b 100644
--- a/mongodb-1.13.0/src/MongoDB/ClientEncryption.c
+++ b/mongodb-1.14.0/src/MongoDB/ClientEncryption.c
@@ -1,581 +1,644 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "php_array_api.h"
#include "php_phongo.h"
#include "phongo_bson_encode.h"
#include "phongo_error.h"
#include "phongo_util.h"
+#include "MongoDB/ClientEncryption.h"
+
zend_class_entry* php_phongo_clientencryption_ce;
/* Forward declarations */
static void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options);
static void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options);
static void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue);
+/* {{{ proto void MongoDB\Driver\ClientEncryption::__construct(array $options)
+ Constructs a new ClientEncryption */
+static PHP_METHOD(ClientEncryption, __construct)
+{
+ zval* options;
+
+ PHONGO_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ARRAY(options)
+ PHONGO_PARSE_PARAMETERS_END();
+
+ /* An exception will be thrown on error. */
+ phongo_clientencryption_init(Z_CLIENTENCRYPTION_OBJ_P(getThis()), options, NULL);
+} /* }}} */
+
/* {{{ proto MongoDB\BSON\Binary MongoDB\Driver\ClientEncryption::createDataKey(string $kmsProvider[, array $options])
Creates a new key document and inserts into the key vault collection. */
static PHP_METHOD(ClientEncryption, createDataKey)
{
char* kms_provider = NULL;
size_t kms_provider_len = 0;
zval* options = NULL;
zend_error_handling error_handling;
php_phongo_clientencryption_t* intern;
intern = Z_CLIENTENCRYPTION_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a!", &kms_provider, &kms_provider_len, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_clientencryption_create_datakey(intern, return_value, kms_provider, options);
} /* }}} */
/* {{{ proto MongoDB\BSON\Binary MongoDB\Driver\ClientEncryption::encrypt(mixed $value[, array $options])
Encrypts a value with a given key and algorithm */
static PHP_METHOD(ClientEncryption, encrypt)
{
zval* value = NULL;
zval* options = NULL;
zend_error_handling error_handling;
php_phongo_clientencryption_t* intern;
intern = Z_CLIENTENCRYPTION_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|a!", &value, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_clientencryption_encrypt(intern, value, return_value, options);
} /* }}} */
/* {{{ proto mixed MongoDB\Driver\ClientEncryption::decrypt(MongoDB\BSON\BinaryInterface $value)
Decrypts an encrypted value (BSON binary of subtype 6). Returns the original BSON value */
static PHP_METHOD(ClientEncryption, decrypt)
{
zval* ciphertext;
zend_error_handling error_handling;
php_phongo_clientencryption_t* intern;
intern = Z_CLIENTENCRYPTION_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &ciphertext, php_phongo_binary_interface_ce) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_clientencryption_decrypt(intern, ciphertext, return_value);
} /* }}} */
+ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption___construct, 0, 0, 0)
+ ZEND_ARG_ARRAY_INFO(0, options, 1)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_createDataKey, 0, 0, 1)
ZEND_ARG_INFO(0, kmsProvider)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_encrypt, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_decrypt, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, keyVaultClient, MongoDB\\BSON\\BinaryInterface, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_ClientEncryption_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_clientencryption_me[] = {
/* clang-format off */
+ PHP_ME(ClientEncryption, __construct, ai_ClientEncryption___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ClientEncryption, createDataKey, ai_ClientEncryption_createDataKey, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ClientEncryption, encrypt, ai_ClientEncryption_encrypt, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(ClientEncryption, decrypt, ai_ClientEncryption_decrypt, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
- ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_ClientEncryption_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_ClientEncryption_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\ClientEncryption object handlers */
static zend_object_handlers php_phongo_handler_clientencryption;
static void php_phongo_clientencryption_free_object(zend_object* object) /* {{{ */
{
php_phongo_clientencryption_t* intern = Z_OBJ_CLIENTENCRYPTION(object);
zend_object_std_dtor(&intern->std);
if (intern->client_encryption) {
mongoc_client_encryption_destroy(intern->client_encryption);
}
/* Free the keyVaultClient last to ensure that a potential non-persistent
* client outlives the mongoc_client_encryption_t as needed */
if (!Z_ISUNDEF(intern->key_vault_client_manager)) {
zval_ptr_dtor(&intern->key_vault_client_manager);
}
} /* }}} */
static zend_object* php_phongo_clientencryption_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_clientencryption_t* intern = zend_object_alloc(sizeof(php_phongo_clientencryption_t), class_type);
zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
intern->std.handlers = &php_phongo_handler_clientencryption;
return &intern->std;
} /* }}} */
static HashTable* php_phongo_clientencryption_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_clientencryption_t* intern = NULL;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_OBJ_CLIENTENCRYPTION(PHONGO_COMPAT_GET_OBJ(object));
array_init(&retval);
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "ClientEncryption", php_phongo_clientencryption_me);
php_phongo_clientencryption_ce = zend_register_internal_class(&ce);
php_phongo_clientencryption_ce->create_object = php_phongo_clientencryption_create_object;
PHONGO_CE_FINAL(php_phongo_clientencryption_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_clientencryption_ce);
memcpy(&php_phongo_handler_clientencryption, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_clientencryption.get_debug_info = php_phongo_clientencryption_get_debug_info;
php_phongo_handler_clientencryption.free_obj = php_phongo_clientencryption_free_object;
php_phongo_handler_clientencryption.offset = XtOffsetOf(php_phongo_clientencryption_t, std);
zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC"), MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM"), MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM);
+ zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("ALGORITHM_INDEXED"), MONGOC_ENCRYPT_ALGORITHM_INDEXED);
+ zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("ALGORITHM_UNINDEXED"), MONGOC_ENCRYPT_ALGORITHM_UNINDEXED);
+ zend_declare_class_constant_string(php_phongo_clientencryption_ce, ZEND_STRL("QUERY_TYPE_EQUALITY"), MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY);
} /* }}} */
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
-/* keyVaultClientManager is an output parameter and will be assigned the
- * keyVaultNamespace Manager (if any). */
-static mongoc_client_encryption_opts_t* phongo_clientencryption_opts_from_zval(zval* defaultKeyVaultClient, zval* options, zval** keyVaultClientManager) /* {{{ */
+/* key_vault_client_manager is an output parameter and will be assigned to the
+ * effective keyVaultClient. */
+static mongoc_client_encryption_opts_t* phongo_clientencryption_opts_from_zval(zval* options, zval* default_key_vault_client_manager, zval** key_vault_client_manager) /* {{{ */
{
- mongoc_client_encryption_opts_t* opts;
+ mongoc_client_encryption_opts_t* opts = mongoc_client_encryption_opts_new();
- opts = mongoc_client_encryption_opts_new();
- *keyVaultClientManager = NULL;
+ *key_vault_client_manager = NULL;
if (!options || Z_TYPE_P(options) != IS_ARRAY) {
/* Returning opts as-is will defer to mongoc_client_encryption_new to
* raise an error for missing required options */
return opts;
}
if (php_array_existsc(options, "keyVaultClient")) {
zval* key_vault_client = php_array_fetch(options, "keyVaultClient");
if (Z_TYPE_P(key_vault_client) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(key_vault_client), php_phongo_manager_ce)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultClient\" encryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultClient\" option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
goto cleanup;
}
mongoc_client_encryption_opts_set_keyvault_client(opts, Z_MANAGER_OBJ_P(key_vault_client)->client);
- *keyVaultClientManager = key_vault_client;
+ *key_vault_client_manager = key_vault_client;
+ } else if (default_key_vault_client_manager) {
+ mongoc_client_encryption_opts_set_keyvault_client(opts, Z_MANAGER_OBJ_P(default_key_vault_client_manager)->client);
+ *key_vault_client_manager = default_key_vault_client_manager;
} else {
- mongoc_client_encryption_opts_set_keyvault_client(opts, Z_MANAGER_OBJ_P(defaultKeyVaultClient)->client);
- *keyVaultClientManager = defaultKeyVaultClient;
+ /* If the ClientEncryption object is being constructed directly, the
+ * "keyVaultClient" option must be explicitly provided. */
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "The \"keyVaultClient\" option is required when constructing a ClientEncryption object directly");
+ goto cleanup;
}
if (php_array_existsc(options, "keyVaultNamespace")) {
char* keyvault_namespace;
char* db_name;
char* coll_name;
int plen;
zend_bool pfree;
keyvault_namespace = php_array_fetchc_string(options, "keyVaultNamespace", &plen, &pfree);
if (!phongo_split_namespace(keyvault_namespace, &db_name, &coll_name)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultNamespace\" encryption option to contain a full collection name");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultNamespace\" option to contain a full collection namespace");
if (pfree) {
efree(keyvault_namespace);
}
goto cleanup;
}
mongoc_client_encryption_opts_set_keyvault_namespace(opts, db_name, coll_name);
efree(db_name);
efree(coll_name);
if (pfree) {
efree(keyvault_namespace);
}
}
if (php_array_existsc(options, "kmsProviders")) {
zval* kms_providers = php_array_fetchc(options, "kmsProviders");
bson_t bson_providers = BSON_INITIALIZER;
if (Z_TYPE_P(kms_providers) != IS_ARRAY && Z_TYPE_P(kms_providers) != IS_OBJECT) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"kmsProviders\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"kmsProviders\" option to be an array or object, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(kms_providers));
goto cleanup;
}
php_phongo_zval_to_bson(kms_providers, PHONGO_BSON_NONE, &bson_providers, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_client_encryption_opts_set_kms_providers(opts, &bson_providers);
bson_destroy(&bson_providers);
}
if (php_array_existsc(options, "tlsOptions")) {
zval* tls_options = php_array_fetchc(options, "tlsOptions");
bson_t bson_options = BSON_INITIALIZER;
if (Z_TYPE_P(tls_options) != IS_ARRAY && Z_TYPE_P(tls_options) != IS_OBJECT) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"tlsOptions\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"tlsOptions\" option to be an array or object, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(tls_options));
goto cleanup;
}
php_phongo_zval_to_bson(tls_options, PHONGO_BSON_NONE, &bson_options, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_client_encryption_opts_set_tls_opts(opts, &bson_options);
bson_destroy(&bson_options);
}
return opts;
cleanup:
if (opts) {
mongoc_client_encryption_opts_destroy(opts);
}
return NULL;
} /* }}} */
-void phongo_clientencryption_init(zval* return_value, zval* manager, zval* options) /* {{{ */
+void phongo_clientencryption_init(php_phongo_clientencryption_t* intern, zval* options, zval* default_key_vault_client_manager) /* {{{ */
{
- php_phongo_clientencryption_t* intern;
mongoc_client_encryption_t* client_encryption;
mongoc_client_encryption_opts_t* opts;
- zval* key_vault_client_manager = manager;
+ zval* key_vault_client_manager = NULL;
bson_error_t error = { 0 };
- opts = phongo_clientencryption_opts_from_zval(manager, options, &key_vault_client_manager);
+ opts = phongo_clientencryption_opts_from_zval(options, default_key_vault_client_manager, &key_vault_client_manager);
+
if (!opts) {
/* Exception already thrown */
goto cleanup;
}
client_encryption = mongoc_client_encryption_new(opts, &error);
+
if (!client_encryption) {
phongo_throw_exception_from_bson_error_t(&error);
-
goto cleanup;
}
- object_init_ex(return_value, php_phongo_clientencryption_ce);
-
- intern = Z_CLIENTENCRYPTION_OBJ_P(return_value);
intern->client_encryption = client_encryption;
- ZVAL_ZVAL(&intern->key_vault_client_manager, key_vault_client_manager, 1, 0);
+
+ /* Note: key_vault_client_manager should always be assigned if options were
+ * successfully parsed by phongo_clientencryption_opts_from_zval, but let's
+ * be defensive. */
+ if (key_vault_client_manager) {
+ ZVAL_ZVAL(&intern->key_vault_client_manager, key_vault_client_manager, 1, 0);
+ }
cleanup:
if (opts) {
mongoc_client_encryption_opts_destroy(opts);
}
} /* }}} */
static mongoc_client_encryption_datakey_opts_t* phongo_clientencryption_datakey_opts_from_zval(zval* options) /* {{{ */
{
mongoc_client_encryption_datakey_opts_t* opts;
opts = mongoc_client_encryption_datakey_opts_new();
if (!options || Z_TYPE_P(options) != IS_ARRAY) {
return opts;
}
if (php_array_existsc(options, "keyAltNames")) {
zval* zkeyaltnames = php_array_fetchc(options, "keyAltNames");
HashTable* ht_data;
uint32_t keyaltnames_count;
char** keyaltnames;
uint32_t i = 0;
uint32_t j = 0;
bool failed = false;
if (!zkeyaltnames || Z_TYPE_P(zkeyaltnames) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected keyAltNames to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zkeyaltnames));
goto cleanup;
}
ht_data = HASH_OF(zkeyaltnames);
keyaltnames_count = ht_data ? zend_hash_num_elements(ht_data) : 0;
keyaltnames = ecalloc(keyaltnames_count, sizeof(char*));
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* keyaltname;
ZEND_HASH_FOREACH_KEY_VAL(ht_data, num_key, string_key, keyaltname)
{
if (i >= keyaltnames_count) {
phongo_throw_exception(PHONGO_ERROR_LOGIC, "Iterating over too many keyAltNames. Please file a bug report");
failed = true;
break;
}
if (Z_TYPE_P(keyaltname) != IS_STRING) {
if (string_key) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected keyAltName with index \"%s\" to be string, %s given", ZSTR_VAL(string_key), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(keyaltname));
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected keyAltName with index \"%lu\" to be string, %s given", num_key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(keyaltname));
}
failed = true;
break;
}
keyaltnames[i] = estrdup(Z_STRVAL_P(keyaltname));
i++;
}
ZEND_HASH_FOREACH_END();
}
if (!failed) {
mongoc_client_encryption_datakey_opts_set_keyaltnames(opts, keyaltnames, keyaltnames_count);
}
for (j = 0; j < i; j++) {
efree(keyaltnames[j]);
}
efree(keyaltnames);
if (failed) {
goto cleanup;
}
}
if (php_array_existsc(options, "masterKey")) {
bson_t masterkey = BSON_INITIALIZER;
php_phongo_zval_to_bson(php_array_fetchc(options, "masterKey"), PHONGO_BSON_NONE, &masterkey, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_client_encryption_datakey_opts_set_masterkey(opts, &masterkey);
}
return opts;
cleanup:
if (opts) {
mongoc_client_encryption_datakey_opts_destroy(opts);
}
return NULL;
} /* }}} */
static void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options) /* {{{ */
{
mongoc_client_encryption_datakey_opts_t* opts;
- bson_value_t keyid;
+ bson_value_t keyid = { 0 };
bson_error_t error = { 0 };
opts = phongo_clientencryption_datakey_opts_from_zval(options);
+
if (!opts) {
/* Exception already thrown */
goto cleanup;
}
if (!mongoc_client_encryption_create_datakey(clientencryption->client_encryption, kms_provider, opts, &keyid, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
if (!php_phongo_bson_value_to_zval(&keyid, return_value)) {
/* Exception already thrown */
goto cleanup;
}
cleanup:
if (opts) {
mongoc_client_encryption_datakey_opts_destroy(opts);
}
+
+ bson_value_destroy(&keyid);
} /* }}} */
static mongoc_client_encryption_encrypt_opts_t* phongo_clientencryption_encrypt_opts_from_zval(zval* options) /* {{{ */
{
mongoc_client_encryption_encrypt_opts_t* opts;
opts = mongoc_client_encryption_encrypt_opts_new();
if (!options || Z_TYPE_P(options) != IS_ARRAY) {
return opts;
}
+ if (php_array_existsc(options, "contentionFactor")) {
+ mongoc_client_encryption_encrypt_opts_set_contention_factor(opts, php_array_fetch_long(options, "contentionFactor"));
+ }
+
if (php_array_existsc(options, "keyId")) {
- bson_value_t keyid;
+ bson_value_t keyid = { 0 };
php_phongo_zval_to_bson_value(php_array_fetchc(options, "keyId"), PHONGO_BSON_NONE, &keyid);
+
if (EG(exception)) {
+ bson_value_destroy(&keyid);
goto cleanup;
}
mongoc_client_encryption_encrypt_opts_set_keyid(opts, &keyid);
+ bson_value_destroy(&keyid);
}
if (php_array_existsc(options, "keyAltName")) {
char* keyaltname;
int plen;
zend_bool pfree;
keyaltname = php_array_fetch_string(options, "keyAltName", &plen, &pfree);
mongoc_client_encryption_encrypt_opts_set_keyaltname(opts, keyaltname);
if (pfree) {
efree(keyaltname);
}
}
if (php_array_existsc(options, "algorithm")) {
char* algorithm;
int plen;
zend_bool pfree;
algorithm = php_array_fetch_string(options, "algorithm", &plen, &pfree);
mongoc_client_encryption_encrypt_opts_set_algorithm(opts, algorithm);
if (pfree) {
efree(algorithm);
}
}
+ if (php_array_existsc(options, "queryType")) {
+ char* querytype;
+ int plen;
+ zend_bool pfree;
+
+ querytype = php_array_fetch_string(options, "queryType", &plen, &pfree);
+ mongoc_client_encryption_encrypt_opts_set_query_type(opts, querytype);
+
+ if (pfree) {
+ efree(querytype);
+ }
+ }
+
return opts;
cleanup:
if (opts) {
mongoc_client_encryption_encrypt_opts_destroy(opts);
}
return NULL;
} /* }}} */
static void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options) /* {{{ */
{
mongoc_client_encryption_encrypt_opts_t* opts;
- bson_value_t ciphertext, value;
- bson_error_t error = { 0 };
+ bson_value_t ciphertext = { 0 };
+ bson_value_t value = { 0 };
+ bson_error_t error = { 0 };
php_phongo_zval_to_bson_value(zvalue, PHONGO_BSON_NONE, &value);
opts = phongo_clientencryption_encrypt_opts_from_zval(options);
+
if (!opts) {
/* Exception already thrown */
goto cleanup;
}
if (!mongoc_client_encryption_encrypt(clientencryption->client_encryption, &value, opts, &ciphertext, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
if (!php_phongo_bson_value_to_zval(&ciphertext, zciphertext)) {
/* Exception already thrown */
goto cleanup;
}
cleanup:
if (opts) {
mongoc_client_encryption_encrypt_opts_destroy(opts);
}
+
+ bson_value_destroy(&ciphertext);
+ bson_value_destroy(&value);
} /* }}} */
static void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue) /* {{{ */
{
- bson_value_t ciphertext, value;
- bson_error_t error = { 0 };
+ bson_value_t ciphertext = { 0 };
+ bson_value_t value = { 0 };
+ bson_error_t error = { 0 };
php_phongo_zval_to_bson_value(zciphertext, PHONGO_BSON_NONE, &ciphertext);
if (!mongoc_client_encryption_decrypt(clientencryption->client_encryption, &ciphertext, &value, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
- return;
+ goto cleanup;
}
if (!php_phongo_bson_value_to_zval(&value, zvalue)) {
/* Exception already thrown */
- return;
+ goto cleanup;
}
+
+cleanup:
+ bson_value_destroy(&ciphertext);
+ bson_value_destroy(&value);
} /* }}} */
#else /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
-void phongo_clientencryption_init(php_phongo_clientencryption_t* clientencryption, zval* manager, zval* options) /* {{{ */
+void phongo_clientencryption_init(php_phongo_clientencryption_t* intern, zval* options, zval* default_key_vault_client_manager) /* {{{ */
{
phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot configure clientEncryption object.");
}
/* }}} */
static void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options) /* {{{ */
{
phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot create encryption key.");
}
/* }}} */
static void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options) /* {{{ */
{
phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot encrypt value.");
}
/* }}} */
static void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue) /* {{{ */
{
phongo_throw_exception_no_cse(PHONGO_ERROR_RUNTIME, "Cannot decrypt value.");
}
/* }}} */
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
diff --git a/mongodb-1.13.0/src/MongoDB/ClientEncryption.h b/mongodb-1.14.0/src/MongoDB/ClientEncryption.h
similarity index 85%
rename from mongodb-1.13.0/src/MongoDB/ClientEncryption.h
rename to mongodb-1.14.0/src/MongoDB/ClientEncryption.h
index 51fe33da..f61d65ed 100644
--- a/mongodb-1.13.0/src/MongoDB/ClientEncryption.h
+++ b/mongodb-1.14.0/src/MongoDB/ClientEncryption.h
@@ -1,24 +1,24 @@
/*
* Copyright 2022-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PHONGO_CLIENTENCRYPTION_H
#define PHONGO_CLIENTENCRYPTION_H
#include <php.h>
-void phongo_clientencryption_init(zval* return_value, zval* manager, zval* options);
+void phongo_clientencryption_init(php_phongo_clientencryption_t* intern, zval* options, zval* default_key_vault_client_manager);
#endif /* PHONGO_CLIENTENCRYPTION_H */
diff --git a/mongodb-1.13.0/src/MongoDB/Command.c b/mongodb-1.14.0/src/MongoDB/Command.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Command.c
rename to mongodb-1.14.0/src/MongoDB/Command.c
diff --git a/mongodb-1.13.0/src/MongoDB/Cursor.c b/mongodb-1.14.0/src/MongoDB/Cursor.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Cursor.c
rename to mongodb-1.14.0/src/MongoDB/Cursor.c
diff --git a/mongodb-1.13.0/src/MongoDB/Cursor.h b/mongodb-1.14.0/src/MongoDB/Cursor.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Cursor.h
rename to mongodb-1.14.0/src/MongoDB/Cursor.h
diff --git a/mongodb-1.13.0/src/MongoDB/CursorId.c b/mongodb-1.14.0/src/MongoDB/CursorId.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/CursorId.c
rename to mongodb-1.14.0/src/MongoDB/CursorId.c
diff --git a/mongodb-1.13.0/src/MongoDB/CursorInterface.c b/mongodb-1.14.0/src/MongoDB/CursorInterface.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/CursorInterface.c
rename to mongodb-1.14.0/src/MongoDB/CursorInterface.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/AuthenticationException.c b/mongodb-1.14.0/src/MongoDB/Exception/AuthenticationException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/AuthenticationException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/AuthenticationException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/BulkWriteException.c b/mongodb-1.14.0/src/MongoDB/Exception/BulkWriteException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/BulkWriteException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/BulkWriteException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/CommandException.c b/mongodb-1.14.0/src/MongoDB/Exception/CommandException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/CommandException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/CommandException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/ConnectionException.c b/mongodb-1.14.0/src/MongoDB/Exception/ConnectionException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/ConnectionException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/ConnectionException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/ConnectionTimeoutException.c b/mongodb-1.14.0/src/MongoDB/Exception/ConnectionTimeoutException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/ConnectionTimeoutException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/ConnectionTimeoutException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/EncryptionException.c b/mongodb-1.14.0/src/MongoDB/Exception/EncryptionException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/EncryptionException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/EncryptionException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/Exception.c b/mongodb-1.14.0/src/MongoDB/Exception/Exception.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/Exception.c
rename to mongodb-1.14.0/src/MongoDB/Exception/Exception.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/ExecutionTimeoutException.c b/mongodb-1.14.0/src/MongoDB/Exception/ExecutionTimeoutException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/ExecutionTimeoutException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/ExecutionTimeoutException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/InvalidArgumentException.c b/mongodb-1.14.0/src/MongoDB/Exception/InvalidArgumentException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/InvalidArgumentException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/InvalidArgumentException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/LogicException.c b/mongodb-1.14.0/src/MongoDB/Exception/LogicException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/LogicException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/LogicException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/RuntimeException.c b/mongodb-1.14.0/src/MongoDB/Exception/RuntimeException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/RuntimeException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/RuntimeException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/SSLConnectionException.c b/mongodb-1.14.0/src/MongoDB/Exception/SSLConnectionException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/SSLConnectionException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/SSLConnectionException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/ServerException.c b/mongodb-1.14.0/src/MongoDB/Exception/ServerException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/ServerException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/ServerException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/UnexpectedValueException.c b/mongodb-1.14.0/src/MongoDB/Exception/UnexpectedValueException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/UnexpectedValueException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/UnexpectedValueException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Exception/WriteException.c b/mongodb-1.14.0/src/MongoDB/Exception/WriteException.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Exception/WriteException.c
rename to mongodb-1.14.0/src/MongoDB/Exception/WriteException.c
diff --git a/mongodb-1.13.0/src/MongoDB/Manager.c b/mongodb-1.14.0/src/MongoDB/Manager.c
similarity index 97%
rename from mongodb-1.13.0/src/MongoDB/Manager.c
rename to mongodb-1.14.0/src/MongoDB/Manager.c
index 5e85e043..09b844c8 100644
--- a/mongodb-1.13.0/src/MongoDB/Manager.c
+++ b/mongodb-1.14.0/src/MongoDB/Manager.c
@@ -1,1022 +1,1040 @@
/*
* Copyright 2014-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <ext/standard/file.h>
#include <Zend/zend_interfaces.h>
#include "php_array_api.h"
#include "php_phongo.h"
#include "phongo_apm.h"
#include "phongo_client.h"
#include "phongo_error.h"
#include "phongo_execute.h"
#include "phongo_util.h"
#include "MongoDB/ClientEncryption.h"
#include "MongoDB/ReadConcern.h"
#include "MongoDB/ReadPreference.h"
#include "MongoDB/Server.h"
#include "MongoDB/Session.h"
#include "MongoDB/WriteConcern.h"
#define PHONGO_MANAGER_URI_DEFAULT "mongodb://127.0.0.1/"
/**
* Manager abstracts a cluster of Server objects (i.e. socket connections).
*
* Typically, users will connect to a cluster using a URI, and the Manager will
* perform tasks such as replica set discovery and create the necessary Server
* objects. That said, it is also possible to create a Manager with an arbitrary
* collection of Server objects using the static factory method (this can be
* useful for testing or administration).
*
* Operation methods do not take socket-level options (e.g. socketTimeoutMS).
* Those options should be specified during construction.
*/
zend_class_entry* php_phongo_manager_ce;
/* Checks if driverOptions contains a stream context resource in the "context"
* key and incorporates any of its SSL options into the base array that did not
* already exist (i.e. array union). The "context" key is then unset from the
* base array.
*
* This handles the merging of any legacy SSL context options and also makes
* driverOptions suitable for serialization by removing the resource zval. */
static bool php_phongo_manager_merge_context_options(zval* zdriverOptions) /* {{{ */
{
php_stream_context* context;
zval * zcontext, *zcontextOptions;
if (!php_array_existsc(zdriverOptions, "context")) {
return true;
}
zcontext = php_array_fetchc(zdriverOptions, "context");
context = php_stream_context_from_zval(zcontext, 1);
if (!context) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"context\" driver option is not a valid Stream-Context resource");
return false;
}
zcontextOptions = php_array_fetchc_array(&context->options, "ssl");
if (!zcontextOptions) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Stream-Context resource does not contain \"ssl\" options array");
return false;
}
/* When running PHP in debug mode, php_error_docref duplicates the current
* scope, leading to a COW violation in zend_hash_merge and
* zend_symtable_str_del (called by php_array_unsetc). This macro allows
* that violation in debug mode and is a NOOP when in non-debug. */
HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(zdriverOptions));
php_error_docref(NULL, E_DEPRECATED, "The \"context\" driver option is deprecated.");
/* Perform array union (see: add_function() in zend_operators.c) */
zend_hash_merge(Z_ARRVAL_P(zdriverOptions), Z_ARRVAL_P(zcontextOptions), zval_add_ref, 0);
php_array_unsetc(zdriverOptions, "context");
return true;
} /* }}} */
/* Prepare authMechanismProperties for BSON encoding by converting a boolean
* value for the "CANONICALIZE_HOST_NAME" option to a string.
*
* Note: URI options are case-insensitive, so we must iterate through the
* HashTable in order to detect options. */
static void php_phongo_manager_prep_authmechanismproperties(zval* properties) /* {{{ */
{
HashTable* ht_data;
if (Z_TYPE_P(properties) != IS_ARRAY && Z_TYPE_P(properties) != IS_OBJECT) {
return;
}
ht_data = HASH_OF(properties);
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* property;
ZEND_HASH_FOREACH_KEY_VAL_IND(ht_data, num_key, string_key, property)
{
if (!string_key) {
continue;
}
/* URI options are case-insensitive */
if (!strcasecmp(ZSTR_VAL(string_key), "CANONICALIZE_HOST_NAME")) {
ZVAL_DEREF(property);
if (Z_TYPE_P(property) != IS_STRING && zend_is_true(property)) {
SEPARATE_ZVAL_NOREF(property);
ZVAL_NEW_STR(property, zend_string_init(ZEND_STRL("true"), 0));
}
}
}
ZEND_HASH_FOREACH_END();
}
} /* }}} */
/* Prepare URI options for BSON encoding.
*
* Read preference tag sets must be an array of documents. In order to ensure
* that empty arrays serialize as empty documents, array elements will be
* converted to objects. php_phongo_read_preference_tags_are_valid() handles
* actual validation of the tag set structure.
*
* Auth mechanism properties must have string values, so a boolean true value
* for the "CANONICALIZE_HOST_NAME" property will be converted to "true".
*
* Note: URI options are case-insensitive, so we must iterate through the
* HashTable in order to detect options. */
static void php_phongo_manager_prep_uri_options(zval* options) /* {{{ */
{
HashTable* ht_data;
if (Z_TYPE_P(options) != IS_ARRAY) {
return;
}
ht_data = HASH_OF(options);
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* option;
ZEND_HASH_FOREACH_KEY_VAL_IND(ht_data, num_key, string_key, option)
{
if (!string_key) {
continue;
}
if (!strcasecmp(ZSTR_VAL(string_key), MONGOC_URI_READPREFERENCETAGS)) {
ZVAL_DEREF(option);
SEPARATE_ZVAL_NOREF(option);
php_phongo_read_preference_prep_tagsets(option);
continue;
}
if (!strcasecmp(ZSTR_VAL(string_key), MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
ZVAL_DEREF(option);
SEPARATE_ZVAL_NOREF(option);
php_phongo_manager_prep_authmechanismproperties(option);
continue;
}
}
ZEND_HASH_FOREACH_END();
}
} /* }}} */
/* Selects a server for an execute method. If "for_writes" is true, a primary
* will be selected. Otherwise, a read preference will be used to select the
* server. If zreadPreference is NULL, the client's read preference will be
* used. If zsession is a session object in a sharded transaction, the session
* will be checked whether it is pinned to a server. If so, that server will be
* selected. Otherwise, server selection
*
* On success, server_id will be set and the function will return true;
* otherwise, false is returned and an exception is thrown. */
static bool php_phongo_manager_select_server(bool for_writes, bool inherit_read_preference, zval* zreadPreference, zval* zsession, mongoc_client_t* client, uint32_t* server_id) /* {{{ */
{
mongoc_server_description_t* selected_server;
const mongoc_read_prefs_t* read_preference = NULL;
bson_error_t error = { 0 };
if (zsession) {
const mongoc_client_session_t* session = Z_SESSION_OBJ_P(zsession)->client_session;
/* Attempt to fetch server pinned to session */
if (mongoc_client_session_get_server_id(session) > 0) {
*server_id = mongoc_client_session_get_server_id(session);
return true;
}
}
if (!for_writes) {
if (zreadPreference) {
read_preference = phongo_read_preference_from_zval(zreadPreference);
} else if (inherit_read_preference) {
read_preference = mongoc_client_get_read_prefs(client);
}
}
selected_server = mongoc_client_select_server(client, for_writes, read_preference, &error);
if (selected_server) {
*server_id = mongoc_server_description_id(selected_server);
mongoc_server_description_destroy(selected_server);
return true;
}
/* Check for connection related exceptions */
if (!EG(exception)) {
phongo_throw_exception_from_bson_error_t(&error);
}
return false;
} /* }}} */
/* {{{ proto void MongoDB\Driver\Manager::__construct([string $uri = "mongodb://127.0.0.1/"[, array $options = array()[, array $driverOptions = array()]]])
Constructs a new Manager */
static PHP_METHOD(Manager, __construct)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
char* uri_string = NULL;
size_t uri_string_len = 0;
zval* options = NULL;
zval* driverOptions = NULL;
intern = Z_MANAGER_OBJ_P(getThis());
/* Separate the options and driverOptions zvals, since we may end up
* modifying them in php_phongo_manager_prep_uri_options() and
* php_phongo_manager_merge_context_options() below, respectively. */
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!a/!a/!", &uri_string, &uri_string_len, &options, &driverOptions) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
if (options) {
php_phongo_manager_prep_uri_options(options);
}
if (driverOptions && !php_phongo_manager_merge_context_options(driverOptions)) {
/* Exception should already have been thrown */
return;
}
phongo_manager_init(intern, uri_string ? uri_string : PHONGO_MANAGER_URI_DEFAULT, options, driverOptions);
if (EG(exception)) {
return;
}
/* Update the request-scoped Manager registry */
if (!php_phongo_manager_register(intern)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to add Manager to internal registry");
}
} /* }}} */
/* {{{ proto void MongoDB\Driver\Manager::addSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber)
Registers an event subscriber for this Manager */
static PHP_METHOD(Manager, addSubscriber)
{
php_phongo_manager_t* intern;
zval* subscriber;
PHONGO_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_OBJECT_OF_CLASS(subscriber, php_phongo_subscriber_ce)
PHONGO_PARSE_PARAMETERS_END();
intern = Z_MANAGER_OBJ_P(getThis());
/* Lazily initialize the subscriber HashTable */
if (!intern->subscribers) {
ALLOC_HASHTABLE(intern->subscribers);
zend_hash_init(intern->subscribers, 0, NULL, ZVAL_PTR_DTOR, 0);
}
phongo_apm_add_subscriber(intern->subscribers, subscriber);
} /* }}} */
/* {{{ proto MongoDB\Driver\ClientEncryption MongoDB\Driver\Manager::createClientEncryption(array $options)
Return a ClientEncryption instance */
static PHP_METHOD(Manager, createClientEncryption)
{
- zend_error_handling error_handling;
- zval* options;
+ zval* options;
- zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &options) == FAILURE) {
- zend_restore_error_handling(&error_handling);
- return;
- }
- zend_restore_error_handling(&error_handling);
+ PHONGO_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ARRAY(options)
+ PHONGO_PARSE_PARAMETERS_END();
+
+ object_init_ex(return_value, php_phongo_clientencryption_ce);
/* An exception will be thrown on error. */
- phongo_clientencryption_init(return_value, getThis(), options);
+ phongo_clientencryption_init(Z_CLIENTENCRYPTION_OBJ_P(return_value), options, getThis());
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a Command */
static PHP_METHOD(Manager, executeCommand)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
char* db;
size_t db_len;
zval* command;
zval* options = NULL;
bool free_options = false;
zval* zreadPreference = NULL;
zval* zsession = NULL;
uint32_t server_id = 0;
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
intern = Z_MANAGER_OBJ_P(getThis());
options = php_phongo_prep_legacy_option(options, "readPreference", &free_options);
if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!php_phongo_manager_select_server(false, false, zreadPreference, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern, intern);
phongo_execute_command(getThis(), PHONGO_COMMAND_RAW, db, command, options, server_id, return_value);
cleanup:
if (free_options) {
php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeReadCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a ReadCommand */
static PHP_METHOD(Manager, executeReadCommand)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
char* db;
size_t db_len;
zval* command;
zval* options = NULL;
zval* zreadPreference = NULL;
uint32_t server_id = 0;
zval* zsession = NULL;
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
intern = Z_MANAGER_OBJ_P(getThis());
if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
return;
}
if (!php_phongo_manager_select_server(false, true, zreadPreference, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern, intern);
phongo_execute_command(getThis(), PHONGO_COMMAND_READ, db, command, options, server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a WriteCommand */
static PHP_METHOD(Manager, executeWriteCommand)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
char* db;
size_t db_len;
zval* command;
zval* options = NULL;
uint32_t server_id = 0;
zval* zsession = NULL;
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
intern = Z_MANAGER_OBJ_P(getThis());
if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
if (!php_phongo_manager_select_server(true, false, NULL, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern, intern);
phongo_execute_command(getThis(), PHONGO_COMMAND_WRITE, db, command, options, server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeReadWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
Execute a ReadWriteCommand */
static PHP_METHOD(Manager, executeReadWriteCommand)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
char* db;
size_t db_len;
zval* command;
zval* options = NULL;
uint32_t server_id = 0;
zval* zsession = NULL;
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|a!", &db, &db_len, &command, php_phongo_command_ce, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
intern = Z_MANAGER_OBJ_P(getThis());
if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
if (!php_phongo_manager_select_server(true, false, NULL, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern, intern);
phongo_execute_command(getThis(), PHONGO_COMMAND_READ_WRITE, db, command, options, server_id, return_value);
} /* }}} */
/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeQuery(string $namespace, MongoDB\Driver\Query $query[, array $options = null])
Execute a Query */
static PHP_METHOD(Manager, executeQuery)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
char* namespace;
size_t namespace_len;
zval* query;
zval* options = NULL;
bool free_options = false;
zval* zreadPreference = NULL;
uint32_t server_id = 0;
zval* zsession = NULL;
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &namespace, &namespace_len, &query, php_phongo_query_ce, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
intern = Z_MANAGER_OBJ_P(getThis());
options = php_phongo_prep_legacy_option(options, "readPreference", &free_options);
if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!php_phongo_manager_select_server(false, true, zreadPreference, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* If the Manager was created in a different process, reset the client so
* that cursors created by this process can be differentiated and its
* session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern, intern);
phongo_execute_query(getThis(), namespace, query, options, server_id, return_value);
cleanup:
if (free_options) {
php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
/* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, array $options = null])
Executes a BulkWrite (i.e. any number of insert, update, and delete ops) */
static PHP_METHOD(Manager, executeBulkWrite)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
char* namespace;
size_t namespace_len;
zval* zbulk;
php_phongo_bulkwrite_t* bulk;
zval* options = NULL;
bool free_options = false;
uint32_t server_id = 0;
zval* zsession = NULL;
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO|z!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
intern = Z_MANAGER_OBJ_P(getThis());
bulk = Z_BULKWRITE_OBJ_P(zbulk);
options = php_phongo_prep_legacy_option(options, "writeConcern", &free_options);
if (!phongo_parse_session(options, intern->client, NULL, &zsession)) {
/* Exception should already have been thrown */
return;
}
if (!php_phongo_manager_select_server(true, false, NULL, zsession, intern->client, &server_id)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* If the Server was created in a different process, reset the client so
* that its session pool is cleared. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern, intern);
phongo_execute_bulk_write(getThis(), namespace, bulk, options, server_id, return_value);
cleanup:
if (free_options) {
php_phongo_prep_legacy_option_free(options);
}
} /* }}} */
+/* {{{ proto array|object|null MongoDB\Driver\Manager::getEncryptedFieldsMap()
+ Returns the autoEncryption.encryptedFieldsMap driver option */
+static PHP_METHOD(Manager, getEncryptedFieldsMap)
+{
+ php_phongo_manager_t* intern;
+
+ intern = Z_MANAGER_OBJ_P(getThis());
+
+ PHONGO_PARSE_PARAMETERS_NONE();
+
+ if (!Z_ISUNDEF(intern->enc_fields_map)) {
+ RETURN_ZVAL(&intern->enc_fields_map, 1, 0);
+ }
+} /* }}} */
+
/* {{{ proto MongoDB\Driver\ReadConcern MongoDB\Driver\Manager::getReadConcern()
Returns the ReadConcern associated with this Manager */
static PHP_METHOD(Manager, getReadConcern)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
intern = Z_MANAGER_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_readconcern_init(return_value, mongoc_client_get_read_concern(intern->client));
} /* }}} */
/* {{{ proto MongoDB\Driver\ReadPreference MongoDB\Driver\Manager::getReadPreference()
Returns the ReadPreference associated with this Manager */
static PHP_METHOD(Manager, getReadPreference)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
intern = Z_MANAGER_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_readpreference_init(return_value, mongoc_client_get_read_prefs(intern->client));
} /* }}} */
/* {{{ proto MongoDB\Driver\Server[] MongoDB\Driver\Manager::getServers()
Returns the Servers associated with this Manager */
static PHP_METHOD(Manager, getServers)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
mongoc_server_description_t** sds;
size_t i, n = 0;
intern = Z_MANAGER_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
sds = mongoc_client_get_server_descriptions(intern->client, &n);
array_init_size(return_value, n);
for (i = 0; i < n; i++) {
zval obj;
phongo_server_init(&obj, getThis(), mongoc_server_description_id(sds[i]));
add_next_index_zval(return_value, &obj);
}
mongoc_server_descriptions_destroy_all(sds, n);
} /* }}} */
/* {{{ proto MongoDB\Driver\WriteConcern MongoDB\Driver\Manager::getWriteConcern()
Returns the WriteConcern associated with this Manager */
static PHP_METHOD(Manager, getWriteConcern)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
intern = Z_MANAGER_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_writeconcern_init(return_value, mongoc_client_get_write_concern(intern->client));
} /* }}} */
/* {{{ proto void MongoDB\Driver\Manager::removeSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber)
Unregisters an event subscriber for this Manager */
static PHP_METHOD(Manager, removeSubscriber)
{
php_phongo_manager_t* intern;
zval* subscriber;
PHONGO_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_OBJECT_OF_CLASS(subscriber, php_phongo_subscriber_ce)
PHONGO_PARSE_PARAMETERS_END();
intern = Z_MANAGER_OBJ_P(getThis());
/* NOP if subscribers HashTable was never initialized by addSubscriber */
if (!intern->subscribers) {
return;
}
phongo_apm_remove_subscriber(intern->subscribers, subscriber);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server MongoDB\Driver\Manager::selectServers([MongoDB\Driver\ReadPreference $readPreference = null])
Selects a Server for the given ReadPreference (default: primary). */
static PHP_METHOD(Manager, selectServer)
{
php_phongo_manager_t* intern;
zval* zreadPreference = NULL;
uint32_t server_id = 0;
PHONGO_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(zreadPreference, php_phongo_readpreference_ce)
PHONGO_PARSE_PARAMETERS_END();
intern = Z_MANAGER_OBJ_P(getThis());
if (!php_phongo_manager_select_server(false, false, zreadPreference, NULL, intern->client, &server_id)) {
/* Exception should already have been thrown */
return;
}
phongo_server_init(return_value, getThis(), server_id);
} /* }}} */
/* {{{ proto MongoDB\Driver\Session MongoDB\Driver\Manager::startSession([array $options = null])
Returns a new client session */
static PHP_METHOD(Manager, startSession)
{
zend_error_handling error_handling;
php_phongo_manager_t* intern;
zval* options = NULL;
mongoc_session_opt_t* cs_opts = NULL;
mongoc_client_session_t* cs;
bson_error_t error = { 0 };
mongoc_transaction_opt_t* txn_opts = NULL;
intern = Z_MANAGER_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
if (options && php_array_existsc(options, "causalConsistency")) {
cs_opts = mongoc_session_opts_new();
mongoc_session_opts_set_causal_consistency(cs_opts, php_array_fetchc_bool(options, "causalConsistency"));
}
if (options && php_array_existsc(options, "defaultTransactionOptions")) {
zval* txn_options = php_array_fetchc(options, "defaultTransactionOptions");
/* Thrown exception and return if the defaultTransactionOptions is not an array */
if (Z_TYPE_P(txn_options) != IS_ARRAY) {
phongo_throw_exception(
PHONGO_ERROR_INVALID_ARGUMENT,
"Expected \"defaultTransactionOptions\" option to be an array, %s given",
PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(txn_options));
goto cleanup;
}
/* Parse transaction options */
txn_opts = php_mongodb_session_parse_transaction_options(txn_options);
/* If an exception is thrown while parsing, the txn_opts struct is also
* NULL, so no need to free it here */
if (EG(exception)) {
goto cleanup;
}
/* If the options are non-empty, add them to the client session opts struct */
if (txn_opts) {
if (!cs_opts) {
cs_opts = mongoc_session_opts_new();
}
mongoc_session_opts_set_default_transaction_opts(cs_opts, txn_opts);
mongoc_transaction_opts_destroy(txn_opts);
}
}
if (options && php_array_existsc(options, "snapshot")) {
if (!cs_opts) {
cs_opts = mongoc_session_opts_new();
}
mongoc_session_opts_set_snapshot(cs_opts, php_array_fetchc_bool(options, "snapshot"));
}
if (cs_opts && mongoc_session_opts_get_causal_consistency(cs_opts) && mongoc_session_opts_get_snapshot(cs_opts)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Only one of \"causalConsistency\" and \"snapshot\" can be enabled");
goto cleanup;
}
/* If the Manager was created in a different process, reset the client so
* that its session pool is cleared. This will ensure that we do not re-use
* a server session (i.e. LSID) created by a parent process. */
PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern, intern);
cs = mongoc_client_start_session(intern->client, cs_opts, &error);
if (cs) {
phongo_session_init(return_value, getThis(), cs);
} else {
phongo_throw_exception_from_bson_error_t(&error);
}
cleanup:
if (cs_opts) {
mongoc_session_opts_destroy(cs_opts);
}
} /* }}} */
/* {{{ MongoDB\Driver\Manager function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Manager___construct, 0, 0, 0)
ZEND_ARG_INFO(0, uri)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_ARG_ARRAY_INFO(0, driverOptions, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_addSubscriber, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, subscriber, MongoDB\\Driver\\Monitoring\\Subscriber, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_createClientEncryption, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeCommand, 0, 0, 2)
ZEND_ARG_INFO(0, db)
ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeRWCommand, 0, 0, 2)
ZEND_ARG_INFO(0, db)
ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeQuery, 0, 0, 2)
ZEND_ARG_INFO(0, namespace)
ZEND_ARG_OBJ_INFO(0, zquery, MongoDB\\Driver\\Query, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeBulkWrite, 0, 0, 2)
ZEND_ARG_INFO(0, namespace)
ZEND_ARG_OBJ_INFO(0, zbulk, MongoDB\\Driver\\BulkWrite, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_removeSubscriber, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, subscriber, MongoDB\\Driver\\Monitoring\\Subscriber, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_selectServer, 0, 0, 0)
ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_startSession, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_manager_me[] = {
/* clang-format off */
PHP_ME(Manager, __construct, ai_Manager___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, addSubscriber, ai_Manager_addSubscriber, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, createClientEncryption, ai_Manager_createClientEncryption, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeCommand, ai_Manager_executeCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeReadCommand, ai_Manager_executeRWCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeWriteCommand, ai_Manager_executeRWCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeReadWriteCommand, ai_Manager_executeCommand, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeQuery, ai_Manager_executeQuery, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, executeBulkWrite, ai_Manager_executeBulkWrite, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
+ PHP_ME(Manager, getEncryptedFieldsMap, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getReadConcern, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getReadPreference, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getServers, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, getWriteConcern, ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, removeSubscriber, ai_Manager_removeSubscriber, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, selectServer, ai_Manager_selectServer, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(Manager, startSession, ai_Manager_startSession, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Manager_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Manager object handlers */
static zend_object_handlers php_phongo_handler_manager;
static void php_phongo_manager_free_object(zend_object* object) /* {{{ */
{
php_phongo_manager_t* intern = Z_OBJ_MANAGER(object);
zend_object_std_dtor(&intern->std);
if (intern->client) {
/* Request-scoped clients will be removed from the registry and
* destroyed. This is a NOP for persistent clients. The return value is
* ignored because we can't reasonably report an error here. On the off
* chance any request-scoped clients are missed, they will ultimately be
* destroyed in RSHUTDOWN along with the registry HashTable. */
php_phongo_client_unregister(intern);
}
/* Update the request-scoped Manager registry. The return value is ignored
* because it's possible that the Manager was never registered due to a
* constructor exception.
*
* Note: this is done after unregistering a request-scoped client to ensure
* APM events can be observed by per-client subscribers, which are collected
* in phongo_apm_get_subscribers_to_notify. */
php_phongo_manager_unregister(intern);
if (intern->client_hash) {
efree(intern->client_hash);
}
+ if (!Z_ISUNDEF(intern->enc_fields_map)) {
+ zval_ptr_dtor(&intern->enc_fields_map);
+ }
+
/* Free the keyVaultClient last to ensure that potential non-persistent
* clients are destroyed in the correct order */
if (!Z_ISUNDEF(intern->key_vault_client_manager)) {
zval_ptr_dtor(&intern->key_vault_client_manager);
}
if (intern->subscribers) {
zend_hash_destroy(intern->subscribers);
FREE_HASHTABLE(intern->subscribers);
}
} /* }}} */
static zend_object* php_phongo_manager_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_manager_t* intern = zend_object_alloc(sizeof(php_phongo_manager_t), class_type);
zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
PHONGO_SET_CREATED_BY_PID(intern);
intern->std.handlers = &php_phongo_handler_manager;
return &intern->std;
} /* }}} */
static HashTable* php_phongo_manager_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_manager_t* intern;
mongoc_server_description_t** sds;
size_t i, n = 0;
zval retval = ZVAL_STATIC_INIT;
zval cluster;
*is_temp = 1;
intern = Z_OBJ_MANAGER(PHONGO_COMPAT_GET_OBJ(object));
array_init_size(&retval, 2);
ADD_ASSOC_STRING(&retval, "uri", mongoc_uri_get_string(mongoc_client_get_uri(intern->client)));
sds = mongoc_client_get_server_descriptions(intern->client, &n);
array_init_size(&cluster, n);
for (i = 0; i < n; i++) {
zval obj;
if (!php_phongo_server_to_zval(&obj, intern->client, sds[i])) {
/* Exception already thrown */
zval_ptr_dtor(&obj);
zval_ptr_dtor(&cluster);
goto done;
}
add_next_index_zval(&cluster, &obj);
}
ADD_ASSOC_ZVAL_EX(&retval, "cluster", &cluster);
done:
mongoc_server_descriptions_destroy_all(sds, n);
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_manager_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Manager", php_phongo_manager_me);
php_phongo_manager_ce = zend_register_internal_class(&ce);
php_phongo_manager_ce->create_object = php_phongo_manager_create_object;
PHONGO_CE_FINAL(php_phongo_manager_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_manager_ce);
memcpy(&php_phongo_handler_manager, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_manager.get_debug_info = php_phongo_manager_get_debug_info;
php_phongo_handler_manager.free_obj = php_phongo_manager_free_object;
php_phongo_handler_manager.offset = XtOffsetOf(php_phongo_manager_t, std);
} /* }}} */
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/CommandFailedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/CommandFailedEvent.c
similarity index 92%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/CommandFailedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/CommandFailedEvent.c
index 4d710e28..340eec2c 100644
--- a/mongodb-1.13.0/src/MongoDB/Monitoring/CommandFailedEvent.c
+++ b/mongodb-1.14.0/src/MongoDB/Monitoring/CommandFailedEvent.c
@@ -1,325 +1,349 @@
/*
* Copyright 2016-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "php_phongo.h"
#include "phongo_bson_encode.h"
#include "phongo_error.h"
#include "BSON/ObjectId.h"
#include "MongoDB/Server.h"
zend_class_entry* php_phongo_commandfailedevent_ce;
/* {{{ proto string CommandFailedEvent::getCommandName()
Returns the command name for this event */
PHP_METHOD(CommandFailedEvent, getCommandName)
{
zend_error_handling error_handling;
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETVAL_STRING(intern->command_name);
} /* }}} */
/* {{{ proto int CommandFailedEvent::getDurationMicros()
Returns the event's duration in microseconds */
PHP_METHOD(CommandFailedEvent, getDurationMicros)
{
zend_error_handling error_handling;
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETURN_LONG(intern->duration_micros);
} /* }}} */
/* {{{ proto Exception CommandFailedEvent::getError()
Returns the error document associated with the event */
PHP_METHOD(CommandFailedEvent, getError)
{
zend_error_handling error_handling;
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETURN_ZVAL(&intern->z_error, 1, 0);
} /* }}} */
/* {{{ proto string CommandFailedEvent::getOperationId()
Returns the event's operation ID */
PHP_METHOD(CommandFailedEvent, getOperationId)
{
zend_error_handling error_handling;
php_phongo_commandfailedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
sprintf(int_as_string, "%" PRIu64, intern->operation_id);
RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto stdClass CommandFailedEvent::getReply()
Returns the reply document associated with the event */
PHP_METHOD(CommandFailedEvent, getReply)
{
zend_error_handling error_handling;
php_phongo_commandfailedevent_t* intern;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
RETURN_ZVAL(&state.zchild, 0, 1);
} /* }}} */
/* {{{ proto string CommandFailedEvent::getRequestId()
Returns the event's request ID */
PHP_METHOD(CommandFailedEvent, getRequestId)
{
zend_error_handling error_handling;
php_phongo_commandfailedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
sprintf(int_as_string, "%" PRIu64, intern->request_id);
RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server CommandFailedEvent::getServer()
Returns the Server from which the event originated */
PHP_METHOD(CommandFailedEvent, getServer)
{
zend_error_handling error_handling;
php_phongo_commandfailedevent_t* intern;
intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_server_init(return_value, &intern->manager, intern->server_id);
} /* }}} */
/* {{{ proto MongoDB\BSON\ObjectId|null CommandFailedEvent::getServiceId()
Returns the event's service ID */
PHP_METHOD(CommandFailedEvent, getServiceId)
{
php_phongo_commandfailedevent_t* intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
PHONGO_PARSE_PARAMETERS_NONE();
if (!intern->has_service_id) {
RETURN_NULL();
}
phongo_objectid_init(return_value, &intern->service_id);
} /* }}} */
+/* {{{ proto int|null CommandFailedEvent::getServerConnectionId()
+ Returns the event's server connection ID */
+PHP_METHOD(CommandFailedEvent, getServerConnectionId)
+{
+ php_phongo_commandfailedevent_t* intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis());
+
+ PHONGO_PARSE_PARAMETERS_NONE();
+
+ /* TODO: Use MONGOC_NO_SERVER_CONNECTION_ID once it is added to libmongoc's public API (CDRIVER-4176) */
+ if (intern->server_connection_id == -1) {
+ RETURN_NULL();
+ }
+
+ RETURN_LONG(intern->server_connection_id);
+} /* }}} */
+
/**
* Event thrown when a command has failed to execute.
*
* This class is only constructed internally.
*/
/* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandFailedEvent_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandfailedevent_me[] = {
/* clang-format off */
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandFailedEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getCommandName, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getError, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getDurationMicros, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getOperationId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getReply, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getRequestId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getServer, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandFailedEvent, getServiceId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
+ PHP_ME(CommandFailedEvent, getServerConnectionId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent object handlers */
static zend_object_handlers php_phongo_handler_commandfailedevent;
static void php_phongo_commandfailedevent_free_object(zend_object* object) /* {{{ */
{
php_phongo_commandfailedevent_t* intern = Z_OBJ_COMMANDFAILEDEVENT(object);
zend_object_std_dtor(&intern->std);
if (!Z_ISUNDEF(intern->z_error)) {
zval_ptr_dtor(&intern->z_error);
}
if (!Z_ISUNDEF(intern->manager)) {
zval_ptr_dtor(&intern->manager);
}
if (intern->reply) {
bson_destroy(intern->reply);
}
if (intern->command_name) {
efree(intern->command_name);
}
} /* }}} */
static zend_object* php_phongo_commandfailedevent_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_commandfailedevent_t* intern = zend_object_alloc(sizeof(php_phongo_commandfailedevent_t), class_type);
zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
intern->std.handlers = &php_phongo_handler_commandfailedevent;
return &intern->std;
} /* }}} */
static HashTable* php_phongo_commandfailedevent_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_commandfailedevent_t* intern;
zval retval = ZVAL_STATIC_INIT;
char operation_id[20], request_id[20];
php_phongo_bson_state reply_state;
PHONGO_BSON_INIT_STATE(reply_state);
intern = Z_OBJ_COMMANDFAILEDEVENT(PHONGO_COMPAT_GET_OBJ(object));
*is_temp = 1;
array_init_size(&retval, 6);
ADD_ASSOC_STRING(&retval, "commandName", intern->command_name);
ADD_ASSOC_INT64(&retval, "durationMicros", (int64_t) intern->duration_micros);
ADD_ASSOC_ZVAL_EX(&retval, "error", &intern->z_error);
Z_ADDREF(intern->z_error);
sprintf(operation_id, "%" PRIu64, intern->operation_id);
ADD_ASSOC_STRING(&retval, "operationId", operation_id);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &reply_state)) {
zval_ptr_dtor(&reply_state.zchild);
goto done;
}
ADD_ASSOC_ZVAL(&retval, "reply", &reply_state.zchild);
sprintf(request_id, "%" PRIu64, intern->request_id);
ADD_ASSOC_STRING(&retval, "requestId", request_id);
{
zval server;
phongo_server_init(&server, &intern->manager, intern->server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
}
if (intern->has_service_id) {
zval service_id;
phongo_objectid_init(&service_id, &intern->service_id);
ADD_ASSOC_ZVAL_EX(&retval, "serviceId", &service_id);
} else {
ADD_ASSOC_NULL_EX(&retval, "serviceId");
}
+ /* TODO: Use MONGOC_NO_SERVER_CONNECTION_ID once it is added to libmongoc's public API (CDRIVER-4176) */
+ if (intern->server_connection_id == -1) {
+ ADD_ASSOC_NULL_EX(&retval, "serverConnectionId");
+ } else {
+ ADD_ASSOC_LONG_EX(&retval, "serverConnectionId", intern->server_connection_id);
+ }
+
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandFailedEvent", php_phongo_commandfailedevent_me);
php_phongo_commandfailedevent_ce = zend_register_internal_class(&ce);
php_phongo_commandfailedevent_ce->create_object = php_phongo_commandfailedevent_create_object;
PHONGO_CE_FINAL(php_phongo_commandfailedevent_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandfailedevent_ce);
memcpy(&php_phongo_handler_commandfailedevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_commandfailedevent.get_debug_info = php_phongo_commandfailedevent_get_debug_info;
php_phongo_handler_commandfailedevent.free_obj = php_phongo_commandfailedevent_free_object;
php_phongo_handler_commandfailedevent.offset = XtOffsetOf(php_phongo_commandfailedevent_t, std);
} /* }}} */
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/CommandStartedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/CommandStartedEvent.c
similarity index 91%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/CommandStartedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/CommandStartedEvent.c
index 3ce634e5..4b1a56a5 100644
--- a/mongodb-1.13.0/src/MongoDB/Monitoring/CommandStartedEvent.c
+++ b/mongodb-1.14.0/src/MongoDB/Monitoring/CommandStartedEvent.c
@@ -1,304 +1,328 @@
/*
* Copyright 2016-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "php_phongo.h"
#include "phongo_bson_encode.h"
#include "phongo_error.h"
#include "BSON/ObjectId.h"
#include "MongoDB/Server.h"
zend_class_entry* php_phongo_commandstartedevent_ce;
/* {{{ proto stdClass CommandStartedEvent::getCommand()
Returns the command document associated with the event */
PHP_METHOD(CommandStartedEvent, getCommand)
{
zend_error_handling error_handling;
php_phongo_commandstartedevent_t* intern;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->command), intern->command->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
RETURN_ZVAL(&state.zchild, 0, 1);
} /* }}} */
/* {{{ proto string CommandStartedEvent::getCommandName()
Returns the command name for this event */
PHP_METHOD(CommandStartedEvent, getCommandName)
{
zend_error_handling error_handling;
php_phongo_commandstartedevent_t* intern;
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETVAL_STRING(intern->command_name);
} /* }}} */
/* {{{ proto string CommandStartedEvent::getDatabaseName()
Returns the database name for this event */
PHP_METHOD(CommandStartedEvent, getDatabaseName)
{
zend_error_handling error_handling;
php_phongo_commandstartedevent_t* intern;
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETVAL_STRING(intern->database_name);
} /* }}} */
/* {{{ proto string CommandStartedEvent::getOperationId()
Returns the event's operation ID */
PHP_METHOD(CommandStartedEvent, getOperationId)
{
zend_error_handling error_handling;
php_phongo_commandstartedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
sprintf(int_as_string, "%" PRIu64, intern->operation_id);
RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto string CommandStartedEvent::getRequestId()
Returns the event's request ID */
PHP_METHOD(CommandStartedEvent, getRequestId)
{
zend_error_handling error_handling;
php_phongo_commandstartedevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
sprintf(int_as_string, "%" PRIu64, intern->request_id);
RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server CommandStartedEvent::getServer()
Returns the Server from which the event originated */
PHP_METHOD(CommandStartedEvent, getServer)
{
zend_error_handling error_handling;
php_phongo_commandstartedevent_t* intern;
intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_server_init(return_value, &intern->manager, intern->server_id);
} /* }}} */
/* {{{ proto MongoDB\BSON\ObjectId|null CommandStartedEvent::getServiceId()
Returns the event's service ID */
PHP_METHOD(CommandStartedEvent, getServiceId)
{
php_phongo_commandstartedevent_t* intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
PHONGO_PARSE_PARAMETERS_NONE();
if (!intern->has_service_id) {
RETURN_NULL();
}
phongo_objectid_init(return_value, &intern->service_id);
} /* }}} */
+/* {{{ proto int|null CommandStartedEvent::getServerConnectionId()
+ Returns the event's server connection ID */
+PHP_METHOD(CommandStartedEvent, getServerConnectionId)
+{
+ php_phongo_commandstartedevent_t* intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis());
+
+ PHONGO_PARSE_PARAMETERS_NONE();
+
+ /* TODO: Use MONGOC_NO_SERVER_CONNECTION_ID once it is added to libmongoc's public API (CDRIVER-4176) */
+ if (intern->server_connection_id == -1) {
+ RETURN_NULL();
+ }
+
+ RETURN_LONG(intern->server_connection_id);
+} /* }}} */
+
/**
* Event thrown when a command has started to execute.
*
* This class is only constructed internally.
*/
/* {{{ MongoDB\Driver\Monitoring\CommandStartedEvent function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandStartedEvent_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandstartedevent_me[] = {
/* clang-format off */
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandStartedEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getCommand, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getCommandName, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getDatabaseName, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getOperationId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getRequestId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getServer, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandStartedEvent, getServiceId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
+ PHP_ME(CommandStartedEvent, getServerConnectionId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Monitoring\CommandStartedEvent object handlers */
static zend_object_handlers php_phongo_handler_commandstartedevent;
static void php_phongo_commandstartedevent_free_object(zend_object* object) /* {{{ */
{
php_phongo_commandstartedevent_t* intern = Z_OBJ_COMMANDSTARTEDEVENT(object);
zend_object_std_dtor(&intern->std);
if (!Z_ISUNDEF(intern->manager)) {
zval_ptr_dtor(&intern->manager);
}
if (intern->command) {
bson_destroy(intern->command);
}
if (intern->command_name) {
efree(intern->command_name);
}
if (intern->database_name) {
efree(intern->database_name);
}
} /* }}} */
static zend_object* php_phongo_commandstartedevent_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_commandstartedevent_t* intern = zend_object_alloc(sizeof(php_phongo_commandstartedevent_t), class_type);
zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
intern->std.handlers = &php_phongo_handler_commandstartedevent;
return &intern->std;
} /* }}} */
static HashTable* php_phongo_commandstartedevent_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_commandstartedevent_t* intern;
zval retval = ZVAL_STATIC_INIT;
char operation_id[20], request_id[20];
php_phongo_bson_state command_state;
PHONGO_BSON_INIT_STATE(command_state);
intern = Z_OBJ_COMMANDSTARTEDEVENT(PHONGO_COMPAT_GET_OBJ(object));
*is_temp = 1;
array_init_size(&retval, 6);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->command), intern->command->len, &command_state)) {
zval_ptr_dtor(&command_state.zchild);
goto done;
}
ADD_ASSOC_ZVAL(&retval, "command", &command_state.zchild);
ADD_ASSOC_STRING(&retval, "commandName", intern->command_name);
ADD_ASSOC_STRING(&retval, "databaseName", intern->database_name);
sprintf(operation_id, "%" PRIu64, intern->operation_id);
ADD_ASSOC_STRING(&retval, "operationId", operation_id);
sprintf(request_id, "%" PRIu64, intern->request_id);
ADD_ASSOC_STRING(&retval, "requestId", request_id);
{
zval server;
phongo_server_init(&server, &intern->manager, intern->server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
}
if (intern->has_service_id) {
zval service_id;
phongo_objectid_init(&service_id, &intern->service_id);
ADD_ASSOC_ZVAL_EX(&retval, "serviceId", &service_id);
} else {
ADD_ASSOC_NULL_EX(&retval, "serviceId");
}
+ /* TODO: Use MONGOC_NO_SERVER_CONNECTION_ID once it is added to libmongoc's public API (CDRIVER-4176) */
+ if (intern->server_connection_id == -1) {
+ ADD_ASSOC_NULL_EX(&retval, "serverConnectionId");
+ } else {
+ ADD_ASSOC_LONG_EX(&retval, "serverConnectionId", intern->server_connection_id);
+ }
+
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_commandstartedevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandStartedEvent", php_phongo_commandstartedevent_me);
php_phongo_commandstartedevent_ce = zend_register_internal_class(&ce);
php_phongo_commandstartedevent_ce->create_object = php_phongo_commandstartedevent_create_object;
PHONGO_CE_FINAL(php_phongo_commandstartedevent_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandstartedevent_ce);
memcpy(&php_phongo_handler_commandstartedevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_commandstartedevent.get_debug_info = php_phongo_commandstartedevent_get_debug_info;
php_phongo_handler_commandstartedevent.free_obj = php_phongo_commandstartedevent_free_object;
php_phongo_handler_commandstartedevent.offset = XtOffsetOf(php_phongo_commandstartedevent_t, std);
return;
} /* }}} */
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/CommandSubscriber.c b/mongodb-1.14.0/src/MongoDB/Monitoring/CommandSubscriber.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/CommandSubscriber.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/CommandSubscriber.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/CommandSucceededEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/CommandSucceededEvent.c
similarity index 91%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/CommandSucceededEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/CommandSucceededEvent.c
index 3fa47b77..efbdeff8 100644
--- a/mongodb-1.13.0/src/MongoDB/Monitoring/CommandSucceededEvent.c
+++ b/mongodb-1.14.0/src/MongoDB/Monitoring/CommandSucceededEvent.c
@@ -1,300 +1,324 @@
/*
* Copyright 2016-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "php_phongo.h"
#include "phongo_bson_encode.h"
#include "phongo_error.h"
#include "BSON/ObjectId.h"
#include "MongoDB/Server.h"
zend_class_entry* php_phongo_commandsucceededevent_ce;
/* {{{ proto string CommandSucceededEvent::getCommandName()
Returns the command name for this event */
PHP_METHOD(CommandSucceededEvent, getCommandName)
{
zend_error_handling error_handling;
php_phongo_commandsucceededevent_t* intern;
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETVAL_STRING(intern->command_name);
} /* }}} */
/* {{{ proto int CommandSucceededEvent::getDurationMicros()
Returns the event's duration in microseconds */
PHP_METHOD(CommandSucceededEvent, getDurationMicros)
{
zend_error_handling error_handling;
php_phongo_commandsucceededevent_t* intern;
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
RETURN_LONG(intern->duration_micros);
} /* }}} */
/* {{{ proto string CommandSucceededEvent::getOperationId()
Returns the event's operation ID */
PHP_METHOD(CommandSucceededEvent, getOperationId)
{
zend_error_handling error_handling;
php_phongo_commandsucceededevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
sprintf(int_as_string, "%" PRIu64, intern->operation_id);
RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto stdClass CommandSucceededEvent::getReply()
Returns the reply document associated with the event */
PHP_METHOD(CommandSucceededEvent, getReply)
{
zend_error_handling error_handling;
php_phongo_commandsucceededevent_t* intern;
php_phongo_bson_state state;
PHONGO_BSON_INIT_STATE(state);
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &state)) {
zval_ptr_dtor(&state.zchild);
return;
}
RETURN_ZVAL(&state.zchild, 0, 1);
} /* }}} */
/* {{{ proto string CommandsucceededEvent::getRequestId()
Returns the event's request ID */
PHP_METHOD(CommandSucceededEvent, getRequestId)
{
zend_error_handling error_handling;
php_phongo_commandsucceededevent_t* intern;
char int_as_string[20];
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
sprintf(int_as_string, "%" PRIu64, intern->request_id);
RETVAL_STRING(int_as_string);
} /* }}} */
/* {{{ proto MongoDB\Driver\Server CommandSucceededEvent::getServer()
Returns the Server from which the event originated */
PHP_METHOD(CommandSucceededEvent, getServer)
{
zend_error_handling error_handling;
php_phongo_commandsucceededevent_t* intern;
intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters_none() == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
phongo_server_init(return_value, &intern->manager, intern->server_id);
} /* }}} */
/* {{{ proto MongoDB\BSON\ObjectId|null CommandSucceededEvent::getServiceId()
Returns the event's service ID */
PHP_METHOD(CommandSucceededEvent, getServiceId)
{
php_phongo_commandsucceededevent_t* intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
PHONGO_PARSE_PARAMETERS_NONE();
if (!intern->has_service_id) {
RETURN_NULL();
}
phongo_objectid_init(return_value, &intern->service_id);
} /* }}} */
+/* {{{ proto int|null CommandSucceededEvent::getServerConnectionId()
+ Returns the event's server connection ID */
+PHP_METHOD(CommandSucceededEvent, getServerConnectionId)
+{
+ php_phongo_commandsucceededevent_t* intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis());
+
+ PHONGO_PARSE_PARAMETERS_NONE();
+
+ /* TODO: Use MONGOC_NO_SERVER_CONNECTION_ID once it is added to libmongoc's public API (CDRIVER-4176) */
+ if (intern->server_connection_id == -1) {
+ RETURN_NULL();
+ }
+
+ RETURN_LONG(intern->server_connection_id);
+} /* }}} */
+
/**
* Event thrown when a command has succeeded to execute.
*
* This class is only constructed internally.
*/
/* {{{ MongoDB\Driver\Monitoring\CommandSucceededEvent function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_CommandSucceededEvent_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_commandsucceededevent_me[] = {
/* clang-format off */
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandSucceededEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getCommandName, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getDurationMicros, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getOperationId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getReply, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getRequestId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getServer, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_ME(CommandSucceededEvent, getServiceId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
+ PHP_ME(CommandSucceededEvent, getServerConnectionId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Monitoring\CommandSucceededEvent object handlers */
static zend_object_handlers php_phongo_handler_commandsucceededevent;
static void php_phongo_commandsucceededevent_free_object(zend_object* object) /* {{{ */
{
php_phongo_commandsucceededevent_t* intern = Z_OBJ_COMMANDSUCCEEDEDEVENT(object);
zend_object_std_dtor(&intern->std);
if (!Z_ISUNDEF(intern->manager)) {
zval_ptr_dtor(&intern->manager);
}
if (intern->reply) {
bson_destroy(intern->reply);
}
if (intern->command_name) {
efree(intern->command_name);
}
} /* }}} */
static zend_object* php_phongo_commandsucceededevent_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_commandsucceededevent_t* intern = zend_object_alloc(sizeof(php_phongo_commandsucceededevent_t), class_type);
zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
intern->std.handlers = &php_phongo_handler_commandsucceededevent;
return &intern->std;
} /* }}} */
static HashTable* php_phongo_commandsucceededevent_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_commandsucceededevent_t* intern;
zval retval = ZVAL_STATIC_INIT;
char operation_id[20], request_id[20];
php_phongo_bson_state reply_state;
PHONGO_BSON_INIT_STATE(reply_state);
intern = Z_OBJ_COMMANDSUCCEEDEDEVENT(PHONGO_COMPAT_GET_OBJ(object));
*is_temp = 1;
array_init_size(&retval, 6);
ADD_ASSOC_STRING(&retval, "commandName", intern->command_name);
ADD_ASSOC_INT64(&retval, "durationMicros", (int64_t) intern->duration_micros);
sprintf(operation_id, "%" PRIu64, intern->operation_id);
ADD_ASSOC_STRING(&retval, "operationId", operation_id);
if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &reply_state)) {
zval_ptr_dtor(&reply_state.zchild);
goto done;
}
ADD_ASSOC_ZVAL(&retval, "reply", &reply_state.zchild);
sprintf(request_id, "%" PRIu64, intern->request_id);
ADD_ASSOC_STRING(&retval, "requestId", request_id);
{
zval server;
phongo_server_init(&server, &intern->manager, intern->server_id);
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
}
if (intern->has_service_id) {
zval service_id;
phongo_objectid_init(&service_id, &intern->service_id);
ADD_ASSOC_ZVAL_EX(&retval, "serviceId", &service_id);
} else {
ADD_ASSOC_NULL_EX(&retval, "serviceId");
}
+ /* TODO: Use MONGOC_NO_SERVER_CONNECTION_ID once it is added to libmongoc's public API (CDRIVER-4176) */
+ if (intern->server_connection_id == -1) {
+ ADD_ASSOC_NULL_EX(&retval, "serverConnectionId");
+ } else {
+ ADD_ASSOC_LONG_EX(&retval, "serverConnectionId", intern->server_connection_id);
+ }
+
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandSucceededEvent", php_phongo_commandsucceededevent_me);
php_phongo_commandsucceededevent_ce = zend_register_internal_class(&ce);
php_phongo_commandsucceededevent_ce->create_object = php_phongo_commandsucceededevent_create_object;
PHONGO_CE_FINAL(php_phongo_commandsucceededevent_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandsucceededevent_ce);
memcpy(&php_phongo_handler_commandsucceededevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_commandsucceededevent.get_debug_info = php_phongo_commandsucceededevent_get_debug_info;
php_phongo_handler_commandsucceededevent.free_obj = php_phongo_commandsucceededevent_free_object;
php_phongo_handler_commandsucceededevent.offset = XtOffsetOf(php_phongo_commandsucceededevent_t, std);
return;
} /* }}} */
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/SDAMSubscriber.c b/mongodb-1.14.0/src/MongoDB/Monitoring/SDAMSubscriber.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/SDAMSubscriber.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/SDAMSubscriber.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/ServerChangedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/ServerChangedEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/ServerChangedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/ServerChangedEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/ServerClosedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/ServerClosedEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/ServerClosedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/ServerClosedEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/ServerOpeningEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/ServerOpeningEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/ServerOpeningEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/ServerOpeningEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/Subscriber.c b/mongodb-1.14.0/src/MongoDB/Monitoring/Subscriber.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/Subscriber.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/Subscriber.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/TopologyChangedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/TopologyChangedEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/TopologyChangedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/TopologyChangedEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/TopologyClosedEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/TopologyClosedEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/TopologyClosedEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/TopologyClosedEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/TopologyOpeningEvent.c b/mongodb-1.14.0/src/MongoDB/Monitoring/TopologyOpeningEvent.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/TopologyOpeningEvent.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/TopologyOpeningEvent.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/functions.c b/mongodb-1.14.0/src/MongoDB/Monitoring/functions.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/functions.c
rename to mongodb-1.14.0/src/MongoDB/Monitoring/functions.c
diff --git a/mongodb-1.13.0/src/MongoDB/Monitoring/functions.h b/mongodb-1.14.0/src/MongoDB/Monitoring/functions.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Monitoring/functions.h
rename to mongodb-1.14.0/src/MongoDB/Monitoring/functions.h
diff --git a/mongodb-1.13.0/src/MongoDB/Query.c b/mongodb-1.14.0/src/MongoDB/Query.c
similarity index 92%
rename from mongodb-1.13.0/src/MongoDB/Query.c
rename to mongodb-1.14.0/src/MongoDB/Query.c
index f01d31cc..50a0fba6 100644
--- a/mongodb-1.13.0/src/MongoDB/Query.c
+++ b/mongodb-1.14.0/src/MongoDB/Query.c
@@ -1,493 +1,530 @@
/*
* Copyright 2014-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "php_array_api.h"
#include "php_phongo.h"
#include "phongo_bson_encode.h"
#include "phongo_error.h"
#include "MongoDB/ReadConcern.h"
zend_class_entry* php_phongo_query_ce;
/* Appends a string field into the BSON options. Returns true on success;
* otherwise, false is returned and an exception is thrown. */
static bool php_phongo_query_opts_append_string(bson_t* opts, const char* opts_key, zval* zarr, const char* zarr_key) /* {{{ */
{
zval* value = php_array_fetch(zarr, zarr_key);
if (Z_TYPE_P(value) != IS_STRING) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be string, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
return false;
}
if (!bson_append_utf8(opts, opts_key, strlen(opts_key), Z_STRVAL_P(value), Z_STRLEN_P(value))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", opts_key);
return false;
}
return true;
} /* }}} */
/* Appends a document field for the given opts document and key. Returns true on
* success; otherwise, false is returned and an exception is thrown. */
static bool php_phongo_query_opts_append_document(bson_t* opts, const char* opts_key, zval* zarr, const char* zarr_key) /* {{{ */
{
zval* value = php_array_fetch(zarr, zarr_key);
bson_t b = BSON_INITIALIZER;
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be array or object, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
return false;
}
php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL);
if (EG(exception)) {
bson_destroy(&b);
return false;
}
if (!bson_validate(&b, BSON_VALIDATE_EMPTY_KEYS, NULL)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use empty keys in \"%s\" %s", zarr_key, zarr_key[0] == '$' ? "modifier" : "option");
bson_destroy(&b);
return false;
}
if (!BSON_APPEND_DOCUMENT(opts, opts_key, &b)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", opts_key);
bson_destroy(&b);
return false;
}
bson_destroy(&b);
return true;
} /* }}} */
+/* Appends an arbitrary BSON value for the given opts document and key. Returns
+ * true on success; otherwise, false is returned and an exception is thrown. */
+static bool php_phongo_query_opts_append_value(bson_t* opts, const char* opts_key, zval* zarr, const char* zarr_key) /* {{{ */
+{
+ bson_value_t value = { 0 };
+
+ php_phongo_zval_to_bson_value(php_array_fetch(zarr, zarr_key), PHONGO_BSON_NONE, &value);
+
+ if (EG(exception)) {
+ /* Exception should already have been thrown */
+ bson_value_destroy(&value);
+ return false;
+ }
+
+ if (!BSON_APPEND_VALUE(opts, opts_key, &value)) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", opts_key);
+ bson_value_destroy(&value);
+ return false;
+ }
+
+ bson_value_destroy(&value);
+ return true;
+} /* }}} */
+
#define PHONGO_QUERY_OPT_BOOL_EX(opt, zarr, key, deprecated) \
if ((zarr) && php_array_existsc((zarr), (key))) { \
if ((deprecated)) { \
php_error_docref(NULL, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
} \
if (!BSON_APPEND_BOOL(intern->opts, (opt), php_array_fetchc_bool((zarr), (key)))) { \
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
return false; \
} \
}
#define PHONGO_QUERY_OPT_BOOL(opt, zarr, key) PHONGO_QUERY_OPT_BOOL_EX((opt), (zarr), (key), 0)
#define PHONGO_QUERY_OPT_BOOL_DEPRECATED(opt, zarr, key) PHONGO_QUERY_OPT_BOOL_EX((opt), (zarr), (key), 1)
+#define PHONGO_QUERY_OPT_BSON_VALUE(opt, zarr, key) \
+ if ((zarr) && php_array_existsc((zarr), (key))) { \
+ if (!php_phongo_query_opts_append_value(intern->opts, (opt), (zarr), (key))) { \
+ return false; \
+ } \
+ }
+
#define PHONGO_QUERY_OPT_DOCUMENT(opt, zarr, key) \
if ((zarr) && php_array_existsc((zarr), (key))) { \
if (!php_phongo_query_opts_append_document(intern->opts, (opt), (zarr), (key))) { \
return false; \
} \
}
/* Note: handling of integer options will depend on SIZEOF_ZEND_LONG and we
* are not converting strings to 64-bit integers for 32-bit platforms. */
#define PHONGO_QUERY_OPT_INT64_EX(opt, zarr, key, deprecated) \
if ((zarr) && php_array_existsc((zarr), (key))) { \
if ((deprecated)) { \
php_error_docref(NULL, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
} \
if (!BSON_APPEND_INT64(intern->opts, (opt), php_array_fetchc_long((zarr), (key)))) { \
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
return false; \
} \
}
#define PHONGO_QUERY_OPT_INT64(opt, zarr, key) PHONGO_QUERY_OPT_INT64_EX((opt), (zarr), (key), 0)
#define PHONGO_QUERY_OPT_INT64_DEPRECATED(opt, zarr, key) PHONGO_QUERY_OPT_INT64_EX((opt), (zarr), (key), 1)
#define PHONGO_QUERY_OPT_STRING(opt, zarr, key) \
if ((zarr) && php_array_existsc((zarr), (key))) { \
if (!php_phongo_query_opts_append_string(intern->opts, (opt), (zarr), (key))) { \
return false; \
} \
}
/* Initialize the "hint" option. Returns true on success; otherwise, false is
* returned and an exception is thrown.
*
* The "hint" option (or "$hint" modifier) must be a string or document. Check
* for both types and merge into BSON options accordingly. */
static bool php_phongo_query_init_hint(php_phongo_query_t* intern, zval* options, zval* modifiers) /* {{{ */
{
/* The "hint" option (or "$hint" modifier) must be a string or document.
* Check for both types and merge into BSON options accordingly. */
if (php_array_existsc(options, "hint")) {
zend_uchar type = Z_TYPE_P(php_array_fetchc(options, "hint"));
if (type == IS_STRING) {
PHONGO_QUERY_OPT_STRING("hint", options, "hint");
} else if (type == IS_OBJECT || type == IS_ARRAY) {
PHONGO_QUERY_OPT_DOCUMENT("hint", options, "hint");
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type));
return false;
}
} else if (modifiers && php_array_existsc(modifiers, "$hint")) {
zend_uchar type = Z_TYPE_P(php_array_fetchc(modifiers, "$hint"));
if (type == IS_STRING) {
PHONGO_QUERY_OPT_STRING("hint", modifiers, "$hint");
} else if (type == IS_OBJECT || type == IS_ARRAY) {
PHONGO_QUERY_OPT_DOCUMENT("hint", modifiers, "$hint");
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"$hint\" modifier to be string, array, or object, %s given", zend_get_type_by_const(type));
return false;
}
}
return true;
} /* }}} */
/* Initialize the "limit" and "singleBatch" options. Returns true on success;
* otherwise, false is returned and an exception is thrown.
*
* mongoc_collection_find_with_opts() requires a non-negative limit. For
* backwards compatibility, a negative limit should be set as a positive value
* and default singleBatch to true. */
static bool php_phongo_query_init_limit_and_singlebatch(php_phongo_query_t* intern, zval* options) /* {{{ */
{
if (php_array_fetchc_long(options, "limit") < 0) {
zend_long limit = php_array_fetchc_long(options, "limit");
if (!BSON_APPEND_INT64(intern->opts, "limit", -limit)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"limit\" option");
return false;
}
if (php_array_existsc(options, "singleBatch") && !php_array_fetchc_bool(options, "singleBatch")) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Negative \"limit\" option conflicts with false \"singleBatch\" option");
return false;
} else {
if (!BSON_APPEND_BOOL(intern->opts, "singleBatch", true)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"singleBatch\" option");
return false;
}
}
} else {
PHONGO_QUERY_OPT_INT64("limit", options, "limit");
PHONGO_QUERY_OPT_BOOL("singleBatch", options, "singleBatch");
}
return true;
} /* }}} */
/* Initialize the "readConcern" option. Returns true on success; otherwise,
* false is returned and an exception is thrown.
*
* The "readConcern" option should be a MongoDB\Driver\ReadConcern instance,
* which must be converted to a mongoc_read_concern_t. */
static bool php_phongo_query_init_readconcern(php_phongo_query_t* intern, zval* options) /* {{{ */
{
zval* read_concern;
if (!php_array_existsc(options, "readConcern")) {
return true;
}
read_concern = php_array_fetchc(options, "readConcern");
if (Z_TYPE_P(read_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_concern), php_phongo_readconcern_ce)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(read_concern));
return false;
}
intern->read_concern = mongoc_read_concern_copy(phongo_read_concern_from_zval(read_concern));
return true;
} /* }}} */
/* Initialize the "maxAwaitTimeMS" option. Returns true on success; otherwise,
* false is returned and an exception is thrown.
*
* The "maxAwaitTimeMS" option is assigned to the cursor after query execution
* via mongoc_cursor_set_max_await_time_ms(). */
static bool php_phongo_query_init_max_await_time_ms(php_phongo_query_t* intern, zval* options) /* {{{ */
{
int64_t max_await_time_ms;
if (!php_array_existsc(options, "maxAwaitTimeMS")) {
return true;
}
max_await_time_ms = php_array_fetchc_long(options, "maxAwaitTimeMS");
if (max_await_time_ms < 0) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxAwaitTimeMS\" option to be >= 0, %" PRId64 " given", max_await_time_ms);
return false;
}
if (max_await_time_ms > UINT32_MAX) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"maxAwaitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_await_time_ms);
return false;
}
intern->max_await_time_ms = (uint32_t) max_await_time_ms;
return true;
} /* }}} */
/* Initializes the php_phongo_query_t from filter and options arguments. This
* function will fall back to a modifier in the absence of a top-level option
* (where applicable). */
static bool php_phongo_query_init(php_phongo_query_t* intern, zval* filter, zval* options) /* {{{ */
{
zval* modifiers = NULL;
intern->filter = bson_new();
intern->opts = bson_new();
intern->max_await_time_ms = 0;
php_phongo_zval_to_bson(filter, PHONGO_BSON_NONE, intern->filter, NULL);
/* Note: if any exceptions are thrown, we can simply return as PHP will
* invoke php_phongo_query_free_object to destruct the object. */
if (EG(exception)) {
return false;
}
if (!bson_validate(intern->filter, BSON_VALIDATE_EMPTY_KEYS, NULL)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use empty keys in filter document");
return false;
}
if (!options) {
return true;
}
if (php_array_existsc(options, "modifiers")) {
modifiers = php_array_fetchc(options, "modifiers");
if (Z_TYPE_P(modifiers) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"modifiers\" option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(modifiers));
return false;
}
}
PHONGO_QUERY_OPT_BOOL("allowDiskUse", options, "allowDiskUse")
PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "allowPartialResults")
else PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "partial");
PHONGO_QUERY_OPT_BOOL("awaitData", options, "awaitData");
PHONGO_QUERY_OPT_INT64("batchSize", options, "batchSize");
PHONGO_QUERY_OPT_DOCUMENT("collation", options, "collation");
- PHONGO_QUERY_OPT_STRING("comment", options, "comment")
- else PHONGO_QUERY_OPT_STRING("comment", modifiers, "$comment");
+ PHONGO_QUERY_OPT_BSON_VALUE("comment", options, "comment")
+ else PHONGO_QUERY_OPT_BSON_VALUE("comment", modifiers, "$comment");
PHONGO_QUERY_OPT_BOOL("exhaust", options, "exhaust");
+ PHONGO_QUERY_OPT_DOCUMENT("let", options, "let");
PHONGO_QUERY_OPT_DOCUMENT("max", options, "max")
else PHONGO_QUERY_OPT_DOCUMENT("max", modifiers, "$max");
PHONGO_QUERY_OPT_INT64_DEPRECATED("maxScan", options, "maxScan")
else PHONGO_QUERY_OPT_INT64_DEPRECATED("maxScan", modifiers, "$maxScan");
PHONGO_QUERY_OPT_INT64("maxTimeMS", options, "maxTimeMS")
else PHONGO_QUERY_OPT_INT64("maxTimeMS", modifiers, "$maxTimeMS");
PHONGO_QUERY_OPT_DOCUMENT("min", options, "min")
else PHONGO_QUERY_OPT_DOCUMENT("min", modifiers, "$min");
PHONGO_QUERY_OPT_BOOL("noCursorTimeout", options, "noCursorTimeout");
PHONGO_QUERY_OPT_BOOL_DEPRECATED("oplogReplay", options, "oplogReplay");
PHONGO_QUERY_OPT_DOCUMENT("projection", options, "projection");
PHONGO_QUERY_OPT_BOOL("returnKey", options, "returnKey")
else PHONGO_QUERY_OPT_BOOL("returnKey", modifiers, "$returnKey");
PHONGO_QUERY_OPT_BOOL("showRecordId", options, "showRecordId")
else PHONGO_QUERY_OPT_BOOL("showRecordId", modifiers, "$showDiskLoc");
PHONGO_QUERY_OPT_INT64("skip", options, "skip");
PHONGO_QUERY_OPT_DOCUMENT("sort", options, "sort")
else PHONGO_QUERY_OPT_DOCUMENT("sort", modifiers, "$orderby");
PHONGO_QUERY_OPT_BOOL_DEPRECATED("snapshot", options, "snapshot")
else PHONGO_QUERY_OPT_BOOL_DEPRECATED("snapshot", modifiers, "$snapshot");
PHONGO_QUERY_OPT_BOOL("tailable", options, "tailable");
/* The "$explain" modifier should be converted to an "explain" option, which
* libmongoc will later convert back to a modifier for the OP_QUERY code
* path. This modifier will be ignored for the find command code path. */
PHONGO_QUERY_OPT_BOOL("explain", modifiers, "$explain");
if (!php_phongo_query_init_hint(intern, options, modifiers)) {
return false;
}
if (!php_phongo_query_init_limit_and_singlebatch(intern, options)) {
return false;
}
if (!php_phongo_query_init_readconcern(intern, options)) {
return false;
}
if (!php_phongo_query_init_max_await_time_ms(intern, options)) {
return false;
}
return true;
} /* }}} */
+#undef PHONGO_QUERY_OPT_BOOL_EX
#undef PHONGO_QUERY_OPT_BOOL
+#undef PHONGO_QUERY_OPT_BOOL_DEPRECATED
+#undef PHONGO_QUERY_OPT_BSON_VALUE
#undef PHONGO_QUERY_OPT_DOCUMENT
+#undef PHONGO_QUERY_OPT_INT64_EX
#undef PHONGO_QUERY_OPT_INT64
+#undef PHONGO_QUERY_OPT_INT64_DEPRECATED
#undef PHONGO_QUERY_OPT_STRING
/* {{{ proto void MongoDB\Driver\Query::__construct(array|object $filter[, array $options = array()])
Constructs a new Query */
static PHP_METHOD(Query, __construct)
{
zend_error_handling error_handling;
php_phongo_query_t* intern;
zval* filter;
zval* options = NULL;
intern = Z_QUERY_OBJ_P(getThis());
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "A|a!", &filter, &options) == FAILURE) {
zend_restore_error_handling(&error_handling);
return;
}
zend_restore_error_handling(&error_handling);
php_phongo_query_init(intern, filter, options);
} /* }}} */
/* {{{ MongoDB\Driver\Query function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_Query___construct, 0, 0, 1)
ZEND_ARG_INFO(0, filter)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(ai_Query_void, 0, 0, 0)
ZEND_END_ARG_INFO()
static zend_function_entry php_phongo_query_me[] = {
/* clang-format off */
PHP_ME(Query, __construct, ai_Query___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Query_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */
/* {{{ MongoDB\Driver\Query object handlers */
static zend_object_handlers php_phongo_handler_query;
static void php_phongo_query_free_object(zend_object* object) /* {{{ */
{
php_phongo_query_t* intern = Z_OBJ_QUERY(object);
zend_object_std_dtor(&intern->std);
if (intern->filter) {
bson_clear(&intern->filter);
}
if (intern->opts) {
bson_clear(&intern->opts);
}
if (intern->read_concern) {
mongoc_read_concern_destroy(intern->read_concern);
}
} /* }}} */
static zend_object* php_phongo_query_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_query_t* intern = zend_object_alloc(sizeof(php_phongo_query_t), class_type);
zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
intern->std.handlers = &php_phongo_handler_query;
return &intern->std;
} /* }}} */
static HashTable* php_phongo_query_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_query_t* intern;
zval retval = ZVAL_STATIC_INIT;
*is_temp = 1;
intern = Z_OBJ_QUERY(PHONGO_COMPAT_GET_OBJ(object));
array_init_size(&retval, 3);
/* Avoid using PHONGO_TYPEMAP_NATIVE_ARRAY for decoding filter and opts
* documents so that users can differentiate BSON arrays and documents. */
if (intern->filter) {
zval zv;
if (!php_phongo_bson_to_zval(bson_get_data(intern->filter), intern->filter->len, &zv)) {
zval_ptr_dtor(&zv);
goto done;
}
ADD_ASSOC_ZVAL_EX(&retval, "filter", &zv);
} else {
ADD_ASSOC_NULL_EX(&retval, "filter");
}
if (intern->opts) {
zval zv;
if (!php_phongo_bson_to_zval(bson_get_data(intern->opts), intern->opts->len, &zv)) {
zval_ptr_dtor(&zv);
goto done;
}
ADD_ASSOC_ZVAL_EX(&retval, "options", &zv);
} else {
ADD_ASSOC_NULL_EX(&retval, "options");
}
if (intern->read_concern) {
zval read_concern;
php_phongo_read_concern_to_zval(&read_concern, intern->read_concern);
ADD_ASSOC_ZVAL_EX(&retval, "readConcern", &read_concern);
} else {
ADD_ASSOC_NULL_EX(&retval, "readConcern");
}
done:
return Z_ARRVAL(retval);
} /* }}} */
/* }}} */
void php_phongo_query_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Query", php_phongo_query_me);
php_phongo_query_ce = zend_register_internal_class(&ce);
php_phongo_query_ce->create_object = php_phongo_query_create_object;
PHONGO_CE_FINAL(php_phongo_query_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_query_ce);
memcpy(&php_phongo_handler_query, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_query.get_debug_info = php_phongo_query_get_debug_info;
php_phongo_handler_query.free_obj = php_phongo_query_free_object;
php_phongo_handler_query.offset = XtOffsetOf(php_phongo_query_t, std);
} /* }}} */
diff --git a/mongodb-1.13.0/src/MongoDB/ReadConcern.c b/mongodb-1.14.0/src/MongoDB/ReadConcern.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/ReadConcern.c
rename to mongodb-1.14.0/src/MongoDB/ReadConcern.c
diff --git a/mongodb-1.13.0/src/MongoDB/ReadConcern.h b/mongodb-1.14.0/src/MongoDB/ReadConcern.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/ReadConcern.h
rename to mongodb-1.14.0/src/MongoDB/ReadConcern.h
diff --git a/mongodb-1.13.0/src/MongoDB/ReadPreference.c b/mongodb-1.14.0/src/MongoDB/ReadPreference.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/ReadPreference.c
rename to mongodb-1.14.0/src/MongoDB/ReadPreference.c
diff --git a/mongodb-1.13.0/src/MongoDB/ReadPreference.h b/mongodb-1.14.0/src/MongoDB/ReadPreference.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/ReadPreference.h
rename to mongodb-1.14.0/src/MongoDB/ReadPreference.h
diff --git a/mongodb-1.13.0/src/MongoDB/Server.c b/mongodb-1.14.0/src/MongoDB/Server.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Server.c
rename to mongodb-1.14.0/src/MongoDB/Server.c
diff --git a/mongodb-1.13.0/src/MongoDB/Server.h b/mongodb-1.14.0/src/MongoDB/Server.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Server.h
rename to mongodb-1.14.0/src/MongoDB/Server.h
diff --git a/mongodb-1.13.0/src/MongoDB/ServerApi.c b/mongodb-1.14.0/src/MongoDB/ServerApi.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/ServerApi.c
rename to mongodb-1.14.0/src/MongoDB/ServerApi.c
diff --git a/mongodb-1.13.0/src/MongoDB/ServerDescription.c b/mongodb-1.14.0/src/MongoDB/ServerDescription.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/ServerDescription.c
rename to mongodb-1.14.0/src/MongoDB/ServerDescription.c
diff --git a/mongodb-1.13.0/src/MongoDB/ServerDescription.h b/mongodb-1.14.0/src/MongoDB/ServerDescription.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/ServerDescription.h
rename to mongodb-1.14.0/src/MongoDB/ServerDescription.h
diff --git a/mongodb-1.13.0/src/MongoDB/Session.c b/mongodb-1.14.0/src/MongoDB/Session.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Session.c
rename to mongodb-1.14.0/src/MongoDB/Session.c
diff --git a/mongodb-1.13.0/src/MongoDB/Session.h b/mongodb-1.14.0/src/MongoDB/Session.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/Session.h
rename to mongodb-1.14.0/src/MongoDB/Session.h
diff --git a/mongodb-1.13.0/src/MongoDB/TopologyDescription.c b/mongodb-1.14.0/src/MongoDB/TopologyDescription.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/TopologyDescription.c
rename to mongodb-1.14.0/src/MongoDB/TopologyDescription.c
diff --git a/mongodb-1.13.0/src/MongoDB/TopologyDescription.h b/mongodb-1.14.0/src/MongoDB/TopologyDescription.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/TopologyDescription.h
rename to mongodb-1.14.0/src/MongoDB/TopologyDescription.h
diff --git a/mongodb-1.13.0/src/MongoDB/WriteConcern.c b/mongodb-1.14.0/src/MongoDB/WriteConcern.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteConcern.c
rename to mongodb-1.14.0/src/MongoDB/WriteConcern.c
diff --git a/mongodb-1.13.0/src/MongoDB/WriteConcern.h b/mongodb-1.14.0/src/MongoDB/WriteConcern.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteConcern.h
rename to mongodb-1.14.0/src/MongoDB/WriteConcern.h
diff --git a/mongodb-1.13.0/src/MongoDB/WriteConcernError.c b/mongodb-1.14.0/src/MongoDB/WriteConcernError.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteConcernError.c
rename to mongodb-1.14.0/src/MongoDB/WriteConcernError.c
diff --git a/mongodb-1.13.0/src/MongoDB/WriteConcernError.h b/mongodb-1.14.0/src/MongoDB/WriteConcernError.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteConcernError.h
rename to mongodb-1.14.0/src/MongoDB/WriteConcernError.h
diff --git a/mongodb-1.13.0/src/MongoDB/WriteError.c b/mongodb-1.14.0/src/MongoDB/WriteError.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteError.c
rename to mongodb-1.14.0/src/MongoDB/WriteError.c
diff --git a/mongodb-1.13.0/src/MongoDB/WriteError.h b/mongodb-1.14.0/src/MongoDB/WriteError.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteError.h
rename to mongodb-1.14.0/src/MongoDB/WriteError.h
diff --git a/mongodb-1.13.0/src/MongoDB/WriteResult.c b/mongodb-1.14.0/src/MongoDB/WriteResult.c
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteResult.c
rename to mongodb-1.14.0/src/MongoDB/WriteResult.c
diff --git a/mongodb-1.13.0/src/MongoDB/WriteResult.h b/mongodb-1.14.0/src/MongoDB/WriteResult.h
similarity index 100%
rename from mongodb-1.13.0/src/MongoDB/WriteResult.h
rename to mongodb-1.14.0/src/MongoDB/WriteResult.h
diff --git a/mongodb-1.13.0/src/contrib/php_array_api.h b/mongodb-1.14.0/src/contrib/php_array_api.h
similarity index 100%
rename from mongodb-1.13.0/src/contrib/php_array_api.h
rename to mongodb-1.14.0/src/contrib/php_array_api.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-b64-private.h b/mongodb-1.14.0/src/libmongoc/src/common/common-b64-private.h
similarity index 53%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-b64-private.h
rename to mongodb-1.14.0/src/libmongoc/src/common/common-b64-private.h
index e3959d3c..531cfc5f 100644
--- a/mongodb-1.13.0/src/libmongoc/src/common/common-b64-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/common/common-b64-private.h
@@ -1,56 +1,63 @@
/*
* Copyright 2018-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common-prelude.h"
#ifndef COMMON_B64_PRIVATE_H
#define COMMON_B64_PRIVATE_H
#include <bson/bson.h>
-/* When encoding from "network" (raw data) to "presentation" (base64 encoded).
+#define mcommon_b64_ntop_calculate_target_size \
+ COMMON_NAME (b64_ntop_calculate_target_size)
+#define mcommon_b64_pton_calculate_target_size \
+ COMMON_NAME (b64_pton_calculate_target_size)
+#define mcommon_b64_ntop COMMON_NAME (b64_ntop)
+#define mcommon_b64_pton COMMON_NAME (b64_pton)
+
+/**
+ * When encoding from "network" (raw data) to "presentation" (base64 encoded).
* Includes the trailing null byte. */
-size_t COMMON_PREFIX (bson_b64_ntop_calculate_target_size) (size_t raw_size);
+size_t
+mcommon_b64_ntop_calculate_target_size (size_t raw_size);
/* When encoding from "presentation" (base64 encoded) to "network" (raw data).
* This may be an overestimate if the base64 data includes spaces. For a more
- * accurate size, call bson_b64_pton (src, NULL, 0), which will read the src
+ * accurate size, call b64_pton (src, NULL, 0), which will read the src
* data and return an exact size. */
-size_t COMMON_PREFIX (bson_b64_pton_calculate_target_size) (
- size_t base64_encoded_size);
+size_t
+mcommon_b64_pton_calculate_target_size (size_t base64_encoded_size);
/* Returns the number of bytes written (excluding NULL byte) to target on
* success or -1 on error. Adds a trailing NULL byte.
* Encodes from "network" (raw data) to "presentation" (base64 encoded),
* hence the obscure name "ntop".
*/
-int COMMON_PREFIX (bson_b64_ntop) (uint8_t const *src,
- size_t srclength,
- char *target,
- size_t targsize);
-
-/* If target is not NULL, the number of bytes written to target on success or -1
- * on error.
- * If target is NULL, returns the exact number of bytes that would be
- * written to target on decoding.
- * Encodes from "presentation" (base64 encoded) to "network" (raw data),
- * hence the obscure name "pton".
+int
+mcommon_b64_ntop (uint8_t const *src,
+ size_t srclength,
+ char *target,
+ size_t targsize);
+
+/** If target is not NULL, the number of bytes written to target on success or
+ * -1 on error. If target is NULL, returns the exact number of bytes that would
+ * be written to target on decoding. Encodes from "presentation" (base64
+ * encoded) to "network" (raw data), hence the obscure name "pton".
*/
-int COMMON_PREFIX (bson_b64_pton) (char const *src,
- uint8_t *target,
- size_t targsize);
+int
+mcommon_b64_pton (char const *src, uint8_t *target, size_t targsize);
#endif /* COMMON_B64_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-b64.c b/mongodb-1.14.0/src/libmongoc/src/common/common-b64.c
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-b64.c
rename to mongodb-1.14.0/src/libmongoc/src/common/common-b64.c
index 552d0e5a..71e197f4 100644
--- a/mongodb-1.13.0/src/libmongoc/src/common/common-b64.c
+++ b/mongodb-1.14.0/src/libmongoc/src/common/common-b64.c
@@ -1,559 +1,560 @@
/*
* Copyright (c) 1996, 1998 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include "bson/bson.h"
#include "common-b64-private.h"
#define Assert(Cond) \
if (!(Cond)) \
abort ()
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
* The following encoding technique is taken from RFC 1521 by Borenstein
* and Freed. It is reproduced here in a slightly edited form for
* convenience.
*
* A 65-character subset of US-ASCII is used, enabling 6 bits to be
* represented per printable character. (The extra 65th character, "=",
* is used to signify a special processing function.)
*
* The encoding process represents 24-bit groups of input bits as output
* strings of 4 encoded characters. Proceeding from left to right, a
* 24-bit input group is formed by concatenating 3 8-bit input groups.
* These 24 bits are then treated as 4 concatenated 6-bit groups, each
* of which is translated into a single digit in the base64 alphabet.
*
* Each 6-bit group is used as an index into an array of 64 printable
* characters. The character referenced by the index is placed in the
* output string.
*
* Table 1: The Base64 Alphabet
*
* Value Encoding Value Encoding Value Encoding Value Encoding
* 0 A 17 R 34 i 51 z
* 1 B 18 S 35 j 52 0
* 2 C 19 T 36 k 53 1
* 3 D 20 U 37 l 54 2
* 4 E 21 V 38 m 55 3
* 5 F 22 W 39 n 56 4
* 6 G 23 X 40 o 57 5
* 7 H 24 Y 41 p 58 6
* 8 I 25 Z 42 q 59 7
* 9 J 26 a 43 r 60 8
* 10 K 27 b 44 s 61 9
* 11 L 28 c 45 t 62 +
* 12 M 29 d 46 u 63 /
* 13 N 30 e 47 v
* 14 O 31 f 48 w (pad) =
* 15 P 32 g 49 x
* 16 Q 33 h 50 y
*
* Special processing is performed if fewer than 24 bits are available
* at the end of the data being encoded. A full encoding quantum is
* always completed at the end of a quantity. When fewer than 24 input
* bits are available in an input group, zero bits are added (on the
* right) to form an integral number of 6-bit groups. Padding at the
* end of the data is performed using the '=' character.
*
* Since all base64 input is an integral number of octets, only the
* following cases can arise:
*
* (1) the final quantum of encoding input is an integral
* multiple of 24 bits; here, the final unit of encoded
* output will be an integral multiple of 4 characters
* with no "=" padding,
* (2) the final quantum of encoding input is exactly 8 bits;
* here, the final unit of encoded output will be two
* characters followed by two "=" padding characters, or
* (3) the final quantum of encoding input is exactly 16 bits;
* here, the final unit of encoded output will be three
* characters followed by one "=" padding character.
*/
-int COMMON_PREFIX (bson_b64_ntop) (uint8_t const *src,
- size_t srclength,
- char *target,
- size_t targsize)
+int
+mcommon_b64_ntop (uint8_t const *src,
+ size_t srclength,
+ char *target,
+ size_t targsize)
{
size_t datalength = 0;
uint8_t input[3];
uint8_t output[4];
size_t i;
if (!target) {
return -1;
}
while (2 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclength -= 3;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
Assert (output[0] < 64);
Assert (output[1] < 64);
Assert (output[2] < 64);
Assert (output[3] < 64);
if (datalength + 4 > targsize) {
return -1;
}
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++) {
input[i] = *src++;
}
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
Assert (output[0] < 64);
Assert (output[1] < 64);
Assert (output[2] < 64);
if (datalength + 4 > targsize) {
return -1;
}
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclength == 1) {
target[datalength++] = Pad64;
} else {
target[datalength++] = Base64[output[2]];
}
target[datalength++] = Pad64;
}
if (datalength >= targsize) {
return -1;
}
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (int) datalength;
}
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
static uint8_t mongoc_b64rmap[256];
static const uint8_t mongoc_b64rmap_special = 0xf0;
static const uint8_t mongoc_b64rmap_end = 0xfd;
static const uint8_t mongoc_b64rmap_space = 0xfe;
static const uint8_t mongoc_b64rmap_invalid = 0xff;
/* initializing the reverse map isn't thread safe, do it in pthread_once */
#if defined(BSON_OS_UNIX)
#include <pthread.h>
#define mongoc_common_once_t pthread_once_t
#define mongoc_common_once pthread_once
#define MONGOC_COMMON_ONCE_FUN(n) void n (void)
#define MONGOC_COMMON_ONCE_RETURN return
#define MONGOC_COMMON_ONCE_INIT PTHREAD_ONCE_INIT
#else
#define mongoc_common_once_t INIT_ONCE
#define MONGOC_COMMON_ONCE_INIT INIT_ONCE_STATIC_INIT
#define mongoc_common_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL)
#define MONGOC_COMMON_ONCE_FUN(n) \
BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c)
#define MONGOC_COMMON_ONCE_RETURN return true
#endif
static MONGOC_COMMON_ONCE_FUN (bson_b64_initialize_rmap)
{
int i;
unsigned char ch;
/* Null: end of string, stop parsing */
mongoc_b64rmap[0] = mongoc_b64rmap_end;
for (i = 1; i < 256; ++i) {
ch = (unsigned char) i;
/* Whitespaces */
if (bson_isspace (ch))
mongoc_b64rmap[i] = mongoc_b64rmap_space;
/* Padding: stop parsing */
else if (ch == Pad64)
mongoc_b64rmap[i] = mongoc_b64rmap_end;
/* Non-base64 char */
else
mongoc_b64rmap[i] = mongoc_b64rmap_invalid;
}
/* Fill reverse mapping for base64 chars */
for (i = 0; Base64[i] != '\0'; ++i)
mongoc_b64rmap[(uint8_t) Base64[i]] = i;
MONGOC_COMMON_ONCE_RETURN;
}
static int
mongoc_b64_pton_do (char const *src, uint8_t *target, size_t targsize)
{
int tarindex, state;
uint8_t ch, ofs;
state = 0;
tarindex = 0;
while (1) {
ch = *src++;
ofs = mongoc_b64rmap[ch];
if (ofs >= mongoc_b64rmap_special) {
/* Ignore whitespaces */
if (ofs == mongoc_b64rmap_space)
continue;
/* End of base64 characters */
if (ofs == mongoc_b64rmap_end)
break;
/* A non-base64 character. */
return (-1);
}
switch (state) {
case 0:
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] = ofs << 2;
state = 1;
break;
case 1:
if ((size_t) tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= ofs >> 4;
target[tarindex + 1] = (ofs & 0x0f) << 4;
tarindex++;
state = 2;
break;
case 2:
if ((size_t) tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= ofs >> 2;
target[tarindex + 1] = (ofs & 0x03) << 6;
tarindex++;
state = 3;
break;
case 3:
if ((size_t) tarindex >= targsize)
return (-1);
target[tarindex] |= ofs;
tarindex++;
state = 0;
break;
default:
abort ();
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target[tarindex] != 0)
return (-1);
default:
break;
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}
static int
mongoc_b64_pton_len (char const *src)
{
int tarindex, state;
uint8_t ch, ofs;
state = 0;
tarindex = 0;
while (1) {
ch = *src++;
ofs = mongoc_b64rmap[ch];
if (ofs >= mongoc_b64rmap_special) {
/* Ignore whitespaces */
if (ofs == mongoc_b64rmap_space)
continue;
/* End of base64 characters */
if (ofs == mongoc_b64rmap_end)
break;
/* A non-base64 character. */
return (-1);
}
switch (state) {
case 0:
state = 1;
break;
case 1:
tarindex++;
state = 2;
break;
case 2:
tarindex++;
state = 3;
break;
case 3:
tarindex++;
state = 0;
break;
default:
abort ();
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for ((void) NULL; ch != '\0'; ch = *src++)
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
return (-1);
default:
break;
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}
-int COMMON_PREFIX (bson_b64_pton) (char const *src,
- uint8_t *target,
- size_t targsize)
+int
+mcommon_b64_pton (char const *src, uint8_t *target, size_t targsize)
{
static mongoc_common_once_t once = MONGOC_COMMON_ONCE_INIT;
mongoc_common_once (&once, bson_b64_initialize_rmap);
if (!src) {
return -1;
}
if (target)
return mongoc_b64_pton_do (src, target, targsize);
else
return mongoc_b64_pton_len (src);
}
-size_t COMMON_PREFIX (bson_b64_ntop_calculate_target_size) (size_t raw_size)
+size_t
+mcommon_b64_ntop_calculate_target_size (size_t raw_size)
{
size_t num_bits = raw_size * 8;
/* Calculate how many groups of six bits this contains, adding 5 to round up
* to the nearest group of 6. */
size_t num_b64_chars = (num_bits + 5) / 6;
/* Round to nearest set of four. */
size_t num_b64_chars_with_padding = 4 * ((num_b64_chars + 3) / 4);
/* Add one for NULL byte. */
return num_b64_chars_with_padding + 1;
}
-size_t COMMON_PREFIX (bson_b64_pton_calculate_target_size) (
- size_t base64_encoded_size)
+size_t
+mcommon_b64_pton_calculate_target_size (size_t base64_encoded_size)
{
/* Without inspecting the data, we don't know how many padding characters
* there are. Assuming none, that means each character represents 6 bits of
* data. */
size_t num_bits = base64_encoded_size * 6;
/* Round down to the nearest group of eight. */
return num_bits / 8;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-config.h b/mongodb-1.14.0/src/libmongoc/src/common/common-config.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-config.h
rename to mongodb-1.14.0/src/libmongoc/src/common/common-config.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-config.h.in b/mongodb-1.14.0/src/libmongoc/src/common/common-config.h.in
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-config.h.in
rename to mongodb-1.14.0/src/libmongoc/src/common/common-config.h.in
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-macros-private.h b/mongodb-1.14.0/src/libmongoc/src/common/common-macros-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-macros-private.h
rename to mongodb-1.14.0/src/libmongoc/src/common/common-macros-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-md5-private.h b/mongodb-1.14.0/src/libmongoc/src/common/common-md5-private.h
similarity index 69%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-md5-private.h
rename to mongodb-1.14.0/src/libmongoc/src/common/common-md5-private.h
index b2d164ae..4feadb93 100644
--- a/mongodb-1.13.0/src/libmongoc/src/common/common-md5-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/common/common-md5-private.h
@@ -1,34 +1,39 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common-prelude.h"
#ifndef COMMON_MD5_PRIVATE_H
#define COMMON_MD5_PRIVATE_H
#include "bson/bson.h"
BSON_BEGIN_DECLS
-void COMMON_PREFIX (_bson_md5_init) (bson_md5_t *pms);
-void COMMON_PREFIX (_bson_md5_append) (bson_md5_t *pms,
- const uint8_t *data,
- uint32_t nbytes);
-void COMMON_PREFIX (_bson_md5_finish) (bson_md5_t *pms, uint8_t digest[16]);
+#define mcommon_md5_init COMMON_NAME (md5_init)
+#define mcommon_md5_append COMMON_NAME (md5_append)
+#define mcommon_md5_finish COMMON_NAME (md5_finish)
+
+void
+mcommon_md5_init (bson_md5_t *pms);
+void
+mcommon_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes);
+void
+mcommon_md5_finish (bson_md5_t *pms, uint8_t digest[16]);
BSON_END_DECLS
#endif /* COMMON_MD5_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-md5.c b/mongodb-1.14.0/src/libmongoc/src/common/common-md5.c
similarity index 96%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-md5.c
rename to mongodb-1.14.0/src/libmongoc/src/common/common-md5.c
index 13254535..c726b918 100644
--- a/mongodb-1.13.0/src/libmongoc/src/common/common-md5.c
+++ b/mongodb-1.14.0/src/libmongoc/src/common/common-md5.c
@@ -1,395 +1,395 @@
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgement in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
/*
* The following MD5 implementation has been modified to use types as
* specified in libbson.
*/
#include <string.h>
#include "common-md5-private.h"
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
#define BYTE_ORDER 1
#else
#define BYTE_ORDER -1
#endif
#define T_MASK ((uint32_t) ~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
bson_md5_process (bson_md5_t *md5, const uint8_t *data)
{
uint32_t a = md5->abcd[0];
uint32_t b = md5->abcd[1];
uint32_t c = md5->abcd[2];
uint32_t d = md5->abcd[3];
uint32_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
uint32_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
uint32_t xbuf[16];
const uint32_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const uint8_t *) &w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const uint8_t *) 0) & 3)) {
/* data are properly aligned */
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-align"
#endif
X = (const uint32_t *) data;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
} else {
/* not aligned */
memcpy (xbuf, data, sizeof (xbuf));
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const uint8_t *xp = data;
int i;
#if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
#else
#define xbuf X /* (static only) */
#endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti) \
t = a + F (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 0, 7, T1);
SET (d, a, b, c, 1, 12, T2);
SET (c, d, a, b, 2, 17, T3);
SET (b, c, d, a, 3, 22, T4);
SET (a, b, c, d, 4, 7, T5);
SET (d, a, b, c, 5, 12, T6);
SET (c, d, a, b, 6, 17, T7);
SET (b, c, d, a, 7, 22, T8);
SET (a, b, c, d, 8, 7, T9);
SET (d, a, b, c, 9, 12, T10);
SET (c, d, a, b, 10, 17, T11);
SET (b, c, d, a, 11, 22, T12);
SET (a, b, c, d, 12, 7, T13);
SET (d, a, b, c, 13, 12, T14);
SET (c, d, a, b, 14, 17, T15);
SET (b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti) \
t = a + G (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 1, 5, T17);
SET (d, a, b, c, 6, 9, T18);
SET (c, d, a, b, 11, 14, T19);
SET (b, c, d, a, 0, 20, T20);
SET (a, b, c, d, 5, 5, T21);
SET (d, a, b, c, 10, 9, T22);
SET (c, d, a, b, 15, 14, T23);
SET (b, c, d, a, 4, 20, T24);
SET (a, b, c, d, 9, 5, T25);
SET (d, a, b, c, 14, 9, T26);
SET (c, d, a, b, 3, 14, T27);
SET (b, c, d, a, 8, 20, T28);
SET (a, b, c, d, 13, 5, T29);
SET (d, a, b, c, 2, 9, T30);
SET (c, d, a, b, 7, 14, T31);
SET (b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti) \
t = a + H (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 5, 4, T33);
SET (d, a, b, c, 8, 11, T34);
SET (c, d, a, b, 11, 16, T35);
SET (b, c, d, a, 14, 23, T36);
SET (a, b, c, d, 1, 4, T37);
SET (d, a, b, c, 4, 11, T38);
SET (c, d, a, b, 7, 16, T39);
SET (b, c, d, a, 10, 23, T40);
SET (a, b, c, d, 13, 4, T41);
SET (d, a, b, c, 0, 11, T42);
SET (c, d, a, b, 3, 16, T43);
SET (b, c, d, a, 6, 23, T44);
SET (a, b, c, d, 9, 4, T45);
SET (d, a, b, c, 12, 11, T46);
SET (c, d, a, b, 15, 16, T47);
SET (b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti) \
t = a + I (b, c, d) + X[k] + Ti; \
a = ROTATE_LEFT (t, s) + b
/* Do the following 16 operations. */
SET (a, b, c, d, 0, 6, T49);
SET (d, a, b, c, 7, 10, T50);
SET (c, d, a, b, 14, 15, T51);
SET (b, c, d, a, 5, 21, T52);
SET (a, b, c, d, 12, 6, T53);
SET (d, a, b, c, 3, 10, T54);
SET (c, d, a, b, 10, 15, T55);
SET (b, c, d, a, 1, 21, T56);
SET (a, b, c, d, 8, 6, T57);
SET (d, a, b, c, 15, 10, T58);
SET (c, d, a, b, 6, 15, T59);
SET (b, c, d, a, 13, 21, T60);
SET (a, b, c, d, 4, 6, T61);
SET (d, a, b, c, 11, 10, T62);
SET (c, d, a, b, 2, 15, T63);
SET (b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
md5->abcd[0] += a;
md5->abcd[1] += b;
md5->abcd[2] += c;
md5->abcd[3] += d;
}
-void COMMON_PREFIX (_bson_md5_init) (bson_md5_t *pms)
+void
+mcommon_md5_init (bson_md5_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
-void COMMON_PREFIX (_bson_md5_append) (bson_md5_t *pms,
- const uint8_t *data,
- uint32_t nbytes)
+void
+mcommon_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes)
{
const uint8_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
uint32_t nbits = (uint32_t) (nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy (pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
bson_md5_process (pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
bson_md5_process (pms, p);
/* Process a final partial block. */
if (left)
memcpy (pms->buf, p, left);
}
-void COMMON_PREFIX (_bson_md5_finish) (bson_md5_t *pms, uint8_t digest[16])
+void
+mcommon_md5_finish (bson_md5_t *pms, uint8_t digest[16])
{
static const uint8_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (uint8_t) (pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
- COMMON_PREFIX (_bson_md5_append)
- (pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ mcommon_md5_append (pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
- COMMON_PREFIX (_bson_md5_append) (pms, data, sizeof (data));
+ mcommon_md5_append (pms, data, sizeof (data));
for (i = 0; i < 16; ++i)
digest[i] = (uint8_t) (pms->abcd[i >> 2] >> ((i & 3) << 3));
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-prelude.h b/mongodb-1.14.0/src/libmongoc/src/common/common-prelude.h
similarity index 77%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-prelude.h
rename to mongodb-1.14.0/src/libmongoc/src/common/common-prelude.h
index 42f0afad..efc18bcd 100644
--- a/mongodb-1.13.0/src/libmongoc/src/common/common-prelude.h
+++ b/mongodb-1.14.0/src/libmongoc/src/common/common-prelude.h
@@ -1,27 +1,28 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) && \
!defined(BSON_COMPILATION) && !defined(BSON_INSIDE)
#error "Only <mongoc/mongoc.h> or <bson/bson.h> can be included directly."
#endif
-#ifndef COMMON_PREFIX_
-#define COMMON_PREFIX_
+#define COMMON_NAME_1(a, b) a##_##b
+
+#if defined(MCOMMON_NAME_PREFIX) && !defined(__INTELLISENSE__)
+#define COMMON_NAME(Name) COMMON_NAME_1 (MCOMMON_NAME_PREFIX, Name)
+#else
+#define COMMON_NAME(Name) COMMON_NAME_1 (mcommon, Name)
#endif
-#define JOINER(x, y) x##_##y
-#define NAME_EVALUATOR(x, y) JOINER (x, y)
-#define COMMON_PREFIX(name) NAME_EVALUATOR (COMMON_PREFIX_, name)
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-thread-private.h b/mongodb-1.14.0/src/libmongoc/src/common/common-thread-private.h
similarity index 92%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-thread-private.h
rename to mongodb-1.14.0/src/libmongoc/src/common/common-thread-private.h
index c0740520..17491f26 100644
--- a/mongodb-1.13.0/src/libmongoc/src/common/common-thread-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/common/common-thread-private.h
@@ -1,183 +1,190 @@
/*
* Copyright 2013-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common-prelude.h"
#include "common-config.h"
#include "common-macros-private.h"
#ifndef COMMON_THREAD_PRIVATE_H
#define COMMON_THREAD_PRIVATE_H
#define BSON_INSIDE
#include "bson/bson-compat.h"
#include "bson/bson-config.h"
#include "bson/bson-macros.h"
#undef BSON_INSIDE
BSON_BEGIN_DECLS
+#define mcommon_thread_create COMMON_NAME (thread_create)
+#define mcommon_thread_join COMMON_NAME (thread_join)
+
#if defined(BSON_OS_UNIX)
#include <pthread.h>
#define BSON_ONCE_FUN(n) void n (void)
#define BSON_ONCE_RETURN return
#define BSON_ONCE_INIT PTHREAD_ONCE_INIT
#define bson_once pthread_once
#define bson_once_t pthread_once_t
#define bson_thread_t pthread_t
#define BSON_THREAD_FUN(_function_name, _arg_name) \
void *(_function_name) (void *(_arg_name))
#define BSON_THREAD_FUN_TYPE(_function_name) void *(*(_function_name)) (void *)
#define BSON_THREAD_RETURN return NULL
/* this macro can be defined as a as a build configuration option
* with -DENABLE_DEBUG_ASSERTIONS=ON. its purpose is to allow for functions
* that require a mutex to be locked on entry to assert that the mutex
* is actually locked.
* this can prevent bugs where a caller forgets to lock the mutex. */
#ifndef MONGOC_ENABLE_DEBUG_ASSERTIONS
#define bson_mutex_destroy pthread_mutex_destroy
#define bson_mutex_init(_n) pthread_mutex_init ((_n), NULL)
#define bson_mutex_lock pthread_mutex_lock
#define bson_mutex_t pthread_mutex_t
#define bson_mutex_unlock pthread_mutex_unlock
#else
typedef struct {
pthread_t lock_owner;
pthread_mutex_t wrapped_mutex;
bool valid_tid;
} bson_mutex_t;
#define bson_mutex_destroy(mutex) \
do { \
pthread_mutex_destroy (&(mutex)->wrapped_mutex); \
} while (0);
#define bson_mutex_init(mutex) \
do { \
pthread_mutex_init (&(mutex)->wrapped_mutex, NULL); \
(mutex)->valid_tid = false; \
} while (0);
#define bson_mutex_lock(mutex) \
do { \
pthread_mutex_lock (&(mutex)->wrapped_mutex); \
(mutex)->lock_owner = pthread_self (); \
(mutex)->valid_tid = true; \
} while (0);
#define bson_mutex_unlock(mutex) \
do { \
(mutex)->valid_tid = false; \
pthread_mutex_unlock (&(mutex)->wrapped_mutex); \
} while (0);
#endif
#else
#include <process.h>
#define BSON_ONCE_FUN(n) \
BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c)
#define BSON_ONCE_INIT INIT_ONCE_STATIC_INIT
#define BSON_ONCE_RETURN return true
#define bson_mutex_destroy DeleteCriticalSection
#define bson_mutex_init InitializeCriticalSection
#define bson_mutex_lock EnterCriticalSection
#define bson_mutex_t CRITICAL_SECTION
#define bson_mutex_unlock LeaveCriticalSection
#define bson_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL)
#define bson_once_t INIT_ONCE
#define bson_thread_t HANDLE
#define BSON_THREAD_FUN(_function_name, _arg_name) \
unsigned (__stdcall _function_name) (void *(_arg_name))
#define BSON_THREAD_FUN_TYPE(_function_name) \
- unsigned(__stdcall * _function_name) (void *)
+ unsigned (__stdcall * _function_name) (void *)
#define BSON_THREAD_RETURN return 0
#endif
/* Functions that require definitions get the common prefix (_mongoc for
* libmongoc or _bson for libbson) to avoid duplicate symbols when linking both
* libbson and libmongoc statically. */
-int COMMON_PREFIX (thread_join) (bson_thread_t thread);
-int COMMON_PREFIX (thread_create) (bson_thread_t *thread,
- BSON_THREAD_FUN_TYPE (func),
- void *arg);
+int
+mcommon_thread_join (bson_thread_t thread);
+int
+mcommon_thread_create (bson_thread_t *thread,
+ BSON_THREAD_FUN_TYPE (func),
+ void *arg);
#if defined(MONGOC_ENABLE_DEBUG_ASSERTIONS) && defined(BSON_OS_UNIX)
-bool COMMON_PREFIX (mutex_is_locked) (bson_mutex_t *mutex);
+#define mcommon_mutex_is_locked COMMON_NAME (mutex_is_locked)
+bool
+mcommon_mutex_is_locked (bson_mutex_t *mutex);
#endif
/**
* @brief A shared mutex (a read-write lock)
*
* A shared mutex can be locked in 'shared' mode or 'exclusive' mode. Only one
* thread may hold exclusive mode at a time. Any number of threads may hold
* the lock in shared mode simultaneously. No thread can hold in exclusive mode
* while another thread holds in shared mode, and vice-versa.
*/
typedef struct bson_shared_mutex_t {
BSON_IF_WINDOWS (SRWLOCK native;)
BSON_IF_POSIX (pthread_rwlock_t native;)
} bson_shared_mutex_t;
static BSON_INLINE void
bson_shared_mutex_init (bson_shared_mutex_t *mtx)
{
BSON_IF_WINDOWS (InitializeSRWLock (&mtx->native));
BSON_IF_POSIX (pthread_rwlock_init (&mtx->native, NULL));
}
static BSON_INLINE void
bson_shared_mutex_destroy (bson_shared_mutex_t *mtx)
{
BSON_IF_WINDOWS ((void) mtx;)
BSON_IF_POSIX (pthread_rwlock_destroy (&mtx->native);)
}
static BSON_INLINE void
bson_shared_mutex_lock_shared (bson_shared_mutex_t *mtx)
{
BSON_IF_WINDOWS (AcquireSRWLockShared (&mtx->native);)
BSON_IF_POSIX (pthread_rwlock_rdlock (&mtx->native);)
}
static BSON_INLINE void
bson_shared_mutex_lock (bson_shared_mutex_t *mtx)
{
BSON_IF_WINDOWS (AcquireSRWLockExclusive (&mtx->native);)
BSON_IF_POSIX (pthread_rwlock_wrlock (&mtx->native);)
}
static BSON_INLINE void
bson_shared_mutex_unlock (bson_shared_mutex_t *mtx)
{
BSON_IF_WINDOWS (ReleaseSRWLockExclusive (&mtx->native);)
BSON_IF_POSIX (pthread_rwlock_unlock (&mtx->native);)
}
static BSON_INLINE void
bson_shared_mutex_unlock_shared (bson_shared_mutex_t *mtx)
{
BSON_IF_WINDOWS (ReleaseSRWLockShared (&mtx->native);)
BSON_IF_POSIX (pthread_rwlock_unlock (&mtx->native);)
}
BSON_END_DECLS
#endif /* COMMON_THREAD_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/common/common-thread.c b/mongodb-1.14.0/src/libmongoc/src/common/common-thread.c
similarity index 73%
rename from mongodb-1.13.0/src/libmongoc/src/common/common-thread.c
rename to mongodb-1.14.0/src/libmongoc/src/common/common-thread.c
index aca86dce..514a9c9d 100644
--- a/mongodb-1.13.0/src/libmongoc/src/common/common-thread.c
+++ b/mongodb-1.14.0/src/libmongoc/src/common/common-thread.c
@@ -1,66 +1,71 @@
/*
* Copyright 2020-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common-thread-private.h"
#if defined(BSON_OS_UNIX)
-int COMMON_PREFIX (thread_create) (bson_thread_t *thread,
- BSON_THREAD_FUN_TYPE (func),
- void *arg)
+int
+mcommon_thread_create (bson_thread_t *thread,
+ BSON_THREAD_FUN_TYPE (func),
+ void *arg)
{
return pthread_create (thread, NULL, func, arg);
}
-int COMMON_PREFIX (thread_join) (bson_thread_t thread)
+int
+mcommon_thread_join (bson_thread_t thread)
{
return pthread_join (thread, NULL);
}
#if defined(MONGOC_ENABLE_DEBUG_ASSERTIONS) && defined(BSON_OS_UNIX)
-bool COMMON_PREFIX (mutex_is_locked) (bson_mutex_t *mutex)
+bool
+mcommon_mutex_is_locked (bson_mutex_t *mutex)
{
return mutex->valid_tid &&
pthread_equal (pthread_self (), mutex->lock_owner);
}
#endif
#else
-int COMMON_PREFIX (thread_create) (bson_thread_t *thread,
- BSON_THREAD_FUN_TYPE (func),
- void *arg)
+int
+mcommon_thread_create (bson_thread_t *thread,
+ BSON_THREAD_FUN_TYPE (func),
+ void *arg)
{
*thread = (HANDLE) _beginthreadex (NULL, 0, func, arg, 0, NULL);
if (0 == *thread) {
return 1;
}
return 0;
}
-int COMMON_PREFIX (thread_join) (bson_thread_t thread)
+int
+mcommon_thread_join (bson_thread_t thread)
{
int ret;
/* zero indicates success for WaitForSingleObject. */
ret = WaitForSingleObject (thread, INFINITE);
if (WAIT_OBJECT_0 != ret) {
return ret;
}
/* zero indicates failure for CloseHandle. */
ret = CloseHandle (thread);
if (0 == ret) {
return 1;
}
return 0;
}
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/hexlify.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/hexlify.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/hexlify.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/hexlify.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/hexlify.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/hexlify.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/hexlify.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/hexlify.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_b64.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_b64.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_b64.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_b64.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_caller_identity_request.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_caller_identity_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_caller_identity_request.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_caller_identity_request.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_apple.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_apple.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_apple.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_apple.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_none.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_none.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_none.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_none.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_windows.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_windows.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_crypto_windows.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_crypto_windows.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_decrypt_request.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_decrypt_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_decrypt_request.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_decrypt_request.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_encrypt_request.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_encrypt_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_encrypt_request.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_encrypt_request.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_kv_list.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_kv_list.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_kv_list.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_kv_list.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_kv_list.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_kv_list.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_kv_list.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_kv_list.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_b64.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_b64.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_b64.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_b64.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_message.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_message.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_message.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_message.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_request.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_request.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_request.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_response.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_response.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_response.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_response.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message_private.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_message_private.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_message_private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_port.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_port.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_port.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_port.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_port.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_port.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_port.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_port.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_opt.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_opt.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_opt.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_opt.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_opt_private.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_opt_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_opt_private.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_opt_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_str.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_str.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_str.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_str.c
index 65207d2f..84c423fc 100644
--- a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_str.c
+++ b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_str.c
@@ -1,514 +1,514 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hexlify.h"
#include "kms_crypto.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_str.h"
#include "kms_port.h"
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
bool rfc_3986_tab[256] = {0};
bool kms_initialized = false;
static void
tables_init ()
{
int i;
if (kms_initialized) {
return;
}
for (i = 0; i < 256; ++i) {
rfc_3986_tab[i] =
isalnum (i) || i == '~' || i == '-' || i == '.' || i == '_';
}
kms_initialized = true;
}
kms_request_str_t *
kms_request_str_new (void)
{
kms_request_str_t *s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
s->len = 0;
s->size = 16;
s->str = malloc (s->size);
KMS_ASSERT (s->str);
s->str[0] = '\0';
return s;
}
kms_request_str_t *
kms_request_str_new_from_chars (const char *chars, ssize_t len)
{
kms_request_str_t *s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
size_t actual_len;
actual_len = len < 0 ? strlen (chars) : (size_t) len;
s->size = actual_len + 1;
s->str = malloc (s->size);
KMS_ASSERT (s->str);
memcpy (s->str, chars, actual_len);
s->str[actual_len] = '\0';
s->len = actual_len;
return s;
}
kms_request_str_t *
kms_request_str_wrap (char *chars, ssize_t len)
{
kms_request_str_t *s;
if (!chars) {
return NULL;
}
s = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (s);
s->str = chars;
s->len = len < 0 ? strlen (chars) : (size_t) len;
s->size = s->len;
return s;
}
void
kms_request_str_destroy (kms_request_str_t *str)
{
if (!str) {
return;
}
free (str->str);
free (str);
}
char *
kms_request_str_detach (kms_request_str_t *str)
{
if (!str) {
return NULL;
}
char *r = str->str;
free (str);
return r;
}
const char *
kms_request_str_get (kms_request_str_t *str)
{
return str->str;
}
bool
kms_request_str_reserve (kms_request_str_t *str, size_t size)
{
size_t next_size = str->len + size + 1;
if (str->size < next_size) {
/* next power of 2 */
--next_size;
next_size |= next_size >> 1U;
next_size |= next_size >> 2U;
next_size |= next_size >> 4U;
next_size |= next_size >> 8U;
next_size |= next_size >> 16U;
++next_size;
str->size = next_size;
str->str = realloc (str->str, next_size);
}
return str->str != NULL;
}
kms_request_str_t *
kms_request_str_dup (kms_request_str_t *str)
{
kms_request_str_t *dup = malloc (sizeof (kms_request_str_t));
KMS_ASSERT (dup);
dup->str = kms_strndup (str->str, str->len);
dup->len = str->len;
dup->size = str->len + 1;
return dup;
}
void
kms_request_str_set_chars (kms_request_str_t *str,
const char *chars,
ssize_t len)
{
size_t actual_len = len < 0 ? strlen (chars) : (size_t) len;
kms_request_str_reserve (str, actual_len); /* adds 1 for nil */
memcpy (str->str, chars, actual_len + 1);
str->len = actual_len;
}
bool
kms_request_str_ends_with (kms_request_str_t *str, kms_request_str_t *suffix)
{
if (str->len >= suffix->len &&
0 == strncmp (
&str->str[str->len - suffix->len], suffix->str, suffix->len)) {
return true;
}
return false;
}
void
kms_request_str_append (kms_request_str_t *str, kms_request_str_t *appended)
{
size_t next_len = str->len + appended->len;
kms_request_str_reserve (str, next_len);
memcpy (str->str + str->len, appended->str, appended->len);
str->len += appended->len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_char (kms_request_str_t *str, char c)
{
kms_request_str_reserve (str, 1);
*(str->str + str->len) = c;
++str->len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_chars (kms_request_str_t *str,
const char *appended,
ssize_t len)
{
if (len < 0) {
len = strlen (appended);
}
kms_request_str_reserve (str, (size_t) len);
memcpy (str->str + str->len, appended, (size_t) len);
str->len += len;
str->str[str->len] = '\0';
}
void
kms_request_str_append_newline (kms_request_str_t *str)
{
kms_request_str_append_char (str, '\n');
}
void
kms_request_str_append_lowercase (kms_request_str_t *str,
kms_request_str_t *appended)
{
size_t i;
char *p;
i = str->len;
kms_request_str_append (str, appended);
/* downcase the chars from the old end to the new end of str */
for (; i < str->len; ++i) {
p = &str->str[i];
/* ignore UTF-8 non-ASCII chars, which have 1 in the top bit */
if ((*p & (0x1U << 7U)) == 0) {
*p = (char) tolower (*p);
}
}
}
void
kms_request_str_appendf (kms_request_str_t *str, const char *format, ...)
{
va_list args;
size_t remaining;
int n;
KMS_ASSERT (format);
while (true) {
remaining = str->size - str->len;
va_start (args, format);
n = vsnprintf (&str->str[str->len], remaining, format, args);
va_end (args);
if (n > -1 && (size_t) n < remaining) {
/* success */
str->len += (size_t) n;
return;
}
if (n > -1) {
kms_request_str_reserve (str, (size_t) n);
} else {
/* TODO: error! */
abort ();
}
}
}
void
kms_request_str_append_escaped (kms_request_str_t *str,
kms_request_str_t *appended,
bool escape_slash)
{
uint8_t *in;
uint8_t *out;
size_t i;
tables_init ();
/* might replace each input char with 3 output chars: "%AB" */
kms_request_str_reserve (str, 3 * appended->len);
in = (uint8_t *) appended->str;
out = (uint8_t *) str->str + str->len;
for (i = 0; i < appended->len; ++i) {
if (rfc_3986_tab[*in] || (*in == '/' && !escape_slash)) {
*out = *in;
++out;
++str->len;
} else {
sprintf ((char *) out, "%%%02X", *in);
out += 3;
str->len += 3;
}
++in;
}
}
void
kms_request_str_append_stripped (kms_request_str_t *str,
kms_request_str_t *appended)
{
const char *src = appended->str;
const char *end = appended->str + appended->len;
bool space = false;
bool comma = false;
kms_request_str_reserve (str, appended->len);
- // msvcrt is unhappy when it gets non-ANSI characters in isspace
+ /* msvcrt is unhappy when it gets non-ANSI characters in isspace */
while (*src >= 0 && isspace (*src)) {
++src;
}
while (src < end) {
/* replace newlines with commas. not documented but see
* get-header-value-multiline.creq */
if (*src == '\n') {
comma = true;
space = false;
} else if (*src >= 0 && isspace (*src)) {
space = true;
} else {
if (comma) {
kms_request_str_append_char (str, ',');
comma = false;
space = false;
}
/* is there a run of spaces waiting to be written as one space? */
if (space) {
kms_request_str_append_char (str, ' ');
space = false;
}
kms_request_str_append_char (str, *src);
}
++src;
}
}
bool
kms_request_str_append_hashed (_kms_crypto_t *crypto,
kms_request_str_t *str,
kms_request_str_t *appended)
{
uint8_t hash[32];
char *hex_chars;
if (!crypto->sha256 (crypto->ctx, appended->str, appended->len, hash)) {
return false;
}
hex_chars = hexlify (hash, sizeof (hash));
kms_request_str_append_chars (str, hex_chars, 2 * sizeof (hash));
free (hex_chars);
return true;
}
bool
kms_request_str_append_hex (kms_request_str_t *str,
unsigned char *data,
size_t len)
{
char *hex_chars;
hex_chars = hexlify (data, len);
kms_request_str_append_chars (str, hex_chars, len * 2);
free (hex_chars);
return true;
}
static bool
starts_with (char *s, const char *prefix)
{
if (strstr (s, prefix) == s) {
return true;
}
return false;
}
/* remove from last slash to the end, but don't remove slash from start */
static void
delete_last_segment (kms_request_str_t *str, bool is_absolute)
{
ssize_t i;
if (!str->len) {
return;
}
for (i = str->len - 1; i >= 0; --i) {
if (str->str[i] == '/') {
if (i == 0 && is_absolute) {
str->len = 1;
} else {
str->len = (size_t) i;
}
goto done;
}
}
/* no slashes */
str->len = 0;
done:
str->str[str->len] = '\0';
}
/* follow algorithm in https://tools.ietf.org/html/rfc3986#section-5.2.4,
* the block comments are copied from there */
kms_request_str_t *
kms_request_str_path_normalized (kms_request_str_t *str)
{
kms_request_str_t *slash = kms_request_str_new_from_chars ("/", 1);
kms_request_str_t *out = kms_request_str_new ();
char *in = strdup (str->str);
char *p = in;
char *end = in + str->len;
bool is_absolute = (*p == '/');
if (0 == strcmp (p, "/")) {
goto done;
}
while (p < end) {
/* If the input buffer begins with a prefix of "../" or "./",
* then remove that prefix from the input buffer */
if (starts_with (p, "../")) {
p += 3;
} else if (starts_with (p, "./")) {
p += 2;
}
/* otherwise, if the input buffer begins with a prefix of "/./" or "/.",
* where "." is a complete path segment, then replace that prefix with "/"
* in the input buffer */
else if (starts_with (p, "/./")) {
p += 2;
} else if (0 == strcmp (p, "/.")) {
break;
}
/* otherwise, if the input buffer begins with a prefix of "/../" or "/..",
* where ".." is a complete path segment, then replace that prefix with
* "/" in the input buffer and remove the last segment and its preceding
* "/" (if any) from the output buffer */
else if (starts_with (p, "/../")) {
p += 3;
delete_last_segment (out, is_absolute);
} else if (0 == strcmp (p, "/..")) {
delete_last_segment (out, is_absolute);
break;
}
/* otherwise, if the input buffer consists only of "." or "..", then
remove that from the input buffer */
else if (0 == strcmp (p, ".") || 0 == strcmp (p, "..")) {
break;
}
/* otherwise, move the first path segment in the input buffer to the end
* of the output buffer, including the initial "/" character (if any) and
* any subsequent characters up to, but not including, the next "/"
* character or the end of the input buffer. */
else {
char *next_slash = strchr (p + 1, '/');
if (!next_slash) {
next_slash = end;
}
/* fold repeated slashes */
if (kms_request_str_ends_with (out, slash) && *p == '/') {
++p;
}
/* normalize "a/../b" as "b", not as "/b" */
if (out->len == 0 && !is_absolute && *p == '/') {
++p;
}
kms_request_str_append_chars (out, p, next_slash - p);
p = next_slash;
}
}
done:
free (in);
kms_request_str_destroy (slash);
if (!out->len) {
kms_request_str_append_char (out, '/');
}
return out;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_str.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_str.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_str.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_request_str.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_response.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_response.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_response.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_response.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_response_parser.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_response_parser.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_response_parser.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/kms_response_parser.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/sort.c b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/sort.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/sort.c
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/sort.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/sort.h b/mongodb-1.14.0/src/libmongoc/src/kms-message/src/sort.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/sort.h
rename to mongodb-1.14.0/src/libmongoc/src/kms-message/src/sort.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bcon.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bcon.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bcon.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bcon.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bcon.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bcon.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bcon.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bcon.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-atomic.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-atomic.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-atomic.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-atomic.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-atomic.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-atomic.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-atomic.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-atomic.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-clock.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-clock.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-clock.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-clock.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-clock.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-clock.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-clock.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-clock.h
diff --git a/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-cmp.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-cmp.h
new file mode 100644
index 00000000..f9196d32
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-cmp.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2022 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bson-prelude.h"
+
+
+#ifndef BSON_CMP_H
+#define BSON_CMP_H
+
+
+#include "bson-compat.h" /* ssize_t */
+#include "bson-macros.h" /* BSON_CONCAT */
+
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+
+BSON_BEGIN_DECLS
+
+
+/* Based on the "Safe Integral Comparisons" proposal merged in C++20:
+ * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0586r2.html
+ *
+ * Due to lack of type deduction in C, relational comparison functions (e.g.
+ * `cmp_less`) are defined in sets of four "functions" according to the
+ * signedness of each value argument, e.g.:
+ * - bson_cmp_less_ss (signed-value, signed-value)
+ * - bson_cmp_less_uu (unsigned-value, unsigned-value)
+ * - bson_cmp_less_su (signed-value, unsigned-value)
+ * - bson_cmp_less_us (unsigned-value, signed-value)
+ *
+ * Similarly, the `in_range` function is defined as a set of two "functions"
+ * according to the signedness of the value argument:
+ * - bson_in_range_signed (Type, signed-value)
+ * - bson_in_range_unsigned (Type, unsigned-value)
+ *
+ * The user must take care to use the correct signedness for the provided
+ * argument(s). Enabling compiler warnings for implicit sign conversions is
+ * recommended.
+ */
+
+
+#define BSON_CMP_SET(op, ss, uu, su, us) \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _ss) (int64_t t, \
+ int64_t u) \
+ { \
+ return (ss); \
+ } \
+ \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _uu) (uint64_t t, \
+ uint64_t u) \
+ { \
+ return (uu); \
+ } \
+ \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _su) (int64_t t, \
+ uint64_t u) \
+ { \
+ return (su); \
+ } \
+ \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _us) (uint64_t t, \
+ int64_t u) \
+ { \
+ return (us); \
+ }
+
+BSON_CMP_SET (equal,
+ t == u,
+ t == u,
+ t < 0 ? false : (uint64_t) (t) == u,
+ u < 0 ? false : t == (uint64_t) (u))
+
+BSON_CMP_SET (not_equal,
+ !bson_cmp_equal_ss (t, u),
+ !bson_cmp_equal_uu (t, u),
+ !bson_cmp_equal_su (t, u),
+ !bson_cmp_equal_us (t, u))
+
+BSON_CMP_SET (less,
+ t < u,
+ t < u,
+ t < 0 ? true : (uint64_t) (t) < u,
+ u < 0 ? false : t < (uint64_t) (u))
+
+BSON_CMP_SET (greater,
+ bson_cmp_less_ss (u, t),
+ bson_cmp_less_uu (u, t),
+ bson_cmp_less_us (u, t),
+ bson_cmp_less_su (u, t))
+
+BSON_CMP_SET (less_equal,
+ !bson_cmp_greater_ss (t, u),
+ !bson_cmp_greater_uu (t, u),
+ !bson_cmp_greater_su (t, u),
+ !bson_cmp_greater_us (t, u))
+
+BSON_CMP_SET (greater_equal,
+ !bson_cmp_less_ss (t, u),
+ !bson_cmp_less_uu (t, u),
+ !bson_cmp_less_su (t, u),
+ !bson_cmp_less_us (t, u))
+
+#undef BSON_CMP_SET
+
+
+/* Define in_range functions for *signed* type Type. */
+#define BSON_IN_RANGE_SET_SIGNED(Type, min, max) \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_in_range_, Type, _signed) ( \
+ int64_t value) \
+ { \
+ return bson_cmp_greater_equal_ss (value, min) && \
+ bson_cmp_less_equal_ss (value, max); \
+ } \
+ \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_in_range_, Type, _unsigned) ( \
+ uint64_t value) \
+ { \
+ return bson_cmp_greater_equal_us (value, min) && \
+ bson_cmp_less_equal_us (value, max); \
+ }
+
+/* Define in_range functions for *unsigned* type Type. */
+#define BSON_IN_RANGE_SET_UNSIGNED(Type, max) \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_in_range_, Type, _signed) ( \
+ int64_t value) \
+ { \
+ return bson_cmp_greater_equal_su (value, 0u) && \
+ bson_cmp_less_equal_su (value, max); \
+ } \
+ \
+ static BSON_INLINE bool BSON_CONCAT3 (bson_in_range_, Type, _unsigned) ( \
+ uint64_t value) \
+ { \
+ return bson_cmp_less_equal_uu (value, max); \
+ }
+
+BSON_IN_RANGE_SET_SIGNED (signed_char, SCHAR_MIN, SCHAR_MAX)
+BSON_IN_RANGE_SET_SIGNED (short, SHRT_MIN, SHRT_MAX)
+BSON_IN_RANGE_SET_SIGNED (int, INT_MIN, INT_MAX)
+BSON_IN_RANGE_SET_SIGNED (long, LONG_MIN, LONG_MAX)
+BSON_IN_RANGE_SET_SIGNED (long_long, LLONG_MIN, LLONG_MAX)
+
+BSON_IN_RANGE_SET_UNSIGNED (unsigned_char, UCHAR_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (unsigned_short, USHRT_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (unsigned_int, UINT_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (unsigned_long, ULONG_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (unsigned_long_long, ULLONG_MAX)
+
+BSON_IN_RANGE_SET_SIGNED (int8_t, INT8_MIN, INT8_MAX)
+BSON_IN_RANGE_SET_SIGNED (int16_t, INT16_MIN, INT16_MAX)
+BSON_IN_RANGE_SET_SIGNED (int32_t, INT32_MIN, INT32_MAX)
+BSON_IN_RANGE_SET_SIGNED (int64_t, INT64_MIN, INT64_MAX)
+
+BSON_IN_RANGE_SET_UNSIGNED (uint8_t, UINT8_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (uint16_t, UINT16_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (uint32_t, UINT32_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (uint64_t, UINT64_MAX)
+
+BSON_IN_RANGE_SET_SIGNED (ssize_t, SSIZE_MIN, SSIZE_MAX)
+BSON_IN_RANGE_SET_UNSIGNED (size_t, SIZE_MAX)
+
+#undef BSON_IN_RANGE_SET_SIGNED
+#undef BSON_IN_RANGE_SET_UNSIGNED
+
+
+/* Return true if the value with *signed* type is in the representable range of
+ * Type and false otherwise. */
+#define bson_in_range_signed(Type, value) \
+ BSON_CONCAT3 (bson_in_range_, Type, _signed) (value)
+
+/* Return true if the value with *unsigned* type is in the representable range
+ * of Type and false otherwise. */
+#define bson_in_range_unsigned(Type, value) \
+ BSON_CONCAT3 (bson_in_range_, Type, _unsigned) (value)
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_CMP_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-compat.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-compat.h
similarity index 53%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-compat.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-compat.h
index d6556a28..ef492925 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-compat.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-compat.h
@@ -1,202 +1,353 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson-prelude.h"
#ifndef BSON_COMPAT_H
#define BSON_COMPAT_H
#if defined(__MINGW32__)
#if defined(__USE_MINGW_ANSI_STDIO)
#if __USE_MINGW_ANSI_STDIO < 1
#error "__USE_MINGW_ANSI_STDIO > 0 is required for correct PRI* macros"
#endif
#else
#define __USE_MINGW_ANSI_STDIO 1
#endif
#endif
#include "bson-config.h"
#include "bson-macros.h"
#ifdef BSON_OS_WIN32
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600)
#undef _WIN32_WINNT
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <winsock2.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#else
#include <windows.h>
#endif
#include <direct.h>
#include <io.h>
#endif
#ifdef BSON_OS_UNIX
#include <unistd.h>
#include <sys/time.h>
#endif
#include "bson-macros.h"
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
BSON_BEGIN_DECLS
#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
#include <inttypes.h>
#endif
#ifdef _MSC_VER
#ifndef __cplusplus
/* benign redefinition of type */
#pragma warning(disable : 4142)
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
typedef SSIZE_T ssize_t;
#endif
#ifndef _SIZE_T_DEFINED
#define _SIZE_T_DEFINED
typedef SIZE_T size_t;
#endif
#pragma warning(default : 4142)
#else
/*
* MSVC++ does not include ssize_t, just size_t.
* So we need to synthesize that as well.
*/
#pragma warning(disable : 4142)
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
typedef SSIZE_T ssize_t;
#endif
#pragma warning(default : 4142)
#endif
#ifndef PRIi32
#define PRIi32 "d"
#endif
#ifndef PRId32
#define PRId32 "d"
#endif
#ifndef PRIu32
#define PRIu32 "u"
#endif
#ifndef PRIi64
#define PRIi64 "I64i"
#endif
#ifndef PRId64
#define PRId64 "I64i"
#endif
#ifndef PRIu64
#define PRIu64 "I64u"
#endif
#endif
+/* Derive the maximum representable value of signed integer type T using the
+ * formula 2^(N - 1) - 1 where N is the number of bits in type T. This assumes
+ * T is represented using two's complement. */
+#define BSON_NUMERIC_LIMITS_MAX_SIGNED(T) \
+ ((T) ((((size_t) 0x01u) << (sizeof (T) * (size_t) CHAR_BIT - 1u)) - 1u))
+
+/* Derive the minimum representable value of signed integer type T as one less
+ * than the negation of its maximum representable value. This assumes T is
+ * represented using two's complement. */
+#define BSON_NUMERIC_LIMITS_MIN_SIGNED(T, max) ((T) ((-(max)) - 1))
+
+/* Derive the maximum representable value of unsigned integer type T by flipping
+ * all its bits to 1. */
+#define BSON_NUMERIC_LIMITS_MAX_UNSIGNED(T) ((T) (~((T) 0)))
+
+/* Define numeric limit constants if not already available for C90
+ * compatibility. These can be removed once C99 is declared the minimum
+ * supported C standard. */
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
+
+#ifndef SCHAR_MAX
+#define SCHAR_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (signed char)
+#endif
+
+#ifndef SHRT_MAX
+#define SHRT_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (short)
+#endif
+
+#ifndef INT_MAX
+#define INT_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int)
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (long)
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (long long)
+#endif
+
+#ifndef UCHAR_MAX
+#define UCHAR_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned char)
+#endif
+
+#ifndef USHRT_MAX
+#define USHRT_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned short)
+#endif
+
+#ifndef UINT_MAX
+#define UINT_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned int)
+#endif
+
+#ifndef ULONG_MAX
+#define ULONG_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned long)
+#endif
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (unsigned long long)
+#endif
+
+#ifndef INT8_MAX
+#define INT8_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int8_t)
+#endif
+
+#ifndef INT16_MAX
+#define INT16_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int16_t)
+#endif
+
+#ifndef INT32_MAX
+#define INT32_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int32_t)
+#endif
+
+#ifndef INT64_MAX
+#define INT64_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (int64_t)
+#endif
+
+#ifndef UINT8_MAX
+#define UINT8_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint8_t)
+#endif
+
+#ifndef UINT16_MAX
+#define UINT16_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint16_t)
+#endif
+
+#ifndef UINT32_MAX
+#define UINT32_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint32_t)
+#endif
+
+#ifndef UINT64_MAX
+#define UINT64_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (uint64_t)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX BSON_NUMERIC_LIMITS_MAX_UNSIGNED (size_t)
+#endif
+
+#ifndef PTRDIFF_MAX
+#define PTRDIFF_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (ptrdiff_t)
+#endif
+
+#ifndef SCHAR_MIN
+#define SCHAR_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (signed char, SCHAR_MAX)
+#endif
+
+#ifndef SHRT_MIN
+#define SHRT_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (short, SHRT_MAX)
+#endif
+
+#ifndef INT_MIN
+#define INT_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int, INT_MAX)
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (long, LONG_MAX)
+#endif
+
+#ifndef LLONG_MIN
+#define LLONG_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (long long, LLONG_MAX)
+#endif
+
+#ifndef INT8_MIN
+#define INT8_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int8_t, INT8_MAX)
+#endif
+
+#ifndef INT16_MIN
+#define INT16_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int16_t, INT16_MAX)
+#endif
+
+#ifndef INT32_MIN
+#define INT32_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int32_t, INT32_MAX)
+#endif
+
+#ifndef INT64_MIN
+#define INT64_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (int64_t, INT64_MAX)
+#endif
+
+#ifndef PTRDIFF_MIN
+#define PTRDIFF_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (ptrdiff_t, PTRDIFF_MAX)
+#endif
+
+#endif /* !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L */
+
+
+#ifndef SSIZE_MAX
+#define SSIZE_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (ssize_t)
+#endif
+
+#ifndef SSIZE_MIN
+#define SSIZE_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (ssize_t, SSIZE_MAX)
+#endif
+
#if defined(__MINGW32__) && !defined(INIT_ONCE_STATIC_INIT)
#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
typedef RTL_RUN_ONCE INIT_ONCE;
#endif
#ifdef BSON_HAVE_STDBOOL_H
#include <stdbool.h>
#elif !defined(__bool_true_false_are_defined)
#ifndef __cplusplus
typedef signed char bool;
#define false 0
#define true 1
#endif
#define __bool_true_false_are_defined 1
#endif
#if defined(__GNUC__)
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
#define bson_sync_synchronize() __sync_synchronize ()
#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \
defined(__i686__) || defined(__x86_64__)
#define bson_sync_synchronize() asm volatile("mfence" ::: "memory")
#else
#define bson_sync_synchronize() asm volatile("sync" ::: "memory")
#endif
#elif defined(_MSC_VER)
#define bson_sync_synchronize() MemoryBarrier ()
#endif
#if !defined(va_copy) && defined(__va_copy)
#define va_copy(dst, src) __va_copy (dst, src)
#endif
#if !defined(va_copy)
#define va_copy(dst, src) ((dst) = (src))
#endif
#ifdef _MSC_VER
/** Expands the arguments if compiling with MSVC, otherwise empty */
#define BSON_IF_MSVC(...) __VA_ARGS__
/** Expands the arguments if compiling with GCC or Clang, otherwise empty */
#define BSON_IF_GNU_LIKE(...)
#elif defined(__GNUC__) || defined(__clang__)
/** Expands the arguments if compiling with MSVC, otherwise empty */
#define BSON_IF_MSVC(...)
/** Expands the arguments if compiling with GCC or Clang, otherwise empty */
#define BSON_IF_GNU_LIKE(...) __VA_ARGS__
#endif
#ifdef BSON_OS_WIN32
/** Expands the arguments if compiling for Windows, otherwise empty */
#define BSON_IF_WINDOWS(...) __VA_ARGS__
/** Expands the arguments if compiling for POSIX, otherwise empty */
#define BSON_IF_POSIX(...)
#elif defined(BSON_OS_UNIX)
/** Expands the arguments if compiling for Windows, otherwise empty */
#define BSON_IF_WINDOWS(...)
/** Expands the arguments if compiling for POSIX, otherwise empty */
#define BSON_IF_POSIX(...) __VA_ARGS__
#endif
BSON_END_DECLS
#endif /* BSON_COMPAT_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-config.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-config.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-config.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-config.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-config.h.in b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-config.h.in
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-config.h.in
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-config.h.in
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-context-private.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-context-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-context-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-context-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-context.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-context.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-context.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-context.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-context.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-context.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-context.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-context.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
index 56e3108c..9f4e9639 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.c
@@ -1,771 +1,771 @@
/*
* Copyright 2015 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "bson-decimal128.h"
#include "bson-types.h"
#include "bson-macros.h"
#include "bson-string.h"
#define BSON_DECIMAL128_EXPONENT_MAX 6111
#define BSON_DECIMAL128_EXPONENT_MIN -6176
#define BSON_DECIMAL128_EXPONENT_BIAS 6176
#define BSON_DECIMAL128_MAX_DIGITS 34
#define BSON_DECIMAL128_SET_NAN(dec) \
do { \
(dec).high = 0x7c00000000000000ull; \
(dec).low = 0; \
} while (0);
#define BSON_DECIMAL128_SET_INF(dec, isneg) \
do { \
(dec).high = 0x7800000000000000ull + 0x8000000000000000ull * (isneg); \
(dec).low = 0; \
} while (0);
/**
* _bson_uint128_t:
*
* This struct represents a 128 bit integer.
*/
typedef struct {
uint32_t parts[4]; /* 32-bit words stored high to low. */
} _bson_uint128_t;
/**
*------------------------------------------------------------------------------
*
* _bson_uint128_divide1B --
*
* This function divides a #_bson_uint128_t by 1000000000 (1 billion) and
* computes the quotient and remainder.
*
* The remainder will contain 9 decimal digits for conversion to string.
*
* @value The #_bson_uint128_t operand.
* @quotient A pointer to store the #_bson_uint128_t quotient.
* @rem A pointer to store the #uint64_t remainder.
*
* Returns:
* The quotient at @quotient and the remainder at @rem.
*
* Side effects:
* None.
*
*------------------------------------------------------------------------------
*/
static void
_bson_uint128_divide1B (_bson_uint128_t value, /* IN */
_bson_uint128_t *quotient, /* OUT */
uint32_t *rem) /* OUT */
{
const uint32_t DIVISOR = 1000 * 1000 * 1000;
uint64_t _rem = 0;
int i = 0;
if (!value.parts[0] && !value.parts[1] && !value.parts[2] &&
!value.parts[3]) {
*quotient = value;
*rem = 0;
return;
}
for (i = 0; i <= 3; i++) {
_rem <<= 32; /* Adjust remainder to match value of next dividend */
_rem += value.parts[i]; /* Add the divided to _rem */
value.parts[i] = (uint32_t) (_rem / DIVISOR);
_rem %= DIVISOR; /* Store the remainder */
}
*quotient = value;
*rem = (uint32_t) _rem;
}
/**
*------------------------------------------------------------------------------
*
* bson_decimal128_to_string --
*
* This function converts a BID formatted decimal128 value to string,
* accepting a &bson_decimal128_t as @dec. The string is stored at @str.
*
* @dec : The BID formatted decimal to convert.
* @str : The output decimal128 string. At least %BSON_DECIMAL128_STRING
*characters.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*------------------------------------------------------------------------------
*/
void
bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */
char *str) /* OUT */
{
uint32_t COMBINATION_MASK = 0x1f; /* Extract least significant 5 bits */
uint32_t EXPONENT_MASK = 0x3fff; /* Extract least significant 14 bits */
uint32_t COMBINATION_INFINITY = 30; /* Value of combination field for Inf */
uint32_t COMBINATION_NAN = 31; /* Value of combination field for NaN */
uint32_t EXPONENT_BIAS = 6176; /* decimal128 exponent bias */
char *str_out = str; /* output pointer in string */
char significand_str[35]; /* decoded significand digits */
/* Note: bits in this routine are referred to starting at 0, */
/* from the sign bit, towards the coefficient. */
uint32_t high; /* bits 0 - 31 */
uint32_t midh; /* bits 32 - 63 */
uint32_t midl; /* bits 64 - 95 */
uint32_t low; /* bits 96 - 127 */
uint32_t combination; /* bits 1 - 5 */
uint32_t biased_exponent; /* decoded biased exponent (14 bits) */
uint32_t significand_digits = 0; /* the number of significand digits */
uint32_t significand[36] = {0}; /* the base-10 digits in the significand */
uint32_t *significand_read = significand; /* read pointer into significand */
int32_t exponent; /* unbiased exponent */
int32_t scientific_exponent; /* the exponent if scientific notation is
* used */
bool is_zero = false; /* true if the number is zero */
uint8_t significand_msb; /* the most signifcant significand bits (50-46) */
_bson_uint128_t
significand128; /* temporary storage for significand decoding */
size_t i; /* indexing variables */
int j, k;
memset (significand_str, 0, sizeof (significand_str));
if ((int64_t) dec->high < 0) { /* negative */
*(str_out++) = '-';
}
low = (uint32_t) dec->low, midl = (uint32_t) (dec->low >> 32),
midh = (uint32_t) dec->high, high = (uint32_t) (dec->high >> 32);
/* Decode combination field and exponent */
combination = (high >> 26) & COMBINATION_MASK;
if (BSON_UNLIKELY ((combination >> 3) == 3)) {
/* Check for 'special' values */
if (combination == COMBINATION_INFINITY) { /* Infinity */
strcpy (str_out, BSON_DECIMAL128_INF);
return;
} else if (combination == COMBINATION_NAN) { /* NaN */
/* str, not str_out, to erase the sign */
strcpy (str, BSON_DECIMAL128_NAN);
/* we don't care about the NaN payload. */
return;
} else {
biased_exponent = (high >> 15) & EXPONENT_MASK;
significand_msb = 0x8 + ((high >> 14) & 0x1);
}
} else {
significand_msb = (high >> 14) & 0x7;
biased_exponent = (high >> 17) & EXPONENT_MASK;
}
exponent = biased_exponent - EXPONENT_BIAS;
/* Create string of significand digits */
/* Convert the 114-bit binary number represented by */
/* (high, midh, midl, low) to at most 34 decimal */
/* digits through modulo and division. */
significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14);
significand128.parts[1] = midh;
significand128.parts[2] = midl;
significand128.parts[3] = low;
if (significand128.parts[0] == 0 && significand128.parts[1] == 0 &&
significand128.parts[2] == 0 && significand128.parts[3] == 0) {
is_zero = true;
} else if (significand128.parts[0] >= (1 << 17)) {
/* The significand is non-canonical or zero.
* In order to preserve compatibility with the densely packed decimal
* format, the maximum value for the significand of decimal128 is
* 1e34 - 1. If the value is greater than 1e34 - 1, the IEEE 754
* standard dictates that the significand is interpreted as zero.
*/
is_zero = true;
} else {
for (k = 3; k >= 0; k--) {
uint32_t least_digits = 0;
_bson_uint128_divide1B (
significand128, &significand128, &least_digits);
/* We now have the 9 least significant digits (in base 2). */
/* Convert and output to string. */
if (!least_digits) {
continue;
}
for (j = 8; j >= 0; j--) {
significand[k * 9 + j] = least_digits % 10;
least_digits /= 10;
}
}
}
/* Output format options: */
/* Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd */
/* Regular - ddd.ddd */
if (is_zero) {
significand_digits = 1;
*significand_read = 0;
} else {
significand_digits = 36;
while (!(*significand_read)) {
significand_digits--;
significand_read++;
}
}
scientific_exponent = significand_digits - 1 + exponent;
/* The scientific exponent checks are dictated by the string conversion
* specification and are somewhat arbitrary cutoffs.
*
* We must check exponent > 0, because if this is the case, the number
* has trailing zeros. However, we *cannot* output these trailing zeros,
* because doing so would change the precision of the value, and would
* change stored data if the string converted number is round tripped.
*/
if (scientific_exponent < -6 || exponent > 0) {
/* Scientific format */
*(str_out++) = *(significand_read++) + '0';
significand_digits--;
if (significand_digits) {
*(str_out++) = '.';
}
for (i = 0; i < significand_digits && (str_out - str) < 36; i++) {
*(str_out++) = *(significand_read++) + '0';
}
/* Exponent */
*(str_out++) = 'E';
bson_snprintf (str_out, 6, "%+d", scientific_exponent);
} else {
/* Regular format with no decimal place */
if (exponent >= 0) {
for (i = 0; i < significand_digits && (str_out - str) < 36; i++) {
*(str_out++) = *(significand_read++) + '0';
}
*str_out = '\0';
} else {
int32_t radix_position = significand_digits + exponent;
if (radix_position > 0) { /* non-zero digits before radix */
for (i = 0;
i < radix_position && (str_out - str) < BSON_DECIMAL128_STRING;
i++) {
*(str_out++) = *(significand_read++) + '0';
}
} else { /* leading zero before radix point */
*(str_out++) = '0';
}
*(str_out++) = '.';
while (radix_position++ < 0) { /* add leading zeros after radix */
*(str_out++) = '0';
}
for (i = 0;
(i < significand_digits - BSON_MAX (radix_position - 1, 0)) &&
(str_out - str) < BSON_DECIMAL128_STRING;
i++) {
*(str_out++) = *(significand_read++) + '0';
}
*str_out = '\0';
}
}
}
typedef struct {
uint64_t high, low;
} _bson_uint128_6464_t;
/**
*-------------------------------------------------------------------------
*
* mul64x64 --
*
* This function multiplies two &uint64_t into a &_bson_uint128_6464_t.
*
* Returns:
* The product of @left and @right.
*
* Side Effects:
* None.
*
*-------------------------------------------------------------------------
*/
static void
_mul_64x64 (uint64_t left, /* IN */
uint64_t right, /* IN */
_bson_uint128_6464_t *product) /* OUT */
{
uint64_t left_high, left_low, right_high, right_low, product_high,
product_mid, product_mid2, product_low;
_bson_uint128_6464_t rt = {0};
if (!left && !right) {
*product = rt;
return;
}
left_high = left >> 32;
left_low = (uint32_t) left;
right_high = right >> 32;
right_low = (uint32_t) right;
product_high = left_high * right_high;
product_mid = left_high * right_low;
product_mid2 = left_low * right_high;
product_low = left_low * right_low;
product_high += product_mid >> 32;
product_mid = (uint32_t) product_mid + product_mid2 + (product_low >> 32);
product_high = product_high + (product_mid >> 32);
product_low = (product_mid << 32) + (uint32_t) product_low;
rt.high = product_high;
rt.low = product_low;
*product = rt;
}
/**
*------------------------------------------------------------------------------
*
* _dec128_tolower --
*
* This function converts the ASCII character @c to lowercase. It is locale
* insensitive (unlike the stdlib tolower).
*
* Returns:
* The lowercased character.
*/
char
_dec128_tolower (char c)
{
if (isupper (c)) {
c += 32;
}
return c;
}
/**
*------------------------------------------------------------------------------
*
* _dec128_istreq --
*
* This function compares the null-terminated *ASCII* strings @a and @b
* for case-insensitive equality.
*
* Returns:
* true if the strings are equal, false otherwise.
*/
bool
_dec128_istreq (const char *a, /* IN */
const char *b /* IN */)
{
while (*a != '\0' || *b != '\0') {
/* strings are different lengths. */
if (*a == '\0' || *b == '\0') {
return false;
}
if (_dec128_tolower (*a) != _dec128_tolower (*b)) {
return false;
}
a++;
b++;
}
return true;
}
/**
*------------------------------------------------------------------------------
*
* bson_decimal128_from_string --
*
* This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to
* decimal128. Out of range values are converted to +/-Infinity. Invalid
* strings are converted to NaN.
*
* If more digits are provided than the available precision allows,
* round to the nearest expressable decimal128 with ties going to even will
* occur.
*
* Note: @string must be ASCII only!
*
* Returns:
* true on success, or false on failure. @dec will be NaN if @str was invalid
* The &bson_decimal128_t converted from @string at @dec.
*
* Side effects:
* None.
*
*------------------------------------------------------------------------------
*/
bool
bson_decimal128_from_string (const char *string, /* IN */
bson_decimal128_t *dec) /* OUT */
{
return bson_decimal128_from_string_w_len (string, -1, dec);
}
/**
*------------------------------------------------------------------------------
*
* bson_decimal128_from_string_w_len --
*
* This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to
* decimal128. Out of range values are converted to +/-Infinity. Invalid
* strings are converted to NaN. @len is the length of the string, or -1
* meaning the string is null-terminated.
*
* If more digits are provided than the available precision allows,
* round to the nearest expressable decimal128 with ties going to even will
* occur.
*
* Note: @string must be ASCII only!
*
* Returns:
* true on success, or false on failure. @dec will be NaN if @str was invalid
* The &bson_decimal128_t converted from @string at @dec.
*
* Side effects:
* None.
*
*------------------------------------------------------------------------------
*/
bool
bson_decimal128_from_string_w_len (const char *string, /* IN */
int len, /* IN */
bson_decimal128_t *dec) /* OUT */
{
_bson_uint128_6464_t significand = {0};
const char *str_read = string; /* Read pointer for consuming str. */
/* Parsing state tracking */
bool is_negative = false;
bool saw_radix = false;
bool includes_sign = false; /* True if the input string contains a sign. */
bool found_nonzero = false;
size_t significant_digits = 0; /* Total number of significant digits
* (no leading or trailing zero) */
size_t ndigits_read = 0; /* Total number of significand digits read */
size_t ndigits = 0; /* Total number of digits (no leading zeros) */
size_t radix_position = 0; /* The number of the digits after radix */
size_t first_nonzero = 0; /* The index of the first non-zero in *str* */
uint16_t digits[BSON_DECIMAL128_MAX_DIGITS] = {0};
uint16_t ndigits_stored = 0; /* The number of digits in digits */
uint16_t *digits_insert = digits; /* Insertion pointer for digits */
size_t first_digit = 0; /* The index of the first non-zero digit */
size_t last_digit = 0; /* The index of the last digit */
int32_t exponent = 0;
uint64_t significand_high = 0; /* The high 17 digits of the significand */
uint64_t significand_low = 0; /* The low 17 digits of the significand */
uint16_t biased_exponent = 0; /* The biased exponent */
BSON_ASSERT (dec);
dec->high = 0;
dec->low = 0;
if (*str_read == '+' || *str_read == '-') {
is_negative = *(str_read++) == '-';
includes_sign = true;
}
/* Check for Infinity or NaN */
if (!isdigit (*str_read) && *str_read != '.') {
if (_dec128_istreq (str_read, "inf") ||
_dec128_istreq (str_read, "infinity")) {
BSON_DECIMAL128_SET_INF (*dec, is_negative);
return true;
} else if (_dec128_istreq (str_read, "nan")) {
BSON_DECIMAL128_SET_NAN (*dec);
return true;
}
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
/* Read digits */
while (((isdigit (*str_read) || *str_read == '.')) &&
(len == -1 || str_read < string + len)) {
if (*str_read == '.') {
if (saw_radix) {
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
saw_radix = true;
str_read++;
continue;
}
- if (ndigits_stored < 34) {
+ if (ndigits_stored < BSON_DECIMAL128_MAX_DIGITS) {
if (*str_read != '0' || found_nonzero) {
if (!found_nonzero) {
first_nonzero = ndigits_read;
}
found_nonzero = true;
*(digits_insert++) = *(str_read) - '0'; /* Only store 34 digits */
ndigits_stored++;
}
}
if (found_nonzero) {
ndigits++;
}
if (saw_radix) {
radix_position++;
}
ndigits_read++;
str_read++;
}
if (saw_radix && !ndigits_read) {
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
/* Read exponent if exists */
if (*str_read == 'e' || *str_read == 'E') {
int nread = 0;
#ifdef _MSC_VER
#define SSCANF sscanf_s
#else
#define SSCANF sscanf
#endif
int read_exponent = SSCANF (++str_read, "%d%n", &exponent, &nread);
str_read += nread;
if (!read_exponent || nread == 0) {
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
#undef SSCANF
}
if ((len == -1 || str_read < string + len) && *str_read) {
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
/* Done reading input. */
/* Find first non-zero digit in digits */
first_digit = 0;
if (!ndigits_stored) { /* value is zero */
first_digit = 0;
last_digit = 0;
digits[0] = 0;
ndigits = 1;
ndigits_stored = 1;
significant_digits = 0;
} else {
last_digit = ndigits_stored - 1;
significant_digits = ndigits;
/* Mark trailing zeros as non-significant */
while (string[first_nonzero + significant_digits - 1 + includes_sign +
saw_radix] == '0') {
significant_digits--;
}
}
/* Normalization of exponent */
/* Correct exponent based on radix position, and shift significand as needed
*/
/* to represent user input */
/* Overflow prevention */
if (exponent <= radix_position && radix_position - exponent > (1 << 14)) {
exponent = BSON_DECIMAL128_EXPONENT_MIN;
} else {
exponent -= radix_position;
}
/* Attempt to normalize the exponent */
while (exponent > BSON_DECIMAL128_EXPONENT_MAX) {
/* Shift exponent to significand and decrease */
last_digit++;
- if (last_digit - first_digit > BSON_DECIMAL128_MAX_DIGITS) {
+ if (last_digit - first_digit >= BSON_DECIMAL128_MAX_DIGITS) {
/* The exponent is too great to shift into the significand. */
if (significant_digits == 0) {
/* Value is zero, we are allowed to clamp the exponent. */
exponent = BSON_DECIMAL128_EXPONENT_MAX;
break;
}
/* Overflow is not permitted, error. */
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
exponent--;
}
while (exponent < BSON_DECIMAL128_EXPONENT_MIN || ndigits_stored < ndigits) {
/* Shift last digit */
if (last_digit == 0) {
/* underflow is not allowed, but zero clamping is */
if (significant_digits == 0) {
exponent = BSON_DECIMAL128_EXPONENT_MIN;
break;
}
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
if (ndigits_stored < ndigits) {
if (string[ndigits - 1 + includes_sign + saw_radix] - '0' != 0 &&
significant_digits != 0) {
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
ndigits--; /* adjust to match digits not stored */
} else {
if (digits[last_digit] != 0) {
/* Inexact rounding is not allowed. */
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
last_digit--; /* adjust to round */
}
if (exponent < BSON_DECIMAL128_EXPONENT_MAX) {
exponent++;
} else {
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
}
/* Round */
/* We've normalized the exponent, but might still need to round. */
if (last_digit - first_digit + 1 < significant_digits) {
uint8_t round_digit;
/* There are non-zero digits after last_digit that need rounding. */
/* We round to nearest, ties to even */
round_digit =
string[first_nonzero + last_digit + includes_sign + saw_radix + 1] -
'0';
if (round_digit != 0) {
/* Inexact (non-zero) rounding is not allowed */
BSON_DECIMAL128_SET_NAN (*dec);
return false;
}
}
/* Encode significand */
if (significant_digits == 0) { /* read a zero */
significand_high = 0;
significand_low = 0;
} else if (last_digit - first_digit < 17) {
size_t d_idx = first_digit;
significand_low = digits[d_idx++];
for (; d_idx <= last_digit; d_idx++) {
significand_low *= 10;
significand_low += digits[d_idx];
significand_high = 0;
}
} else {
size_t d_idx = first_digit;
significand_high = digits[d_idx++];
for (; d_idx <= last_digit - 17; d_idx++) {
significand_high *= 10;
significand_high += digits[d_idx];
}
significand_low = digits[d_idx++];
for (; d_idx <= last_digit; d_idx++) {
significand_low *= 10;
significand_low += digits[d_idx];
}
}
_mul_64x64 (significand_high, 100000000000000000ull, &significand);
significand.low += significand_low;
if (significand.low < significand_low) {
significand.high += 1;
}
biased_exponent = (exponent + (int16_t) BSON_DECIMAL128_EXPONENT_BIAS);
/* Encode combination, exponent, and significand. */
if ((significand.high >> 49) & 1) {
/* Encode '11' into bits 1 to 3 */
dec->high |= (0x3ull << 61);
dec->high |= (biased_exponent & 0x3fffull) << 47;
dec->high |= significand.high & 0x7fffffffffffull;
} else {
dec->high |= (biased_exponent & 0x3fffull) << 49;
dec->high |= significand.high & 0x1ffffffffffffull;
}
dec->low = significand.low;
/* Encode sign */
if (is_negative) {
dec->high |= 0x8000000000000000ull;
}
return true;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-decimal128.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-endian.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-endian.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-endian.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-endian.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-error.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-error.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-error.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-error.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-error.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-error.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-error.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-error.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iso8601.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iso8601.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iso8601.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iso8601.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iter.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iter.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iter.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iter.c
index c9e839e8..7b4630f9 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iter.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iter.c
@@ -1,2528 +1,2528 @@
/*
* Copyright 2013-2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson-iter.h"
#include "bson-config.h"
#include "bson-decimal128.h"
#include "bson-types.h"
#define ITER_TYPE(i) ((bson_type_t) * ((i)->raw + (i)->type))
/*
*--------------------------------------------------------------------------
*
* bson_iter_init --
*
* Initializes @iter to be used to iterate @bson.
*
* Returns:
* true if bson_iter_t was initialized. otherwise false.
*
* Side effects:
* @iter is initialized.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_init (bson_iter_t *iter, /* OUT */
const bson_t *bson) /* IN */
{
BSON_ASSERT (iter);
BSON_ASSERT (bson);
if (BSON_UNLIKELY (bson->len < 5)) {
memset (iter, 0, sizeof *iter);
return false;
}
iter->raw = bson_get_data (bson);
iter->len = bson->len;
iter->off = 0;
iter->type = 0;
iter->key = 0;
iter->d1 = 0;
iter->d2 = 0;
iter->d3 = 0;
iter->d4 = 0;
iter->next_off = 4;
iter->err_off = 0;
return true;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_init_from_data --
*
* Initializes @iter to be used to iterate @data of length @length
*
* Returns:
* true if bson_iter_t was initialized. otherwise false.
*
* Side effects:
* @iter is initialized.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_init_from_data (bson_iter_t *iter, /* OUT */
const uint8_t *data, /* IN */
size_t length) /* IN */
{
uint32_t len_le;
BSON_ASSERT (iter);
BSON_ASSERT (data);
if (BSON_UNLIKELY ((length < 5) || (length > INT_MAX))) {
memset (iter, 0, sizeof *iter);
return false;
}
memcpy (&len_le, data, sizeof (len_le));
if (BSON_UNLIKELY ((size_t) BSON_UINT32_FROM_LE (len_le) != length)) {
memset (iter, 0, sizeof *iter);
return false;
}
if (BSON_UNLIKELY (data[length - 1])) {
memset (iter, 0, sizeof *iter);
return false;
}
iter->raw = (uint8_t *) data;
iter->len = length;
iter->off = 0;
iter->type = 0;
iter->key = 0;
iter->d1 = 0;
iter->d2 = 0;
iter->d3 = 0;
iter->d4 = 0;
iter->next_off = 4;
iter->err_off = 0;
return true;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_recurse --
*
* Creates a new sub-iter looking at the document or array that @iter
* is currently pointing at.
*
* Returns:
* true if successful and @child was initialized.
*
* Side effects:
* @child is initialized.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_recurse (const bson_iter_t *iter, /* IN */
bson_iter_t *child) /* OUT */
{
const uint8_t *data = NULL;
uint32_t len = 0;
BSON_ASSERT (iter);
BSON_ASSERT (child);
if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) {
bson_iter_document (iter, &len, &data);
} else if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) {
bson_iter_array (iter, &len, &data);
} else {
return false;
}
child->raw = data;
child->len = len;
child->off = 0;
child->type = 0;
child->key = 0;
child->d1 = 0;
child->d2 = 0;
child->d3 = 0;
child->d4 = 0;
child->next_off = 4;
child->err_off = 0;
return true;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_init_find --
*
* Initializes a #bson_iter_t and moves the iter to the first field
* matching @key.
*
* Returns:
* true if the field named @key was found; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_init_find (bson_iter_t *iter, /* INOUT */
const bson_t *bson, /* IN */
const char *key) /* IN */
{
BSON_ASSERT (iter);
BSON_ASSERT (bson);
BSON_ASSERT (key);
return bson_iter_init (iter, bson) && bson_iter_find (iter, key);
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_init_find_w_len --
*
* Initializes a #bson_iter_t and moves the iter to the first field
* matching @key.
*
* Returns:
* true if the field named @key was found; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_init_find_w_len (bson_iter_t *iter, /* INOUT */
const bson_t *bson, /* IN */
const char *key, /* IN */
int keylen) /* IN */
{
BSON_ASSERT (iter);
BSON_ASSERT (bson);
BSON_ASSERT (key);
return bson_iter_init (iter, bson) &&
bson_iter_find_w_len (iter, key, keylen);
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_init_find_case --
*
* A case-insensitive version of bson_iter_init_find().
*
* Returns:
* true if the field was found and @iter is observing that field.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_init_find_case (bson_iter_t *iter, /* INOUT */
const bson_t *bson, /* IN */
const char *key) /* IN */
{
BSON_ASSERT (iter);
BSON_ASSERT (bson);
BSON_ASSERT (key);
return bson_iter_init (iter, bson) && bson_iter_find_case (iter, key);
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_find_w_len --
*
* Searches through @iter starting from the current position for a key
* matching @key. @keylen indicates the length of @key, or -1 to
* determine the length with strlen().
*
* Returns:
* true if the field @key was found.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_find_w_len (bson_iter_t *iter, /* INOUT */
const char *key, /* IN */
int keylen) /* IN */
{
const char *ikey;
if (keylen < 0) {
keylen = (int) strlen (key);
}
while (bson_iter_next (iter)) {
ikey = bson_iter_key (iter);
if ((0 == strncmp (key, ikey, keylen)) && (ikey[keylen] == '\0')) {
return true;
}
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_find --
*
* Searches through @iter starting from the current position for a key
* matching @key. This is a case-sensitive search meaning "KEY" and
* "key" would NOT match.
*
* Returns:
* true if @key is found.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_find (bson_iter_t *iter, /* INOUT */
const char *key) /* IN */
{
BSON_ASSERT (iter);
BSON_ASSERT (key);
return bson_iter_find_w_len (iter, key, -1);
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_find_case --
*
* Searches through @iter starting from the current position for a key
* matching @key. This is a case-insensitive search meaning "KEY" and
* "key" would match.
*
* Returns:
* true if @key is found.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_find_case (bson_iter_t *iter, /* INOUT */
const char *key) /* IN */
{
BSON_ASSERT (iter);
BSON_ASSERT (key);
while (bson_iter_next (iter)) {
if (!bson_strcasecmp (key, bson_iter_key (iter))) {
return true;
}
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_find_descendant --
*
* Locates a descendant using the "parent.child.key" notation. This
* operates similar to bson_iter_find() except that it can recurse
* into children documents using the dot notation.
*
* Returns:
* true if the descendant was found and @descendant was initialized.
*
* Side effects:
* @descendant may be initialized.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_find_descendant (bson_iter_t *iter, /* INOUT */
const char *dotkey, /* IN */
bson_iter_t *descendant) /* OUT */
{
bson_iter_t tmp;
const char *dot;
size_t sublen;
BSON_ASSERT (iter);
BSON_ASSERT (dotkey);
BSON_ASSERT (descendant);
if ((dot = strchr (dotkey, '.'))) {
sublen = dot - dotkey;
} else {
sublen = strlen (dotkey);
}
if (bson_iter_find_w_len (iter, dotkey, (int) sublen)) {
if (!dot) {
*descendant = *iter;
return true;
}
if (BSON_ITER_HOLDS_DOCUMENT (iter) || BSON_ITER_HOLDS_ARRAY (iter)) {
if (bson_iter_recurse (iter, &tmp)) {
return bson_iter_find_descendant (&tmp, dot + 1, descendant);
}
}
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_key --
*
* Retrieves the key of the current field. The resulting key is valid
* while @iter is valid.
*
* Returns:
* A string that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const char *
bson_iter_key (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
return bson_iter_key_unsafe (iter);
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_type --
*
* Retrieves the type of the current field. It may be useful to check
* the type using the BSON_ITER_HOLDS_*() macros.
*
* Returns:
* A bson_type_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bson_type_t
bson_iter_type (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
BSON_ASSERT (iter->raw);
BSON_ASSERT (iter->len);
return bson_iter_type_unsafe (iter);
}
/*
*--------------------------------------------------------------------------
*
* _bson_iter_next_internal --
*
* Internal function to advance @iter to the next field and retrieve
* the key and BSON type before error-checking. @next_keylen is
* the key length of the next field being iterated or 0 if this is
* not known.
*
* Return:
* true if an element was decoded, else false.
*
* Side effects:
* @key and @bson_type are set.
*
* If the return value is false:
* - @iter is invalidated: @iter->raw is NULLed
* - @unsupported is set to true if the bson type is unsupported
* - otherwise if the BSON is corrupt, @iter->err_off is nonzero
* - otherwise @bson_type is set to BSON_TYPE_EOD
*
*--------------------------------------------------------------------------
*/
static bool
_bson_iter_next_internal (bson_iter_t *iter, /* INOUT */
uint32_t next_keylen, /* IN */
const char **key, /* OUT */
uint32_t *bson_type, /* OUT */
bool *unsupported) /* OUT */
{
const uint8_t *data;
uint32_t o;
unsigned int len;
BSON_ASSERT (iter);
*unsupported = false;
if (!iter->raw) {
*key = NULL;
*bson_type = BSON_TYPE_EOD;
return false;
}
data = iter->raw;
len = iter->len;
iter->off = iter->next_off;
iter->type = iter->off;
iter->key = iter->off + 1;
iter->d1 = 0;
iter->d2 = 0;
iter->d3 = 0;
iter->d4 = 0;
if (next_keylen == 0) {
/* iterate from start to end of NULL-terminated key string */
for (o = iter->key; o < len; o++) {
if (!data[o]) {
iter->d1 = ++o;
goto fill_data_fields;
}
}
} else {
o = iter->key + next_keylen + 1;
iter->d1 = o;
goto fill_data_fields;
}
goto mark_invalid;
fill_data_fields:
*key = bson_iter_key_unsafe (iter);
*bson_type = ITER_TYPE (iter);
switch (*bson_type) {
case BSON_TYPE_DATE_TIME:
case BSON_TYPE_DOUBLE:
case BSON_TYPE_INT64:
case BSON_TYPE_TIMESTAMP:
iter->next_off = o + 8;
break;
case BSON_TYPE_CODE:
case BSON_TYPE_SYMBOL:
case BSON_TYPE_UTF8: {
uint32_t l;
if ((o + 4) >= len) {
iter->err_off = o;
goto mark_invalid;
}
iter->d2 = o + 4;
memcpy (&l, iter->raw + iter->d1, sizeof (l));
l = BSON_UINT32_FROM_LE (l);
if (l > (len - (o + 4))) {
iter->err_off = o;
goto mark_invalid;
}
iter->next_off = o + 4 + l;
/*
* Make sure the string length includes the NUL byte.
*/
if (BSON_UNLIKELY ((l == 0) || (iter->next_off >= len))) {
iter->err_off = o;
goto mark_invalid;
}
/*
* Make sure the last byte is a NUL byte.
*/
if (BSON_UNLIKELY ((iter->raw + iter->d2)[l - 1] != '\0')) {
iter->err_off = o + 4 + l - 1;
goto mark_invalid;
}
} break;
case BSON_TYPE_BINARY: {
bson_subtype_t subtype;
uint32_t l;
if (o >= (len - 4)) {
iter->err_off = o;
goto mark_invalid;
}
iter->d2 = o + 4;
iter->d3 = o + 5;
memcpy (&l, iter->raw + iter->d1, sizeof (l));
l = BSON_UINT32_FROM_LE (l);
if (l >= (len - o - 4)) {
iter->err_off = o;
goto mark_invalid;
}
subtype = *(iter->raw + iter->d2);
if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
int32_t binary_len;
if (l < 4) {
iter->err_off = o;
goto mark_invalid;
}
/* subtype 2 has a redundant length header in the data */
memcpy (&binary_len, (iter->raw + iter->d3), sizeof (binary_len));
binary_len = BSON_UINT32_FROM_LE (binary_len);
if (binary_len + 4 != l) {
iter->err_off = iter->d3;
goto mark_invalid;
}
}
iter->next_off = o + 5 + l;
} break;
case BSON_TYPE_ARRAY:
case BSON_TYPE_DOCUMENT: {
uint32_t l;
if (o >= (len - 4)) {
iter->err_off = o;
goto mark_invalid;
}
memcpy (&l, iter->raw + iter->d1, sizeof (l));
l = BSON_UINT32_FROM_LE (l);
if ((l > len) || (l > (len - o))) {
iter->err_off = o;
goto mark_invalid;
}
iter->next_off = o + l;
} break;
case BSON_TYPE_OID:
iter->next_off = o + 12;
break;
case BSON_TYPE_BOOL: {
char val;
if (iter->d1 >= len) {
iter->err_off = o;
goto mark_invalid;
}
memcpy (&val, iter->raw + iter->d1, 1);
if (val != 0x00 && val != 0x01) {
iter->err_off = o;
goto mark_invalid;
}
iter->next_off = o + 1;
} break;
case BSON_TYPE_REGEX: {
bool eor = false;
bool eoo = false;
for (; o < len; o++) {
if (!data[o]) {
iter->d2 = ++o;
eor = true;
break;
}
}
if (!eor) {
iter->err_off = iter->next_off;
goto mark_invalid;
}
for (; o < len; o++) {
if (!data[o]) {
eoo = true;
break;
}
}
if (!eoo) {
iter->err_off = iter->next_off;
goto mark_invalid;
}
iter->next_off = o + 1;
} break;
case BSON_TYPE_DBPOINTER: {
uint32_t l;
if (o >= (len - 4)) {
iter->err_off = o;
goto mark_invalid;
}
iter->d2 = o + 4;
memcpy (&l, iter->raw + iter->d1, sizeof (l));
l = BSON_UINT32_FROM_LE (l);
/* Check valid string length. l counts '\0' but not 4 bytes for itself. */
if (l == 0 || l > (len - o - 4)) {
iter->err_off = o;
goto mark_invalid;
}
if (*(iter->raw + o + l + 3)) {
/* not null terminated */
iter->err_off = o + l + 3;
goto mark_invalid;
}
iter->d3 = o + 4 + l;
iter->next_off = o + 4 + l + 12;
} break;
case BSON_TYPE_CODEWSCOPE: {
uint32_t l;
uint32_t doclen;
if ((len < 19) || (o >= (len - 14))) {
iter->err_off = o;
goto mark_invalid;
}
iter->d2 = o + 4;
iter->d3 = o + 8;
memcpy (&l, iter->raw + iter->d1, sizeof (l));
l = BSON_UINT32_FROM_LE (l);
if ((l < 14) || (l >= (len - o))) {
iter->err_off = o;
goto mark_invalid;
}
iter->next_off = o + l;
if (iter->next_off >= len) {
iter->err_off = o;
goto mark_invalid;
}
memcpy (&l, iter->raw + iter->d2, sizeof (l));
l = BSON_UINT32_FROM_LE (l);
if (l == 0 || l >= (len - o - 4 - 4)) {
iter->err_off = o;
goto mark_invalid;
}
if ((o + 4 + 4 + l + 4) >= iter->next_off) {
iter->err_off = o + 4;
goto mark_invalid;
}
iter->d4 = o + 4 + 4 + l;
memcpy (&doclen, iter->raw + iter->d4, sizeof (doclen));
doclen = BSON_UINT32_FROM_LE (doclen);
if ((o + 4 + 4 + l + doclen) != iter->next_off) {
iter->err_off = o + 4 + 4 + l;
goto mark_invalid;
}
} break;
case BSON_TYPE_INT32:
iter->next_off = o + 4;
break;
case BSON_TYPE_DECIMAL128:
iter->next_off = o + 16;
break;
case BSON_TYPE_MAXKEY:
case BSON_TYPE_MINKEY:
case BSON_TYPE_NULL:
case BSON_TYPE_UNDEFINED:
iter->next_off = o;
break;
default:
*unsupported = true;
/* FALL THROUGH */
case BSON_TYPE_EOD:
iter->err_off = o;
goto mark_invalid;
}
/*
* Check to see if any of the field locations would overflow the
* current BSON buffer. If so, set the error location to the offset
* of where the field starts.
*/
if (iter->next_off >= len) {
iter->err_off = o;
goto mark_invalid;
}
iter->err_off = 0;
return true;
mark_invalid:
iter->raw = NULL;
iter->len = 0;
iter->next_off = 0;
return false;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_next --
*
* Advances @iter to the next field of the underlying BSON document.
* If all fields have been exhausted, then %false is returned.
*
* It is a programming error to use @iter after this function has
* returned false.
*
* Returns:
* true if the iter was advanced to the next record.
* otherwise false and @iter should be considered invalid.
*
* Side effects:
* @iter may be invalidated.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_next (bson_iter_t *iter) /* INOUT */
{
uint32_t bson_type;
const char *key;
bool unsupported;
return _bson_iter_next_internal (iter, 0, &key, &bson_type, &unsupported);
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_binary --
*
* Retrieves the BSON_TYPE_BINARY field. The subtype is stored in
* @subtype. The length of @binary in bytes is stored in @binary_len.
*
* @binary should not be modified or freed and is only valid while
* @iter's bson_t is valid and unmodified.
*
* Parameters:
* @iter: A bson_iter_t
* @subtype: A location for the binary subtype.
* @binary_len: A location for the length of @binary.
* @binary: A location for a pointer to the binary data.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_binary (const bson_iter_t *iter, /* IN */
bson_subtype_t *subtype, /* OUT */
uint32_t *binary_len, /* OUT */
const uint8_t **binary) /* OUT */
{
bson_subtype_t backup;
BSON_ASSERT (iter);
BSON_ASSERT (!binary || binary_len);
if (ITER_TYPE (iter) == BSON_TYPE_BINARY) {
if (!subtype) {
subtype = &backup;
}
*subtype = (bson_subtype_t) * (iter->raw + iter->d2);
if (binary) {
memcpy (binary_len, (iter->raw + iter->d1), sizeof (*binary_len));
*binary_len = BSON_UINT32_FROM_LE (*binary_len);
*binary = iter->raw + iter->d3;
if (*subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
*binary_len -= sizeof (int32_t);
*binary += sizeof (int32_t);
}
}
return;
}
if (binary) {
*binary = NULL;
}
if (binary_len) {
*binary_len = 0;
}
if (subtype) {
*subtype = BSON_SUBTYPE_BINARY;
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_bool --
*
* Retrieves the current field of type BSON_TYPE_BOOL.
*
* Returns:
* true or false, dependent on bson document.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_bool (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_BOOL) {
return bson_iter_bool_unsafe (iter);
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_as_bool --
*
* If @iter is on a boolean field, returns the boolean. If it is on a
* non-boolean field such as int32, int64, or double, it will convert
* the value to a boolean.
*
* Zero is false, and non-zero is true.
*
* Returns:
* true or false, dependent on field type.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_as_bool (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
switch ((int) ITER_TYPE (iter)) {
case BSON_TYPE_BOOL:
return bson_iter_bool (iter);
case BSON_TYPE_DOUBLE:
return !(bson_iter_double (iter) == 0.0);
case BSON_TYPE_INT64:
return !(bson_iter_int64 (iter) == 0);
case BSON_TYPE_INT32:
return !(bson_iter_int32 (iter) == 0);
case BSON_TYPE_UTF8:
return true;
case BSON_TYPE_NULL:
case BSON_TYPE_UNDEFINED:
return false;
default:
return true;
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_double --
*
* Retrieves the current field of type BSON_TYPE_DOUBLE.
*
* Returns:
* A double.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
double
bson_iter_double (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) {
return bson_iter_double_unsafe (iter);
}
return 0;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_as_double --
*
* If @iter is on a field of type BSON_TYPE_DOUBLE,
* returns the double. If it is on an integer field
* such as int32, int64, or bool, it will convert
* the value to a double.
*
*
* Returns:
* A double.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
double
bson_iter_as_double (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
switch ((int) ITER_TYPE (iter)) {
case BSON_TYPE_BOOL:
return (double) bson_iter_bool (iter);
case BSON_TYPE_DOUBLE:
return bson_iter_double (iter);
case BSON_TYPE_INT32:
return (double) bson_iter_int32 (iter);
case BSON_TYPE_INT64:
return (double) bson_iter_int64 (iter);
default:
return 0;
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_int32 --
*
* Retrieves the value of the field of type BSON_TYPE_INT32.
*
* Returns:
* A 32-bit signed integer.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int32_t
bson_iter_int32 (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_INT32) {
return bson_iter_int32_unsafe (iter);
}
return 0;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_int64 --
*
* Retrieves a 64-bit signed integer for the current BSON_TYPE_INT64
* field.
*
* Returns:
* A 64-bit signed integer.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int64_t
bson_iter_int64 (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_INT64) {
return bson_iter_int64_unsafe (iter);
}
return 0;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_as_int64 --
*
* If @iter is not an int64 field, it will try to convert the value to
* an int64. Such field types include:
*
* - bool
* - double
* - int32
*
* Returns:
* An int64_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int64_t
bson_iter_as_int64 (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
switch ((int) ITER_TYPE (iter)) {
case BSON_TYPE_BOOL:
return (int64_t) bson_iter_bool (iter);
case BSON_TYPE_DOUBLE:
return (int64_t) bson_iter_double (iter);
case BSON_TYPE_INT64:
return bson_iter_int64 (iter);
case BSON_TYPE_INT32:
return (int64_t) bson_iter_int32 (iter);
default:
return 0;
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_decimal128 --
*
* This function retrieves the current field of type
*%BSON_TYPE_DECIMAL128.
* The result is valid while @iter is valid, and is stored in @dec.
*
* Returns:
*
* True on success, false on failure.
*
* Side Effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_iter_decimal128 (const bson_iter_t *iter, /* IN */
bson_decimal128_t *dec) /* OUT */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) {
bson_iter_decimal128_unsafe (iter, dec);
return true;
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_oid --
*
* Retrieves the current field of type %BSON_TYPE_OID. The result is
* valid while @iter is valid.
*
* Returns:
* A bson_oid_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const bson_oid_t *
bson_iter_oid (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_OID) {
return bson_iter_oid_unsafe (iter);
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_regex --
*
* Fetches the current field from the iter which should be of type
* BSON_TYPE_REGEX.
*
* Returns:
* Regex from @iter. This should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const char *
bson_iter_regex (const bson_iter_t *iter, /* IN */
const char **options) /* IN */
{
const char *ret = NULL;
const char *ret_options = NULL;
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_REGEX) {
ret = (const char *) (iter->raw + iter->d1);
ret_options = (const char *) (iter->raw + iter->d2);
}
if (options) {
*options = ret_options;
}
return ret;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_utf8 --
*
* Retrieves the current field of type %BSON_TYPE_UTF8 as a UTF-8
* encoded string.
*
* Parameters:
* @iter: A bson_iter_t.
* @length: A location for the length of the string.
*
* Returns:
* A string that should not be modified or freed.
*
* Side effects:
* @length will be set to the result strings length if non-NULL.
*
*--------------------------------------------------------------------------
*/
const char *
bson_iter_utf8 (const bson_iter_t *iter, /* IN */
uint32_t *length) /* OUT */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_UTF8) {
if (length) {
*length = bson_iter_utf8_len_unsafe (iter);
}
return (const char *) (iter->raw + iter->d2);
}
if (length) {
*length = 0;
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_dup_utf8 --
*
* Copies the current UTF-8 element into a newly allocated string. The
* string should be freed using bson_free() when the caller is
* finished with it.
*
* Returns:
* A newly allocated char* that should be freed with bson_free().
*
* Side effects:
* @length will be set to the result strings length if non-NULL.
*
*--------------------------------------------------------------------------
*/
char *
bson_iter_dup_utf8 (const bson_iter_t *iter, /* IN */
uint32_t *length) /* OUT */
{
uint32_t local_length = 0;
const char *str;
char *ret = NULL;
BSON_ASSERT (iter);
if ((str = bson_iter_utf8 (iter, &local_length))) {
ret = bson_malloc0 (local_length + 1);
memcpy (ret, str, local_length);
ret[local_length] = '\0';
}
if (length) {
*length = local_length;
}
return ret;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_code --
*
* Retrieves the current field of type %BSON_TYPE_CODE. The length of
* the resulting string is stored in @length.
*
* Parameters:
* @iter: A bson_iter_t.
* @length: A location for the code length.
*
* Returns:
* A NUL-terminated string containing the code which should not be
* modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const char *
bson_iter_code (const bson_iter_t *iter, /* IN */
uint32_t *length) /* OUT */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_CODE) {
if (length) {
*length = bson_iter_utf8_len_unsafe (iter);
}
return (const char *) (iter->raw + iter->d2);
}
if (length) {
*length = 0;
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_codewscope --
*
* Similar to bson_iter_code() but with a scope associated encoded as
* a BSON document. @scope should not be modified or freed. It is
* valid while @iter is valid.
*
* Parameters:
* @iter: A #bson_iter_t.
* @length: A location for the length of resulting string.
* @scope_len: A location for the length of @scope.
* @scope: A location for the scope encoded as BSON.
*
* Returns:
* A NUL-terminated string that should not be modified or freed.
*
* Side effects:
* @length is set to the resulting string length in bytes.
* @scope_len is set to the length of @scope in bytes.
* @scope is set to the scope documents buffer which can be
* turned into a bson document with bson_init_static().
*
*--------------------------------------------------------------------------
*/
const char *
bson_iter_codewscope (const bson_iter_t *iter, /* IN */
uint32_t *length, /* OUT */
uint32_t *scope_len, /* OUT */
const uint8_t **scope) /* OUT */
{
uint32_t len;
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_CODEWSCOPE) {
if (length) {
memcpy (&len, iter->raw + iter->d2, sizeof (len));
/* The string length was checked > 0 in _bson_iter_next_internal. */
len = BSON_UINT32_FROM_LE (len);
BSON_ASSERT (len > 0);
*length = len - 1;
}
memcpy (&len, iter->raw + iter->d4, sizeof (len));
*scope_len = BSON_UINT32_FROM_LE (len);
*scope = iter->raw + iter->d4;
return (const char *) (iter->raw + iter->d3);
}
if (length) {
*length = 0;
}
if (scope_len) {
*scope_len = 0;
}
if (scope) {
*scope = NULL;
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_dbpointer --
*
* Retrieves a BSON_TYPE_DBPOINTER field. @collection_len will be set
* to the length of the collection name. The collection name will be
* placed into @collection. The oid will be placed into @oid.
*
* @collection and @oid should not be modified.
*
* Parameters:
* @iter: A #bson_iter_t.
* @collection_len: A location for the length of @collection.
* @collection: A location for the collection name.
* @oid: A location for the oid.
*
* Returns:
* None.
*
* Side effects:
* @collection_len is set to the length of @collection in bytes
* excluding the null byte.
* @collection is set to the collection name, including a terminating
* null byte.
* @oid is initialized with the oid.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_dbpointer (const bson_iter_t *iter, /* IN */
uint32_t *collection_len, /* OUT */
const char **collection, /* OUT */
const bson_oid_t **oid) /* OUT */
{
BSON_ASSERT (iter);
if (collection) {
*collection = NULL;
}
if (oid) {
*oid = NULL;
}
if (ITER_TYPE (iter) == BSON_TYPE_DBPOINTER) {
if (collection_len) {
memcpy (
collection_len, (iter->raw + iter->d1), sizeof (*collection_len));
*collection_len = BSON_UINT32_FROM_LE (*collection_len);
if ((*collection_len) > 0) {
(*collection_len)--;
}
}
if (collection) {
*collection = (const char *) (iter->raw + iter->d2);
}
if (oid) {
*oid = (const bson_oid_t *) (iter->raw + iter->d3);
}
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_symbol --
*
* Retrieves the symbol of the current field of type BSON_TYPE_SYMBOL.
*
* Parameters:
* @iter: A bson_iter_t.
* @length: A location for the length of the symbol.
*
* Returns:
* A string containing the symbol as UTF-8. The value should not be
* modified or freed.
*
* Side effects:
* @length is set to the resulting strings length in bytes,
* excluding the null byte.
*
*--------------------------------------------------------------------------
*/
const char *
bson_iter_symbol (const bson_iter_t *iter, /* IN */
uint32_t *length) /* OUT */
{
const char *ret = NULL;
uint32_t ret_length = 0;
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_SYMBOL) {
ret = (const char *) (iter->raw + iter->d2);
ret_length = bson_iter_utf8_len_unsafe (iter);
}
if (length) {
*length = ret_length;
}
return ret;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_date_time --
*
* Fetches the number of milliseconds elapsed since the UNIX epoch.
* This value can be negative as times before 1970 are valid.
*
* Returns:
* A signed 64-bit integer containing the number of milliseconds.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
int64_t
bson_iter_date_time (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
return bson_iter_int64_unsafe (iter);
}
return 0;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_time_t --
*
* Retrieves the current field of type BSON_TYPE_DATE_TIME as a
* time_t.
*
* Returns:
* A #time_t of the number of seconds since UNIX epoch in UTC.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
time_t
bson_iter_time_t (const bson_iter_t *iter) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
return bson_iter_time_t_unsafe (iter);
}
return 0;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_timestamp --
*
* Fetches the current field if it is a BSON_TYPE_TIMESTAMP.
*
* Parameters:
* @iter: A #bson_iter_t.
* @timestamp: a location for the timestamp.
* @increment: A location for the increment.
*
* Returns:
* None.
*
* Side effects:
* @timestamp is initialized.
* @increment is initialized.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_timestamp (const bson_iter_t *iter, /* IN */
uint32_t *timestamp, /* OUT */
uint32_t *increment) /* OUT */
{
uint64_t encoded;
uint32_t ret_timestamp = 0;
uint32_t ret_increment = 0;
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_TIMESTAMP) {
memcpy (&encoded, iter->raw + iter->d1, sizeof (encoded));
encoded = BSON_UINT64_FROM_LE (encoded);
ret_timestamp = (encoded >> 32) & 0xFFFFFFFF;
ret_increment = encoded & 0xFFFFFFFF;
}
if (timestamp) {
*timestamp = ret_timestamp;
}
if (increment) {
*increment = ret_increment;
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_timeval --
*
* Retrieves the current field of type BSON_TYPE_DATE_TIME and stores
* it into the struct timeval provided. tv->tv_sec is set to the
* number of seconds since the UNIX epoch in UTC.
*
* Since BSON_TYPE_DATE_TIME does not support fractions of a second,
* tv->tv_usec will always be set to zero.
*
* Returns:
* None.
*
* Side effects:
* @tv is initialized.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_timeval (const bson_iter_t *iter, /* IN */
struct timeval *tv) /* OUT */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
bson_iter_timeval_unsafe (iter, tv);
return;
}
memset (tv, 0, sizeof *tv);
}
/**
* bson_iter_document:
* @iter: a bson_iter_t.
* @document_len: A location for the document length.
* @document: A location for a pointer to the document buffer.
*
*/
/*
*--------------------------------------------------------------------------
*
* bson_iter_document --
*
* Retrieves the data to the document BSON structure and stores the
* length of the document buffer in @document_len and the document
* buffer in @document.
*
* If you would like to iterate over the child contents, you might
* consider creating a bson_t on the stack such as the following. It
* allows you to call functions taking a const bson_t* only.
*
* bson_t b;
* uint32_t len;
* const uint8_t *data;
*
* bson_iter_document(iter, &len, &data);
*
* if (bson_init_static (&b, data, len)) {
* ...
* }
*
* There is no need to cleanup the bson_t structure as no data can be
* modified in the process of its use (as it is static/const).
*
* Returns:
* None.
*
* Side effects:
* @document_len is initialized.
* @document is initialized.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_document (const bson_iter_t *iter, /* IN */
uint32_t *document_len, /* OUT */
const uint8_t **document) /* OUT */
{
BSON_ASSERT (iter);
BSON_ASSERT (document_len);
BSON_ASSERT (document);
*document = NULL;
*document_len = 0;
if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) {
memcpy (document_len, (iter->raw + iter->d1), sizeof (*document_len));
*document_len = BSON_UINT32_FROM_LE (*document_len);
*document = (iter->raw + iter->d1);
}
}
/**
* bson_iter_array:
* @iter: a #bson_iter_t.
* @array_len: A location for the array length.
* @array: A location for a pointer to the array buffer.
*/
/*
*--------------------------------------------------------------------------
*
* bson_iter_array --
*
* Retrieves the data to the array BSON structure and stores the
* length of the array buffer in @array_len and the array buffer in
* @array.
*
* If you would like to iterate over the child contents, you might
* consider creating a bson_t on the stack such as the following. It
* allows you to call functions taking a const bson_t* only.
*
* bson_t b;
* uint32_t len;
* const uint8_t *data;
*
* bson_iter_array (iter, &len, &data);
*
* if (bson_init_static (&b, data, len)) {
* ...
* }
*
* There is no need to cleanup the #bson_t structure as no data can be
* modified in the process of its use.
*
* Returns:
* None.
*
* Side effects:
* @array_len is initialized.
* @array is initialized.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_array (const bson_iter_t *iter, /* IN */
uint32_t *array_len, /* OUT */
const uint8_t **array) /* OUT */
{
BSON_ASSERT (iter);
BSON_ASSERT (array_len);
BSON_ASSERT (array);
*array = NULL;
*array_len = 0;
if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) {
memcpy (array_len, (iter->raw + iter->d1), sizeof (*array_len));
*array_len = BSON_UINT32_FROM_LE (*array_len);
*array = (iter->raw + iter->d1);
}
}
#define VISIT_FIELD(name) visitor->visit_##name && visitor->visit_##name
#define VISIT_AFTER VISIT_FIELD (after)
#define VISIT_BEFORE VISIT_FIELD (before)
#define VISIT_CORRUPT \
if (visitor->visit_corrupt) \
visitor->visit_corrupt
#define VISIT_DOUBLE VISIT_FIELD (double)
#define VISIT_UTF8 VISIT_FIELD (utf8)
#define VISIT_DOCUMENT VISIT_FIELD (document)
#define VISIT_ARRAY VISIT_FIELD (array)
#define VISIT_BINARY VISIT_FIELD (binary)
#define VISIT_UNDEFINED VISIT_FIELD (undefined)
#define VISIT_OID VISIT_FIELD (oid)
#define VISIT_BOOL VISIT_FIELD (bool)
#define VISIT_DATE_TIME VISIT_FIELD (date_time)
#define VISIT_NULL VISIT_FIELD (null)
#define VISIT_REGEX VISIT_FIELD (regex)
#define VISIT_DBPOINTER VISIT_FIELD (dbpointer)
#define VISIT_CODE VISIT_FIELD (code)
#define VISIT_SYMBOL VISIT_FIELD (symbol)
#define VISIT_CODEWSCOPE VISIT_FIELD (codewscope)
#define VISIT_INT32 VISIT_FIELD (int32)
#define VISIT_TIMESTAMP VISIT_FIELD (timestamp)
#define VISIT_INT64 VISIT_FIELD (int64)
#define VISIT_DECIMAL128 VISIT_FIELD (decimal128)
#define VISIT_MAXKEY VISIT_FIELD (maxkey)
#define VISIT_MINKEY VISIT_FIELD (minkey)
bool
bson_iter_visit_all (bson_iter_t *iter, /* INOUT */
const bson_visitor_t *visitor, /* IN */
void *data) /* IN */
{
- uint32_t bson_type;
- const char *key;
+ uint32_t bson_type = 0;
+ const char *key = NULL;
bool unsupported;
BSON_ASSERT (iter);
BSON_ASSERT (visitor);
while (_bson_iter_next_internal (iter, 0, &key, &bson_type, &unsupported)) {
if (*key && !bson_utf8_validate (key, strlen (key), false)) {
iter->err_off = iter->off;
break;
}
if (VISIT_BEFORE (iter, key, data)) {
return true;
}
switch (bson_type) {
case BSON_TYPE_DOUBLE:
if (VISIT_DOUBLE (iter, key, bson_iter_double (iter), data)) {
return true;
}
break;
case BSON_TYPE_UTF8: {
uint32_t utf8_len;
const char *utf8;
utf8 = bson_iter_utf8 (iter, &utf8_len);
if (!bson_utf8_validate (utf8, utf8_len, true)) {
iter->err_off = iter->off;
return true;
}
if (VISIT_UTF8 (iter, key, utf8_len, utf8, data)) {
return true;
}
} break;
case BSON_TYPE_DOCUMENT: {
const uint8_t *docbuf = NULL;
uint32_t doclen = 0;
bson_t b;
bson_iter_document (iter, &doclen, &docbuf);
if (bson_init_static (&b, docbuf, doclen) &&
VISIT_DOCUMENT (iter, key, &b, data)) {
return true;
}
} break;
case BSON_TYPE_ARRAY: {
const uint8_t *docbuf = NULL;
uint32_t doclen = 0;
bson_t b;
bson_iter_array (iter, &doclen, &docbuf);
if (bson_init_static (&b, docbuf, doclen) &&
VISIT_ARRAY (iter, key, &b, data)) {
return true;
}
} break;
case BSON_TYPE_BINARY: {
const uint8_t *binary = NULL;
bson_subtype_t subtype = BSON_SUBTYPE_BINARY;
uint32_t binary_len = 0;
bson_iter_binary (iter, &subtype, &binary_len, &binary);
if (VISIT_BINARY (iter, key, subtype, binary_len, binary, data)) {
return true;
}
} break;
case BSON_TYPE_UNDEFINED:
if (VISIT_UNDEFINED (iter, key, data)) {
return true;
}
break;
case BSON_TYPE_OID:
if (VISIT_OID (iter, key, bson_iter_oid (iter), data)) {
return true;
}
break;
case BSON_TYPE_BOOL:
if (VISIT_BOOL (iter, key, bson_iter_bool (iter), data)) {
return true;
}
break;
case BSON_TYPE_DATE_TIME:
if (VISIT_DATE_TIME (iter, key, bson_iter_date_time (iter), data)) {
return true;
}
break;
case BSON_TYPE_NULL:
if (VISIT_NULL (iter, key, data)) {
return true;
}
break;
case BSON_TYPE_REGEX: {
const char *regex = NULL;
const char *options = NULL;
regex = bson_iter_regex (iter, &options);
if (!bson_utf8_validate (regex, strlen (regex), true)) {
iter->err_off = iter->off;
return true;
}
if (VISIT_REGEX (iter, key, regex, options, data)) {
return true;
}
} break;
case BSON_TYPE_DBPOINTER: {
uint32_t collection_len = 0;
const char *collection = NULL;
const bson_oid_t *oid = NULL;
bson_iter_dbpointer (iter, &collection_len, &collection, &oid);
if (!bson_utf8_validate (collection, collection_len, true)) {
iter->err_off = iter->off;
return true;
}
if (VISIT_DBPOINTER (
iter, key, collection_len, collection, oid, data)) {
return true;
}
} break;
case BSON_TYPE_CODE: {
uint32_t code_len;
const char *code;
code = bson_iter_code (iter, &code_len);
if (!bson_utf8_validate (code, code_len, true)) {
iter->err_off = iter->off;
return true;
}
if (VISIT_CODE (iter, key, code_len, code, data)) {
return true;
}
} break;
case BSON_TYPE_SYMBOL: {
uint32_t symbol_len;
const char *symbol;
symbol = bson_iter_symbol (iter, &symbol_len);
if (!bson_utf8_validate (symbol, symbol_len, true)) {
iter->err_off = iter->off;
return true;
}
if (VISIT_SYMBOL (iter, key, symbol_len, symbol, data)) {
return true;
}
} break;
case BSON_TYPE_CODEWSCOPE: {
uint32_t length = 0;
const char *code;
const uint8_t *docbuf = NULL;
uint32_t doclen = 0;
bson_t b;
code = bson_iter_codewscope (iter, &length, &doclen, &docbuf);
if (!bson_utf8_validate (code, length, true)) {
iter->err_off = iter->off;
return true;
}
if (bson_init_static (&b, docbuf, doclen) &&
VISIT_CODEWSCOPE (iter, key, length, code, &b, data)) {
return true;
}
} break;
case BSON_TYPE_INT32:
if (VISIT_INT32 (iter, key, bson_iter_int32 (iter), data)) {
return true;
}
break;
case BSON_TYPE_TIMESTAMP: {
uint32_t timestamp;
uint32_t increment;
bson_iter_timestamp (iter, &timestamp, &increment);
if (VISIT_TIMESTAMP (iter, key, timestamp, increment, data)) {
return true;
}
} break;
case BSON_TYPE_INT64:
if (VISIT_INT64 (iter, key, bson_iter_int64 (iter), data)) {
return true;
}
break;
case BSON_TYPE_DECIMAL128: {
bson_decimal128_t dec;
bson_iter_decimal128 (iter, &dec);
if (VISIT_DECIMAL128 (iter, key, &dec, data)) {
return true;
}
} break;
case BSON_TYPE_MAXKEY:
if (VISIT_MAXKEY (iter, bson_iter_key_unsafe (iter), data)) {
return true;
}
break;
case BSON_TYPE_MINKEY:
if (VISIT_MINKEY (iter, bson_iter_key_unsafe (iter), data)) {
return true;
}
break;
case BSON_TYPE_EOD:
default:
break;
}
if (VISIT_AFTER (iter, bson_iter_key_unsafe (iter), data)) {
return true;
}
}
if (iter->err_off) {
if (unsupported && visitor->visit_unsupported_type &&
bson_utf8_validate (key, strlen (key), false)) {
visitor->visit_unsupported_type (iter, key, bson_type, data);
return false;
}
VISIT_CORRUPT (iter, data);
}
#undef VISIT_FIELD
return false;
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_overwrite_bool --
*
* Overwrites the current BSON_TYPE_BOOLEAN field with a new value.
* This is performed in-place and therefore no keys are moved.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_overwrite_bool (bson_iter_t *iter, /* IN */
bool value) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_BOOL) {
memcpy ((void *) (iter->raw + iter->d1), &value, 1);
}
}
void
bson_iter_overwrite_oid (bson_iter_t *iter, const bson_oid_t *value)
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_OID) {
memcpy (
(void *) (iter->raw + iter->d1), value->bytes, sizeof (value->bytes));
}
}
void
bson_iter_overwrite_timestamp (bson_iter_t *iter,
uint32_t timestamp,
uint32_t increment)
{
uint64_t value;
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_TIMESTAMP) {
value = ((((uint64_t) timestamp) << 32U) | ((uint64_t) increment));
value = BSON_UINT64_TO_LE (value);
memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
}
}
void
bson_iter_overwrite_date_time (bson_iter_t *iter, int64_t value)
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
value = BSON_UINT64_TO_LE (value);
memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_overwrite_int32 --
*
* Overwrites the current BSON_TYPE_INT32 field with a new value.
* This is performed in-place and therefore no keys are moved.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_overwrite_int32 (bson_iter_t *iter, /* IN */
int32_t value) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_INT32) {
#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
value = BSON_UINT32_TO_LE (value);
#endif
memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_overwrite_int64 --
*
* Overwrites the current BSON_TYPE_INT64 field with a new value.
* This is performed in-place and therefore no keys are moved.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_overwrite_int64 (bson_iter_t *iter, /* IN */
int64_t value) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_INT64) {
#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
value = BSON_UINT64_TO_LE (value);
#endif
memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_overwrite_double --
*
* Overwrites the current BSON_TYPE_DOUBLE field with a new value.
* This is performed in-place and therefore no keys are moved.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_overwrite_double (bson_iter_t *iter, /* IN */
double value) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) {
value = BSON_DOUBLE_TO_LE (value);
memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_overwrite_decimal128 --
*
* Overwrites the current BSON_TYPE_DECIMAL128 field with a new value.
* This is performed in-place and therefore no keys are moved.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
bson_iter_overwrite_decimal128 (bson_iter_t *iter, /* IN */
const bson_decimal128_t *value) /* IN */
{
BSON_ASSERT (iter);
if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) {
#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
uint64_t data[2];
data[0] = BSON_UINT64_TO_LE (value->low);
data[1] = BSON_UINT64_TO_LE (value->high);
memcpy ((void *) (iter->raw + iter->d1), data, sizeof (data));
#else
memcpy ((void *) (iter->raw + iter->d1), value, sizeof (*value));
#endif
}
}
/*
*--------------------------------------------------------------------------
*
* bson_iter_value --
*
* Retrieves a bson_value_t containing the boxed value of the current
* element. The result of this function valid until the state of
* iter has been changed (through the use of bson_iter_next()).
*
* Returns:
* A bson_value_t that should not be modified or freed. If you need
* to hold on to the value, use bson_value_copy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const bson_value_t *
bson_iter_value (bson_iter_t *iter) /* IN */
{
bson_value_t *value;
BSON_ASSERT (iter);
value = &iter->value;
value->value_type = ITER_TYPE (iter);
switch (value->value_type) {
case BSON_TYPE_DOUBLE:
value->value.v_double = bson_iter_double (iter);
break;
case BSON_TYPE_UTF8:
value->value.v_utf8.str =
(char *) bson_iter_utf8 (iter, &value->value.v_utf8.len);
break;
case BSON_TYPE_DOCUMENT:
bson_iter_document (iter,
&value->value.v_doc.data_len,
(const uint8_t **) &value->value.v_doc.data);
break;
case BSON_TYPE_ARRAY:
bson_iter_array (iter,
&value->value.v_doc.data_len,
(const uint8_t **) &value->value.v_doc.data);
break;
case BSON_TYPE_BINARY:
bson_iter_binary (iter,
&value->value.v_binary.subtype,
&value->value.v_binary.data_len,
(const uint8_t **) &value->value.v_binary.data);
break;
case BSON_TYPE_OID:
bson_oid_copy (bson_iter_oid (iter), &value->value.v_oid);
break;
case BSON_TYPE_BOOL:
value->value.v_bool = bson_iter_bool (iter);
break;
case BSON_TYPE_DATE_TIME:
value->value.v_datetime = bson_iter_date_time (iter);
break;
case BSON_TYPE_REGEX:
value->value.v_regex.regex = (char *) bson_iter_regex (
iter, (const char **) &value->value.v_regex.options);
break;
case BSON_TYPE_DBPOINTER: {
const bson_oid_t *oid;
bson_iter_dbpointer (iter,
&value->value.v_dbpointer.collection_len,
(const char **) &value->value.v_dbpointer.collection,
&oid);
bson_oid_copy (oid, &value->value.v_dbpointer.oid);
break;
}
case BSON_TYPE_CODE:
value->value.v_code.code =
(char *) bson_iter_code (iter, &value->value.v_code.code_len);
break;
case BSON_TYPE_SYMBOL:
value->value.v_symbol.symbol =
(char *) bson_iter_symbol (iter, &value->value.v_symbol.len);
break;
case BSON_TYPE_CODEWSCOPE:
value->value.v_codewscope.code = (char *) bson_iter_codewscope (
iter,
&value->value.v_codewscope.code_len,
&value->value.v_codewscope.scope_len,
(const uint8_t **) &value->value.v_codewscope.scope_data);
break;
case BSON_TYPE_INT32:
value->value.v_int32 = bson_iter_int32 (iter);
break;
case BSON_TYPE_TIMESTAMP:
bson_iter_timestamp (iter,
&value->value.v_timestamp.timestamp,
&value->value.v_timestamp.increment);
break;
case BSON_TYPE_INT64:
value->value.v_int64 = bson_iter_int64 (iter);
break;
case BSON_TYPE_DECIMAL128:
bson_iter_decimal128 (iter, &(value->value.v_decimal128));
break;
case BSON_TYPE_NULL:
case BSON_TYPE_UNDEFINED:
case BSON_TYPE_MAXKEY:
case BSON_TYPE_MINKEY:
break;
case BSON_TYPE_EOD:
default:
return NULL;
}
return value;
}
uint32_t
bson_iter_key_len (const bson_iter_t *iter)
{
/*
* f i e l d n a m e \0 _
* ^ ^
* | |
* iter->key iter->d1
*
*/
BSON_ASSERT (iter->d1 > iter->key);
return iter->d1 - iter->key - 1;
}
bool
bson_iter_init_from_data_at_offset (bson_iter_t *iter,
const uint8_t *data,
size_t length,
uint32_t offset,
uint32_t keylen)
{
const char *key;
uint32_t bson_type;
bool unsupported;
BSON_ASSERT (iter);
BSON_ASSERT (data);
if (BSON_UNLIKELY ((length < 5) || (length > INT_MAX))) {
memset (iter, 0, sizeof *iter);
return false;
}
iter->raw = (uint8_t *) data;
iter->len = (uint32_t) length;
iter->off = 0;
iter->type = 0;
iter->key = 0;
iter->next_off = offset;
iter->err_off = 0;
if (!_bson_iter_next_internal (
iter, keylen, &key, &bson_type, &unsupported)) {
memset (iter, 0, sizeof *iter);
return false;
}
return true;
}
uint32_t
bson_iter_offset (bson_iter_t *iter)
{
return iter->off;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iter.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iter.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-iter.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-iter.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-json-private.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-json-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-json-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-json-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-json.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-json.c
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-json.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-json.c
index 7e838f2a..26182227 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-json.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-json.c
@@ -1,2504 +1,2545 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <math.h>
#include "bson.h"
#include "bson-config.h"
#include "bson-json.h"
#include "bson-json-private.h"
#include "bson-iso8601-private.h"
#include "common-b64-private.h"
#include "jsonsl/jsonsl.h"
#ifdef _WIN32
#include <io.h>
#include <share.h>
#endif
#ifndef _MSC_VER
#include <strings.h>
#endif
#ifdef _MSC_VER
#define SSCANF sscanf_s
#else
#define SSCANF sscanf
#endif
#define STACK_MAX 100
#define BSON_JSON_DEFAULT_BUF_SIZE (1 << 14)
#define AT_LEAST_0(x) ((x) >= 0 ? (x) : 0)
#define READ_STATE_ENUM(ENUM) BSON_JSON_##ENUM,
#define GENERATE_STRING(STRING) #STRING,
#define FOREACH_READ_STATE(RS) \
RS (REGULAR) \
RS (DONE) \
RS (ERROR) \
RS (IN_START_MAP) \
RS (IN_BSON_TYPE) \
RS (IN_BSON_TYPE_DATE_NUMBERLONG) \
RS (IN_BSON_TYPE_DATE_ENDMAP) \
RS (IN_BSON_TYPE_TIMESTAMP_STARTMAP) \
RS (IN_BSON_TYPE_TIMESTAMP_VALUES) \
RS (IN_BSON_TYPE_TIMESTAMP_ENDMAP) \
RS (IN_BSON_TYPE_REGEX_STARTMAP) \
RS (IN_BSON_TYPE_REGEX_VALUES) \
RS (IN_BSON_TYPE_REGEX_ENDMAP) \
RS (IN_BSON_TYPE_BINARY_VALUES) \
RS (IN_BSON_TYPE_BINARY_ENDMAP) \
RS (IN_BSON_TYPE_SCOPE_STARTMAP) \
RS (IN_BSON_TYPE_DBPOINTER_STARTMAP) \
RS (IN_SCOPE) \
RS (IN_DBPOINTER)
typedef enum { FOREACH_READ_STATE (READ_STATE_ENUM) } bson_json_read_state_t;
static const char *read_state_names[] = {FOREACH_READ_STATE (GENERATE_STRING)};
#define BSON_STATE_ENUM(ENUM) BSON_JSON_LF_##ENUM,
#define FOREACH_BSON_STATE(BS) \
/* legacy {$regex: "...", $options: "..."} */ \
BS (REGEX) \
BS (OPTIONS) \
/* modern $regularExpression: {pattern: "...", options: "..."} */ \
BS (REGULAR_EXPRESSION_PATTERN) \
BS (REGULAR_EXPRESSION_OPTIONS) \
BS (CODE) \
BS (SCOPE) \
BS (OID) \
BS (BINARY) \
BS (TYPE) \
BS (DATE) \
BS (TIMESTAMP_T) \
BS (TIMESTAMP_I) \
BS (UNDEFINED) \
BS (MINKEY) \
BS (MAXKEY) \
BS (INT32) \
BS (INT64) \
BS (DOUBLE) \
BS (DECIMAL128) \
BS (DBPOINTER) \
BS (SYMBOL) \
BS (UUID)
typedef enum {
FOREACH_BSON_STATE (BSON_STATE_ENUM)
} bson_json_read_bson_state_t;
static const char *bson_state_names[] = {FOREACH_BSON_STATE (GENERATE_STRING)};
typedef struct {
uint8_t *buf;
size_t n_bytes;
size_t len;
} bson_json_buf_t;
typedef enum {
BSON_JSON_FRAME_INITIAL = 0,
BSON_JSON_FRAME_ARRAY,
BSON_JSON_FRAME_DOC,
BSON_JSON_FRAME_SCOPE,
BSON_JSON_FRAME_DBPOINTER,
} bson_json_frame_type_t;
typedef struct {
int i;
bson_json_frame_type_t type;
bson_t bson;
} bson_json_stack_frame_t;
typedef union {
struct {
bool has_pattern;
bool has_options;
bool is_legacy;
} regex;
struct {
bool has_oid;
bson_oid_t oid;
} oid;
struct {
bool has_binary;
bool has_subtype;
bson_subtype_t type;
bool is_legacy;
} binary;
struct {
bool has_date;
int64_t date;
} date;
struct {
bool has_t;
bool has_i;
uint32_t t;
uint32_t i;
} timestamp;
struct {
bool has_undefined;
} undefined;
struct {
bool has_minkey;
} minkey;
struct {
bool has_maxkey;
} maxkey;
struct {
int32_t value;
} v_int32;
struct {
int64_t value;
} v_int64;
struct {
double value;
} v_double;
struct {
bson_decimal128_t value;
} v_decimal128;
} bson_json_bson_data_t;
/* collect info while parsing a {$code: "...", $scope: {...}} object */
typedef struct {
bool has_code;
bool has_scope;
bool in_scope;
bson_json_buf_t key_buf;
bson_json_buf_t code_buf;
} bson_json_code_t;
static void
_bson_json_code_cleanup (bson_json_code_t *code_data)
{
bson_free (code_data->key_buf.buf);
bson_free (code_data->code_buf.buf);
}
typedef struct {
bson_t *bson;
bson_json_stack_frame_t stack[STACK_MAX];
int n;
const char *key;
bson_json_buf_t key_buf;
bson_json_buf_t unescaped;
bson_json_read_state_t read_state;
bson_json_read_bson_state_t bson_state;
bson_type_t bson_type;
bson_json_buf_t bson_type_buf[3];
bson_json_bson_data_t bson_type_data;
bson_json_code_t code_data;
bson_json_buf_t dbpointer_key;
} bson_json_reader_bson_t;
typedef struct {
void *data;
bson_json_reader_cb cb;
bson_json_destroy_cb dcb;
uint8_t *buf;
size_t buf_size;
size_t bytes_read;
size_t bytes_parsed;
bool all_whitespace;
} bson_json_reader_producer_t;
struct _bson_json_reader_t {
bson_json_reader_producer_t producer;
bson_json_reader_bson_t bson;
jsonsl_t json;
ssize_t json_text_pos;
bool should_reset;
ssize_t advance;
bson_json_buf_t tok_accumulator;
bson_error_t *error;
};
typedef struct {
int fd;
bool do_close;
} bson_json_reader_handle_fd_t;
/* forward decl */
static void
_bson_json_save_map_key (bson_json_reader_bson_t *bson,
const uint8_t *val,
size_t len);
static void
_noop (void)
{
}
#define STACK_ELE(_delta, _name) (bson->stack[(_delta) + bson->n]._name)
#define STACK_BSON(_delta) \
(((_delta) + bson->n) == 0 ? bson->bson : &STACK_ELE (_delta, bson))
#define STACK_BSON_PARENT STACK_BSON (-1)
#define STACK_BSON_CHILD STACK_BSON (0)
#define STACK_I STACK_ELE (0, i)
#define STACK_FRAME_TYPE STACK_ELE (0, type)
#define STACK_IS_INITIAL (STACK_FRAME_TYPE == BSON_JSON_FRAME_INITIAL)
#define STACK_IS_ARRAY (STACK_FRAME_TYPE == BSON_JSON_FRAME_ARRAY)
#define STACK_IS_DOC (STACK_FRAME_TYPE == BSON_JSON_FRAME_DOC)
#define STACK_IS_SCOPE (STACK_FRAME_TYPE == BSON_JSON_FRAME_SCOPE)
#define STACK_IS_DBPOINTER (STACK_FRAME_TYPE == BSON_JSON_FRAME_DBPOINTER)
#define FRAME_TYPE_HAS_BSON(_type) \
((_type) == BSON_JSON_FRAME_SCOPE || (_type) == BSON_JSON_FRAME_DBPOINTER)
#define STACK_HAS_BSON FRAME_TYPE_HAS_BSON (STACK_FRAME_TYPE)
#define STACK_PUSH(frame_type) \
do { \
if (bson->n >= (STACK_MAX - 1)) { \
return; \
} \
bson->n++; \
if (STACK_HAS_BSON) { \
if (FRAME_TYPE_HAS_BSON (frame_type)) { \
bson_reinit (STACK_BSON_CHILD); \
} else { \
bson_destroy (STACK_BSON_CHILD); \
} \
} else if (FRAME_TYPE_HAS_BSON (frame_type)) { \
bson_init (STACK_BSON_CHILD); \
} \
STACK_FRAME_TYPE = frame_type; \
} while (0)
#define STACK_PUSH_ARRAY(statement) \
do { \
STACK_PUSH (BSON_JSON_FRAME_ARRAY); \
STACK_I = 0; \
if (bson->n != 0) { \
statement; \
} \
} while (0)
#define STACK_PUSH_DOC(statement) \
do { \
STACK_PUSH (BSON_JSON_FRAME_DOC); \
if (bson->n != 0) { \
statement; \
} \
} while (0)
#define STACK_PUSH_SCOPE \
do { \
STACK_PUSH (BSON_JSON_FRAME_SCOPE); \
bson->code_data.in_scope = true; \
} while (0)
#define STACK_PUSH_DBPOINTER \
do { \
STACK_PUSH (BSON_JSON_FRAME_DBPOINTER); \
} while (0)
#define STACK_POP_ARRAY(statement) \
do { \
if (!STACK_IS_ARRAY) { \
return; \
} \
if (bson->n < 0) { \
return; \
} \
if (bson->n > 0) { \
statement; \
} \
bson->n--; \
} while (0)
#define STACK_POP_DOC(statement) \
do { \
if (STACK_IS_ARRAY) { \
return; \
} \
if (bson->n < 0) { \
return; \
} \
if (bson->n > 0) { \
statement; \
} \
bson->n--; \
} while (0)
#define STACK_POP_SCOPE \
do { \
STACK_POP_DOC (_noop ()); \
bson->code_data.in_scope = false; \
} while (0);
#define STACK_POP_DBPOINTER STACK_POP_DOC (_noop ())
#define BASIC_CB_PREAMBLE \
const char *key; \
size_t len; \
bson_json_reader_bson_t *bson = &reader->bson; \
_bson_json_read_fixup_key (bson); \
key = bson->key; \
len = bson->key_buf.len;
#define BASIC_CB_BAIL_IF_NOT_NORMAL(_type) \
if (bson->read_state != BSON_JSON_REGULAR) { \
_bson_json_read_set_error (reader, \
"Invalid read of %s in state %s", \
(_type), \
read_state_names[bson->read_state]); \
return; \
} else if (!key) { \
_bson_json_read_set_error (reader, \
"Invalid read of %s without key in state %s", \
(_type), \
read_state_names[bson->read_state]); \
return; \
}
#define HANDLE_OPTION(_key, _type, _state) \
(len == strlen (_key) && strncmp ((const char *) val, (_key), len) == 0) \
{ \
if (bson->bson_type && bson->bson_type != (_type)) { \
_bson_json_read_set_error (reader, \
"Invalid key \"%s\". Looking for values " \
"for type \"%s\", got \"%s\"", \
(_key), \
_bson_json_type_name (bson->bson_type), \
_bson_json_type_name (_type)); \
return; \
} \
bson->bson_type = (_type); \
bson->bson_state = (_state); \
}
bson_json_opts_t *
bson_json_opts_new (bson_json_mode_t mode, int32_t max_len)
{
bson_json_opts_t *opts;
opts = (bson_json_opts_t *) bson_malloc (sizeof *opts);
opts->mode = mode;
opts->max_len = max_len;
return opts;
}
void
bson_json_opts_destroy (bson_json_opts_t *opts)
{
bson_free (opts);
}
static void
_bson_json_read_set_error (bson_json_reader_t *reader, const char *fmt, ...)
BSON_GNUC_PRINTF (2, 3);
static void
_bson_json_read_set_error (bson_json_reader_t *reader, /* IN */
const char *fmt, /* IN */
...)
{
va_list ap;
if (reader->error) {
reader->error->domain = BSON_ERROR_JSON;
reader->error->code = BSON_JSON_ERROR_READ_INVALID_PARAM;
va_start (ap, fmt);
bson_vsnprintf (
reader->error->message, sizeof reader->error->message, fmt, ap);
va_end (ap);
reader->error->message[sizeof reader->error->message - 1] = '\0';
}
reader->bson.read_state = BSON_JSON_ERROR;
jsonsl_stop (reader->json);
}
static void
_bson_json_read_corrupt (bson_json_reader_t *reader, const char *fmt, ...)
BSON_GNUC_PRINTF (2, 3);
static void
_bson_json_read_corrupt (bson_json_reader_t *reader, /* IN */
const char *fmt, /* IN */
...)
{
va_list ap;
if (reader->error) {
reader->error->domain = BSON_ERROR_JSON;
reader->error->code = BSON_JSON_ERROR_READ_CORRUPT_JS;
va_start (ap, fmt);
bson_vsnprintf (
reader->error->message, sizeof reader->error->message, fmt, ap);
va_end (ap);
reader->error->message[sizeof reader->error->message - 1] = '\0';
}
reader->bson.read_state = BSON_JSON_ERROR;
jsonsl_stop (reader->json);
}
static void
_bson_json_buf_ensure (bson_json_buf_t *buf, /* IN */
size_t len) /* IN */
{
if (buf->n_bytes < len) {
bson_free (buf->buf);
buf->n_bytes = bson_next_power_of_two (len);
buf->buf = bson_malloc (buf->n_bytes);
}
}
static void
_bson_json_buf_set (bson_json_buf_t *buf, const void *from, size_t len)
{
_bson_json_buf_ensure (buf, len + 1);
memcpy (buf->buf, from, len);
buf->buf[len] = '\0';
buf->len = len;
}
static void
_bson_json_buf_append (bson_json_buf_t *buf, const void *from, size_t len)
{
size_t len_with_null = len + 1;
if (buf->len == 0) {
_bson_json_buf_ensure (buf, len_with_null);
} else if (buf->n_bytes < buf->len + len_with_null) {
buf->n_bytes = bson_next_power_of_two (buf->len + len_with_null);
buf->buf = bson_realloc (buf->buf, buf->n_bytes);
}
memcpy (buf->buf + buf->len, from, len);
buf->len += len;
buf->buf[buf->len] = '\0';
}
static const char *
_bson_json_type_name (bson_type_t type)
{
switch (type) {
case BSON_TYPE_EOD:
return "end of document";
case BSON_TYPE_DOUBLE:
return "double";
case BSON_TYPE_UTF8:
return "utf-8";
case BSON_TYPE_DOCUMENT:
return "document";
case BSON_TYPE_ARRAY:
return "array";
case BSON_TYPE_BINARY:
return "binary";
case BSON_TYPE_UNDEFINED:
return "undefined";
case BSON_TYPE_OID:
return "objectid";
case BSON_TYPE_BOOL:
return "bool";
case BSON_TYPE_DATE_TIME:
return "datetime";
case BSON_TYPE_NULL:
return "null";
case BSON_TYPE_REGEX:
return "regex";
case BSON_TYPE_DBPOINTER:
return "dbpointer";
case BSON_TYPE_CODE:
return "code";
case BSON_TYPE_SYMBOL:
return "symbol";
case BSON_TYPE_CODEWSCOPE:
return "code with scope";
case BSON_TYPE_INT32:
return "int32";
case BSON_TYPE_TIMESTAMP:
return "timestamp";
case BSON_TYPE_INT64:
return "int64";
case BSON_TYPE_DECIMAL128:
return "decimal128";
case BSON_TYPE_MAXKEY:
return "maxkey";
case BSON_TYPE_MINKEY:
return "minkey";
default:
return "";
}
}
static void
_bson_json_read_fixup_key (bson_json_reader_bson_t *bson) /* IN */
{
bson_json_read_state_t rs = bson->read_state;
if (bson->n >= 0 && STACK_IS_ARRAY && rs == BSON_JSON_REGULAR) {
_bson_json_buf_ensure (&bson->key_buf, 12);
bson->key_buf.len = bson_uint32_to_string (
STACK_I, &bson->key, (char *) bson->key_buf.buf, 12);
STACK_I++;
}
}
static void
_bson_json_read_null (bson_json_reader_t *reader)
{
BASIC_CB_PREAMBLE;
BASIC_CB_BAIL_IF_NOT_NORMAL ("null");
bson_append_null (STACK_BSON_CHILD, key, (int) len);
}
static void
_bson_json_read_boolean (bson_json_reader_t *reader, /* IN */
int val) /* IN */
{
BASIC_CB_PREAMBLE;
if (bson->read_state == BSON_JSON_IN_BSON_TYPE &&
bson->bson_state == BSON_JSON_LF_UNDEFINED) {
bson->bson_type_data.undefined.has_undefined = true;
return;
}
BASIC_CB_BAIL_IF_NOT_NORMAL ("boolean");
bson_append_bool (STACK_BSON_CHILD, key, (int) len, val);
}
/* sign is -1 or 1 */
static void
_bson_json_read_integer (bson_json_reader_t *reader, uint64_t val, int64_t sign)
{
bson_json_read_state_t rs;
bson_json_read_bson_state_t bs;
BASIC_CB_PREAMBLE;
if (sign == 1 && val > INT64_MAX) {
_bson_json_read_set_error (
reader, "Number \"%" PRIu64 "\" is out of range", val);
return;
} else if (sign == -1 && val > ((uint64_t) INT64_MAX + 1)) {
_bson_json_read_set_error (
reader, "Number \"-%" PRIu64 "\" is out of range", val);
return;
}
rs = bson->read_state;
bs = bson->bson_state;
if (rs == BSON_JSON_REGULAR) {
BASIC_CB_BAIL_IF_NOT_NORMAL ("integer");
if (val <= INT32_MAX || (sign == -1 && val <= (uint64_t) INT32_MAX + 1)) {
bson_append_int32 (
STACK_BSON_CHILD, key, (int) len, (int) (val * sign));
} else if (sign == -1) {
bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) -val);
} else {
bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) val);
}
} else if (rs == BSON_JSON_IN_BSON_TYPE ||
rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
switch (bs) {
case BSON_JSON_LF_DATE:
bson->bson_type_data.date.has_date = true;
bson->bson_type_data.date.date = sign * val;
break;
case BSON_JSON_LF_TIMESTAMP_T:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid timestamp value: \"-%" PRIu64 "\"", val);
return;
}
bson->bson_type_data.timestamp.has_t = true;
bson->bson_type_data.timestamp.t = (uint32_t) val;
break;
case BSON_JSON_LF_TIMESTAMP_I:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid timestamp value: \"-%" PRIu64 "\"", val);
return;
}
bson->bson_type_data.timestamp.has_i = true;
bson->bson_type_data.timestamp.i = (uint32_t) val;
break;
case BSON_JSON_LF_MINKEY:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"-%" PRIu64 "\"", val);
return;
} else if (val != 1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"%" PRIu64 "\"", val);
}
bson->bson_type_data.minkey.has_minkey = true;
break;
case BSON_JSON_LF_MAXKEY:
if (sign == -1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"-%" PRIu64 "\"", val);
return;
} else if (val != 1) {
_bson_json_read_set_error (
reader, "Invalid MinKey value: \"%" PRIu64 "\"", val);
}
bson->bson_type_data.maxkey.has_maxkey = true;
break;
case BSON_JSON_LF_INT32:
case BSON_JSON_LF_INT64:
_bson_json_read_set_error (
reader,
"Invalid state for integer read: %s, "
"expected number as quoted string like \"123\"",
bson_state_names[bs]);
break;
case BSON_JSON_LF_REGEX:
case BSON_JSON_LF_OPTIONS:
case BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN:
case BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS:
case BSON_JSON_LF_CODE:
case BSON_JSON_LF_SCOPE:
case BSON_JSON_LF_OID:
case BSON_JSON_LF_BINARY:
case BSON_JSON_LF_TYPE:
case BSON_JSON_LF_UUID:
case BSON_JSON_LF_UNDEFINED:
case BSON_JSON_LF_DOUBLE:
case BSON_JSON_LF_DECIMAL128:
case BSON_JSON_LF_DBPOINTER:
case BSON_JSON_LF_SYMBOL:
default:
_bson_json_read_set_error (reader,
"Unexpected integer %s%" PRIu64
" in type \"%s\"",
sign == -1 ? "-" : "",
val,
_bson_json_type_name (bson->bson_type));
}
} else {
_bson_json_read_set_error (reader,
"Unexpected integer %s%" PRIu64
" in state \"%s\"",
sign == -1 ? "-" : "",
val,
read_state_names[rs]);
}
}
static bool
_bson_json_parse_double (bson_json_reader_t *reader,
const char *val,
size_t vlen,
double *d)
{
errno = 0;
*d = strtod (val, NULL);
#ifdef _MSC_VER
/* Microsoft's strtod parses "NaN", "Infinity", "-Infinity" as 0 */
if (*d == 0.0) {
if (!_strnicmp (val, "nan", vlen)) {
#ifdef NAN
*d = NAN;
#else
/* Visual Studio 2010 doesn't define NAN or INFINITY
* https://msdn.microsoft.com/en-us/library/w22adx1s(v=vs.100).aspx */
unsigned long nan[2] = {0xffffffff, 0x7fffffff};
*d = *(double *) nan;
#endif
return true;
} else if (!_strnicmp (val, "infinity", vlen)) {
#ifdef INFINITY
*d = INFINITY;
#else
unsigned long inf[2] = {0x00000000, 0x7ff00000};
*d = *(double *) inf;
#endif
return true;
} else if (!_strnicmp (val, "-infinity", vlen)) {
#ifdef INFINITY
*d = -INFINITY;
#else
unsigned long inf[2] = {0x00000000, 0xfff00000};
*d = *(double *) inf;
#endif
return true;
}
}
if ((*d == HUGE_VAL || *d == -HUGE_VAL) && errno == ERANGE) {
_bson_json_read_set_error (
reader, "Number \"%.*s\" is out of range", (int) vlen, val);
return false;
}
#else
/* not MSVC - set err on overflow, but avoid err for infinity */
if ((*d == HUGE_VAL || *d == -HUGE_VAL) && errno == ERANGE &&
strncasecmp (val, "infinity", vlen) &&
strncasecmp (val, "-infinity", vlen)) {
_bson_json_read_set_error (
reader, "Number \"%.*s\" is out of range", (int) vlen, val);
return false;
}
#endif /* _MSC_VER */
return true;
}
static void
_bson_json_read_double (bson_json_reader_t *reader, /* IN */
double val) /* IN */
{
BASIC_CB_PREAMBLE;
BASIC_CB_BAIL_IF_NOT_NORMAL ("double");
if (!bson_append_double (STACK_BSON_CHILD, key, (int) len, val)) {
_bson_json_read_set_error (reader, "Cannot append double value %g", val);
}
}
static bool
_bson_json_read_int64_or_set_error (bson_json_reader_t *reader, /* IN */
const unsigned char *val, /* IN */
size_t vlen, /* IN */
int64_t *v64) /* OUT */
{
bson_json_reader_bson_t *bson = &reader->bson;
char *endptr = NULL;
_bson_json_read_fixup_key (bson);
errno = 0;
*v64 = bson_ascii_strtoll ((const char *) val, &endptr, 10);
if (((*v64 == INT64_MIN) || (*v64 == INT64_MAX)) && (errno == ERANGE)) {
_bson_json_read_set_error (reader, "Number \"%s\" is out of range", val);
return false;
}
if (endptr != ((const char *) val + vlen)) {
_bson_json_read_set_error (reader, "Number \"%s\" is invalid", val);
return false;
}
return true;
}
static bool
_unhexlify_uuid (const char *uuid, uint8_t *out, size_t max)
{
unsigned int byte;
int x = 0;
int i = 0;
BSON_ASSERT (strlen (uuid) == 32);
while (SSCANF (&uuid[i], "%2x", &byte) == 1) {
if (x >= max) {
return false;
}
out[x++] = (uint8_t) byte;
i += 2;
}
return i == 32;
}
/* parse a value for "base64", "subType", legacy "$binary" or "$type", or
* "$uuid" */
static void
_bson_json_parse_binary_elem (bson_json_reader_t *reader,
const char *val_w_null,
size_t vlen)
{
bson_json_read_bson_state_t bs;
bson_json_bson_data_t *data;
int binary_len;
BASIC_CB_PREAMBLE;
bs = bson->bson_state;
data = &bson->bson_type_data;
if (bs == BSON_JSON_LF_BINARY) {
data->binary.has_binary = true;
- binary_len = COMMON_PREFIX (bson_b64_pton (val_w_null, NULL, 0));
+ binary_len = mcommon_b64_pton (val_w_null, NULL, 0);
if (binary_len < 0) {
_bson_json_read_set_error (
reader,
"Invalid input string \"%s\", looking for base64-encoded binary",
val_w_null);
}
_bson_json_buf_ensure (&bson->bson_type_buf[0], (size_t) binary_len + 1);
- if (COMMON_PREFIX (bson_b64_pton (val_w_null,
- bson->bson_type_buf[0].buf,
- (size_t) binary_len + 1) < 0)) {
+ if (mcommon_b64_pton (val_w_null,
+ bson->bson_type_buf[0].buf,
+ (size_t) binary_len + 1) < 0) {
_bson_json_read_set_error (
reader,
"Invalid input string \"%s\", looking for base64-encoded binary",
val_w_null);
}
bson->bson_type_buf[0].len = (size_t) binary_len;
} else if (bs == BSON_JSON_LF_TYPE) {
data->binary.has_subtype = true;
if (SSCANF (val_w_null, "%02x", &data->binary.type) != 1) {
if (!data->binary.is_legacy || data->binary.has_binary) {
/* misformatted subtype, like {$binary: {base64: "", subType: "x"}},
* or legacy {$binary: "", $type: "x"} */
_bson_json_read_set_error (
reader,
"Invalid input string \"%s\", looking for binary subtype",
val_w_null);
} else {
/* actually a query operator: {x: {$type: "array"}}*/
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (
STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD));
bson_append_utf8 (STACK_BSON_CHILD,
"$type",
5,
(const char *) val_w_null,
(int) vlen);
}
}
} else if (bs == BSON_JSON_LF_UUID) {
int nread = 0;
char uuid[33];
data->binary.has_binary = true;
data->binary.has_subtype = true;
data->binary.type = BSON_SUBTYPE_UUID;
/* Validate the UUID and extract relevant portions */
/* We can't use %x here as it allows +, -, and 0x prefixes */
#ifdef _MSC_VER
SSCANF (val_w_null,
"%8c-%4c-%4c-%4c-%12c%n",
&uuid[0],
8,
&uuid[8],
4,
&uuid[12],
4,
&uuid[16],
4,
&uuid[20],
12,
&nread);
#else
SSCANF (val_w_null,
"%8c-%4c-%4c-%4c-%12c%n",
&uuid[0],
&uuid[8],
&uuid[12],
&uuid[16],
&uuid[20],
&nread);
#endif
uuid[32] = '\0';
if (nread != 36 || val_w_null[nread] != '\0') {
_bson_json_read_set_error (reader,
"Invalid input string \"%s\", looking for "
"a dash-separated UUID string",
val_w_null);
return;
}
binary_len = 16;
_bson_json_buf_ensure (&bson->bson_type_buf[0], (size_t) binary_len + 1);
if (!_unhexlify_uuid (
&uuid[0], bson->bson_type_buf[0].buf, (size_t) binary_len)) {
_bson_json_read_set_error (reader,
"Invalid input string \"%s\", looking for "
"a dash-separated UUID string",
val_w_null);
}
bson->bson_type_buf[0].len = (size_t) binary_len;
}
}
static bool
_bson_json_allow_embedded_nulls (bson_json_reader_t const *reader)
{
const bson_json_read_state_t read_state = reader->bson.read_state;
const bson_json_read_bson_state_t bson_state = reader->bson.bson_state;
if (read_state == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES) {
if (bson_state == BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN ||
bson_state == BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS) {
/* Prohibit embedded NULL bytes for canonical extended regex:
* { $regularExpression: { pattern: "pattern", options: "options" } }
*/
return false;
}
}
if (read_state == BSON_JSON_IN_BSON_TYPE) {
if (bson_state == BSON_JSON_LF_REGEX ||
bson_state == BSON_JSON_LF_OPTIONS) {
/* Prohibit embedded NULL bytes for legacy regex:
* { $regex: "pattern", $options: "options" } */
return false;
}
}
/* Embedded nulls are okay in any other context */
return true;
}
static void
_bson_json_read_string (bson_json_reader_t *reader, /* IN */
const unsigned char *val, /* IN */
size_t vlen) /* IN */
{
bson_json_read_state_t rs;
bson_json_read_bson_state_t bs;
const bool allow_null = _bson_json_allow_embedded_nulls (reader);
BASIC_CB_PREAMBLE;
rs = bson->read_state;
bs = bson->bson_state;
if (!bson_utf8_validate ((const char *) val, vlen, allow_null)) {
_bson_json_read_corrupt (reader, "invalid bytes in UTF8 string");
return;
}
if (rs == BSON_JSON_REGULAR) {
BASIC_CB_BAIL_IF_NOT_NORMAL ("string");
bson_append_utf8 (
STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen);
} else if (rs == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP ||
rs == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
_bson_json_read_set_error (reader,
"Invalid read of \"%s\" in state \"%s\"",
val,
read_state_names[rs]);
} else if (rs == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) {
const char *val_w_null;
_bson_json_buf_set (&bson->bson_type_buf[2], val, vlen);
val_w_null = (const char *) bson->bson_type_buf[2].buf;
_bson_json_parse_binary_elem (reader, val_w_null, vlen);
} else if (rs == BSON_JSON_IN_BSON_TYPE ||
rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES ||
rs == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES ||
rs == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
const char *val_w_null;
_bson_json_buf_set (&bson->bson_type_buf[2], val, vlen);
val_w_null = (const char *) bson->bson_type_buf[2].buf;
switch (bs) {
case BSON_JSON_LF_REGEX:
bson->bson_type_data.regex.is_legacy = true;
/* FALL THROUGH */
case BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN:
bson->bson_type_data.regex.has_pattern = true;
_bson_json_buf_set (&bson->bson_type_buf[0], val, vlen);
break;
case BSON_JSON_LF_OPTIONS:
bson->bson_type_data.regex.is_legacy = true;
/* FALL THROUGH */
case BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS:
bson->bson_type_data.regex.has_options = true;
_bson_json_buf_set (&bson->bson_type_buf[1], val, vlen);
break;
case BSON_JSON_LF_OID:
if (vlen != 24) {
goto BAD_PARSE;
}
bson->bson_type_data.oid.has_oid = true;
bson_oid_init_from_string (&bson->bson_type_data.oid.oid, val_w_null);
break;
case BSON_JSON_LF_BINARY:
case BSON_JSON_LF_TYPE:
bson->bson_type_data.binary.is_legacy = true;
/* FALL THROUGH */
case BSON_JSON_LF_UUID:
_bson_json_parse_binary_elem (reader, val_w_null, vlen);
break;
case BSON_JSON_LF_INT32: {
int64_t v64;
if (!_bson_json_read_int64_or_set_error (reader, val, vlen, &v64)) {
/* the error is set, return and let the reader exit */
return;
}
if (v64 < INT32_MIN || v64 > INT32_MAX) {
goto BAD_PARSE;
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
bson->bson_type_data.v_int32.value = (int32_t) v64;
} else {
goto BAD_PARSE;
}
} break;
case BSON_JSON_LF_INT64: {
int64_t v64;
if (!_bson_json_read_int64_or_set_error (reader, val, vlen, &v64)) {
/* the error is set, return and let the reader exit */
return;
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
bson->bson_type_data.v_int64.value = v64;
} else if (bson->read_state ==
BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
bson->bson_type_data.date.has_date = true;
bson->bson_type_data.date.date = v64;
} else {
goto BAD_PARSE;
}
} break;
case BSON_JSON_LF_DOUBLE: {
if (!_bson_json_parse_double (reader,
(const char *) val,
vlen,
&bson->bson_type_data.v_double.value)) {
/* the error is set, return and let the reader exit */
return;
}
} break;
case BSON_JSON_LF_DATE: {
int64_t v64;
if (!_bson_iso8601_date_parse (
(char *) val, (int) vlen, &v64, reader->error)) {
jsonsl_stop (reader->json);
} else {
bson->bson_type_data.date.has_date = true;
bson->bson_type_data.date.date = v64;
}
} break;
case BSON_JSON_LF_DECIMAL128: {
bson_decimal128_t decimal128;
bson_decimal128_from_string (val_w_null, &decimal128);
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
bson->bson_type_data.v_decimal128.value = decimal128;
} else {
goto BAD_PARSE;
}
} break;
case BSON_JSON_LF_CODE:
_bson_json_buf_set (&bson->code_data.code_buf, val, vlen);
break;
case BSON_JSON_LF_SYMBOL:
bson_append_symbol (
STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen);
break;
case BSON_JSON_LF_SCOPE:
case BSON_JSON_LF_TIMESTAMP_T:
case BSON_JSON_LF_TIMESTAMP_I:
case BSON_JSON_LF_UNDEFINED:
case BSON_JSON_LF_MINKEY:
case BSON_JSON_LF_MAXKEY:
case BSON_JSON_LF_DBPOINTER:
default:
goto BAD_PARSE;
}
return;
BAD_PARSE:
_bson_json_read_set_error (reader,
"Invalid input string \"%s\", looking for %s",
val_w_null,
bson_state_names[bs]);
} else {
_bson_json_read_set_error (
reader, "Invalid state to look for string: %s", read_state_names[rs]);
}
}
static void
_bson_json_read_start_map (bson_json_reader_t *reader) /* IN */
{
BASIC_CB_PREAMBLE;
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
- if (bson->bson_state == BSON_JSON_LF_DATE) {
+ switch (bson->bson_state) {
+ case BSON_JSON_LF_DATE:
bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG;
- } else if (bson->bson_state == BSON_JSON_LF_BINARY) {
+ break;
+ case BSON_JSON_LF_BINARY:
bson->read_state = BSON_JSON_IN_BSON_TYPE_BINARY_VALUES;
- } else if (bson->bson_state == BSON_JSON_LF_TYPE) {
+ break;
+ case BSON_JSON_LF_TYPE:
/* special case, we started parsing {$type: {$numberInt: "2"}} and we
* expected a legacy Binary format. now we see the second "{", so
* backtrack and parse $type query operator. */
bson->read_state = BSON_JSON_IN_START_MAP;
STACK_PUSH_DOC (bson_append_document_begin (
STACK_BSON_PARENT, key, len, STACK_BSON_CHILD));
_bson_json_save_map_key (bson, (const uint8_t *) "$type", 5);
+ break;
+ case BSON_JSON_LF_CODE:
+ case BSON_JSON_LF_DECIMAL128:
+ case BSON_JSON_LF_DOUBLE:
+ case BSON_JSON_LF_INT32:
+ case BSON_JSON_LF_INT64:
+ case BSON_JSON_LF_MAXKEY:
+ case BSON_JSON_LF_MINKEY:
+ case BSON_JSON_LF_OID:
+ case BSON_JSON_LF_OPTIONS:
+ case BSON_JSON_LF_REGEX:
+ /**
+ * NOTE: A read_state of BSON_JSON_IN_BSON_TYPE is used when "$regex" is
+ * found, but BSON_JSON_IN_BSON_TYPE_REGEX_STARTMAP is used for
+ * "$regularExpression", which will instead go to a below 'if else' branch
+ * instead of this switch statement. They're both called "regex" in their
+ * respective enumerators, but they behave differently when parsing.
+ */
+ // fallthrough
+ case BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS:
+ case BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN:
+ case BSON_JSON_LF_SYMBOL:
+ case BSON_JSON_LF_UNDEFINED:
+ case BSON_JSON_LF_UUID:
+ // These special keys do not expect objects as their values. Fail.
+ _bson_json_read_set_error (
+ reader,
+ "Unexpected nested object value for \"%s\" key",
+ reader->bson.unescaped.buf);
+ break;
+ case BSON_JSON_LF_DBPOINTER:
+ case BSON_JSON_LF_SCOPE:
+ case BSON_JSON_LF_TIMESTAMP_I:
+ case BSON_JSON_LF_TIMESTAMP_T:
+ default:
+ // These special LF keys aren't handled with BSON_JSON_IN_BSON_TYPE
+ BSON_UNREACHABLE (
+ "These LF values are handled with a different read_state");
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) {
bson->read_state = BSON_JSON_IN_SCOPE;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
bson->read_state = BSON_JSON_IN_DBPOINTER;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_STARTMAP) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_VALUES;
} else {
bson->read_state = BSON_JSON_IN_START_MAP;
}
/* silence some warnings */
(void) len;
(void) key;
}
static bool
_is_known_key (const char *key, size_t len)
{
bool ret;
#define IS_KEY(k) (len == strlen (k) && (0 == memcmp (k, key, len)))
ret = (IS_KEY ("$regularExpression") || IS_KEY ("$regex") ||
IS_KEY ("$options") || IS_KEY ("$code") || IS_KEY ("$scope") ||
IS_KEY ("$oid") || IS_KEY ("$binary") || IS_KEY ("$type") ||
IS_KEY ("$date") || IS_KEY ("$undefined") || IS_KEY ("$maxKey") ||
IS_KEY ("$minKey") || IS_KEY ("$timestamp") ||
IS_KEY ("$numberInt") || IS_KEY ("$numberLong") ||
IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") ||
IS_KEY ("$numberInt") || IS_KEY ("$numberLong") ||
IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") ||
IS_KEY ("$dbPointer") || IS_KEY ("$symbol") || IS_KEY ("$uuid"));
#undef IS_KEY
return ret;
}
static void
_bson_json_save_map_key (bson_json_reader_bson_t *bson,
const uint8_t *val,
size_t len)
{
_bson_json_buf_set (&bson->key_buf, val, len);
bson->key = (const char *) bson->key_buf.buf;
}
static void
_bson_json_read_code_or_scope_key (bson_json_reader_bson_t *bson,
bool is_scope,
const uint8_t *val,
size_t len)
{
bson_json_code_t *code = &bson->code_data;
if (code->in_scope) {
/* we're reading something weirdly nested, e.g. we just read "$code" in
* "$scope: {x: {$code: {}}}". just create the subdoc within the scope. */
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
bson->key,
(int) bson->key_buf.len,
STACK_BSON_CHILD));
_bson_json_save_map_key (bson, val, len);
} else {
if (!bson->code_data.key_buf.len) {
/* save the key, e.g. {"key": {"$code": "return x", "$scope":{"x":1}}},
* in case it is overwritten while parsing scope sub-object */
_bson_json_buf_set (
&bson->code_data.key_buf, bson->key_buf.buf, bson->key_buf.len);
}
if (is_scope) {
bson->bson_type = BSON_TYPE_CODEWSCOPE;
bson->read_state = BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP;
bson->bson_state = BSON_JSON_LF_SCOPE;
bson->code_data.has_scope = true;
} else {
bson->bson_type = BSON_TYPE_CODE;
bson->bson_state = BSON_JSON_LF_CODE;
bson->code_data.has_code = true;
}
}
}
static void
_bson_json_bad_key_in_type (bson_json_reader_t *reader, /* IN */
const uint8_t *val) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
_bson_json_read_set_error (
reader,
"Invalid key \"%s\". Looking for values for type \"%s\"",
val,
_bson_json_type_name (bson->bson_type));
}
static void
_bson_json_read_map_key (bson_json_reader_t *reader, /* IN */
const uint8_t *val, /* IN */
size_t len) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
if (!bson_utf8_validate ((const char *) val, len, false /* allow null */)) {
_bson_json_read_corrupt (reader, "invalid bytes in UTF8 string");
return;
}
if (bson->read_state == BSON_JSON_IN_START_MAP) {
if (len > 0 && val[0] == '$' && _is_known_key ((const char *) val, len) &&
bson->n >= 0 /* key is in subdocument */) {
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_type = (bson_type_t) 0;
memset (&bson->bson_type_data, 0, sizeof bson->bson_type_data);
} else {
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
bson->key,
(int) bson->key_buf.len,
STACK_BSON_CHILD));
}
} else if (bson->read_state == BSON_JSON_IN_SCOPE) {
/* we've read "key" in {$code: "", $scope: {key: ""}}*/
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_SCOPE;
_bson_json_save_map_key (bson, val, len);
} else if (bson->read_state == BSON_JSON_IN_DBPOINTER) {
/* we've read "$ref" or "$id" in {$dbPointer: {$ref: ..., $id: ...}} */
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DBPOINTER;
_bson_json_save_map_key (bson, val, len);
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
if
HANDLE_OPTION ("$regex", BSON_TYPE_REGEX, BSON_JSON_LF_REGEX)
else if
HANDLE_OPTION ("$options", BSON_TYPE_REGEX, BSON_JSON_LF_OPTIONS)
else if
HANDLE_OPTION ("$oid", BSON_TYPE_OID, BSON_JSON_LF_OID)
else if
HANDLE_OPTION ("$binary", BSON_TYPE_BINARY, BSON_JSON_LF_BINARY)
else if
HANDLE_OPTION ("$type", BSON_TYPE_BINARY, BSON_JSON_LF_TYPE)
else if
HANDLE_OPTION ("$uuid", BSON_TYPE_BINARY, BSON_JSON_LF_UUID)
else if
HANDLE_OPTION ("$date", BSON_TYPE_DATE_TIME, BSON_JSON_LF_DATE)
else if
HANDLE_OPTION (
"$undefined", BSON_TYPE_UNDEFINED, BSON_JSON_LF_UNDEFINED)
else if
HANDLE_OPTION ("$minKey", BSON_TYPE_MINKEY, BSON_JSON_LF_MINKEY)
else if
HANDLE_OPTION ("$maxKey", BSON_TYPE_MAXKEY, BSON_JSON_LF_MAXKEY)
else if
HANDLE_OPTION ("$numberInt", BSON_TYPE_INT32, BSON_JSON_LF_INT32)
else if
HANDLE_OPTION ("$numberLong", BSON_TYPE_INT64, BSON_JSON_LF_INT64)
else if
HANDLE_OPTION ("$numberDouble", BSON_TYPE_DOUBLE, BSON_JSON_LF_DOUBLE)
else if
HANDLE_OPTION ("$symbol", BSON_TYPE_SYMBOL, BSON_JSON_LF_SYMBOL)
else if
HANDLE_OPTION (
"$numberDecimal", BSON_TYPE_DECIMAL128, BSON_JSON_LF_DECIMAL128)
else if (!strcmp ("$timestamp", (const char *) val)) {
bson->bson_type = BSON_TYPE_TIMESTAMP;
bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP;
} else if (!strcmp ("$regularExpression", (const char *) val)) {
bson->bson_type = BSON_TYPE_REGEX;
bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_STARTMAP;
} else if (!strcmp ("$dbPointer", (const char *) val)) {
/* start parsing "key": {"$dbPointer": {...}}, save "key" for later */
_bson_json_buf_set (
&bson->dbpointer_key, bson->key_buf.buf, bson->key_buf.len);
bson->bson_type = BSON_TYPE_DBPOINTER;
bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP;
} else if (!strcmp ("$code", (const char *) val)) {
_bson_json_read_code_or_scope_key (
bson, false /* is_scope */, val, len);
} else if (!strcmp ("$scope", (const char *) val)) {
_bson_json_read_code_or_scope_key (
bson, true /* is_scope */, val, len);
} else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
if
HANDLE_OPTION ("$numberLong", BSON_TYPE_DATE_TIME, BSON_JSON_LF_INT64)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
if
HANDLE_OPTION ("t", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_T)
else if
HANDLE_OPTION ("i", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_I)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES) {
if
HANDLE_OPTION (
"pattern", BSON_TYPE_REGEX, BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN)
else if
HANDLE_OPTION (
"options", BSON_TYPE_REGEX, BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) {
if
HANDLE_OPTION ("base64", BSON_TYPE_BINARY, BSON_JSON_LF_BINARY)
else if
HANDLE_OPTION ("subType", BSON_TYPE_BINARY, BSON_JSON_LF_TYPE)
else {
_bson_json_bad_key_in_type (reader, val);
}
} else {
_bson_json_save_map_key (bson, val, len);
}
}
static void
_bson_json_read_append_binary (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_json_bson_data_t *data = &bson->bson_type_data;
if (data->binary.is_legacy) {
if (!data->binary.has_binary) {
_bson_json_read_set_error (
reader,
"Missing \"$binary\" after \"$type\" reading type \"binary\"");
return;
} else if (!data->binary.has_subtype) {
_bson_json_read_set_error (
reader,
"Missing \"$type\" after \"$binary\" reading type \"binary\"");
return;
}
} else {
if (!data->binary.has_binary) {
_bson_json_read_set_error (
reader,
"Missing \"base64\" after \"subType\" reading type \"binary\"");
return;
} else if (!data->binary.has_subtype) {
_bson_json_read_set_error (
reader,
"Missing \"subType\" after \"base64\" reading type \"binary\"");
return;
}
}
if (!bson_append_binary (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
data->binary.type,
bson->bson_type_buf[0].buf,
(uint32_t) bson->bson_type_buf[0].len)) {
_bson_json_read_set_error (reader, "Error storing binary data");
}
}
static void
_bson_json_read_append_regex (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_json_bson_data_t *data = &bson->bson_type_data;
if (data->regex.is_legacy) {
if (!data->regex.has_pattern) {
_bson_json_read_set_error (reader,
"Missing \"$regex\" after \"$options\"");
return;
}
} else if (!data->regex.has_pattern) {
_bson_json_read_set_error (
reader, "Missing \"pattern\" after \"options\" in regular expression");
return;
} else if (!data->regex.has_options) {
_bson_json_read_set_error (
reader, "Missing \"options\" after \"pattern\" in regular expression");
return;
}
if (!bson_append_regex (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
(char *) bson->bson_type_buf[0].buf,
(char *) bson->bson_type_buf[1].buf)) {
_bson_json_read_set_error (reader, "Error storing regex");
}
}
static void
_bson_json_read_append_code (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_json_code_t *code_data;
char *code = NULL;
bson_t *scope = NULL;
bool r;
code_data = &bson->code_data;
BSON_ASSERT (!code_data->in_scope);
if (!code_data->has_code) {
_bson_json_read_set_error (reader, "Missing $code after $scope");
return;
}
code = (char *) code_data->code_buf.buf;
if (code_data->has_scope) {
scope = STACK_BSON (1);
}
/* creates BSON "code" elem, or "code with scope" if scope is not NULL */
r = bson_append_code_with_scope (STACK_BSON_CHILD,
(const char *) code_data->key_buf.buf,
(int) code_data->key_buf.len,
code,
scope);
if (!r) {
_bson_json_read_set_error (reader, "Error storing Javascript code");
}
/* keep the buffer but truncate it */
code_data->key_buf.len = 0;
code_data->has_code = code_data->has_scope = false;
}
static void
_bson_json_read_append_dbpointer (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
bson_t *db_pointer;
bson_iter_t iter;
const char *ns = NULL;
const bson_oid_t *oid = NULL;
bool r;
BSON_ASSERT (reader->bson.dbpointer_key.buf);
db_pointer = STACK_BSON (1);
if (!bson_iter_init (&iter, db_pointer)) {
_bson_json_read_set_error (reader, "Error storing DBPointer");
return;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "$id")) {
if (!BSON_ITER_HOLDS_OID (&iter)) {
_bson_json_read_set_error (
reader, "$dbPointer.$id must be like {\"$oid\": ...\"}");
return;
}
oid = bson_iter_oid (&iter);
} else if (!strcmp (bson_iter_key (&iter), "$ref")) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
_bson_json_read_set_error (
reader,
"$dbPointer.$ref must be a string like \"db.collection\"");
return;
}
ns = bson_iter_utf8 (&iter, NULL);
} else {
_bson_json_read_set_error (reader,
"$dbPointer contains invalid key: \"%s\"",
bson_iter_key (&iter));
return;
}
}
if (!oid || !ns) {
_bson_json_read_set_error (reader,
"$dbPointer requires both $id and $ref");
return;
}
r = bson_append_dbpointer (STACK_BSON_CHILD,
(char *) reader->bson.dbpointer_key.buf,
(int) reader->bson.dbpointer_key.len,
ns,
oid);
if (!r) {
_bson_json_read_set_error (reader, "Error storing DBPointer");
}
}
static void
_bson_json_read_append_oid (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
if (!bson_append_oid (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
&bson->bson_type_data.oid.oid)) {
_bson_json_read_set_error (reader, "Error storing ObjectId");
}
}
static void
_bson_json_read_append_date_time (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
if (!bson_append_date_time (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.date.date)) {
_bson_json_read_set_error (reader, "Error storing datetime");
}
}
static void
_bson_json_read_append_timestamp (bson_json_reader_t *reader, /* IN */
bson_json_reader_bson_t *bson) /* IN */
{
if (!bson->bson_type_data.timestamp.has_t) {
_bson_json_read_set_error (
reader, "Missing t after $timestamp in BSON_TYPE_TIMESTAMP");
return;
} else if (!bson->bson_type_data.timestamp.has_i) {
_bson_json_read_set_error (
reader, "Missing i after $timestamp in BSON_TYPE_TIMESTAMP");
return;
}
bson_append_timestamp (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.timestamp.t,
bson->bson_type_data.timestamp.i);
}
static void
_bad_extended_json (bson_json_reader_t *reader)
{
_bson_json_read_corrupt (reader, "Invalid MongoDB extended JSON");
}
static void
_bson_json_read_end_map (bson_json_reader_t *reader) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
bool r = true;
if (bson->read_state == BSON_JSON_IN_START_MAP) {
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
bson->key,
(int) bson->key_buf.len,
STACK_BSON_CHILD));
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) {
bson->read_state = BSON_JSON_REGULAR;
STACK_PUSH_SCOPE;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
/* we've read last "}" in "{$dbPointer: {$id: ..., $ref: ...}}" */
_bson_json_read_append_dbpointer (reader, bson);
bson->read_state = BSON_JSON_REGULAR;
return;
}
if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
if (!bson->key) {
/* invalid, like {$numberLong: "1"} at the document top level */
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_REGULAR;
switch (bson->bson_type) {
case BSON_TYPE_REGEX:
_bson_json_read_append_regex (reader, bson);
break;
case BSON_TYPE_CODE:
case BSON_TYPE_CODEWSCOPE:
/* we've read the closing "}" in "{$code: ..., $scope: ...}" */
_bson_json_read_append_code (reader, bson);
break;
case BSON_TYPE_OID:
_bson_json_read_append_oid (reader, bson);
break;
case BSON_TYPE_BINARY:
_bson_json_read_append_binary (reader, bson);
break;
case BSON_TYPE_DATE_TIME:
_bson_json_read_append_date_time (reader, bson);
break;
case BSON_TYPE_UNDEFINED:
r = bson_append_undefined (
STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
break;
case BSON_TYPE_MINKEY:
r = bson_append_minkey (
STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
break;
case BSON_TYPE_MAXKEY:
r = bson_append_maxkey (
STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
break;
case BSON_TYPE_INT32:
r = bson_append_int32 (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.v_int32.value);
break;
case BSON_TYPE_INT64:
r = bson_append_int64 (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.v_int64.value);
break;
case BSON_TYPE_DOUBLE:
r = bson_append_double (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
bson->bson_type_data.v_double.value);
break;
case BSON_TYPE_DECIMAL128:
r = bson_append_decimal128 (STACK_BSON_CHILD,
bson->key,
(int) bson->key_buf.len,
&bson->bson_type_data.v_decimal128.value);
break;
case BSON_TYPE_DBPOINTER:
/* shouldn't set type to DBPointer unless inside $dbPointer: {...} */
_bson_json_read_set_error (
reader,
"Internal error: shouldn't be in state BSON_TYPE_DBPOINTER");
break;
case BSON_TYPE_SYMBOL:
break;
case BSON_TYPE_EOD:
case BSON_TYPE_UTF8:
case BSON_TYPE_DOCUMENT:
case BSON_TYPE_ARRAY:
case BSON_TYPE_BOOL:
case BSON_TYPE_NULL:
case BSON_TYPE_TIMESTAMP:
default:
_bson_json_read_set_error (
reader,
"Internal error: can't parse JSON wrapper for type \"%s\"",
_bson_json_type_name (bson->bson_type));
break;
}
if (!r) {
_bson_json_read_set_error (
reader,
"Cannot append value at end of JSON object for key %s",
bson->key);
}
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP;
_bson_json_read_append_timestamp (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_ENDMAP;
_bson_json_read_append_regex (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_BINARY_ENDMAP;
_bson_json_read_append_binary (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
if (!bson->key) {
_bad_extended_json (reader);
return;
}
bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP;
_bson_json_read_append_date_time (reader, bson);
return;
} else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP) {
bson->read_state = BSON_JSON_REGULAR;
} else if (bson->read_state == BSON_JSON_REGULAR) {
if (STACK_IS_SCOPE) {
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_type = BSON_TYPE_CODE;
STACK_POP_SCOPE;
} else if (STACK_IS_DBPOINTER) {
bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP;
STACK_POP_DBPOINTER;
} else {
STACK_POP_DOC (
bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
}
if (bson->n == -1) {
bson->read_state = BSON_JSON_DONE;
}
} else if (bson->read_state == BSON_JSON_IN_SCOPE) {
/* empty $scope */
BSON_ASSERT (bson->code_data.has_scope);
STACK_PUSH_SCOPE;
STACK_POP_SCOPE;
bson->read_state = BSON_JSON_IN_BSON_TYPE;
bson->bson_type = BSON_TYPE_CODE;
} else if (bson->read_state == BSON_JSON_IN_DBPOINTER) {
/* empty $dbPointer??? */
_bson_json_read_set_error (reader, "Empty $dbPointer");
} else {
_bson_json_read_set_error (
reader, "Invalid state \"%s\"", read_state_names[bson->read_state]);
}
}
static void
_bson_json_read_start_array (bson_json_reader_t *reader) /* IN */
{
const char *key;
size_t len;
bson_json_reader_bson_t *bson = &reader->bson;
if (bson->read_state != BSON_JSON_REGULAR) {
_bson_json_read_set_error (reader,
"Invalid read of \"[\" in state \"%s\"",
read_state_names[bson->read_state]);
return;
}
if (bson->n == -1) {
STACK_PUSH_ARRAY (_noop ());
} else {
_bson_json_read_fixup_key (bson);
key = bson->key;
len = bson->key_buf.len;
STACK_PUSH_ARRAY (bson_append_array_begin (
STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD));
}
}
static void
_bson_json_read_end_array (bson_json_reader_t *reader) /* IN */
{
bson_json_reader_bson_t *bson = &reader->bson;
if (bson->read_state != BSON_JSON_REGULAR) {
_bson_json_read_set_error (reader,
"Invalid read of \"]\" in state \"%s\"",
read_state_names[bson->read_state]);
return;
}
STACK_POP_ARRAY (
bson_append_array_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
if (bson->n == -1) {
bson->read_state = BSON_JSON_DONE;
}
}
/* put unescaped text in reader->bson.unescaped, or set reader->error.
* json_text has length len and it is not null-terminated. */
static bool
_bson_json_unescape (bson_json_reader_t *reader,
struct jsonsl_state_st *state,
const char *json_text,
ssize_t len)
{
bson_json_reader_bson_t *reader_bson;
jsonsl_error_t err;
reader_bson = &reader->bson;
/* add 1 for NULL */
_bson_json_buf_ensure (&reader_bson->unescaped, (size_t) len + 1);
/* length of unescaped str is always <= len */
reader_bson->unescaped.len = jsonsl_util_unescape (
json_text, (char *) reader_bson->unescaped.buf, (size_t) len, NULL, &err);
if (err != JSONSL_ERROR_SUCCESS) {
bson_set_error (reader->error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_CORRUPT_JS,
"error near position %d: \"%s\"",
(int) state->pos_begin,
jsonsl_strerror (err));
return false;
}
reader_bson->unescaped.buf[reader_bson->unescaped.len] = '\0';
return true;
}
/* read the buffered JSON plus new data, and fill out @len with its length */
static const char *
_get_json_text (jsonsl_t json, /* IN */
struct jsonsl_state_st *state, /* IN */
const char *buf /* IN */,
ssize_t *len /* OUT */)
{
bson_json_reader_t *reader;
ssize_t bytes_available;
reader = (bson_json_reader_t *) json->data;
BSON_ASSERT (state->pos_cur > state->pos_begin);
*len = (ssize_t) (state->pos_cur - state->pos_begin);
bytes_available = buf - json->base;
if (*len <= bytes_available) {
/* read directly from stream, not from saved JSON */
return buf - (size_t) *len;
} else {
/* combine saved text with new data from the jsonsl_t */
ssize_t append = buf - json->base;
if (append > 0) {
_bson_json_buf_append (
&reader->tok_accumulator, buf - append, (size_t) append);
}
return (const char *) reader->tok_accumulator.buf;
}
}
static void
_push_callback (jsonsl_t json,
jsonsl_action_t action,
struct jsonsl_state_st *state,
const char *buf)
{
bson_json_reader_t *reader = (bson_json_reader_t *) json->data;
switch (state->type) {
case JSONSL_T_STRING:
case JSONSL_T_HKEY:
case JSONSL_T_SPECIAL:
case JSONSL_T_UESCAPE:
reader->json_text_pos = state->pos_begin;
break;
case JSONSL_T_OBJECT:
_bson_json_read_start_map (reader);
break;
case JSONSL_T_LIST:
_bson_json_read_start_array (reader);
break;
default:
break;
}
}
static void
_pop_callback (jsonsl_t json,
jsonsl_action_t action,
struct jsonsl_state_st *state,
const char *buf)
{
bson_json_reader_t *reader;
bson_json_reader_bson_t *reader_bson;
ssize_t len;
double d;
const char *obj_text;
reader = (bson_json_reader_t *) json->data;
reader_bson = &reader->bson;
switch (state->type) {
case JSONSL_T_HKEY:
case JSONSL_T_STRING:
obj_text = _get_json_text (json, state, buf, &len);
BSON_ASSERT (obj_text[0] == '"');
/* remove start/end quotes, replace backslash-escapes, null-terminate */
/* you'd think it would be faster to check if state->nescapes > 0 first,
* but tests show no improvement */
if (!_bson_json_unescape (reader, state, obj_text + 1, len - 1)) {
/* reader->error is set */
jsonsl_stop (json);
break;
}
if (state->type == JSONSL_T_HKEY) {
_bson_json_read_map_key (
reader, reader_bson->unescaped.buf, reader_bson->unescaped.len);
} else {
_bson_json_read_string (
reader, reader_bson->unescaped.buf, reader_bson->unescaped.len);
}
break;
case JSONSL_T_OBJECT:
_bson_json_read_end_map (reader);
break;
case JSONSL_T_LIST:
_bson_json_read_end_array (reader);
break;
case JSONSL_T_SPECIAL:
obj_text = _get_json_text (json, state, buf, &len);
if (state->special_flags & JSONSL_SPECIALf_NUMNOINT) {
if (_bson_json_parse_double (reader, obj_text, (size_t) len, &d)) {
_bson_json_read_double (reader, d);
}
} else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
/* jsonsl puts the unsigned value in state->nelem */
_bson_json_read_integer (
reader,
state->nelem,
state->special_flags & JSONSL_SPECIALf_SIGNED ? -1 : 1);
} else if (state->special_flags & JSONSL_SPECIALf_BOOLEAN) {
_bson_json_read_boolean (reader, obj_text[0] == 't' ? 1 : 0);
} else if (state->special_flags & JSONSL_SPECIALf_NULL) {
_bson_json_read_null (reader);
}
break;
default:
break;
}
reader->json_text_pos = -1;
reader->tok_accumulator.len = 0;
}
static int
_error_callback (jsonsl_t json,
jsonsl_error_t err,
struct jsonsl_state_st *state,
char *errat)
{
bson_json_reader_t *reader = (bson_json_reader_t *) json->data;
if (err == JSONSL_ERROR_CANT_INSERT && *errat == '{') {
/* start the next document */
reader->should_reset = true;
reader->advance = errat - json->base;
return 0;
}
bson_set_error (reader->error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_CORRUPT_JS,
"Got parse error at \"%c\", position %d: \"%s\"",
*errat,
(int) json->pos,
jsonsl_strerror (err));
return 0;
}
/*
*--------------------------------------------------------------------------
*
* bson_json_reader_read --
*
* Read the next json document from @reader and write its value
* into @bson. @bson will be allocated as part of this process.
*
* @bson MUST be initialized before calling this function as it
* will not be initialized automatically. The reasoning for this
* is so that you can chain together bson_json_reader_t with
* other components like bson_writer_t.
*
* Returns:
* 1 if successful and data was read.
* 0 if successful and no data was read.
* -1 if there was an error and @error is set.
*
* Side effects:
* @error may be set.
*
*--------------------------------------------------------------------------
*/
int
bson_json_reader_read (bson_json_reader_t *reader, /* IN */
bson_t *bson, /* IN */
bson_error_t *error) /* OUT */
{
bson_json_reader_producer_t *p;
ssize_t start_pos;
ssize_t r;
ssize_t buf_offset;
ssize_t accum;
bson_error_t error_tmp;
int ret = 0;
BSON_ASSERT (reader);
BSON_ASSERT (bson);
p = &reader->producer;
reader->bson.bson = bson;
reader->bson.n = -1;
reader->bson.read_state = BSON_JSON_REGULAR;
reader->error = error ? error : &error_tmp;
memset (reader->error, 0, sizeof (bson_error_t));
for (;;) {
start_pos = reader->json->pos;
if (p->bytes_read > 0) {
/* leftover data from previous JSON doc in the stream */
r = p->bytes_read;
} else {
/* read a chunk of bytes by executing the callback */
r = p->cb (p->data, p->buf, p->buf_size);
}
if (r < 0) {
if (error) {
bson_set_error (error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_CB_FAILURE,
"reader cb failed");
}
ret = -1;
goto cleanup;
} else if (r == 0) {
break;
} else {
ret = 1;
p->bytes_read = (size_t) r;
jsonsl_feed (reader->json, (const jsonsl_char_t *) p->buf, (size_t) r);
if (reader->should_reset) {
/* end of a document */
jsonsl_reset (reader->json);
reader->should_reset = false;
/* advance past already-parsed data */
memmove (p->buf, p->buf + reader->advance, r - reader->advance);
p->bytes_read -= reader->advance;
ret = 1;
goto cleanup;
}
if (reader->error->domain) {
ret = -1;
goto cleanup;
}
/* accumulate a key or string value */
if (reader->json_text_pos != -1) {
if (reader->json_text_pos < reader->json->pos) {
accum = BSON_MIN (reader->json->pos - reader->json_text_pos, r);
/* if this chunk stopped mid-token, buf_offset is how far into
* our current chunk the token begins. */
buf_offset = AT_LEAST_0 (reader->json_text_pos - start_pos);
_bson_json_buf_append (&reader->tok_accumulator,
p->buf + buf_offset,
(size_t) accum);
}
}
p->bytes_read = 0;
}
}
cleanup:
if (ret == 1 && reader->bson.read_state != BSON_JSON_DONE) {
/* data ended in the middle */
_bson_json_read_corrupt (reader, "%s", "Incomplete JSON");
return -1;
}
return ret;
}
bson_json_reader_t *
bson_json_reader_new (void *data, /* IN */
bson_json_reader_cb cb, /* IN */
bson_json_destroy_cb dcb, /* IN */
bool allow_multiple, /* unused */
size_t buf_size) /* IN */
{
bson_json_reader_t *r;
bson_json_reader_producer_t *p;
r = bson_malloc0 (sizeof *r);
r->json = jsonsl_new (STACK_MAX);
r->json->error_callback = _error_callback;
r->json->action_callback_PUSH = _push_callback;
r->json->action_callback_POP = _pop_callback;
r->json->data = r;
r->json_text_pos = -1;
jsonsl_enable_all_callbacks (r->json);
p = &r->producer;
p->data = data;
p->cb = cb;
p->dcb = dcb;
p->buf_size = buf_size ? buf_size : BSON_JSON_DEFAULT_BUF_SIZE;
p->buf = bson_malloc (p->buf_size);
return r;
}
void
bson_json_reader_destroy (bson_json_reader_t *reader) /* IN */
{
int i;
bson_json_reader_producer_t *p;
bson_json_reader_bson_t *b;
if (!reader) {
return;
}
p = &reader->producer;
b = &reader->bson;
if (reader->producer.dcb) {
reader->producer.dcb (reader->producer.data);
}
bson_free (p->buf);
bson_free (b->key_buf.buf);
bson_free (b->unescaped.buf);
bson_free (b->dbpointer_key.buf);
/* destroy each bson_t initialized in parser stack frames */
for (i = 1; i < STACK_MAX; i++) {
if (b->stack[i].type == BSON_JSON_FRAME_INITIAL) {
/* highest the stack grew */
break;
}
if (FRAME_TYPE_HAS_BSON (b->stack[i].type)) {
bson_destroy (&b->stack[i].bson);
}
}
for (i = 0; i < 3; i++) {
bson_free (b->bson_type_buf[i].buf);
}
_bson_json_code_cleanup (&b->code_data);
jsonsl_destroy (reader->json);
bson_free (reader->tok_accumulator.buf);
bson_free (reader);
}
typedef struct {
const uint8_t *data;
size_t len;
size_t bytes_parsed;
} bson_json_data_reader_t;
static ssize_t
_bson_json_data_reader_cb (void *_ctx, uint8_t *buf, size_t len)
{
size_t bytes;
bson_json_data_reader_t *ctx = (bson_json_data_reader_t *) _ctx;
if (!ctx->data) {
return -1;
}
bytes = BSON_MIN (len, ctx->len - ctx->bytes_parsed);
memcpy (buf, ctx->data + ctx->bytes_parsed, bytes);
ctx->bytes_parsed += bytes;
return bytes;
}
bson_json_reader_t *
bson_json_data_reader_new (bool allow_multiple, /* IN */
size_t size) /* IN */
{
bson_json_data_reader_t *dr = bson_malloc0 (sizeof *dr);
return bson_json_reader_new (
dr, &_bson_json_data_reader_cb, &bson_free, allow_multiple, size);
}
void
bson_json_data_reader_ingest (bson_json_reader_t *reader, /* IN */
const uint8_t *data, /* IN */
size_t len) /* IN */
{
bson_json_data_reader_t *ctx =
(bson_json_data_reader_t *) reader->producer.data;
ctx->data = data;
ctx->len = len;
ctx->bytes_parsed = 0;
}
bson_t *
bson_new_from_json (const uint8_t *data, /* IN */
ssize_t len, /* IN */
bson_error_t *error) /* OUT */
{
bson_json_reader_t *reader;
bson_t *bson;
int r;
BSON_ASSERT (data);
if (len < 0) {
len = (ssize_t) strlen ((const char *) data);
}
bson = bson_new ();
reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE);
bson_json_data_reader_ingest (reader, data, len);
r = bson_json_reader_read (reader, bson, error);
bson_json_reader_destroy (reader);
if (r == 0) {
bson_set_error (error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_INVALID_PARAM,
"Empty JSON string");
}
if (r != 1) {
bson_destroy (bson);
return NULL;
}
return bson;
}
bool
bson_init_from_json (bson_t *bson, /* OUT */
const char *data, /* IN */
ssize_t len, /* IN */
bson_error_t *error) /* OUT */
{
bson_json_reader_t *reader;
int r;
BSON_ASSERT (bson);
BSON_ASSERT (data);
if (len < 0) {
len = strlen (data);
}
bson_init (bson);
reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE);
bson_json_data_reader_ingest (reader, (const uint8_t *) data, len);
r = bson_json_reader_read (reader, bson, error);
bson_json_reader_destroy (reader);
if (r == 0) {
bson_set_error (error,
BSON_ERROR_JSON,
BSON_JSON_ERROR_READ_INVALID_PARAM,
"Empty JSON string");
}
if (r != 1) {
bson_destroy (bson);
return false;
}
return true;
}
static void
_bson_json_reader_handle_fd_destroy (void *handle) /* IN */
{
bson_json_reader_handle_fd_t *fd = handle;
if (fd) {
if ((fd->fd != -1) && fd->do_close) {
#ifdef _WIN32
_close (fd->fd);
#else
close (fd->fd);
#endif
}
bson_free (fd);
}
}
static ssize_t
_bson_json_reader_handle_fd_read (void *handle, /* IN */
uint8_t *buf, /* IN */
size_t len) /* IN */
{
bson_json_reader_handle_fd_t *fd = handle;
ssize_t ret = -1;
if (fd && (fd->fd != -1)) {
again:
#ifdef BSON_OS_WIN32
ret = _read (fd->fd, buf, (unsigned int) len);
#else
ret = read (fd->fd, buf, len);
#endif
if ((ret == -1) && (errno == EAGAIN)) {
goto again;
}
}
return ret;
}
bson_json_reader_t *
bson_json_reader_new_from_fd (int fd, /* IN */
bool close_on_destroy) /* IN */
{
bson_json_reader_handle_fd_t *handle;
BSON_ASSERT (fd != -1);
handle = bson_malloc0 (sizeof *handle);
handle->fd = fd;
handle->do_close = close_on_destroy;
return bson_json_reader_new (handle,
_bson_json_reader_handle_fd_read,
_bson_json_reader_handle_fd_destroy,
true,
BSON_JSON_DEFAULT_BUF_SIZE);
}
bson_json_reader_t *
bson_json_reader_new_from_file (const char *path, /* IN */
bson_error_t *error) /* OUT */
{
char errmsg_buf[BSON_ERROR_BUFFER_SIZE];
char *errmsg;
int fd = -1;
BSON_ASSERT (path);
#ifdef BSON_OS_WIN32
_sopen_s (&fd, path, (_O_RDONLY | _O_BINARY), _SH_DENYNO, _S_IREAD);
#else
fd = open (path, O_RDONLY);
#endif
if (fd == -1) {
errmsg = bson_strerror_r (errno, errmsg_buf, sizeof errmsg_buf);
bson_set_error (
error, BSON_ERROR_READER, BSON_ERROR_READER_BADFD, "%s", errmsg);
return NULL;
}
return bson_json_reader_new_from_fd (fd, true);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-json.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-json.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-json.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-json.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-keys.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-keys.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-keys.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-keys.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-keys.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-keys.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-keys.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-keys.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-macros.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-macros.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-macros.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-macros.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-md5.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-md5.c
similarity index 64%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-md5.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-md5.c
index 36377314..71d7a54c 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-md5.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-md5.c
@@ -1,24 +1,24 @@
#include "bson-compat.h"
#include "bson-md5.h"
#include "common-md5-private.h"
void
bson_md5_init (bson_md5_t *pms)
{
- COMMON_PREFIX (_bson_md5_init (pms));
+ mcommon_md5_init (pms);
}
void
bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes)
{
- COMMON_PREFIX (_bson_md5_append (pms, data, nbytes));
+ mcommon_md5_append (pms, data, nbytes);
}
void
bson_md5_finish (bson_md5_t *pms, uint8_t digest[16])
{
- COMMON_PREFIX (_bson_md5_finish (pms, digest));
+ mcommon_md5_finish (pms, digest);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-md5.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-md5.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-md5.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-md5.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-memory.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-memory.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-memory.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-memory.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-memory.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-memory.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-memory.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-memory.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-oid.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-oid.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-oid.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-oid.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-oid.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-oid.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-oid.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-oid.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-prelude.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-prelude.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-prelude.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-prelude.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-private.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-reader.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-reader.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-reader.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-reader.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-reader.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-reader.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-reader.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-reader.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-string.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-string.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-string.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-string.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-string.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-string.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-string.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-string.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-timegm-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-timegm.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-timegm.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-timegm.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-timegm.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-types.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-types.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-types.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-types.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-utf8.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-utf8.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-utf8.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-utf8.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-utf8.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-utf8.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-utf8.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-utf8.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-value.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-value.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-value.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-value.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-value.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-value.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-value.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-value.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version-functions.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version.h
similarity index 94%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version.h
index dec6ad95..c1a8ceab 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version.h
@@ -1,101 +1,101 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION)
#error "Only <bson/bson.h> can be included directly."
#endif
#ifndef BSON_VERSION_H
#define BSON_VERSION_H
/**
* BSON_MAJOR_VERSION:
*
* BSON major version component (e.g. 1 if %BSON_VERSION is 1.2.3)
*/
#define BSON_MAJOR_VERSION (1)
/**
* BSON_MINOR_VERSION:
*
* BSON minor version component (e.g. 2 if %BSON_VERSION is 1.2.3)
*/
-#define BSON_MINOR_VERSION (21)
+#define BSON_MINOR_VERSION (22)
/**
* BSON_MICRO_VERSION:
*
* BSON micro version component (e.g. 3 if %BSON_VERSION is 1.2.3)
*/
-#define BSON_MICRO_VERSION (1)
+#define BSON_MICRO_VERSION (0)
/**
* BSON_PRERELEASE_VERSION:
*
* BSON prerelease version component (e.g. pre if %BSON_VERSION is 1.2.3-pre)
*/
#define BSON_PRERELEASE_VERSION ()
/**
* BSON_VERSION:
*
* BSON version.
*/
-#define BSON_VERSION (1.21.1)
+#define BSON_VERSION (1.22.0)
/**
* BSON_VERSION_S:
*
* BSON version, encoded as a string, useful for printing and
* concatenation.
*/
-#define BSON_VERSION_S "1.21.1"
+#define BSON_VERSION_S "1.22.0"
/**
* BSON_VERSION_HEX:
*
* BSON version, encoded as an hexadecimal number, useful for
* integer comparisons.
*/
#define BSON_VERSION_HEX (BSON_MAJOR_VERSION << 24 | \
BSON_MINOR_VERSION << 16 | \
BSON_MICRO_VERSION << 8)
/**
* BSON_CHECK_VERSION:
* @major: required major version
* @minor: required minor version
* @micro: required micro version
*
* Compile-time version checking. Evaluates to %TRUE if the version
* of BSON is greater than the required one.
*/
#define BSON_CHECK_VERSION(major,minor,micro) \
(BSON_MAJOR_VERSION > (major) || \
(BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION > (minor)) || \
(BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION == (minor) && \
BSON_MICRO_VERSION >= (micro)))
#endif /* BSON_VERSION_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version.h.in b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version.h.in
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-version.h.in
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-version.h.in
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-writer.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-writer.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-writer.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-writer.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-writer.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-writer.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson-writer.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson-writer.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson.c
index c4b8d4fc..5af710e4 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson.c
@@ -1,3594 +1,3593 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson.h"
#include "bson-config.h"
#include "bson-private.h"
#include "bson-json-private.h"
#include "bson-string.h"
#include "bson-iso8601-private.h"
#include "common-b64-private.h"
#include <string.h>
#include <math.h>
#ifndef BSON_MAX_RECURSION
#define BSON_MAX_RECURSION 200
#endif
typedef enum {
BSON_VALIDATE_PHASE_START,
BSON_VALIDATE_PHASE_TOP,
BSON_VALIDATE_PHASE_LF_REF_KEY,
BSON_VALIDATE_PHASE_LF_REF_UTF8,
BSON_VALIDATE_PHASE_LF_ID_KEY,
BSON_VALIDATE_PHASE_LF_DB_KEY,
BSON_VALIDATE_PHASE_LF_DB_UTF8,
BSON_VALIDATE_PHASE_NOT_DBREF,
} bson_validate_phase_t;
/*
* Structures.
*/
typedef struct {
bson_validate_flags_t flags;
ssize_t err_offset;
bson_validate_phase_t phase;
bson_error_t error;
} bson_validate_state_t;
typedef struct {
uint32_t count;
bool keys;
ssize_t *err_offset;
uint32_t depth;
bson_string_t *str;
bson_json_mode_t mode;
int32_t max_len;
bool max_len_reached;
} bson_json_state_t;
/*
* Forward declarations.
*/
static bool
_bson_as_json_visit_array (const bson_iter_t *iter,
const char *key,
const bson_t *v_array,
void *data);
static bool
_bson_as_json_visit_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data);
static char *
_bson_as_json_visit_all (const bson_t *bson,
size_t *length,
bson_json_mode_t mode,
int32_t max_len);
/*
* Globals.
*/
static const uint8_t gZero;
/*
*--------------------------------------------------------------------------
*
* _bson_impl_inline_grow --
*
* Document growth implementation for documents that currently
* contain stack based buffers. The document may be switched to
* a malloc based buffer.
*
* Returns:
* true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_impl_inline_grow (bson_impl_inline_t *impl, /* IN */
size_t size) /* IN */
{
bson_impl_alloc_t *alloc = (bson_impl_alloc_t *) impl;
uint8_t *data;
size_t req;
if (((size_t) impl->len + size) <= sizeof impl->data) {
return true;
}
req = bson_next_power_of_two (impl->len + size);
if (req <= BSON_MAX_SIZE) {
data = bson_malloc (req);
memcpy (data, impl->data, impl->len);
#ifdef BSON_MEMCHECK
bson_free (impl->canary);
#endif
alloc->flags &= ~BSON_FLAG_INLINE;
alloc->parent = NULL;
alloc->depth = 0;
alloc->buf = &alloc->alloc;
alloc->buflen = &alloc->alloclen;
alloc->offset = 0;
alloc->alloc = data;
alloc->alloclen = req;
alloc->realloc = bson_realloc_ctx;
alloc->realloc_func_ctx = NULL;
return true;
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* _bson_impl_alloc_grow --
*
* Document growth implementation for documents containing malloc
* based buffers.
*
* Returns:
* true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_impl_alloc_grow (bson_impl_alloc_t *impl, /* IN */
size_t size) /* IN */
{
size_t req;
/*
* Determine how many bytes we need for this document in the buffer
* including necessary trailing bytes for parent documents.
*/
req = (impl->offset + impl->len + size + impl->depth);
if (req <= *impl->buflen) {
return true;
}
req = bson_next_power_of_two (req);
if ((req <= BSON_MAX_SIZE) && impl->realloc) {
*impl->buf = impl->realloc (*impl->buf, req, impl->realloc_func_ctx);
*impl->buflen = req;
return true;
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* _bson_grow --
*
* Grows the bson_t structure to be large enough to contain @size
* bytes.
*
* Returns:
* true if successful, false if the size would overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_grow (bson_t *bson, /* IN */
uint32_t size) /* IN */
{
if ((bson->flags & BSON_FLAG_INLINE)) {
return _bson_impl_inline_grow ((bson_impl_inline_t *) bson, size);
}
return _bson_impl_alloc_grow ((bson_impl_alloc_t *) bson, size);
}
/*
*--------------------------------------------------------------------------
*
* _bson_data --
*
* A helper function to return the contents of the bson document
* taking into account the polymorphic nature of bson_t.
*
* Returns:
* A buffer which should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE uint8_t *
_bson_data (const bson_t *bson) /* IN */
{
if ((bson->flags & BSON_FLAG_INLINE)) {
return ((bson_impl_inline_t *) bson)->data;
} else {
bson_impl_alloc_t *impl = (bson_impl_alloc_t *) bson;
return (*impl->buf) + impl->offset;
}
}
/*
*--------------------------------------------------------------------------
*
* _bson_encode_length --
*
* Helper to encode the length of the bson_t in the first 4 bytes
* of the bson document. Little endian format is used as specified
* by bsonspec.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE void
_bson_encode_length (bson_t *bson) /* IN */
{
#if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN
memcpy (_bson_data (bson), &bson->len, sizeof (bson->len));
#else
uint32_t length_le = BSON_UINT32_TO_LE (bson->len);
memcpy (_bson_data (bson), &length_le, sizeof (length_le));
#endif
}
/*
*--------------------------------------------------------------------------
*
* _bson_append_va --
*
* Appends the length,buffer pairs to the bson_t. @n_bytes is an
* optimization to perform one array growth rather than many small
* growths.
*
* @bson: A bson_t
* @n_bytes: The number of bytes to append to the document.
* @n_pairs: The number of length,buffer pairs.
* @first_len: Length of first buffer.
* @first_data: First buffer.
* @args: va_list of additional tuples.
*
* Returns:
* true if the bytes were appended successfully.
* false if it bson would overflow BSON_MAX_SIZE.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE bool
_bson_append_va (bson_t *bson, /* IN */
uint32_t n_bytes, /* IN */
uint32_t n_pairs, /* IN */
uint32_t first_len, /* IN */
const uint8_t *first_data, /* IN */
va_list args) /* IN */
{
const uint8_t *data;
uint32_t data_len;
uint8_t *buf;
BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD));
BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY));
if (BSON_UNLIKELY (!_bson_grow (bson, n_bytes))) {
return false;
}
data = first_data;
data_len = first_len;
buf = _bson_data (bson) + bson->len - 1;
do {
n_pairs--;
/* data may be NULL if data_len is 0. memcpy is not safe to call with
* NULL. */
if (BSON_LIKELY (data_len != 0 && data != NULL)) {
memcpy (buf, data, data_len);
bson->len += data_len;
buf += data_len;
} else if (BSON_UNLIKELY (data_len != 0 && data == NULL)) {
/* error, user appending NULL with non-zero length. */
return false;
}
if (n_pairs) {
data_len = va_arg (args, uint32_t);
data = va_arg (args, const uint8_t *);
}
} while (n_pairs);
_bson_encode_length (bson);
*buf = '\0';
return true;
}
/*
*--------------------------------------------------------------------------
*
* _bson_append --
*
* Variadic function to append length,buffer pairs to a bson_t. If the
* append would cause the bson_t to overflow a 32-bit length, it will
* return false and no append will have occurred.
*
* Parameters:
* @bson: A bson_t.
* @n_pairs: Number of length,buffer pairs.
* @n_bytes: the total number of bytes being appended.
* @first_len: Length of first buffer.
* @first_data: First buffer.
*
* Returns:
* true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_append (bson_t *bson, /* IN */
uint32_t n_pairs, /* IN */
uint32_t n_bytes, /* IN */
uint32_t first_len, /* IN */
const uint8_t *first_data, /* IN */
...)
{
va_list args;
bool ok;
BSON_ASSERT (n_pairs);
BSON_ASSERT (first_len);
BSON_ASSERT (first_data);
/*
* Check to see if this append would overflow 32-bit signed integer. I know
* what you're thinking. BSON uses a signed 32-bit length field? Yeah. It
* does.
*/
if (BSON_UNLIKELY (n_bytes > (BSON_MAX_SIZE - bson->len))) {
return false;
}
va_start (args, first_data);
ok = _bson_append_va (bson, n_bytes, n_pairs, first_len, first_data, args);
va_end (args);
return ok;
}
static BSON_INLINE bool
_string_contains_null (const char *str, size_t len)
{
for (; len; ++str, --len) {
if (*str == 0) {
return true;
}
}
return false;
}
#define HANDLE_KEY_LENGTH(key, key_length) \
do { \
if (key_length < 0) { \
key_length = (int) strlen (key); \
} else { \
/* Necessary to validate embedded NULL is not present in key. */ \
if (_string_contains_null (key, key_length)) { \
return false; \
} \
} \
} while (0)
/*
*--------------------------------------------------------------------------
*
* _bson_append_bson_begin --
*
* Begin appending a subdocument or subarray to the document using
* the key provided by @key.
*
* If @key_length is < 0, then strlen() will be called on @key
* to determine the length.
*
* @key_type MUST be either BSON_TYPE_DOCUMENT or BSON_TYPE_ARRAY.
*
* Returns:
* true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* @child is initialized if true is returned.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_append_bson_begin (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_type_t child_type, /* IN */
bson_t *child) /* OUT */
{
const uint8_t type = child_type;
const uint8_t empty[5] = {5};
bson_impl_alloc_t *aparent = (bson_impl_alloc_t *) bson;
bson_impl_alloc_t *achild = (bson_impl_alloc_t *) child;
BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY));
BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD));
BSON_ASSERT (key);
BSON_ASSERT ((child_type == BSON_TYPE_DOCUMENT) ||
(child_type == BSON_TYPE_ARRAY));
BSON_ASSERT (child);
HANDLE_KEY_LENGTH (key, key_length);
/*
* If the parent is an inline bson_t, then we need to convert
* it to a heap allocated buffer. This makes extending buffers
* of child bson documents much simpler logic, as they can just
* realloc the *buf pointer.
*/
if ((bson->flags & BSON_FLAG_INLINE)) {
BSON_ASSERT (bson->len <= 120);
if (!_bson_grow (bson, 128 - bson->len)) {
return false;
}
BSON_ASSERT (!(bson->flags & BSON_FLAG_INLINE));
}
/*
* Append the type and key for the field.
*/
if (!_bson_append (bson,
4,
(1 + key_length + 1 + 5),
1,
&type,
key_length,
key,
1,
&gZero,
5,
empty)) {
return false;
}
/*
* Mark the document as working on a child document so that no
* further modifications can happen until the caller has called
* bson_append_{document,array}_end().
*/
bson->flags |= BSON_FLAG_IN_CHILD;
/*
* Initialize the child bson_t structure and point it at the parents
* buffers. This allows us to realloc directly from the child without
* walking up to the parent bson_t.
*/
achild->flags = (BSON_FLAG_CHILD | BSON_FLAG_NO_FREE | BSON_FLAG_STATIC);
if ((bson->flags & BSON_FLAG_CHILD)) {
achild->depth = ((bson_impl_alloc_t *) bson)->depth + 1;
} else {
achild->depth = 1;
}
achild->parent = bson;
achild->buf = aparent->buf;
achild->buflen = aparent->buflen;
achild->offset = aparent->offset + aparent->len - 1 - 5;
achild->len = 5;
achild->alloc = NULL;
achild->alloclen = 0;
achild->realloc = aparent->realloc;
achild->realloc_func_ctx = aparent->realloc_func_ctx;
return true;
}
/*
*--------------------------------------------------------------------------
*
* _bson_append_bson_end --
*
* Complete a call to _bson_append_bson_begin.
*
* Returns:
* true if successful.
*
* Side effects:
* @child is destroyed and no longer valid after calling this
* function.
*
*--------------------------------------------------------------------------
*/
static bool
_bson_append_bson_end (bson_t *bson, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT ((bson->flags & BSON_FLAG_IN_CHILD));
BSON_ASSERT (!(child->flags & BSON_FLAG_IN_CHILD));
/*
* Unmark the IN_CHILD flag.
*/
bson->flags &= ~BSON_FLAG_IN_CHILD;
/*
* Now that we are done building the sub-document, add the size to the
* parent, not including the default 5 byte empty document already added.
*/
bson->len = (bson->len + child->len - 5);
/*
* Ensure we have a \0 byte at the end and proper length encoded at
* the beginning of the document.
*/
_bson_data (bson)[bson->len - 1] = '\0';
_bson_encode_length (bson);
return true;
}
/*
*--------------------------------------------------------------------------
*
* bson_append_array_begin --
*
* Start appending a new array.
*
* Use @child to append to the data area for the given field.
*
* It is a programming error to call any other bson function on
* @bson until bson_append_array_end() has been called. It is
* valid to call bson_append*() functions on @child.
*
* This function is useful to allow building nested documents using
* a single buffer owned by the top-level bson document.
*
* Returns:
* true if successful; otherwise false and @child is invalid.
*
* Side effects:
* @child is initialized if true is returned.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_array_begin (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (child);
return _bson_append_bson_begin (
bson, key, key_length, BSON_TYPE_ARRAY, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_array_end --
*
* Complete a call to bson_append_array_begin().
*
* It is safe to append other fields to @bson after calling this
* function.
*
* Returns:
* true if successful.
*
* Side effects:
* @child is invalid after calling this function.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_array_end (bson_t *bson, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (child);
return _bson_append_bson_end (bson, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_document_begin --
*
* Start appending a new document.
*
* Use @child to append to the data area for the given field.
*
* It is a programming error to call any other bson function on
* @bson until bson_append_document_end() has been called. It is
* valid to call bson_append*() functions on @child.
*
* This function is useful to allow building nested documents using
* a single buffer owned by the top-level bson document.
*
* Returns:
* true if successful; otherwise false and @child is invalid.
*
* Side effects:
* @child is initialized if true is returned.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_document_begin (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (child);
return _bson_append_bson_begin (
bson, key, key_length, BSON_TYPE_DOCUMENT, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_document_end --
*
* Complete a call to bson_append_document_begin().
*
* It is safe to append new fields to @bson after calling this
* function, if true is returned.
*
* Returns:
* true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* @child is destroyed and invalid after calling this function.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_document_end (bson_t *bson, /* IN */
bson_t *child) /* IN */
{
BSON_ASSERT (bson);
BSON_ASSERT (child);
return _bson_append_bson_end (bson, child);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_array --
*
* Append an array to @bson.
*
* Generally, bson_append_array_begin() will result in faster code
* since few buffers need to be malloced.
*
* Returns:
* true if successful; otherwise false indicating BSON_MAX_SIZE overflow.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_array (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const bson_t *array) /* IN */
{
static const uint8_t type = BSON_TYPE_ARRAY;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (array);
HANDLE_KEY_LENGTH (key, key_length);
/*
* Let's be a bit pedantic and ensure the array has properly formatted key
* names. We will verify this simply by checking the first element for "0"
* if the array is non-empty.
*/
if (array && !bson_empty (array)) {
bson_iter_t iter;
if (bson_iter_init (&iter, array) && bson_iter_next (&iter)) {
if (0 != strcmp ("0", bson_iter_key (&iter))) {
fprintf (stderr,
"%s(): invalid array detected. first element of array "
"parameter is not \"0\".\n",
BSON_FUNC);
}
}
}
return _bson_append (bson,
4,
(1 + key_length + 1 + array->len),
1,
&type,
key_length,
key,
1,
&gZero,
array->len,
_bson_data (array));
}
/*
*--------------------------------------------------------------------------
*
* bson_append_binary --
*
* Append binary data to @bson. The field will have the
* BSON_TYPE_BINARY type.
*
* Parameters:
* @subtype: the BSON Binary Subtype. See bsonspec.org for more
* information.
* @binary: a pointer to the raw binary data.
* @length: the size of @binary in bytes.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_binary (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bson_subtype_t subtype, /* IN */
const uint8_t *binary, /* IN */
uint32_t length) /* IN */
{
static const uint8_t type = BSON_TYPE_BINARY;
uint32_t length_le;
uint32_t deprecated_length_le;
uint8_t subtype8 = 0;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
subtype8 = subtype;
if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
length_le = BSON_UINT32_TO_LE (length + 4);
deprecated_length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
7,
(1 + key_length + 1 + 4 + 1 + 4 + length),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
1,
&subtype8,
4,
&deprecated_length_le,
length,
binary);
} else {
length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + 1 + length),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
1,
&subtype8,
length,
binary);
}
}
/*
*--------------------------------------------------------------------------
*
* bson_append_bool --
*
* Append a new field to @bson with the name @key. The value is
* a boolean indicated by @value.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_bool (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
bool value) /* IN */
{
static const uint8_t type = BSON_TYPE_BOOL;
uint8_t abyte = !!value;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
return _bson_append (bson,
4,
(1 + key_length + 1 + 1),
1,
&type,
key_length,
key,
1,
&gZero,
1,
&abyte);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_code --
*
* Append a new field to @bson containing javascript code.
*
* @javascript MUST be a zero terminated UTF-8 string. It MUST NOT
* containing embedded \0 characters.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
* See also:
* bson_append_code_with_scope().
*
*--------------------------------------------------------------------------
*/
bool
bson_append_code (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const char *javascript) /* IN */
{
static const uint8_t type = BSON_TYPE_CODE;
uint32_t length;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (javascript);
HANDLE_KEY_LENGTH (key, key_length);
length = (int) strlen (javascript) + 1;
length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
5,
(1 + key_length + 1 + 4 + length),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
javascript);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_code_with_scope --
*
* Append a new field to @bson containing javascript code with
* supplied scope.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_code_with_scope (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const char *javascript, /* IN */
const bson_t *scope) /* IN */
{
static const uint8_t type = BSON_TYPE_CODEWSCOPE;
uint32_t codews_length_le;
uint32_t codews_length;
uint32_t js_length_le;
uint32_t js_length;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (javascript);
if (scope == NULL) {
return bson_append_code (bson, key, key_length, javascript);
}
HANDLE_KEY_LENGTH (key, key_length);
js_length = (int) strlen (javascript) + 1;
js_length_le = BSON_UINT32_TO_LE (js_length);
codews_length = 4 + 4 + js_length + scope->len;
codews_length_le = BSON_UINT32_TO_LE (codews_length);
return _bson_append (bson,
7,
(1 + key_length + 1 + 4 + 4 + js_length + scope->len),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&codews_length_le,
4,
&js_length_le,
js_length,
javascript,
scope->len,
_bson_data (scope));
}
/*
*--------------------------------------------------------------------------
*
* bson_append_dbpointer --
*
* This BSON data type is DEPRECATED.
*
* Append a BSON dbpointer field to @bson.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
bson_append_dbpointer (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const char *collection, /* IN */
const bson_oid_t *oid)
{
static const uint8_t type = BSON_TYPE_DBPOINTER;
uint32_t length;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (collection);
BSON_ASSERT (oid);
HANDLE_KEY_LENGTH (key, key_length);
length = (int) strlen (collection) + 1;
length_le = BSON_UINT32_TO_LE (length);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + length + 12),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
collection,
12,
oid);
}
/*
*--------------------------------------------------------------------------
*
* bson_append_document --
*
* Append a new field to @bson containing a BSON document.
*
* In general, using bson_append_document_begin() results in faster
* code and less memory fragmentation.
*
* Returns:
* true if successful; otherwise false.
*
* Side effects:
* None.
*
* See also:
* bson_append_document_begin().
*
*--------------------------------------------------------------------------
*/
bool
bson_append_document (bson_t *bson, /* IN */
const char *key, /* IN */
int key_length, /* IN */
const bson_t *value) /* IN */
{
static const uint8_t type = BSON_TYPE_DOCUMENT;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
HANDLE_KEY_LENGTH (key, key_length);
return _bson_append (bson,
4,
(1 + key_length + 1 + value->len),
1,
&type,
key_length,
key,
1,
&gZero,
value->len,
_bson_data (value));
}
bool
bson_append_double (bson_t *bson, const char *key, int key_length, double value)
{
static const uint8_t type = BSON_TYPE_DOUBLE;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
value = BSON_DOUBLE_TO_LE (value);
#endif
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value);
}
bool
bson_append_int32 (bson_t *bson, const char *key, int key_length, int32_t value)
{
static const uint8_t type = BSON_TYPE_INT32;
uint32_t value_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
value_le = BSON_UINT32_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 4),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&value_le);
}
bool
bson_append_int64 (bson_t *bson, const char *key, int key_length, int64_t value)
{
static const uint8_t type = BSON_TYPE_INT64;
uint64_t value_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
value_le = BSON_UINT64_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value_le);
}
bool
bson_append_decimal128 (bson_t *bson,
const char *key,
int key_length,
const bson_decimal128_t *value)
{
static const uint8_t type = BSON_TYPE_DECIMAL128;
uint64_t value_le[2];
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
HANDLE_KEY_LENGTH (key, key_length);
value_le[0] = BSON_UINT64_TO_LE (value->low);
value_le[1] = BSON_UINT64_TO_LE (value->high);
return _bson_append (bson,
4,
(1 + key_length + 1 + 16),
1,
&type,
key_length,
key,
1,
&gZero,
16,
value_le);
}
bool
bson_append_iter (bson_t *bson,
const char *key,
int key_length,
const bson_iter_t *iter)
{
bool ret = false;
BSON_ASSERT (bson);
BSON_ASSERT (iter);
if (!key) {
key = bson_iter_key (iter);
key_length = -1;
}
switch (bson_iter_type_unsafe (iter)) {
case BSON_TYPE_EOD:
return false;
case BSON_TYPE_DOUBLE:
ret = bson_append_double (bson, key, key_length, bson_iter_double (iter));
break;
case BSON_TYPE_UTF8: {
uint32_t len = 0;
const char *str;
str = bson_iter_utf8 (iter, &len);
ret = bson_append_utf8 (bson, key, key_length, str, len);
} break;
case BSON_TYPE_DOCUMENT: {
const uint8_t *buf = NULL;
uint32_t len = 0;
bson_t doc;
bson_iter_document (iter, &len, &buf);
if (bson_init_static (&doc, buf, len)) {
ret = bson_append_document (bson, key, key_length, &doc);
bson_destroy (&doc);
}
} break;
case BSON_TYPE_ARRAY: {
const uint8_t *buf = NULL;
uint32_t len = 0;
bson_t doc;
bson_iter_array (iter, &len, &buf);
if (bson_init_static (&doc, buf, len)) {
ret = bson_append_array (bson, key, key_length, &doc);
bson_destroy (&doc);
}
} break;
case BSON_TYPE_BINARY: {
const uint8_t *binary = NULL;
bson_subtype_t subtype = BSON_SUBTYPE_BINARY;
uint32_t len = 0;
bson_iter_binary (iter, &subtype, &len, &binary);
ret = bson_append_binary (bson, key, key_length, subtype, binary, len);
} break;
case BSON_TYPE_UNDEFINED:
ret = bson_append_undefined (bson, key, key_length);
break;
case BSON_TYPE_OID:
ret = bson_append_oid (bson, key, key_length, bson_iter_oid (iter));
break;
case BSON_TYPE_BOOL:
ret = bson_append_bool (bson, key, key_length, bson_iter_bool (iter));
break;
case BSON_TYPE_DATE_TIME:
ret = bson_append_date_time (
bson, key, key_length, bson_iter_date_time (iter));
break;
case BSON_TYPE_NULL:
ret = bson_append_null (bson, key, key_length);
break;
case BSON_TYPE_REGEX: {
const char *regex;
const char *options;
regex = bson_iter_regex (iter, &options);
ret = bson_append_regex (bson, key, key_length, regex, options);
} break;
case BSON_TYPE_DBPOINTER: {
const bson_oid_t *oid;
uint32_t len;
const char *collection;
bson_iter_dbpointer (iter, &len, &collection, &oid);
ret = bson_append_dbpointer (bson, key, key_length, collection, oid);
} break;
case BSON_TYPE_CODE: {
uint32_t len;
const char *code;
code = bson_iter_code (iter, &len);
ret = bson_append_code (bson, key, key_length, code);
} break;
case BSON_TYPE_SYMBOL: {
uint32_t len;
const char *symbol;
symbol = bson_iter_symbol (iter, &len);
ret = bson_append_symbol (bson, key, key_length, symbol, len);
} break;
case BSON_TYPE_CODEWSCOPE: {
const uint8_t *scope = NULL;
uint32_t scope_len = 0;
uint32_t len = 0;
const char *javascript = NULL;
bson_t doc;
javascript = bson_iter_codewscope (iter, &len, &scope_len, &scope);
if (bson_init_static (&doc, scope, scope_len)) {
ret = bson_append_code_with_scope (
bson, key, key_length, javascript, &doc);
bson_destroy (&doc);
}
} break;
case BSON_TYPE_INT32:
ret = bson_append_int32 (bson, key, key_length, bson_iter_int32 (iter));
break;
case BSON_TYPE_TIMESTAMP: {
uint32_t ts;
uint32_t inc;
bson_iter_timestamp (iter, &ts, &inc);
ret = bson_append_timestamp (bson, key, key_length, ts, inc);
} break;
case BSON_TYPE_INT64:
ret = bson_append_int64 (bson, key, key_length, bson_iter_int64 (iter));
break;
case BSON_TYPE_DECIMAL128: {
bson_decimal128_t dec;
if (!bson_iter_decimal128 (iter, &dec)) {
return false;
}
ret = bson_append_decimal128 (bson, key, key_length, &dec);
} break;
case BSON_TYPE_MAXKEY:
ret = bson_append_maxkey (bson, key, key_length);
break;
case BSON_TYPE_MINKEY:
ret = bson_append_minkey (bson, key, key_length);
break;
default:
break;
}
return ret;
}
bool
bson_append_maxkey (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_MAXKEY;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_minkey (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_MINKEY;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_null (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_NULL;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_oid (bson_t *bson,
const char *key,
int key_length,
const bson_oid_t *value)
{
static const uint8_t type = BSON_TYPE_OID;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
HANDLE_KEY_LENGTH (key, key_length);
return _bson_append (bson,
4,
(1 + key_length + 1 + 12),
1,
&type,
key_length,
key,
1,
&gZero,
12,
value);
}
/*
*--------------------------------------------------------------------------
*
* _bson_append_regex_options_sorted --
*
* Helper to append regex options to a buffer in a sorted order.
* Any duplicate or unsupported options will be ignored.
*
* Parameters:
* @buffer: Buffer to which sorted options will be appended
* @options: Regex options
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static BSON_INLINE void
_bson_append_regex_options_sorted (bson_string_t *buffer, /* IN */
const char *options) /* IN */
{
const char *c;
for (c = BSON_REGEX_OPTIONS_SORTED; *c; c++) {
if (strchr (options, *c)) {
bson_string_append_c (buffer, *c);
}
}
}
bool
bson_append_regex (bson_t *bson,
const char *key,
int key_length,
const char *regex,
const char *options)
{
return bson_append_regex_w_len (bson, key, key_length, regex, -1, options);
}
bool
bson_append_regex_w_len (bson_t *bson,
const char *key,
int key_length,
const char *regex,
int regex_length,
const char *options)
{
static const uint8_t type = BSON_TYPE_REGEX;
bson_string_t *options_sorted;
bool r;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
if (regex_length < 0) {
regex_length = (int) strlen (regex);
} else {
/* Necessary to validate embedded NULL is not present in key. */
if (_string_contains_null (regex, regex_length)) {
return false;
}
}
if (!regex) {
regex = "";
}
if (!options) {
options = "";
}
options_sorted = bson_string_new (NULL);
_bson_append_regex_options_sorted (options_sorted, options);
r = _bson_append (
bson,
6,
(1 + key_length + 1 + regex_length + 1 + options_sorted->len + 1),
1,
&type,
key_length,
key,
1,
&gZero,
regex_length,
regex,
1,
&gZero,
options_sorted->len + 1,
options_sorted->str);
bson_string_free (options_sorted, true);
return r;
}
bool
bson_append_utf8 (
bson_t *bson, const char *key, int key_length, const char *value, int length)
{
static const uint8_t type = BSON_TYPE_UTF8;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (BSON_UNLIKELY (!value)) {
return bson_append_null (bson, key, key_length);
}
HANDLE_KEY_LENGTH (key, key_length);
if (BSON_UNLIKELY (length < 0)) {
length = (int) strlen (value);
}
length_le = BSON_UINT32_TO_LE (length + 1);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + length + 1),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
value,
1,
&gZero);
}
bool
bson_append_symbol (
bson_t *bson, const char *key, int key_length, const char *value, int length)
{
static const uint8_t type = BSON_TYPE_SYMBOL;
uint32_t length_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (!value) {
return bson_append_null (bson, key, key_length);
}
HANDLE_KEY_LENGTH (key, key_length);
if (length < 0) {
length = (int) strlen (value);
}
length_le = BSON_UINT32_TO_LE (length + 1);
return _bson_append (bson,
6,
(1 + key_length + 1 + 4 + length + 1),
1,
&type,
key_length,
key,
1,
&gZero,
4,
&length_le,
length,
value,
1,
&gZero);
}
bool
bson_append_time_t (bson_t *bson, const char *key, int key_length, time_t value)
{
#ifdef BSON_OS_WIN32
struct timeval tv = {(long) value, 0};
#else
struct timeval tv = {value, 0};
#endif
BSON_ASSERT (bson);
BSON_ASSERT (key);
return bson_append_timeval (bson, key, key_length, &tv);
}
bool
bson_append_timestamp (bson_t *bson,
const char *key,
int key_length,
uint32_t timestamp,
uint32_t increment)
{
static const uint8_t type = BSON_TYPE_TIMESTAMP;
uint64_t value;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
value = ((((uint64_t) timestamp) << 32) | ((uint64_t) increment));
value = BSON_UINT64_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value);
}
bool
bson_append_now_utc (bson_t *bson, const char *key, int key_length)
{
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (key_length >= -1);
return bson_append_time_t (bson, key, key_length, time (NULL));
}
bool
bson_append_date_time (bson_t *bson,
const char *key,
int key_length,
int64_t value)
{
static const uint8_t type = BSON_TYPE_DATE_TIME;
uint64_t value_le;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
value_le = BSON_UINT64_TO_LE (value);
return _bson_append (bson,
4,
(1 + key_length + 1 + 8),
1,
&type,
key_length,
key,
1,
&gZero,
8,
&value_le);
}
bool
bson_append_timeval (bson_t *bson,
const char *key,
int key_length,
struct timeval *value)
{
uint64_t unix_msec;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
unix_msec =
(((uint64_t) value->tv_sec) * 1000UL) + (value->tv_usec / 1000UL);
return bson_append_date_time (bson, key, key_length, unix_msec);
}
bool
bson_append_undefined (bson_t *bson, const char *key, int key_length)
{
static const uint8_t type = BSON_TYPE_UNDEFINED;
BSON_ASSERT (bson);
BSON_ASSERT (key);
HANDLE_KEY_LENGTH (key, key_length);
return _bson_append (
bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
}
bool
bson_append_value (bson_t *bson,
const char *key,
int key_length,
const bson_value_t *value)
{
bson_t local;
bool ret = false;
BSON_ASSERT (bson);
BSON_ASSERT (key);
BSON_ASSERT (value);
switch (value->value_type) {
case BSON_TYPE_DOUBLE:
ret = bson_append_double (bson, key, key_length, value->value.v_double);
break;
case BSON_TYPE_UTF8:
ret = bson_append_utf8 (bson,
key,
key_length,
value->value.v_utf8.str,
value->value.v_utf8.len);
break;
case BSON_TYPE_DOCUMENT:
if (bson_init_static (
&local, value->value.v_doc.data, value->value.v_doc.data_len)) {
ret = bson_append_document (bson, key, key_length, &local);
bson_destroy (&local);
}
break;
case BSON_TYPE_ARRAY:
if (bson_init_static (
&local, value->value.v_doc.data, value->value.v_doc.data_len)) {
ret = bson_append_array (bson, key, key_length, &local);
bson_destroy (&local);
}
break;
case BSON_TYPE_BINARY:
ret = bson_append_binary (bson,
key,
key_length,
value->value.v_binary.subtype,
value->value.v_binary.data,
value->value.v_binary.data_len);
break;
case BSON_TYPE_UNDEFINED:
ret = bson_append_undefined (bson, key, key_length);
break;
case BSON_TYPE_OID:
ret = bson_append_oid (bson, key, key_length, &value->value.v_oid);
break;
case BSON_TYPE_BOOL:
ret = bson_append_bool (bson, key, key_length, value->value.v_bool);
break;
case BSON_TYPE_DATE_TIME:
ret =
bson_append_date_time (bson, key, key_length, value->value.v_datetime);
break;
case BSON_TYPE_NULL:
ret = bson_append_null (bson, key, key_length);
break;
case BSON_TYPE_REGEX:
ret = bson_append_regex (bson,
key,
key_length,
value->value.v_regex.regex,
value->value.v_regex.options);
break;
case BSON_TYPE_DBPOINTER:
ret = bson_append_dbpointer (bson,
key,
key_length,
value->value.v_dbpointer.collection,
&value->value.v_dbpointer.oid);
break;
case BSON_TYPE_CODE:
ret = bson_append_code (bson, key, key_length, value->value.v_code.code);
break;
case BSON_TYPE_SYMBOL:
ret = bson_append_symbol (bson,
key,
key_length,
value->value.v_symbol.symbol,
value->value.v_symbol.len);
break;
case BSON_TYPE_CODEWSCOPE:
if (bson_init_static (&local,
value->value.v_codewscope.scope_data,
value->value.v_codewscope.scope_len)) {
ret = bson_append_code_with_scope (
bson, key, key_length, value->value.v_codewscope.code, &local);
bson_destroy (&local);
}
break;
case BSON_TYPE_INT32:
ret = bson_append_int32 (bson, key, key_length, value->value.v_int32);
break;
case BSON_TYPE_TIMESTAMP:
ret = bson_append_timestamp (bson,
key,
key_length,
value->value.v_timestamp.timestamp,
value->value.v_timestamp.increment);
break;
case BSON_TYPE_INT64:
ret = bson_append_int64 (bson, key, key_length, value->value.v_int64);
break;
case BSON_TYPE_DECIMAL128:
ret = bson_append_decimal128 (
bson, key, key_length, &(value->value.v_decimal128));
break;
case BSON_TYPE_MAXKEY:
ret = bson_append_maxkey (bson, key, key_length);
break;
case BSON_TYPE_MINKEY:
ret = bson_append_minkey (bson, key, key_length);
break;
case BSON_TYPE_EOD:
default:
break;
}
return ret;
}
void
bson_init (bson_t *bson)
{
bson_impl_inline_t *impl = (bson_impl_inline_t *) bson;
BSON_ASSERT (bson);
#ifdef BSON_MEMCHECK
impl->canary = bson_malloc (1);
#endif
impl->flags = BSON_FLAG_INLINE | BSON_FLAG_STATIC;
impl->len = 5;
impl->data[0] = 5;
impl->data[1] = 0;
impl->data[2] = 0;
impl->data[3] = 0;
impl->data[4] = 0;
}
void
bson_reinit (bson_t *bson)
{
uint8_t *data;
BSON_ASSERT (bson);
data = _bson_data (bson);
bson->len = 5;
data[0] = 5;
data[1] = 0;
data[2] = 0;
data[3] = 0;
data[4] = 0;
}
bool
bson_init_static (bson_t *bson, const uint8_t *data, size_t length)
{
bson_impl_alloc_t *impl = (bson_impl_alloc_t *) bson;
uint32_t len_le;
BSON_ASSERT (bson);
BSON_ASSERT (data);
if ((length < 5) || (length > BSON_MAX_SIZE)) {
return false;
}
memcpy (&len_le, data, sizeof (len_le));
if ((size_t) BSON_UINT32_FROM_LE (len_le) != length) {
return false;
}
if (data[length - 1]) {
return false;
}
impl->flags = BSON_FLAG_STATIC | BSON_FLAG_RDONLY;
impl->len = (uint32_t) length;
impl->parent = NULL;
impl->depth = 0;
impl->buf = &impl->alloc;
impl->buflen = &impl->alloclen;
impl->offset = 0;
impl->alloc = (uint8_t *) data;
impl->alloclen = length;
impl->realloc = NULL;
impl->realloc_func_ctx = NULL;
return true;
}
bson_t *
bson_new (void)
{
bson_impl_inline_t *impl;
bson_t *bson;
bson = bson_malloc (sizeof *bson);
impl = (bson_impl_inline_t *) bson;
impl->flags = BSON_FLAG_INLINE;
impl->len = 5;
#ifdef BSON_MEMCHECK
impl->canary = bson_malloc (1);
#endif
impl->data[0] = 5;
impl->data[1] = 0;
impl->data[2] = 0;
impl->data[3] = 0;
impl->data[4] = 0;
return bson;
}
bson_t *
bson_sized_new (size_t size)
{
bson_impl_alloc_t *impl_a;
bson_t *b;
BSON_ASSERT (size <= BSON_MAX_SIZE);
b = bson_malloc (sizeof *b);
impl_a = (bson_impl_alloc_t *) b;
if (size <= BSON_INLINE_DATA_SIZE) {
bson_init (b);
b->flags &= ~BSON_FLAG_STATIC;
} else {
impl_a->flags = BSON_FLAG_NONE;
impl_a->len = 5;
impl_a->parent = NULL;
impl_a->depth = 0;
impl_a->buf = &impl_a->alloc;
impl_a->buflen = &impl_a->alloclen;
impl_a->offset = 0;
impl_a->alloclen = BSON_MAX (5, size);
impl_a->alloc = bson_malloc (impl_a->alloclen);
impl_a->alloc[0] = 5;
impl_a->alloc[1] = 0;
impl_a->alloc[2] = 0;
impl_a->alloc[3] = 0;
impl_a->alloc[4] = 0;
impl_a->realloc = bson_realloc_ctx;
impl_a->realloc_func_ctx = NULL;
}
return b;
}
bson_t *
bson_new_from_data (const uint8_t *data, size_t length)
{
uint32_t len_le;
bson_t *bson;
BSON_ASSERT (data);
if ((length < 5) || (length > BSON_MAX_SIZE) || data[length - 1]) {
return NULL;
}
memcpy (&len_le, data, sizeof (len_le));
if (length != (size_t) BSON_UINT32_FROM_LE (len_le)) {
return NULL;
}
bson = bson_sized_new (length);
memcpy (_bson_data (bson), data, length);
bson->len = (uint32_t) length;
return bson;
}
bson_t *
bson_new_from_buffer (uint8_t **buf,
size_t *buf_len,
bson_realloc_func realloc_func,
void *realloc_func_ctx)
{
bson_impl_alloc_t *impl;
uint32_t len_le;
uint32_t length;
bson_t *bson;
BSON_ASSERT (buf);
BSON_ASSERT (buf_len);
if (!realloc_func) {
realloc_func = bson_realloc_ctx;
}
bson = bson_malloc0 (sizeof *bson);
impl = (bson_impl_alloc_t *) bson;
if (!*buf) {
length = 5;
len_le = BSON_UINT32_TO_LE (length);
*buf_len = 5;
*buf = realloc_func (*buf, *buf_len, realloc_func_ctx);
memcpy (*buf, &len_le, sizeof (len_le));
(*buf)[4] = '\0';
} else {
if ((*buf_len < 5) || (*buf_len > BSON_MAX_SIZE)) {
bson_free (bson);
return NULL;
}
memcpy (&len_le, *buf, sizeof (len_le));
length = BSON_UINT32_FROM_LE (len_le);
}
if ((*buf)[length - 1]) {
bson_free (bson);
return NULL;
}
impl->flags = BSON_FLAG_NO_FREE;
impl->len = length;
impl->buf = buf;
impl->buflen = buf_len;
impl->realloc = realloc_func;
impl->realloc_func_ctx = realloc_func_ctx;
return bson;
}
bson_t *
bson_copy (const bson_t *bson)
{
const uint8_t *data;
BSON_ASSERT (bson);
data = _bson_data (bson);
return bson_new_from_data (data, bson->len);
}
void
bson_copy_to (const bson_t *src, bson_t *dst)
{
const uint8_t *data;
bson_impl_alloc_t *adst;
size_t len;
BSON_ASSERT (src);
BSON_ASSERT (dst);
if ((src->flags & BSON_FLAG_INLINE)) {
#ifdef BSON_MEMCHECK
dst->len = src->len;
dst->canary = malloc (1);
memcpy (dst->padding, src->padding, sizeof dst->padding);
#else
memcpy (dst, src, sizeof *dst);
#endif
dst->flags = (BSON_FLAG_STATIC | BSON_FLAG_INLINE);
return;
}
data = _bson_data (src);
len = bson_next_power_of_two ((size_t) src->len);
adst = (bson_impl_alloc_t *) dst;
adst->flags = BSON_FLAG_STATIC;
adst->len = src->len;
adst->parent = NULL;
adst->depth = 0;
adst->buf = &adst->alloc;
adst->buflen = &adst->alloclen;
adst->offset = 0;
adst->alloc = bson_malloc (len);
adst->alloclen = len;
adst->realloc = bson_realloc_ctx;
adst->realloc_func_ctx = NULL;
memcpy (adst->alloc, data, src->len);
}
static bool
should_ignore (const char *first_exclude, va_list args, const char *name)
{
bool ret = false;
const char *exclude = first_exclude;
va_list args_copy;
va_copy (args_copy, args);
do {
if (!strcmp (name, exclude)) {
ret = true;
break;
}
} while ((exclude = va_arg (args_copy, const char *)));
va_end (args_copy);
return ret;
}
void
bson_copy_to_excluding_noinit_va (const bson_t *src,
bson_t *dst,
const char *first_exclude,
va_list args)
{
bson_iter_t iter;
if (bson_iter_init (&iter, src)) {
while (bson_iter_next (&iter)) {
if (!should_ignore (first_exclude, args, bson_iter_key (&iter))) {
if (!bson_append_iter (dst, NULL, 0, &iter)) {
/*
* This should not be able to happen since we are copying
* from within a valid bson_t.
*/
BSON_ASSERT (false);
return;
}
}
}
}
}
void
bson_copy_to_excluding (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...)
{
va_list args;
BSON_ASSERT (src);
BSON_ASSERT (dst);
BSON_ASSERT (first_exclude);
bson_init (dst);
va_start (args, first_exclude);
bson_copy_to_excluding_noinit_va (src, dst, first_exclude, args);
va_end (args);
}
void
bson_copy_to_excluding_noinit (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...)
{
va_list args;
BSON_ASSERT (src);
BSON_ASSERT (dst);
BSON_ASSERT (first_exclude);
va_start (args, first_exclude);
bson_copy_to_excluding_noinit_va (src, dst, first_exclude, args);
va_end (args);
}
void
bson_destroy (bson_t *bson)
{
if (!bson) {
return;
}
if (!(bson->flags &
(BSON_FLAG_RDONLY | BSON_FLAG_INLINE | BSON_FLAG_NO_FREE))) {
bson_free (*((bson_impl_alloc_t *) bson)->buf);
}
#ifdef BSON_MEMCHECK
if (bson->flags & BSON_FLAG_INLINE) {
bson_free (bson->canary);
}
#endif
if (!(bson->flags & BSON_FLAG_STATIC)) {
bson_free (bson);
}
}
uint8_t *
bson_reserve_buffer (bson_t *bson, uint32_t size)
{
if (bson->flags &
(BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) {
return NULL;
}
if (!_bson_grow (bson, size)) {
return NULL;
}
if (bson->flags & BSON_FLAG_INLINE) {
/* bson_grow didn't spill over */
((bson_impl_inline_t *) bson)->len = size;
} else {
((bson_impl_alloc_t *) bson)->len = size;
}
return _bson_data (bson);
}
bool
bson_steal (bson_t *dst, bson_t *src)
{
bson_impl_inline_t *src_inline;
bson_impl_inline_t *dst_inline;
bson_impl_alloc_t *alloc;
BSON_ASSERT (dst);
BSON_ASSERT (src);
bson_init (dst);
if (src->flags & (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) {
return false;
}
if (src->flags & BSON_FLAG_INLINE) {
src_inline = (bson_impl_inline_t *) src;
dst_inline = (bson_impl_inline_t *) dst;
dst_inline->len = src_inline->len;
memcpy (dst_inline->data, src_inline->data, sizeof src_inline->data);
/* for consistency, src is always invalid after steal, even if inline */
src->len = 0;
#ifdef BSON_MEMCHECK
bson_free (src->canary);
#endif
} else {
#ifdef BSON_MEMCHECK
bson_free (dst->canary);
#endif
memcpy (dst, src, sizeof (bson_t));
alloc = (bson_impl_alloc_t *) dst;
alloc->flags |= BSON_FLAG_STATIC;
alloc->buf = &alloc->alloc;
alloc->buflen = &alloc->alloclen;
}
if (!(src->flags & BSON_FLAG_STATIC)) {
bson_free (src);
} else {
/* src is invalid after steal */
src->len = 0;
}
return true;
}
uint8_t *
bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length)
{
uint8_t *ret = NULL;
BSON_ASSERT (bson);
if (length) {
*length = bson->len;
}
if (!steal) {
bson_destroy (bson);
return NULL;
}
if ((bson->flags &
(BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY))) {
/* Do nothing */
} else if ((bson->flags & BSON_FLAG_INLINE)) {
bson_impl_inline_t *inl;
inl = (bson_impl_inline_t *) bson;
ret = bson_malloc (bson->len);
memcpy (ret, inl->data, bson->len);
} else {
bson_impl_alloc_t *alloc;
alloc = (bson_impl_alloc_t *) bson;
ret = *alloc->buf;
*alloc->buf = NULL;
}
bson_destroy (bson);
return ret;
}
const uint8_t *
bson_get_data (const bson_t *bson)
{
BSON_ASSERT (bson);
return _bson_data (bson);
}
uint32_t
bson_count_keys (const bson_t *bson)
{
uint32_t count = 0;
bson_iter_t iter;
BSON_ASSERT (bson);
if (bson_iter_init (&iter, bson)) {
while (bson_iter_next (&iter)) {
count++;
}
}
return count;
}
bool
bson_has_field (const bson_t *bson, const char *key)
{
bson_iter_t iter;
bson_iter_t child;
BSON_ASSERT (bson);
BSON_ASSERT (key);
if (NULL != strchr (key, '.')) {
return (bson_iter_init (&iter, bson) &&
bson_iter_find_descendant (&iter, key, &child));
}
return bson_iter_init_find (&iter, bson, key);
}
int
bson_compare (const bson_t *bson, const bson_t *other)
{
const uint8_t *data1;
const uint8_t *data2;
size_t len1;
size_t len2;
int64_t ret;
data1 = _bson_data (bson) + 4;
len1 = bson->len - 4;
data2 = _bson_data (other) + 4;
len2 = other->len - 4;
if (len1 == len2) {
return memcmp (data1, data2, len1);
}
ret = memcmp (data1, data2, BSON_MIN (len1, len2));
if (ret == 0) {
ret = (int64_t) len1 - (int64_t) len2;
}
return (ret < 0) ? -1 : (ret > 0);
}
bool
bson_equal (const bson_t *bson, const bson_t *other)
{
return !bson_compare (bson, other);
}
static bool
_bson_as_json_visit_utf8 (const bson_iter_t *iter,
const char *key,
size_t v_utf8_len,
const char *v_utf8,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_utf8, v_utf8_len);
if (escaped) {
bson_string_append (state->str, "\"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
bson_free (escaped);
return false;
}
return true;
}
static bool
_bson_as_json_visit_int32 (const bson_iter_t *iter,
const char *key,
int32_t v_int32,
void *data)
{
bson_json_state_t *state = data;
if (state->mode == BSON_JSON_MODE_CANONICAL) {
bson_string_append_printf (
state->str, "{ \"$numberInt\" : \"%" PRId32 "\" }", v_int32);
} else {
bson_string_append_printf (state->str, "%" PRId32, v_int32);
}
return false;
}
static bool
_bson_as_json_visit_int64 (const bson_iter_t *iter,
const char *key,
int64_t v_int64,
void *data)
{
bson_json_state_t *state = data;
if (state->mode == BSON_JSON_MODE_CANONICAL) {
bson_string_append_printf (
state->str, "{ \"$numberLong\" : \"%" PRId64 "\" }", v_int64);
} else {
bson_string_append_printf (state->str, "%" PRId64, v_int64);
}
return false;
}
static bool
_bson_as_json_visit_decimal128 (const bson_iter_t *iter,
const char *key,
const bson_decimal128_t *value,
void *data)
{
bson_json_state_t *state = data;
char decimal128_string[BSON_DECIMAL128_STRING];
bson_decimal128_to_string (value, decimal128_string);
bson_string_append (state->str, "{ \"$numberDecimal\" : \"");
bson_string_append (state->str, decimal128_string);
bson_string_append (state->str, "\" }");
return false;
}
static bool
_bson_as_json_visit_double (const bson_iter_t *iter,
const char *key,
double v_double,
void *data)
{
bson_json_state_t *state = data;
bson_string_t *str = state->str;
uint32_t start_len;
bool legacy;
/* Determine if legacy (i.e. unwrapped) output should be used. Relaxed mode
* will use this for nan and inf values, which we check manually since old
* platforms may not have isinf or isnan. */
legacy = state->mode == BSON_JSON_MODE_LEGACY ||
(state->mode == BSON_JSON_MODE_RELAXED &&
!(v_double != v_double || v_double * 0 != 0));
if (!legacy) {
bson_string_append (state->str, "{ \"$numberDouble\" : \"");
}
if (!legacy && v_double != v_double) {
bson_string_append (str, "NaN");
} else if (!legacy && v_double * 0 != 0) {
if (v_double > 0) {
bson_string_append (str, "Infinity");
} else {
bson_string_append (str, "-Infinity");
}
} else {
start_len = str->len;
bson_string_append_printf (str, "%.20g", v_double);
/* ensure trailing ".0" to distinguish "3" from "3.0" */
if (strspn (&str->str[start_len], "0123456789-") ==
str->len - start_len) {
bson_string_append (str, ".0");
}
}
if (!legacy) {
bson_string_append (state->str, "\" }");
}
return false;
}
static bool
_bson_as_json_visit_undefined (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$undefined\" : true }");
return false;
}
static bool
_bson_as_json_visit_null (const bson_iter_t *iter, const char *key, void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "null");
return false;
}
static bool
_bson_as_json_visit_oid (const bson_iter_t *iter,
const char *key,
const bson_oid_t *oid,
void *data)
{
bson_json_state_t *state = data;
char str[25];
bson_oid_to_string (oid, str);
bson_string_append (state->str, "{ \"$oid\" : \"");
bson_string_append (state->str, str);
bson_string_append (state->str, "\" }");
return false;
}
static bool
_bson_as_json_visit_binary (const bson_iter_t *iter,
const char *key,
bson_subtype_t v_subtype,
size_t v_binary_len,
const uint8_t *v_binary,
void *data)
{
bson_json_state_t *state = data;
size_t b64_len;
char *b64;
- b64_len = COMMON_PREFIX (bson_b64_ntop_calculate_target_size (v_binary_len));
+ b64_len = mcommon_b64_ntop_calculate_target_size (v_binary_len);
b64 = bson_malloc0 (b64_len);
- BSON_ASSERT (
- COMMON_PREFIX (bson_b64_ntop (v_binary, v_binary_len, b64, b64_len) != -1));
+ BSON_ASSERT (mcommon_b64_ntop (v_binary, v_binary_len, b64, b64_len) != -1);
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$binary\" : { \"base64\" : \"");
bson_string_append (state->str, b64);
bson_string_append (state->str, "\", \"subType\" : \"");
bson_string_append_printf (state->str, "%02x", v_subtype);
bson_string_append (state->str, "\" } }");
} else {
bson_string_append (state->str, "{ \"$binary\" : \"");
bson_string_append (state->str, b64);
bson_string_append (state->str, "\", \"$type\" : \"");
bson_string_append_printf (state->str, "%02x", v_subtype);
bson_string_append (state->str, "\" }");
}
bson_free (b64);
return false;
}
static bool
_bson_as_json_visit_bool (const bson_iter_t *iter,
const char *key,
bool v_bool,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, v_bool ? "true" : "false");
return false;
}
static bool
_bson_as_json_visit_date_time (const bson_iter_t *iter,
const char *key,
int64_t msec_since_epoch,
void *data)
{
bson_json_state_t *state = data;
if (state->mode == BSON_JSON_MODE_CANONICAL ||
(state->mode == BSON_JSON_MODE_RELAXED && msec_since_epoch < 0)) {
bson_string_append (state->str, "{ \"$date\" : { \"$numberLong\" : \"");
bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch);
bson_string_append (state->str, "\" } }");
} else if (state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$date\" : \"");
_bson_iso8601_date_format (msec_since_epoch, state->str);
bson_string_append (state->str, "\" }");
} else {
bson_string_append (state->str, "{ \"$date\" : ");
bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch);
bson_string_append (state->str, " }");
}
return false;
}
static bool
_bson_as_json_visit_regex (const bson_iter_t *iter,
const char *key,
const char *v_regex,
const char *v_options,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_regex, -1);
if (!escaped) {
return true;
}
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str,
"{ \"$regularExpression\" : { \"pattern\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\", \"options\" : \"");
_bson_append_regex_options_sorted (state->str, v_options);
bson_string_append (state->str, "\" } }");
} else {
bson_string_append (state->str, "{ \"$regex\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\", \"$options\" : \"");
_bson_append_regex_options_sorted (state->str, v_options);
bson_string_append (state->str, "\" }");
}
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_timestamp (const bson_iter_t *iter,
const char *key,
uint32_t v_timestamp,
uint32_t v_increment,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$timestamp\" : { \"t\" : ");
bson_string_append_printf (state->str, "%u", v_timestamp);
bson_string_append (state->str, ", \"i\" : ");
bson_string_append_printf (state->str, "%u", v_increment);
bson_string_append (state->str, " } }");
return false;
}
static bool
_bson_as_json_visit_dbpointer (const bson_iter_t *iter,
const char *key,
size_t v_collection_len,
const char *v_collection,
const bson_oid_t *v_oid,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
char str[25];
escaped = bson_utf8_escape_for_json (v_collection, -1);
if (!escaped) {
return true;
}
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$dbPointer\" : { \"$ref\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
if (v_oid) {
bson_oid_to_string (v_oid, str);
bson_string_append (state->str, ", \"$id\" : { \"$oid\" : \"");
bson_string_append (state->str, str);
bson_string_append (state->str, "\" }");
}
bson_string_append (state->str, " } }");
} else {
bson_string_append (state->str, "{ \"$ref\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
if (v_oid) {
bson_oid_to_string (v_oid, str);
bson_string_append (state->str, ", \"$id\" : \"");
bson_string_append (state->str, str);
bson_string_append (state->str, "\"");
}
bson_string_append (state->str, " }");
}
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_minkey (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$minKey\" : 1 }");
return false;
}
static bool
_bson_as_json_visit_maxkey (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
bson_string_append (state->str, "{ \"$maxKey\" : 1 }");
return false;
}
static bool
_bson_as_json_visit_before (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
if (state->max_len_reached) {
return true;
}
if (state->count) {
bson_string_append (state->str, ", ");
}
if (state->keys) {
escaped = bson_utf8_escape_for_json (key, -1);
if (escaped) {
bson_string_append (state->str, "\"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\" : ");
bson_free (escaped);
} else {
return true;
}
}
state->count++;
return false;
}
static bool
_bson_as_json_visit_after (const bson_iter_t *iter, const char *key, void *data)
{
bson_json_state_t *state = data;
if (state->max_len == BSON_MAX_LEN_UNLIMITED) {
return false;
}
if (state->str->len >= state->max_len) {
state->max_len_reached = true;
if (state->str->len > state->max_len) {
/* Truncate string to maximum length */
bson_string_truncate (state->str, state->max_len);
}
return true;
}
return false;
}
static void
_bson_as_json_visit_corrupt (const bson_iter_t *iter, void *data)
{
*(((bson_json_state_t *) data)->err_offset) = iter->off;
}
static bool
_bson_as_json_visit_code (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_code, v_code_len);
if (!escaped) {
return true;
}
bson_string_append (state->str, "{ \"$code\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\" }");
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_symbol (const bson_iter_t *iter,
const char *key,
size_t v_symbol_len,
const char *v_symbol,
void *data)
{
bson_json_state_t *state = data;
char *escaped;
escaped = bson_utf8_escape_for_json (v_symbol, v_symbol_len);
if (!escaped) {
return true;
}
if (state->mode == BSON_JSON_MODE_CANONICAL ||
state->mode == BSON_JSON_MODE_RELAXED) {
bson_string_append (state->str, "{ \"$symbol\" : \"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\" }");
} else {
bson_string_append (state->str, "\"");
bson_string_append (state->str, escaped);
bson_string_append (state->str, "\"");
}
bson_free (escaped);
return false;
}
static bool
_bson_as_json_visit_codewscope (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
const bson_t *v_scope,
void *data)
{
bson_json_state_t *state = data;
char *code_escaped;
char *scope;
int32_t max_scope_len = BSON_MAX_LEN_UNLIMITED;
code_escaped = bson_utf8_escape_for_json (v_code, v_code_len);
if (!code_escaped) {
return true;
}
bson_string_append (state->str, "{ \"$code\" : \"");
bson_string_append (state->str, code_escaped);
bson_string_append (state->str, "\", \"$scope\" : ");
bson_free (code_escaped);
/* Encode scope with the same mode */
if (state->max_len != BSON_MAX_LEN_UNLIMITED) {
max_scope_len = BSON_MAX (0, state->max_len - state->str->len);
}
scope = _bson_as_json_visit_all (v_scope, NULL, state->mode, max_scope_len);
if (!scope) {
return true;
}
bson_string_append (state->str, scope);
bson_string_append (state->str, " }");
bson_free (scope);
return false;
}
static const bson_visitor_t bson_as_json_visitors = {
_bson_as_json_visit_before, _bson_as_json_visit_after,
_bson_as_json_visit_corrupt, _bson_as_json_visit_double,
_bson_as_json_visit_utf8, _bson_as_json_visit_document,
_bson_as_json_visit_array, _bson_as_json_visit_binary,
_bson_as_json_visit_undefined, _bson_as_json_visit_oid,
_bson_as_json_visit_bool, _bson_as_json_visit_date_time,
_bson_as_json_visit_null, _bson_as_json_visit_regex,
_bson_as_json_visit_dbpointer, _bson_as_json_visit_code,
_bson_as_json_visit_symbol, _bson_as_json_visit_codewscope,
_bson_as_json_visit_int32, _bson_as_json_visit_timestamp,
_bson_as_json_visit_int64, _bson_as_json_visit_maxkey,
_bson_as_json_visit_minkey, NULL, /* visit_unsupported_type */
_bson_as_json_visit_decimal128,
};
static bool
_bson_as_json_visit_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data)
{
bson_json_state_t *state = data;
bson_json_state_t child_state = {0, true, state->err_offset};
bson_iter_t child;
if (state->depth >= BSON_MAX_RECURSION) {
bson_string_append (state->str, "{ ... }");
return false;
}
if (bson_iter_init (&child, v_document)) {
child_state.str = bson_string_new ("{ ");
child_state.depth = state->depth + 1;
child_state.mode = state->mode;
child_state.max_len = BSON_MAX_LEN_UNLIMITED;
if (state->max_len != BSON_MAX_LEN_UNLIMITED) {
child_state.max_len = BSON_MAX (0, state->max_len - state->str->len);
}
child_state.max_len_reached = child_state.max_len == 0;
if (bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state)) {
if (child_state.max_len_reached) {
bson_string_append (state->str, child_state.str->str);
}
bson_string_free (child_state.str, true);
/* If max_len was reached, we return a success state to ensure that
* VISIT_AFTER is still called
*/
return !child_state.max_len_reached;
}
bson_string_append (child_state.str, " }");
bson_string_append (state->str, child_state.str->str);
bson_string_free (child_state.str, true);
}
return false;
}
static bool
_bson_as_json_visit_array (const bson_iter_t *iter,
const char *key,
const bson_t *v_array,
void *data)
{
bson_json_state_t *state = data;
bson_json_state_t child_state = {0, false, state->err_offset};
bson_iter_t child;
if (state->depth >= BSON_MAX_RECURSION) {
bson_string_append (state->str, "{ ... }");
return false;
}
if (bson_iter_init (&child, v_array)) {
child_state.str = bson_string_new ("[ ");
child_state.depth = state->depth + 1;
child_state.mode = state->mode;
child_state.max_len = BSON_MAX_LEN_UNLIMITED;
if (state->max_len != BSON_MAX_LEN_UNLIMITED) {
child_state.max_len = BSON_MAX (0, state->max_len - state->str->len);
}
child_state.max_len_reached = child_state.max_len == 0;
if (bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state)) {
if (child_state.max_len_reached) {
bson_string_append (state->str, child_state.str->str);
}
bson_string_free (child_state.str, true);
/* If max_len was reached, we return a success state to ensure that
* VISIT_AFTER is still called
*/
return !child_state.max_len_reached;
}
bson_string_append (child_state.str, " ]");
bson_string_append (state->str, child_state.str->str);
bson_string_free (child_state.str, true);
}
return false;
}
static char *
_bson_as_json_visit_all (const bson_t *bson,
size_t *length,
bson_json_mode_t mode,
int32_t max_len)
{
bson_json_state_t state;
bson_iter_t iter;
ssize_t err_offset = -1;
int32_t remaining;
BSON_ASSERT (bson);
if (length) {
*length = 0;
}
if (bson_empty0 (bson)) {
if (length) {
*length = 3;
}
return bson_strdup ("{ }");
}
if (!bson_iter_init (&iter, bson)) {
return NULL;
}
state.count = 0;
state.keys = true;
state.str = bson_string_new ("{ ");
state.depth = 0;
state.err_offset = &err_offset;
state.mode = mode;
state.max_len = max_len;
state.max_len_reached = false;
if ((bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) ||
err_offset != -1) &&
!state.max_len_reached) {
/*
* We were prematurely exited due to corruption or failed visitor.
*/
bson_string_free (state.str, true);
if (length) {
*length = 0;
}
return NULL;
}
/* Append closing space and } separately, in case we hit the max in between. */
remaining = state.max_len - state.str->len;
if (state.max_len == BSON_MAX_LEN_UNLIMITED ||
remaining > 1) {
bson_string_append (state.str, " }");
} else if (remaining == 1) {
bson_string_append (state.str, " ");
}
if (length) {
*length = state.str->len;
}
return bson_string_free (state.str, false);
}
char *
bson_as_json_with_opts (const bson_t *bson,
size_t *length,
const bson_json_opts_t *opts)
{
return _bson_as_json_visit_all (bson, length, opts->mode, opts->max_len);
}
char *
bson_as_canonical_extended_json (const bson_t *bson, size_t *length)
{
const bson_json_opts_t opts = {BSON_JSON_MODE_CANONICAL,
BSON_MAX_LEN_UNLIMITED};
return bson_as_json_with_opts (bson, length, &opts);
}
char *
bson_as_json (const bson_t *bson, size_t *length)
{
const bson_json_opts_t opts = {BSON_JSON_MODE_LEGACY,
BSON_MAX_LEN_UNLIMITED};
return bson_as_json_with_opts (bson, length, &opts);
}
char *
bson_as_relaxed_extended_json (const bson_t *bson, size_t *length)
{
const bson_json_opts_t opts = {BSON_JSON_MODE_RELAXED,
BSON_MAX_LEN_UNLIMITED};
return bson_as_json_with_opts (bson, length, &opts);
}
char *
bson_array_as_json (const bson_t *bson, size_t *length)
{
bson_json_state_t state;
bson_iter_t iter;
ssize_t err_offset = -1;
BSON_ASSERT (bson);
if (length) {
*length = 0;
}
if (bson_empty0 (bson)) {
if (length) {
*length = 3;
}
return bson_strdup ("[ ]");
}
if (!bson_iter_init (&iter, bson)) {
return NULL;
}
state.count = 0;
state.keys = false;
state.str = bson_string_new ("[ ");
state.depth = 0;
state.err_offset = &err_offset;
state.mode = BSON_JSON_MODE_LEGACY;
state.max_len = BSON_MAX_LEN_UNLIMITED;
state.max_len_reached = false;
if ((bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) ||
err_offset != -1) &&
!state.max_len_reached) {
/*
* We were prematurely exited due to corruption or failed visitor.
*/
bson_string_free (state.str, true);
if (length) {
*length = 0;
}
return NULL;
}
bson_string_append (state.str, " ]");
if (length) {
*length = state.str->len;
}
return bson_string_free (state.str, false);
}
#define VALIDATION_ERR(_flag, _msg, ...) \
bson_set_error (&state->error, BSON_ERROR_INVALID, _flag, _msg, __VA_ARGS__)
static bool
_bson_iter_validate_utf8 (const bson_iter_t *iter,
const char *key,
size_t v_utf8_len,
const char *v_utf8,
void *data)
{
bson_validate_state_t *state = data;
bool allow_null;
if ((state->flags & BSON_VALIDATE_UTF8)) {
allow_null = !!(state->flags & BSON_VALIDATE_UTF8_ALLOW_NULL);
if (!bson_utf8_validate (v_utf8, v_utf8_len, allow_null)) {
state->err_offset = iter->off;
VALIDATION_ERR (
BSON_VALIDATE_UTF8, "invalid utf8 string for key \"%s\"", key);
return true;
}
}
if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) {
if (state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8) {
state->phase = BSON_VALIDATE_PHASE_LF_ID_KEY;
} else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
state->phase = BSON_VALIDATE_PHASE_NOT_DBREF;
}
}
return false;
}
static void
_bson_iter_validate_corrupt (const bson_iter_t *iter, void *data)
{
bson_validate_state_t *state = data;
state->err_offset = iter->err_off;
VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON");
}
static bool
_bson_iter_validate_before (const bson_iter_t *iter,
const char *key,
void *data)
{
bson_validate_state_t *state = data;
if ((state->flags & BSON_VALIDATE_EMPTY_KEYS)) {
if (key[0] == '\0') {
state->err_offset = iter->off;
VALIDATION_ERR (BSON_VALIDATE_EMPTY_KEYS, "%s", "empty key");
return true;
}
}
if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) {
if (key[0] == '$') {
if (state->phase == BSON_VALIDATE_PHASE_LF_REF_KEY &&
strcmp (key, "$ref") == 0) {
state->phase = BSON_VALIDATE_PHASE_LF_REF_UTF8;
} else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY &&
strcmp (key, "$id") == 0) {
state->phase = BSON_VALIDATE_PHASE_LF_DB_KEY;
} else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_KEY &&
strcmp (key, "$db") == 0) {
state->phase = BSON_VALIDATE_PHASE_LF_DB_UTF8;
} else {
state->err_offset = iter->off;
VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS,
"keys cannot begin with \"$\": \"%s\"",
key);
return true;
}
} else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY ||
state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 ||
state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
state->err_offset = iter->off;
VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS,
"invalid key within DBRef subdocument: \"%s\"",
key);
return true;
} else {
state->phase = BSON_VALIDATE_PHASE_NOT_DBREF;
}
}
if ((state->flags & BSON_VALIDATE_DOT_KEYS)) {
if (strstr (key, ".")) {
state->err_offset = iter->off;
VALIDATION_ERR (
BSON_VALIDATE_DOT_KEYS, "keys cannot contain \".\": \"%s\"", key);
return true;
}
}
return false;
}
static bool
_bson_iter_validate_codewscope (const bson_iter_t *iter,
const char *key,
size_t v_code_len,
const char *v_code,
const bson_t *v_scope,
void *data)
{
bson_validate_state_t *state = data;
size_t offset = 0;
if (!bson_validate (v_scope, state->flags, &offset)) {
state->err_offset = iter->off + offset;
VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt code-with-scope");
return false;
}
return true;
}
static bool
_bson_iter_validate_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data);
static const bson_visitor_t bson_validate_funcs = {
_bson_iter_validate_before,
NULL, /* visit_after */
_bson_iter_validate_corrupt,
NULL, /* visit_double */
_bson_iter_validate_utf8,
_bson_iter_validate_document,
_bson_iter_validate_document, /* visit_array */
NULL, /* visit_binary */
NULL, /* visit_undefined */
NULL, /* visit_oid */
NULL, /* visit_bool */
NULL, /* visit_date_time */
NULL, /* visit_null */
NULL, /* visit_regex */
NULL, /* visit_dbpoint */
NULL, /* visit_code */
NULL, /* visit_symbol */
_bson_iter_validate_codewscope,
};
static bool
_bson_iter_validate_document (const bson_iter_t *iter,
const char *key,
const bson_t *v_document,
void *data)
{
bson_validate_state_t *state = data;
bson_iter_t child;
bson_validate_phase_t phase = state->phase;
if (!bson_iter_init (&child, v_document)) {
state->err_offset = iter->off;
return true;
}
if (state->phase == BSON_VALIDATE_PHASE_START) {
state->phase = BSON_VALIDATE_PHASE_TOP;
} else {
state->phase = BSON_VALIDATE_PHASE_LF_REF_KEY;
}
(void) bson_iter_visit_all (&child, &bson_validate_funcs, state);
if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY ||
state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 ||
state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
if (state->err_offset <= 0) {
state->err_offset = iter->off;
}
return true;
}
state->phase = phase;
return false;
}
static void
_bson_validate_internal (const bson_t *bson, bson_validate_state_t *state)
{
bson_iter_t iter;
state->err_offset = -1;
state->phase = BSON_VALIDATE_PHASE_START;
memset (&state->error, 0, sizeof state->error);
if (!bson_iter_init (&iter, bson)) {
state->err_offset = 0;
VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON");
} else {
_bson_iter_validate_document (&iter, NULL, bson, state);
}
}
bool
bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset)
{
bson_validate_state_t state;
state.flags = flags;
_bson_validate_internal (bson, &state);
if (state.err_offset > 0 && offset) {
*offset = (size_t) state.err_offset;
}
return state.err_offset < 0;
}
bool
bson_validate_with_error (const bson_t *bson,
bson_validate_flags_t flags,
bson_error_t *error)
{
bson_validate_state_t state;
state.flags = flags;
_bson_validate_internal (bson, &state);
if (state.err_offset > 0 && error) {
memcpy (error, &state.error, sizeof *error);
}
return state.err_offset < 0;
}
bool
bson_concat (bson_t *dst, const bson_t *src)
{
BSON_ASSERT (dst);
BSON_ASSERT (src);
if (!bson_empty (src)) {
return _bson_append (
dst, 1, src->len - 5, src->len - 5, _bson_data (src) + 4);
}
return true;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson.h
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson.h
index 6a5006fa..8ffc58ec 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/bson/bson.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/bson/bson.h
@@ -1,1175 +1,1176 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BSON_H
#define BSON_H
#define BSON_INSIDE
#include "bson-compat.h"
#include <string.h>
#include <time.h>
#include "bson-macros.h"
#include "bson-config.h"
#include "bson-atomic.h"
+#include "bson-cmp.h"
#include "bson-context.h"
#include "bson-clock.h"
#include "bson-decimal128.h"
#include "bson-error.h"
#include "bson-iter.h"
#include "bson-json.h"
#include "bson-keys.h"
#include "bson-md5.h"
#include "bson-memory.h"
#include "bson-oid.h"
#include "bson-reader.h"
#include "bson-string.h"
#include "bson-types.h"
#include "bson-utf8.h"
#include "bson-value.h"
#include "bson-version.h"
#include "bson-version-functions.h"
#include "bson-writer.h"
#include "bcon.h"
#undef BSON_INSIDE
BSON_BEGIN_DECLS
/**
* bson_empty:
* @b: a bson_t.
*
* Checks to see if @b is an empty BSON document. An empty BSON document is
* a 5 byte document which contains the length (4 bytes) and a single NUL
* byte indicating end of fields.
*/
#define bson_empty(b) (((b)->len == 5) || !bson_get_data ((b))[4])
/**
* bson_empty0:
*
* Like bson_empty() but treats NULL the same as an empty bson_t document.
*/
#define bson_empty0(b) (!(b) || bson_empty (b))
/**
* bson_clear:
*
* Easily free a bson document and set it to NULL. Use like:
*
* bson_t *doc = bson_new();
* bson_clear (&doc);
* BSON_ASSERT (doc == NULL);
*/
#define bson_clear(bptr) \
do { \
if (*(bptr)) { \
bson_destroy (*(bptr)); \
*(bptr) = NULL; \
} \
} while (0)
/**
* BSON_MAX_SIZE:
*
* The maximum size in bytes of a BSON document.
*/
#define BSON_MAX_SIZE ((size_t) ((1U << 31) - 1))
#define BSON_APPEND_ARRAY(b, key, val) \
bson_append_array (b, key, (int) strlen (key), val)
#define BSON_APPEND_ARRAY_BEGIN(b, key, child) \
bson_append_array_begin (b, key, (int) strlen (key), child)
#define BSON_APPEND_BINARY(b, key, subtype, val, len) \
bson_append_binary (b, key, (int) strlen (key), subtype, val, len)
#define BSON_APPEND_BOOL(b, key, val) \
bson_append_bool (b, key, (int) strlen (key), val)
#define BSON_APPEND_CODE(b, key, val) \
bson_append_code (b, key, (int) strlen (key), val)
#define BSON_APPEND_CODE_WITH_SCOPE(b, key, val, scope) \
bson_append_code_with_scope (b, key, (int) strlen (key), val, scope)
#define BSON_APPEND_DBPOINTER(b, key, coll, oid) \
bson_append_dbpointer (b, key, (int) strlen (key), coll, oid)
#define BSON_APPEND_DOCUMENT_BEGIN(b, key, child) \
bson_append_document_begin (b, key, (int) strlen (key), child)
#define BSON_APPEND_DOUBLE(b, key, val) \
bson_append_double (b, key, (int) strlen (key), val)
#define BSON_APPEND_DOCUMENT(b, key, val) \
bson_append_document (b, key, (int) strlen (key), val)
#define BSON_APPEND_INT32(b, key, val) \
bson_append_int32 (b, key, (int) strlen (key), val)
#define BSON_APPEND_INT64(b, key, val) \
bson_append_int64 (b, key, (int) strlen (key), val)
#define BSON_APPEND_MINKEY(b, key) \
bson_append_minkey (b, key, (int) strlen (key))
#define BSON_APPEND_DECIMAL128(b, key, val) \
bson_append_decimal128 (b, key, (int) strlen (key), val)
#define BSON_APPEND_MAXKEY(b, key) \
bson_append_maxkey (b, key, (int) strlen (key))
#define BSON_APPEND_NULL(b, key) bson_append_null (b, key, (int) strlen (key))
#define BSON_APPEND_OID(b, key, val) \
bson_append_oid (b, key, (int) strlen (key), val)
#define BSON_APPEND_REGEX(b, key, val, opt) \
bson_append_regex (b, key, (int) strlen (key), val, opt)
#define BSON_APPEND_UTF8(b, key, val) \
bson_append_utf8 (b, key, (int) strlen (key), val, (int) strlen (val))
#define BSON_APPEND_SYMBOL(b, key, val) \
bson_append_symbol (b, key, (int) strlen (key), val, (int) strlen (val))
#define BSON_APPEND_TIME_T(b, key, val) \
bson_append_time_t (b, key, (int) strlen (key), val)
#define BSON_APPEND_TIMEVAL(b, key, val) \
bson_append_timeval (b, key, (int) strlen (key), val)
#define BSON_APPEND_DATE_TIME(b, key, val) \
bson_append_date_time (b, key, (int) strlen (key), val)
#define BSON_APPEND_TIMESTAMP(b, key, val, inc) \
bson_append_timestamp (b, key, (int) strlen (key), val, inc)
#define BSON_APPEND_UNDEFINED(b, key) \
bson_append_undefined (b, key, (int) strlen (key))
#define BSON_APPEND_VALUE(b, key, val) \
bson_append_value (b, key, (int) strlen (key), (val))
/**
* bson_new:
*
* Allocates a new bson_t structure. Call the various bson_append_*()
* functions to add fields to the bson. You can iterate the bson_t at any
* time using a bson_iter_t and bson_iter_init().
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
*/
BSON_EXPORT (bson_t *)
bson_new (void);
BSON_EXPORT (bson_t *)
bson_new_from_json (const uint8_t *data, ssize_t len, bson_error_t *error);
BSON_EXPORT (bool)
bson_init_from_json (bson_t *bson,
const char *data,
ssize_t len,
bson_error_t *error);
/**
* bson_init_static:
* @b: A pointer to a bson_t.
* @data: The data buffer to use.
* @length: The length of @data.
*
* Initializes a bson_t using @data and @length. This is ideal if you would
* like to use a stack allocation for your bson and do not need to grow the
* buffer. @data must be valid for the life of @b.
*
* Returns: true if initialized successfully; otherwise false.
*/
BSON_EXPORT (bool)
bson_init_static (bson_t *b, const uint8_t *data, size_t length);
/**
* bson_init:
* @b: A pointer to a bson_t.
*
* Initializes a bson_t for use. This function is useful to those that want a
* stack allocated bson_t. The usefulness of a stack allocated bson_t is
* marginal as the target buffer for content will still require heap
* allocations. It can help reduce heap fragmentation on allocators that do
* not employ SLAB/magazine semantics.
*
* You must call bson_destroy() with @b to release resources when you are done
* using @b.
*/
BSON_EXPORT (void)
bson_init (bson_t *b);
/**
* bson_reinit:
* @b: (inout): A bson_t.
*
* This is equivalent to calling bson_destroy() and bson_init() on a #bson_t.
* However, it will try to persist the existing malloc'd buffer if one exists.
* This is useful in cases where you want to reduce malloc overhead while
* building many documents.
*/
BSON_EXPORT (void)
bson_reinit (bson_t *b);
/**
* bson_new_from_data:
* @data: A buffer containing a serialized bson document.
* @length: The length of the document in bytes.
*
* Creates a new bson_t structure using the data provided. @data should contain
* at least @length bytes that can be copied into the new bson_t structure.
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
* If the first four bytes (little-endian) of data do not match @length,
* then NULL will be returned.
*/
BSON_EXPORT (bson_t *)
bson_new_from_data (const uint8_t *data, size_t length);
/**
* bson_new_from_buffer:
* @buf: A pointer to a buffer containing a serialized bson document.
* @buf_len: The length of the buffer in bytes.
* @realloc_fun: a realloc like function
* @realloc_fun_ctx: a context for the realloc function
*
* Creates a new bson_t structure using the data provided. @buf should contain
* a bson document, or null pointer should be passed for new allocations.
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
* The underlying buffer will be used and not be freed in destroy.
*/
BSON_EXPORT (bson_t *)
bson_new_from_buffer (uint8_t **buf,
size_t *buf_len,
bson_realloc_func realloc_func,
void *realloc_func_ctx);
/**
* bson_sized_new:
* @size: A size_t containing the number of bytes to allocate.
*
* This will allocate a new bson_t with enough bytes to hold a buffer
* sized @size. @size must be smaller than INT_MAX bytes.
*
* Returns: A newly allocated bson_t that should be freed with bson_destroy().
*/
BSON_EXPORT (bson_t *)
bson_sized_new (size_t size);
/**
* bson_copy:
* @bson: A bson_t.
*
* Copies @bson into a newly allocated bson_t. You must call bson_destroy()
* when you are done with the resulting value to free its resources.
*
* Returns: A newly allocated bson_t that should be free'd with bson_destroy()
*/
BSON_EXPORT (bson_t *)
bson_copy (const bson_t *bson);
/**
* bson_copy_to:
* @src: The source bson_t.
* @dst: The destination bson_t.
*
* Initializes @dst and copies the content from @src into @dst.
*/
BSON_EXPORT (void)
bson_copy_to (const bson_t *src, bson_t *dst);
/**
* bson_copy_to_excluding:
* @src: A bson_t.
* @dst: A bson_t to initialize and copy into.
* @first_exclude: First field name to exclude.
*
* Copies @src into @dst excluding any field that is provided.
* This is handy for situations when you need to remove one or
* more fields in a bson_t. Note that bson_init() will be called
* on dst.
*/
BSON_EXPORT (void)
bson_copy_to_excluding (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...) BSON_GNUC_NULL_TERMINATED
BSON_GNUC_DEPRECATED_FOR (bson_copy_to_excluding_noinit);
/**
* bson_copy_to_excluding_noinit:
* @src: A bson_t.
* @dst: A bson_t to initialize and copy into.
* @first_exclude: First field name to exclude.
*
* The same as bson_copy_to_excluding, but does not call bson_init()
* on the dst. This version should be preferred in new code, but the
* old function is left for backwards compatibility.
*/
BSON_EXPORT (void)
bson_copy_to_excluding_noinit (const bson_t *src,
bson_t *dst,
const char *first_exclude,
...) BSON_GNUC_NULL_TERMINATED;
BSON_EXPORT (void)
bson_copy_to_excluding_noinit_va (const bson_t *src,
bson_t *dst,
const char *first_exclude,
va_list args);
/**
* bson_destroy:
* @bson: A bson_t.
*
* Frees the resources associated with @bson.
*/
BSON_EXPORT (void)
bson_destroy (bson_t *bson);
BSON_EXPORT (uint8_t *)
bson_reserve_buffer (bson_t *bson, uint32_t size);
BSON_EXPORT (bool)
bson_steal (bson_t *dst, bson_t *src);
/**
* bson_destroy_with_steal:
* @bson: A #bson_t.
* @steal: If ownership of the data buffer should be transferred to caller.
* @length: (out): location for the length of the buffer.
*
* Destroys @bson similar to calling bson_destroy() except that the underlying
* buffer will be returned and ownership transferred to the caller if @steal
* is non-zero.
*
* If length is non-NULL, the length of @bson will be stored in @length.
*
* It is a programming error to call this function with any bson that has
* been initialized static, or is being used to create a subdocument with
* functions such as bson_append_document_begin() or bson_append_array_begin().
*
* Returns: a buffer owned by the caller if @steal is true. Otherwise NULL.
* If there was an error, NULL is returned.
*/
BSON_EXPORT (uint8_t *)
bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length);
/**
* bson_get_data:
* @bson: A bson_t.
*
* Fetched the data buffer for @bson of @bson->len bytes in length.
*
* Returns: A buffer that should not be modified or freed.
*/
BSON_EXPORT (const uint8_t *)
bson_get_data (const bson_t *bson);
/**
* bson_count_keys:
* @bson: A bson_t.
*
* Counts the number of elements found in @bson.
*/
BSON_EXPORT (uint32_t)
bson_count_keys (const bson_t *bson);
/**
* bson_has_field:
* @bson: A bson_t.
* @key: The key to lookup.
*
* Checks to see if @bson contains a field named @key.
*
* This function is case-sensitive.
*
* Returns: true if @key exists in @bson; otherwise false.
*/
BSON_EXPORT (bool)
bson_has_field (const bson_t *bson, const char *key);
/**
* bson_compare:
* @bson: A bson_t.
* @other: A bson_t.
*
* Compares @bson to @other in a qsort() style comparison.
* See qsort() for information on how this function works.
*
* Returns: Less than zero, zero, or greater than zero.
*/
BSON_EXPORT (int)
bson_compare (const bson_t *bson, const bson_t *other);
/*
* bson_equal:
* @bson: A bson_t.
* @other: A bson_t.
*
* Checks to see if @bson and @other are equal.
*
* Returns: true if equal; otherwise false.
*/
BSON_EXPORT (bool)
bson_equal (const bson_t *bson, const bson_t *other);
/**
* bson_validate:
* @bson: A bson_t.
* @offset: A location for the error offset.
*
* Validates a BSON document by walking through the document and inspecting
* the fields for valid content.
*
* Returns: true if @bson is valid; otherwise false and @offset is set.
*/
BSON_EXPORT (bool)
bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset);
/**
* bson_validate_with_error:
* @bson: A bson_t.
* @error: A location for the error info.
*
* Validates a BSON document by walking through the document and inspecting
* the fields for valid content.
*
* Returns: true if @bson is valid; otherwise false and @error is filled out.
*/
BSON_EXPORT (bool)
bson_validate_with_error (const bson_t *bson,
bson_validate_flags_t flags,
bson_error_t *error);
/**
* bson_as_json_with_opts:
* @bson: A bson_t.
* @length: A location for the string length, or NULL.
* @opts: A bson_t_json_opts_t defining options for the conversion
*
* Creates a new string containing @bson in the selected JSON format,
* conforming to the MongoDB Extended JSON Spec:
*
* github.com/mongodb/specifications/blob/master/source/extended-json.rst
*
* The caller is responsible for freeing the resulting string. If @length is
* non-NULL, then the length of the resulting string will be placed in @length.
*
* See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for
* more information on extended JSON.
*
* Returns: A newly allocated string that should be freed with bson_free().
*/
BSON_EXPORT (char *)
bson_as_json_with_opts (const bson_t *bson,
size_t *length,
const bson_json_opts_t *opts);
/**
* bson_as_canonical_extended_json:
* @bson: A bson_t.
* @length: A location for the string length, or NULL.
*
* Creates a new string containing @bson in canonical extended JSON format,
* conforming to the MongoDB Extended JSON Spec:
*
* github.com/mongodb/specifications/blob/master/source/extended-json.rst
*
* The caller is responsible for freeing the resulting string. If @length is
* non-NULL, then the length of the resulting string will be placed in @length.
*
* See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for
* more information on extended JSON.
*
* Returns: A newly allocated string that should be freed with bson_free().
*/
BSON_EXPORT (char *)
bson_as_canonical_extended_json (const bson_t *bson, size_t *length);
/**
* bson_as_json:
* @bson: A bson_t.
* @length: A location for the string length, or NULL.
*
* Creates a new string containing @bson in libbson's legacy JSON format.
* Superseded by bson_as_canonical_extended_json and
* bson_as_relaxed_extended_json. The caller is
* responsible for freeing the resulting string. If @length is non-NULL, then
* the length of the resulting string will be placed in @length.
*
* Returns: A newly allocated string that should be freed with bson_free().
*/
BSON_EXPORT (char *)
bson_as_json (const bson_t *bson, size_t *length);
/**
* bson_as_relaxed_extended_json:
* @bson: A bson_t.
* @length: A location for the string length, or NULL.
*
* Creates a new string containing @bson in relaxed extended JSON format,
* conforming to the MongoDB Extended JSON Spec:
*
* github.com/mongodb/specifications/blob/master/source/extended-json.rst
*
* The caller is responsible for freeing the resulting string. If @length is
* non-NULL, then the length of the resulting string will be placed in @length.
*
* See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for
* more information on extended JSON.
*
* Returns: A newly allocated string that should be freed with bson_free().
*/
BSON_EXPORT (char *)
bson_as_relaxed_extended_json (const bson_t *bson, size_t *length);
/* like bson_as_json() but for outermost arrays. */
BSON_EXPORT (char *)
bson_array_as_json (const bson_t *bson, size_t *length);
BSON_EXPORT (bool)
bson_append_value (bson_t *bson,
const char *key,
int key_length,
const bson_value_t *value);
/**
* bson_append_array:
* @bson: A bson_t.
* @key: The key for the field.
* @array: A bson_t containing the array.
*
* Appends a BSON array to @bson. BSON arrays are like documents where the
* key is the string version of the index. For example, the first item of the
* array would have the key "0". The second item would have the index "1".
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_array (bson_t *bson,
const char *key,
int key_length,
const bson_t *array);
/**
* bson_append_binary:
* @bson: A bson_t to append.
* @key: The key for the field.
* @subtype: The bson_subtype_t of the binary.
* @binary: The binary buffer to append.
* @length: The length of @binary.
*
* Appends a binary buffer to the BSON document.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_binary (bson_t *bson,
const char *key,
int key_length,
bson_subtype_t subtype,
const uint8_t *binary,
uint32_t length);
/**
* bson_append_bool:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The boolean value.
*
* Appends a new field to @bson of type BSON_TYPE_BOOL.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_bool (bson_t *bson, const char *key, int key_length, bool value);
/**
* bson_append_code:
* @bson: A bson_t.
* @key: The key for the document.
* @javascript: JavaScript code to be executed.
*
* Appends a field of type BSON_TYPE_CODE to the BSON document. @javascript
* should contain a script in javascript to be executed.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_code (bson_t *bson,
const char *key,
int key_length,
const char *javascript);
/**
* bson_append_code_with_scope:
* @bson: A bson_t.
* @key: The key for the document.
* @javascript: JavaScript code to be executed.
* @scope: A bson_t containing the scope for @javascript.
*
* Appends a field of type BSON_TYPE_CODEWSCOPE to the BSON document.
* @javascript should contain a script in javascript to be executed.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_code_with_scope (bson_t *bson,
const char *key,
int key_length,
const char *javascript,
const bson_t *scope);
/**
* bson_append_dbpointer:
* @bson: A bson_t.
* @key: The key for the field.
* @collection: The collection name.
* @oid: The oid to the reference.
*
* Appends a new field of type BSON_TYPE_DBPOINTER. This datum type is
* deprecated in the BSON spec and should not be used in new code.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_dbpointer (bson_t *bson,
const char *key,
int key_length,
const char *collection,
const bson_oid_t *oid);
/**
* bson_append_double:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field to @bson of the type BSON_TYPE_DOUBLE.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_double (bson_t *bson,
const char *key,
int key_length,
double value);
/**
* bson_append_document:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A bson_t containing the subdocument.
*
* Appends a new field to @bson of the type BSON_TYPE_DOCUMENT.
* The documents contents will be copied into @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_document (bson_t *bson,
const char *key,
int key_length,
const bson_t *value);
/**
* bson_append_document_begin:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key in bytes not including NUL or -1
* if @key_length is NUL terminated.
* @child: A location to an uninitialized bson_t.
*
* Appends a new field named @key to @bson. The field is, however,
* incomplete. @child will be initialized so that you may add fields to the
* child document. Child will use a memory buffer owned by @bson and
* therefore grow the parent buffer as additional space is used. This allows
* a single malloc'd buffer to be used when building documents which can help
* reduce memory fragmentation.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_document_begin (bson_t *bson,
const char *key,
int key_length,
bson_t *child);
/**
* bson_append_document_end:
* @bson: A bson_t.
* @child: A bson_t supplied to bson_append_document_begin().
*
* Finishes the appending of a document to a @bson. @child is considered
* disposed after this call and should not be used any further.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_document_end (bson_t *bson, bson_t *child);
/**
* bson_append_array_begin:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key in bytes not including NUL or -1
* if @key_length is NUL terminated.
* @child: A location to an uninitialized bson_t.
*
* Appends a new field named @key to @bson. The field is, however,
* incomplete. @child will be initialized so that you may add fields to the
* child array. Child will use a memory buffer owned by @bson and
* therefore grow the parent buffer as additional space is used. This allows
* a single malloc'd buffer to be used when building arrays which can help
* reduce memory fragmentation.
*
* The type of @child will be BSON_TYPE_ARRAY and therefore the keys inside
* of it MUST be "0", "1", etc.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_array_begin (bson_t *bson,
const char *key,
int key_length,
bson_t *child);
/**
* bson_append_array_end:
* @bson: A bson_t.
* @child: A bson_t supplied to bson_append_array_begin().
*
* Finishes the appending of a array to a @bson. @child is considered
* disposed after this call and should not be used any further.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_array_end (bson_t *bson, bson_t *child);
/**
* bson_append_int32:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The int32_t 32-bit integer value.
*
* Appends a new field of type BSON_TYPE_INT32 to @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_int32 (bson_t *bson,
const char *key,
int key_length,
int32_t value);
/**
* bson_append_int64:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The int64_t 64-bit integer value.
*
* Appends a new field of type BSON_TYPE_INT64 to @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_int64 (bson_t *bson,
const char *key,
int key_length,
int64_t value);
/**
* bson_append_decimal128:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The bson_decimal128_t decimal128 value.
*
* Appends a new field of type BSON_TYPE_DECIMAL128 to @bson.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_decimal128 (bson_t *bson,
const char *key,
int key_length,
const bson_decimal128_t *value);
/**
* bson_append_iter:
* @bson: A bson_t to append to.
* @key: The key name or %NULL to take current key from @iter.
* @key_length: The key length or -1 to use strlen().
* @iter: The iter located on the position of the element to append.
*
* Appends a new field to @bson that is equivalent to the field currently
* pointed to by @iter.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_iter (bson_t *bson,
const char *key,
int key_length,
const bson_iter_t *iter);
/**
* bson_append_minkey:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field of type BSON_TYPE_MINKEY to @bson. This is a special
* type that compares lower than all other possible BSON element values.
*
* See http://bsonspec.org for more information on this type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_minkey (bson_t *bson, const char *key, int key_length);
/**
* bson_append_maxkey:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field of type BSON_TYPE_MAXKEY to @bson. This is a special
* type that compares higher than all other possible BSON element values.
*
* See http://bsonspec.org for more information on this type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_maxkey (bson_t *bson, const char *key, int key_length);
/**
* bson_append_null:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a new field to @bson with NULL for the value.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_null (bson_t *bson, const char *key, int key_length);
/**
* bson_append_oid:
* @bson: A bson_t.
* @key: The key for the field.
* @oid: bson_oid_t.
*
* Appends a new field to the @bson of type BSON_TYPE_OID using the contents of
* @oid.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_oid (bson_t *bson,
const char *key,
int key_length,
const bson_oid_t *oid);
/**
* bson_append_regex:
* @bson: A bson_t.
* @key: The key of the field.
* @regex: The regex to append to the bson.
* @options: Options for @regex.
*
* Appends a new field to @bson of type BSON_TYPE_REGEX. @regex should
* be the regex string. @options should contain the options for the regex.
*
* Valid options for @options are:
*
* 'i' for case-insensitive.
* 'm' for multiple matching.
* 'x' for verbose mode.
* 'l' to make \w and \W locale dependent.
* 's' for dotall mode ('.' matches everything)
* 'u' to make \w and \W match unicode.
*
* For more detailed information about BSON regex elements, see bsonspec.org.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_regex (bson_t *bson,
const char *key,
int key_length,
const char *regex,
const char *options);
/**
* bson_append_regex:
* @bson: A bson_t.
* @key: The key of the field.
* @key_length: The length of the key string.
* @regex: The regex to append to the bson.
* @regex_length: The length of the regex string.
* @options: Options for @regex.
*
* Appends a new field to @bson of type BSON_TYPE_REGEX. @regex should
* be the regex string. @options should contain the options for the regex.
*
* Valid options for @options are:
*
* 'i' for case-insensitive.
* 'm' for multiple matching.
* 'x' for verbose mode.
* 'l' to make \w and \W locale dependent.
* 's' for dotall mode ('.' matches everything)
* 'u' to make \w and \W match unicode.
*
* For more detailed information about BSON regex elements, see bsonspec.org.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_regex_w_len (bson_t *bson,
const char *key,
int key_length,
const char *regex,
int regex_length,
const char *options);
/**
* bson_append_utf8:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A UTF-8 encoded string.
* @length: The length of @value or -1 if it is NUL terminated.
*
* Appends a new field to @bson using @key as the key and @value as the UTF-8
* encoded value.
*
* It is the callers responsibility to ensure @value is valid UTF-8. You can
* use bson_utf8_validate() to perform this check.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_utf8 (bson_t *bson,
const char *key,
int key_length,
const char *value,
int length);
/**
* bson_append_symbol:
* @bson: A bson_t.
* @key: The key for the field.
* @value: The symbol as a string.
* @length: The length of @value or -1 if NUL-terminated.
*
* Appends a new field to @bson of type BSON_TYPE_SYMBOL. This BSON type is
* deprecated and should not be used in new code.
*
* See http://bsonspec.org for more information on this type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_symbol (bson_t *bson,
const char *key,
int key_length,
const char *value,
int length);
/**
* bson_append_time_t:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A time_t.
*
* Appends a BSON_TYPE_DATE_TIME field to @bson using the time_t @value for the
* number of seconds since UNIX epoch in UTC.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_time_t (bson_t *bson,
const char *key,
int key_length,
time_t value);
/**
* bson_append_timeval:
* @bson: A bson_t.
* @key: The key for the field.
* @value: A struct timeval containing the date and time.
*
* Appends a BSON_TYPE_DATE_TIME field to @bson using the struct timeval
* provided. The time is persisted in milliseconds since the UNIX epoch in UTC.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_timeval (bson_t *bson,
const char *key,
int key_length,
struct timeval *value);
/**
* bson_append_date_time:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key in bytes or -1 if \0 terminated.
* @value: The number of milliseconds elapsed since UNIX epoch.
*
* Appends a new field to @bson of type BSON_TYPE_DATE_TIME.
*
* Returns: true if successful; otherwise false.
*/
BSON_EXPORT (bool)
bson_append_date_time (bson_t *bson,
const char *key,
int key_length,
int64_t value);
/**
* bson_append_now_utc:
* @bson: A bson_t.
* @key: The key for the field.
* @key_length: The length of @key or -1 if it is NULL terminated.
*
* Appends a BSON_TYPE_DATE_TIME field to @bson using the current time in UTC
* as the field value.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_now_utc (bson_t *bson, const char *key, int key_length);
/**
* bson_append_timestamp:
* @bson: A bson_t.
* @key: The key for the field.
* @timestamp: 4 byte timestamp.
* @increment: 4 byte increment for timestamp.
*
* Appends a field of type BSON_TYPE_TIMESTAMP to @bson. This is a special type
* used by MongoDB replication and sharding. If you need generic time and date
* fields use bson_append_time_t() or bson_append_timeval().
*
* Setting @increment and @timestamp to zero has special semantics. See
* http://bsonspec.org for more information on this field type.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_timestamp (bson_t *bson,
const char *key,
int key_length,
uint32_t timestamp,
uint32_t increment);
/**
* bson_append_undefined:
* @bson: A bson_t.
* @key: The key for the field.
*
* Appends a field of type BSON_TYPE_UNDEFINED. This type is deprecated in the
* spec and should not be used for new code. However, it is provided for those
* needing to interact with legacy systems.
*
* Returns: true if successful; false if append would overflow max size.
*/
BSON_EXPORT (bool)
bson_append_undefined (bson_t *bson, const char *key, int key_length);
BSON_EXPORT (bool)
bson_concat (bson_t *dst, const bson_t *src);
BSON_END_DECLS
#endif /* BSON_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c b/mongodb-1.14.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
index dddd973c..a7bb8f48 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.c
@@ -1,1670 +1,1680 @@
/* Copyright (C) 2012-2015 Mark Nunberg.
*
* See included LICENSE file for license details.
*/
#include "jsonsl.h"
#include "bson/bson-memory.h"
#include <limits.h>
#include <ctype.h>
#ifdef JSONSL_USE_METRICS
#define XMETRICS \
X(STRINGY_INSIGNIFICANT) \
X(STRINGY_SLOWPATH) \
X(ALLOWED_WHITESPACE) \
X(QUOTE_FASTPATH) \
X(SPECIAL_FASTPATH) \
X(SPECIAL_WSPOP) \
X(SPECIAL_SLOWPATH) \
X(GENERIC) \
X(STRUCTURAL_TOKEN) \
X(SPECIAL_SWITCHFIRST) \
X(STRINGY_CATCH) \
X(NUMBER_FASTPATH) \
X(ESCAPES) \
X(TOTAL) \
struct jsonsl_metrics_st {
#define X(m) \
unsigned long metric_##m;
XMETRICS
#undef X
};
static struct jsonsl_metrics_st GlobalMetrics = { 0 };
static unsigned long GenericCounter[0x100] = { 0 };
static unsigned long StringyCatchCounter[0x100] = { 0 };
#define INCR_METRIC(m) \
GlobalMetrics.metric_##m++;
#define INCR_GENERIC(c) \
INCR_METRIC(GENERIC); \
GenericCounter[c]++; \
#define INCR_STRINGY_CATCH(c) \
INCR_METRIC(STRINGY_CATCH); \
StringyCatchCounter[c]++;
JSONSL_API
void jsonsl_dump_global_metrics(void)
{
int ii;
printf("JSONSL Metrics:\n");
#define X(m) \
printf("\t%-30s %20lu (%0.2f%%)\n", #m, GlobalMetrics.metric_##m, \
(float)((float)(GlobalMetrics.metric_##m/(float)GlobalMetrics.metric_TOTAL)) * 100);
XMETRICS
#undef X
printf("Generic Characters:\n");
for (ii = 0; ii < 0xff; ii++) {
if (GenericCounter[ii]) {
printf("\t[ %c ] %lu\n", ii, GenericCounter[ii]);
}
}
printf("Weird string loop\n");
for (ii = 0; ii < 0xff; ii++) {
if (StringyCatchCounter[ii]) {
printf("\t[ %c ] %lu\n", ii, StringyCatchCounter[ii]);
}
}
}
#else
#define INCR_METRIC(m)
#define INCR_GENERIC(c)
#define INCR_STRINGY_CATCH(c)
JSONSL_API
void jsonsl_dump_global_metrics(void) { }
#endif /* JSONSL_USE_METRICS */
#define CASE_DIGITS \
case '1': \
case '2': \
case '3': \
case '4': \
case '5': \
case '6': \
case '7': \
case '8': \
case '9': \
case '0':
static unsigned extract_special(unsigned);
static int is_special_end(unsigned);
static int is_allowed_whitespace(unsigned);
static int is_allowed_escape(unsigned);
static int is_simple_char(unsigned);
static char get_escape_equiv(unsigned);
JSONSL_API
jsonsl_t jsonsl_new(int nlevels)
{
unsigned int ii;
struct jsonsl_st * jsn;
if (nlevels < 2) {
return NULL;
}
jsn = (struct jsonsl_st *)
bson_malloc0(sizeof (*jsn) +
( (nlevels-1) * sizeof (struct jsonsl_state_st) )
);
jsn->levels_max = (unsigned int) nlevels;
jsn->max_callback_level = UINT_MAX;
jsonsl_reset(jsn);
for (ii = 0; ii < jsn->levels_max; ii++) {
jsn->stack[ii].level = ii;
}
return jsn;
}
JSONSL_API
void jsonsl_reset(jsonsl_t jsn)
{
jsn->tok_last = 0;
jsn->can_insert = 1;
jsn->pos = 0;
jsn->level = 0;
jsn->stopfl = 0;
jsn->in_escape = 0;
jsn->expecting = 0;
}
JSONSL_API
void jsonsl_destroy(jsonsl_t jsn)
{
if (jsn) {
bson_free(jsn);
}
}
#define FASTPARSE_EXHAUSTED 1
#define FASTPARSE_BREAK 0
/*
* This function is meant to accelerate string parsing, reducing the main loop's
* check if we are indeed a string.
*
* @param jsn the parser
* @param[in,out] bytes_p A pointer to the current buffer (i.e. current position)
* @param[in,out] nbytes_p A pointer to the current size of the buffer
* @return true if all bytes have been exhausted (and thus the main loop can
* return), false if a special character was examined which requires greater
* examination.
*/
static int
jsonsl__str_fastparse(jsonsl_t jsn,
const jsonsl_uchar_t **bytes_p, size_t *nbytes_p)
{
const jsonsl_uchar_t *bytes = *bytes_p;
const jsonsl_uchar_t *end;
for (end = bytes + *nbytes_p; bytes != end; bytes++) {
if (
#ifdef JSONSL_USE_WCHAR
*bytes >= 0x100 ||
#endif /* JSONSL_USE_WCHAR */
(is_simple_char(*bytes))) {
INCR_METRIC(TOTAL);
INCR_METRIC(STRINGY_INSIGNIFICANT);
} else {
/* Once we're done here, re-calculate the position variables */
jsn->pos += (bytes - *bytes_p);
*nbytes_p -= (bytes - *bytes_p);
*bytes_p = bytes;
return FASTPARSE_BREAK;
}
}
/* Once we're done here, re-calculate the position variables */
jsn->pos += (bytes - *bytes_p);
return FASTPARSE_EXHAUSTED;
}
/* Functions exactly like str_fastparse, except it also accepts a 'state'
* argument, since the number's value is updated in the state. */
static int
jsonsl__num_fastparse(jsonsl_t jsn,
const jsonsl_uchar_t **bytes_p, size_t *nbytes_p,
struct jsonsl_state_st *state)
{
int exhausted = 1;
size_t nbytes = *nbytes_p;
const jsonsl_uchar_t *bytes = *bytes_p;
for (; nbytes; nbytes--, bytes++) {
jsonsl_uchar_t c = *bytes;
if (isdigit(c)) {
INCR_METRIC(TOTAL);
INCR_METRIC(NUMBER_FASTPATH);
state->nelem = (state->nelem * 10) + (c - 0x30);
} else {
exhausted = 0;
break;
}
}
jsn->pos += (*nbytes_p - nbytes);
if (exhausted) {
return FASTPARSE_EXHAUSTED;
}
*nbytes_p = nbytes;
*bytes_p = bytes;
return FASTPARSE_BREAK;
}
JSONSL_API
void
jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes)
{
#define INVOKE_ERROR(eb) \
if (jsn->error_callback(jsn, JSONSL_ERROR_##eb, state, (char*)c)) { \
goto GT_AGAIN; \
} \
return;
#define STACK_PUSH \
if (jsn->level >= (levels_max-1)) { \
jsn->error_callback(jsn, JSONSL_ERROR_LEVELS_EXCEEDED, state, (char*)c); \
return; \
} \
state = jsn->stack + (++jsn->level); \
state->ignore_callback = jsn->stack[jsn->level-1].ignore_callback; \
state->pos_begin = jsn->pos;
#define STACK_POP_NOPOS \
state->pos_cur = jsn->pos; \
state = jsn->stack + (--jsn->level);
#define STACK_POP \
STACK_POP_NOPOS; \
state->pos_cur = jsn->pos;
#define CALLBACK_AND_POP_NOPOS(T) \
state->pos_cur = jsn->pos; \
DO_CALLBACK(T, POP); \
state->nescapes = 0; \
state = jsn->stack + (--jsn->level);
#define CALLBACK_AND_POP(T) \
CALLBACK_AND_POP_NOPOS(T); \
state->pos_cur = jsn->pos;
#define SPECIAL_POP \
CALLBACK_AND_POP(SPECIAL); \
jsn->expecting = 0; \
jsn->tok_last = 0; \
#define CUR_CHAR (*(jsonsl_uchar_t*)c)
#define DO_CALLBACK(T, action) \
if (jsn->call_##T && \
jsn->max_callback_level > state->level && \
state->ignore_callback == 0) { \
\
if (jsn->action_callback_##action) { \
jsn->action_callback_##action(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \
} else if (jsn->action_callback) { \
jsn->action_callback(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \
} \
if (jsn->stopfl) { return; } \
}
/**
* Verifies that we are able to insert the (non-string) item into a hash.
*/
#define ENSURE_HVAL \
if (state->nelem % 2 == 0 && state->type == JSONSL_T_OBJECT) { \
INVOKE_ERROR(HKEY_EXPECTED); \
}
#define VERIFY_SPECIAL(lit, lit_len) \
if ((jsn->pos - state->pos_begin) > lit_len \
|| CUR_CHAR != (lit)[jsn->pos - state->pos_begin]) { \
INVOKE_ERROR(SPECIAL_EXPECTED); \
}
#define VERIFY_SPECIAL_CI(lit, lit_len) \
if ((jsn->pos - state->pos_begin) > lit_len \
|| tolower(CUR_CHAR) != (lit)[jsn->pos - state->pos_begin]) { \
INVOKE_ERROR(SPECIAL_EXPECTED); \
}
#define STATE_SPECIAL_LENGTH \
(state)->nescapes
#define IS_NORMAL_NUMBER \
((state)->special_flags == JSONSL_SPECIALf_UNSIGNED || \
(state)->special_flags == JSONSL_SPECIALf_SIGNED)
#define STATE_NUM_LAST jsn->tok_last
#define CONTINUE_NEXT_CHAR() continue
const jsonsl_uchar_t *c = (jsonsl_uchar_t*)bytes;
size_t levels_max = jsn->levels_max;
struct jsonsl_state_st *state = jsn->stack + jsn->level;
jsn->base = bytes;
for (; nbytes; nbytes--, jsn->pos++, c++) {
unsigned state_type;
INCR_METRIC(TOTAL);
GT_AGAIN:
state_type = state->type;
/* Most common type is typically a string: */
if (state_type & JSONSL_Tf_STRINGY) {
/* Special escape handling for some stuff */
if (jsn->in_escape) {
jsn->in_escape = 0;
if (!is_allowed_escape(CUR_CHAR)) {
INVOKE_ERROR(ESCAPE_INVALID);
} else if (CUR_CHAR == 'u') {
DO_CALLBACK(UESCAPE, UESCAPE);
if (jsn->return_UESCAPE) {
return;
}
}
CONTINUE_NEXT_CHAR();
}
if (jsonsl__str_fastparse(jsn, &c, &nbytes) ==
FASTPARSE_EXHAUSTED) {
/* No need to readjust variables as we've exhausted the iterator */
return;
} else {
if (CUR_CHAR == '"') {
goto GT_QUOTE;
} else if (CUR_CHAR == '\\') {
goto GT_ESCAPE;
} else {
INVOKE_ERROR(WEIRD_WHITESPACE);
}
}
INCR_METRIC(STRINGY_SLOWPATH);
} else if (state_type == JSONSL_T_SPECIAL) {
/* Fast track for signed/unsigned */
if (IS_NORMAL_NUMBER) {
if (jsonsl__num_fastparse(jsn, &c, &nbytes, state) ==
FASTPARSE_EXHAUSTED) {
return;
} else {
goto GT_SPECIAL_NUMERIC;
}
} else if (state->special_flags == JSONSL_SPECIALf_DASH) {
#ifdef JSONSL_PARSE_NAN
if (CUR_CHAR == 'I' || CUR_CHAR == 'i') {
/* parsing -Infinity? */
state->special_flags = JSONSL_SPECIALf_NEG_INF;
CONTINUE_NEXT_CHAR();
}
#endif
if (!isdigit(CUR_CHAR)) {
INVOKE_ERROR(INVALID_NUMBER);
}
if (CUR_CHAR == '0') {
state->special_flags = JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED;
} else if (isdigit(CUR_CHAR)) {
state->special_flags = JSONSL_SPECIALf_SIGNED;
state->nelem = CUR_CHAR - 0x30;
} else {
INVOKE_ERROR(INVALID_NUMBER);
}
CONTINUE_NEXT_CHAR();
} else if (state->special_flags == JSONSL_SPECIALf_ZERO) {
if (isdigit(CUR_CHAR)) {
/* Following a zero! */
INVOKE_ERROR(INVALID_NUMBER);
}
/* Unset the 'zero' flag: */
if (state->special_flags & JSONSL_SPECIALf_SIGNED) {
state->special_flags = JSONSL_SPECIALf_SIGNED;
} else {
state->special_flags = JSONSL_SPECIALf_UNSIGNED;
}
goto GT_SPECIAL_NUMERIC;
}
if ((state->special_flags & JSONSL_SPECIALf_NUMERIC) &&
!(state->special_flags & JSONSL_SPECIALf_INF)) {
GT_SPECIAL_NUMERIC:
switch (CUR_CHAR) {
CASE_DIGITS
STATE_NUM_LAST = '1';
CONTINUE_NEXT_CHAR();
case '.':
if (state->special_flags & JSONSL_SPECIALf_FLOAT) {
INVOKE_ERROR(INVALID_NUMBER);
}
state->special_flags |= JSONSL_SPECIALf_FLOAT;
STATE_NUM_LAST = '.';
CONTINUE_NEXT_CHAR();
case 'e':
case 'E':
if (state->special_flags & JSONSL_SPECIALf_EXPONENT) {
INVOKE_ERROR(INVALID_NUMBER);
}
state->special_flags |= JSONSL_SPECIALf_EXPONENT;
STATE_NUM_LAST = 'e';
CONTINUE_NEXT_CHAR();
case '-':
case '+':
if (STATE_NUM_LAST != 'e') {
INVOKE_ERROR(INVALID_NUMBER);
}
STATE_NUM_LAST = '-';
CONTINUE_NEXT_CHAR();
default:
if (is_special_end(CUR_CHAR)) {
goto GT_SPECIAL_POP;
}
INVOKE_ERROR(INVALID_NUMBER);
break;
}
}
/* else if (!NUMERIC) */
if (!is_special_end(CUR_CHAR)) {
STATE_SPECIAL_LENGTH++;
/* Verify TRUE, FALSE, NULL */
if (state->special_flags == JSONSL_SPECIALf_TRUE) {
VERIFY_SPECIAL("true", 4 /* strlen("true") */);
} else if (state->special_flags == JSONSL_SPECIALf_FALSE) {
VERIFY_SPECIAL("false", 5 /* strlen("false") */);
} else if (state->special_flags == JSONSL_SPECIALf_NULL) {
VERIFY_SPECIAL("null", 4 /* strlen("null") */);
#ifdef JSONSL_PARSE_NAN
} else if (state->special_flags == JSONSL_SPECIALf_POS_INF) {
VERIFY_SPECIAL_CI("infinity", 8 /* strlen("infinity") */);
} else if (state->special_flags == JSONSL_SPECIALf_NEG_INF) {
VERIFY_SPECIAL_CI("-infinity", 9 /* strlen("-infinity") */);
} else if (state->special_flags == JSONSL_SPECIALf_NAN) {
VERIFY_SPECIAL_CI("nan", 3 /* strlen("nan") */);
} else if (state->special_flags & JSONSL_SPECIALf_NULL ||
state->special_flags & JSONSL_SPECIALf_NAN) {
/* previous char was "n", are we parsing null or nan? */
- if (CUR_CHAR != 'u') {
+ const bool not_u = CUR_CHAR != 'u';
+ const bool not_a = tolower (CUR_CHAR) != 'a';
+ if (not_u) {
state->special_flags &= ~JSONSL_SPECIALf_NULL;
}
-
- if (tolower(CUR_CHAR) != 'a') {
+ if (not_a) {
state->special_flags &= ~JSONSL_SPECIALf_NAN;
}
+ if (not_u && not_a) {
+ /* This verify will always fail, as we have an 'n'
+ * followed by a character that is neither 'a' nor 'u'
+ * (and hence cannot be "null"). The purpose of this
+ * VERIFY_SPECIAL is to generate an error in tokenization
+ * that stops if a bare 'n' cannot possibly be a "nan" or
+ * a "null". */
+ VERIFY_SPECIAL ("null", 4);
+ }
#endif
}
INCR_METRIC(SPECIAL_FASTPATH);
CONTINUE_NEXT_CHAR();
}
GT_SPECIAL_POP:
jsn->can_insert = 0;
if (IS_NORMAL_NUMBER) {
/* Nothing */
} else if (state->special_flags == JSONSL_SPECIALf_ZERO ||
state->special_flags == (JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED)) {
/* 0 is unsigned! */
state->special_flags = JSONSL_SPECIALf_UNSIGNED;
} else if (state->special_flags == JSONSL_SPECIALf_DASH) {
/* Still in dash! */
INVOKE_ERROR(INVALID_NUMBER);
} else if (state->special_flags & JSONSL_SPECIALf_INF) {
if (STATE_SPECIAL_LENGTH != 8) {
INVOKE_ERROR(SPECIAL_INCOMPLETE);
}
state->nelem = 1;
} else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
/* Check that we're not at the end of a token */
if (STATE_NUM_LAST != '1') {
INVOKE_ERROR(INVALID_NUMBER);
}
} else if (state->special_flags == JSONSL_SPECIALf_TRUE) {
if (STATE_SPECIAL_LENGTH != 4) {
INVOKE_ERROR(SPECIAL_INCOMPLETE);
}
state->nelem = 1;
} else if (state->special_flags == JSONSL_SPECIALf_FALSE) {
if (STATE_SPECIAL_LENGTH != 5) {
INVOKE_ERROR(SPECIAL_INCOMPLETE);
}
} else if (state->special_flags == JSONSL_SPECIALf_NULL) {
if (STATE_SPECIAL_LENGTH != 4) {
INVOKE_ERROR(SPECIAL_INCOMPLETE);
}
}
SPECIAL_POP;
jsn->expecting = ',';
if (is_allowed_whitespace(CUR_CHAR)) {
CONTINUE_NEXT_CHAR();
}
/**
* This works because we have a non-whitespace token
* which is not a special token. If this is a structural
* character then it will be gracefully handled by the
* switch statement. Otherwise it will default to the 'special'
* state again,
*/
goto GT_STRUCTURAL_TOKEN;
} else if (is_allowed_whitespace(CUR_CHAR)) {
INCR_METRIC(ALLOWED_WHITESPACE);
/* So we're not special. Harmless insignificant whitespace
* passthrough
*/
CONTINUE_NEXT_CHAR();
} else if (extract_special(CUR_CHAR)) {
/* not a string, whitespace, or structural token. must be special */
goto GT_SPECIAL_BEGIN;
}
INCR_GENERIC(CUR_CHAR);
if (CUR_CHAR == '"') {
GT_QUOTE:
jsn->can_insert = 0;
switch (state_type) {
/* the end of a string or hash key */
case JSONSL_T_STRING:
CALLBACK_AND_POP(STRING);
CONTINUE_NEXT_CHAR();
case JSONSL_T_HKEY:
CALLBACK_AND_POP(HKEY);
CONTINUE_NEXT_CHAR();
case JSONSL_T_OBJECT:
state->nelem++;
if ( (state->nelem-1) % 2 ) {
/* Odd, this must be a hash value */
if (jsn->tok_last != ':') {
INVOKE_ERROR(MISSING_TOKEN);
}
jsn->expecting = ','; /* Can't figure out what to expect next */
jsn->tok_last = 0;
STACK_PUSH;
state->type = JSONSL_T_STRING;
DO_CALLBACK(STRING, PUSH);
} else {
/* hash key */
if (jsn->expecting != '"') {
INVOKE_ERROR(STRAY_TOKEN);
}
jsn->tok_last = 0;
jsn->expecting = ':';
STACK_PUSH;
state->type = JSONSL_T_HKEY;
DO_CALLBACK(HKEY, PUSH);
}
CONTINUE_NEXT_CHAR();
case JSONSL_T_LIST:
state->nelem++;
STACK_PUSH;
state->type = JSONSL_T_STRING;
jsn->expecting = ',';
jsn->tok_last = 0;
DO_CALLBACK(STRING, PUSH);
CONTINUE_NEXT_CHAR();
case JSONSL_T_SPECIAL:
INVOKE_ERROR(STRAY_TOKEN);
break;
default:
INVOKE_ERROR(STRING_OUTSIDE_CONTAINER);
break;
} /* switch(state->type) */
} else if (CUR_CHAR == '\\') {
GT_ESCAPE:
INCR_METRIC(ESCAPES);
/* Escape */
if ( (state->type & JSONSL_Tf_STRINGY) == 0 ) {
INVOKE_ERROR(ESCAPE_OUTSIDE_STRING);
}
state->nescapes++;
jsn->in_escape = 1;
CONTINUE_NEXT_CHAR();
} /* " or \ */
GT_STRUCTURAL_TOKEN:
switch (CUR_CHAR) {
case ':':
INCR_METRIC(STRUCTURAL_TOKEN);
if (jsn->expecting != CUR_CHAR) {
INVOKE_ERROR(STRAY_TOKEN);
}
jsn->tok_last = ':';
jsn->can_insert = 1;
jsn->expecting = '"';
CONTINUE_NEXT_CHAR();
case ',':
INCR_METRIC(STRUCTURAL_TOKEN);
/**
* The comma is one of the more generic tokens.
* In the context of an OBJECT, the can_insert flag
* should never be set, and no other action is
* necessary.
*/
if (jsn->expecting != CUR_CHAR) {
/* make this branch execute only when we haven't manually
* just placed the ',' in the expecting register.
*/
INVOKE_ERROR(STRAY_TOKEN);
}
if (state->type == JSONSL_T_OBJECT) {
/* end of hash value, expect a string as a hash key */
jsn->expecting = '"';
} else {
jsn->can_insert = 1;
}
jsn->tok_last = ',';
jsn->expecting = '"';
CONTINUE_NEXT_CHAR();
/* new list or object */
/* hashes are more common */
case '{':
case '[':
INCR_METRIC(STRUCTURAL_TOKEN);
if (!jsn->can_insert) {
INVOKE_ERROR(CANT_INSERT);
}
ENSURE_HVAL;
state->nelem++;
STACK_PUSH;
/* because the constants match the opening delimiters, we can do this: */
state->type = CUR_CHAR;
state->nelem = 0;
jsn->can_insert = 1;
if (CUR_CHAR == '{') {
/* If we're a hash, we expect a key first, which is quouted */
jsn->expecting = '"';
}
if (CUR_CHAR == JSONSL_T_OBJECT) {
DO_CALLBACK(OBJECT, PUSH);
} else {
DO_CALLBACK(LIST, PUSH);
}
jsn->tok_last = 0;
CONTINUE_NEXT_CHAR();
/* closing of list or object */
case '}':
case ']':
INCR_METRIC(STRUCTURAL_TOKEN);
if (jsn->tok_last == ',' && jsn->options.allow_trailing_comma == 0) {
INVOKE_ERROR(TRAILING_COMMA);
}
jsn->can_insert = 0;
jsn->level--;
jsn->expecting = ',';
jsn->tok_last = 0;
if (CUR_CHAR == ']') {
if (state->type != '[') {
INVOKE_ERROR(BRACKET_MISMATCH);
}
DO_CALLBACK(LIST, POP);
} else {
if (state->type != '{') {
INVOKE_ERROR(BRACKET_MISMATCH);
} else if (state->nelem && state->nelem % 2 != 0) {
INVOKE_ERROR(VALUE_EXPECTED);
}
DO_CALLBACK(OBJECT, POP);
}
state = jsn->stack + jsn->level;
state->pos_cur = jsn->pos;
CONTINUE_NEXT_CHAR();
default:
GT_SPECIAL_BEGIN:
/**
* Not a string, not a structural token, and not benign whitespace.
* Technically we should iterate over the character always, but since
* we are not doing full numerical/value decoding anyway (but only hinting),
* we only check upon entry.
*/
if (state->type != JSONSL_T_SPECIAL) {
int special_flags = extract_special(CUR_CHAR);
if (!special_flags) {
/**
* Try to do some heuristics here anyway to figure out what kind of
* error this is. The 'special' case is a fallback scenario anyway.
*/
if (CUR_CHAR == '\0') {
INVOKE_ERROR(FOUND_NULL_BYTE);
} else if (CUR_CHAR < 0x20) {
INVOKE_ERROR(WEIRD_WHITESPACE);
} else {
INVOKE_ERROR(SPECIAL_EXPECTED);
}
}
ENSURE_HVAL;
state->nelem++;
if (!jsn->can_insert) {
INVOKE_ERROR(CANT_INSERT);
}
STACK_PUSH;
state->type = JSONSL_T_SPECIAL;
state->special_flags = special_flags;
STATE_SPECIAL_LENGTH = 1;
if (special_flags == JSONSL_SPECIALf_UNSIGNED) {
state->nelem = CUR_CHAR - 0x30;
STATE_NUM_LAST = '1';
} else {
STATE_NUM_LAST = '-';
state->nelem = 0;
}
DO_CALLBACK(SPECIAL, PUSH);
}
CONTINUE_NEXT_CHAR();
}
}
}
JSONSL_API
const char* jsonsl_strerror(jsonsl_error_t err)
{
if (err == JSONSL_ERROR_SUCCESS) {
return "SUCCESS";
}
#define X(t) \
if (err == JSONSL_ERROR_##t) \
return #t;
JSONSL_XERR;
#undef X
return "<UNKNOWN_ERROR>";
}
JSONSL_API
const char *jsonsl_strtype(jsonsl_type_t type)
{
#define X(o,c) \
if (type == JSONSL_T_##o) \
return #o;
JSONSL_XTYPE
#undef X
return "UNKNOWN TYPE";
}
/*
*
* JPR/JSONPointer functions
*
*
*/
#ifndef JSONSL_NO_JPR
static
jsonsl_jpr_type_t
populate_component(char *in,
struct jsonsl_jpr_component_st *component,
char **next,
jsonsl_error_t *errp)
{
unsigned long pctval;
char *c = NULL, *outp = NULL, *end = NULL;
size_t input_len;
jsonsl_jpr_type_t ret = JSONSL_PATH_NONE;
if (*next == NULL || *(*next) == '\0') {
return JSONSL_PATH_NONE;
}
/* Replace the next / with a NULL */
*next = strstr(in, "/");
if (*next != NULL) {
*(*next) = '\0'; /* drop the forward slash */
input_len = *next - in;
end = *next;
*next += 1; /* next character after the '/' */
} else {
input_len = strlen(in);
end = in + input_len + 1;
}
component->pstr = in;
/* Check for special components of interest */
if (*in == JSONSL_PATH_WILDCARD_CHAR && input_len == 1) {
/* Lone wildcard */
ret = JSONSL_PATH_WILDCARD;
goto GT_RET;
} else if (isdigit(*in)) {
/* ASCII Numeric */
char *endptr;
component->idx = strtoul(in, &endptr, 10);
if (endptr && *endptr == '\0') {
ret = JSONSL_PATH_NUMERIC;
goto GT_RET;
}
}
/* Default, it's a string */
ret = JSONSL_PATH_STRING;
for (c = outp = in; c < end; c++, outp++) {
char origc;
if (*c != '%') {
goto GT_ASSIGN;
}
/*
* c = { [+0] = '%', [+1] = 'b', [+2] = 'e', [+3] = '\0' }
*/
/* Need %XX */
if (c+2 >= end) {
*errp = JSONSL_ERROR_PERCENT_BADHEX;
return JSONSL_PATH_INVALID;
}
if (! (isxdigit(*(c+1)) && isxdigit(*(c+2))) ) {
*errp = JSONSL_ERROR_PERCENT_BADHEX;
return JSONSL_PATH_INVALID;
}
/* Temporarily null-terminate the characters */
origc = *(c+3);
*(c+3) = '\0';
pctval = strtoul(c+1, NULL, 16);
*(c+3) = origc;
*outp = (char) pctval;
c += 2;
continue;
GT_ASSIGN:
*outp = *c;
}
/* Null-terminate the string */
for (; outp < c; outp++) {
*outp = '\0';
}
GT_RET:
component->ptype = ret;
if (ret != JSONSL_PATH_WILDCARD) {
component->len = strlen(component->pstr);
}
return ret;
}
JSONSL_API
jsonsl_jpr_t
jsonsl_jpr_new(const char *path, jsonsl_error_t *errp)
{
char *my_copy = NULL;
int count, curidx;
struct jsonsl_jpr_st *ret = NULL;
struct jsonsl_jpr_component_st *components = NULL;
size_t origlen;
jsonsl_error_t errstacked;
#define JPR_BAIL(err) *errp = err; goto GT_ERROR;
if (errp == NULL) {
errp = &errstacked;
}
if (path == NULL || *path != '/') {
JPR_BAIL(JSONSL_ERROR_JPR_NOROOT);
}
count = 1;
path++;
{
const char *c = path;
for (; *c; c++) {
if (*c == '/') {
count++;
if (*(c+1) == '/') {
JPR_BAIL(JSONSL_ERROR_JPR_DUPSLASH);
}
}
}
}
if(*path) {
count++;
}
components = (struct jsonsl_jpr_component_st *)
malloc(sizeof(*components) * count);
if (!components) {
JPR_BAIL(JSONSL_ERROR_ENOMEM);
}
my_copy = (char *)malloc(strlen(path) + 1);
if (!my_copy) {
JPR_BAIL(JSONSL_ERROR_ENOMEM);
}
strcpy(my_copy, path);
components[0].ptype = JSONSL_PATH_ROOT;
if (*my_copy) {
char *cur = my_copy;
int pathret = JSONSL_PATH_STRING;
curidx = 1;
while (curidx < count) {
pathret = populate_component(cur, components + curidx, &cur, errp);
if (pathret > 0) {
curidx++;
} else {
break;
}
}
if (pathret == JSONSL_PATH_INVALID) {
JPR_BAIL(JSONSL_ERROR_JPR_BADPATH);
}
} else {
curidx = 1;
}
path--; /*revert path to leading '/' */
origlen = strlen(path) + 1;
ret = (struct jsonsl_jpr_st *)malloc(sizeof(*ret));
if (!ret) {
JPR_BAIL(JSONSL_ERROR_ENOMEM);
}
ret->orig = (char *)malloc(origlen);
if (!ret->orig) {
JPR_BAIL(JSONSL_ERROR_ENOMEM);
}
ret->components = components;
ret->ncomponents = curidx;
ret->basestr = my_copy;
ret->norig = origlen-1;
strcpy(ret->orig, path);
return ret;
GT_ERROR:
free(my_copy);
free(components);
if (ret) {
free(ret->orig);
}
free(ret);
return NULL;
#undef JPR_BAIL
}
void jsonsl_jpr_destroy(jsonsl_jpr_t jpr)
{
free(jpr->components);
free(jpr->basestr);
free(jpr->orig);
free(jpr);
}
/**
* Call when there is a possibility of a match, either as a final match or
* as a path within a match
* @param jpr The JPR path
* @param component Component corresponding to the current element
* @param prlevel The level of the *parent*
* @param chtype The type of the child
* @return Match status
*/
static jsonsl_jpr_match_t
jsonsl__match_continue(jsonsl_jpr_t jpr,
const struct jsonsl_jpr_component_st *component,
unsigned prlevel, unsigned chtype)
{
const struct jsonsl_jpr_component_st *next_comp = component + 1;
if (prlevel == jpr->ncomponents - 1) {
/* This is the match. Check the expected type of the match against
* the child */
if (jpr->match_type == 0 || jpr->match_type == chtype) {
return JSONSL_MATCH_COMPLETE;
} else {
return JSONSL_MATCH_TYPE_MISMATCH;
}
}
if (chtype == JSONSL_T_LIST) {
if (next_comp->ptype == JSONSL_PATH_NUMERIC) {
return JSONSL_MATCH_POSSIBLE;
} else {
return JSONSL_MATCH_TYPE_MISMATCH;
}
} else if (chtype == JSONSL_T_OBJECT) {
if (next_comp->ptype == JSONSL_PATH_NUMERIC) {
return JSONSL_MATCH_TYPE_MISMATCH;
} else {
return JSONSL_MATCH_POSSIBLE;
}
} else {
return JSONSL_MATCH_TYPE_MISMATCH;
}
}
JSONSL_API
jsonsl_jpr_match_t
jsonsl_path_match(jsonsl_jpr_t jpr,
const struct jsonsl_state_st *parent,
const struct jsonsl_state_st *child,
const char *key, size_t nkey)
{
const struct jsonsl_jpr_component_st *comp;
if (!parent) {
/* No parent. Return immediately since it's always a match */
return jsonsl__match_continue(jpr, jpr->components, 0, child->type);
}
comp = jpr->components + parent->level;
/* note that we don't need to verify the type of the match, this is
* always done through the previous call to jsonsl__match_continue.
* If we are in a POSSIBLE tree then we can be certain the types (at
* least at this level) are correct */
if (parent->type == JSONSL_T_OBJECT) {
if (comp->len != nkey || strncmp(key, comp->pstr, nkey) != 0) {
return JSONSL_MATCH_NOMATCH;
}
} else {
if (comp->idx != parent->nelem - 1) {
return JSONSL_MATCH_NOMATCH;
}
}
return jsonsl__match_continue(jpr, comp, parent->level, child->type);
}
JSONSL_API
jsonsl_jpr_match_t
jsonsl_jpr_match(jsonsl_jpr_t jpr,
unsigned int parent_type,
unsigned int parent_level,
const char *key,
size_t nkey)
{
/* find our current component. This is the child level */
int cmpret;
struct jsonsl_jpr_component_st *p_component;
p_component = jpr->components + parent_level;
if (parent_level >= jpr->ncomponents) {
return JSONSL_MATCH_NOMATCH;
}
/* Lone query for 'root' element. Always matches */
if (parent_level == 0) {
if (jpr->ncomponents == 1) {
return JSONSL_MATCH_COMPLETE;
} else {
return JSONSL_MATCH_POSSIBLE;
}
}
/* Wildcard, always matches */
if (p_component->ptype == JSONSL_PATH_WILDCARD) {
if (parent_level == jpr->ncomponents-1) {
return JSONSL_MATCH_COMPLETE;
} else {
return JSONSL_MATCH_POSSIBLE;
}
}
/* Check numeric array index. This gets its special block so we can avoid
* string comparisons */
if (p_component->ptype == JSONSL_PATH_NUMERIC) {
if (parent_type == JSONSL_T_LIST) {
if (p_component->idx != nkey) {
/* Wrong index */
return JSONSL_MATCH_NOMATCH;
} else {
if (parent_level == jpr->ncomponents-1) {
/* This is the last element of the path */
return JSONSL_MATCH_COMPLETE;
} else {
/* Intermediate element */
return JSONSL_MATCH_POSSIBLE;
}
}
} else if (p_component->is_arridx) {
/* Numeric and an array index (set explicitly by user). But not
* a list for a parent */
return JSONSL_MATCH_TYPE_MISMATCH;
}
} else if (parent_type == JSONSL_T_LIST) {
return JSONSL_MATCH_TYPE_MISMATCH;
}
/* Check lengths */
if (p_component->len != nkey) {
return JSONSL_MATCH_NOMATCH;
}
/* Check string comparison */
cmpret = strncmp(p_component->pstr, key, nkey);
if (cmpret == 0) {
if (parent_level == jpr->ncomponents-1) {
return JSONSL_MATCH_COMPLETE;
} else {
return JSONSL_MATCH_POSSIBLE;
}
}
return JSONSL_MATCH_NOMATCH;
}
JSONSL_API
void jsonsl_jpr_match_state_init(jsonsl_t jsn,
jsonsl_jpr_t *jprs,
size_t njprs)
{
size_t ii, *firstjmp;
if (njprs == 0) {
return;
}
jsn->jprs = (jsonsl_jpr_t *)malloc(sizeof(jsonsl_jpr_t) * njprs);
jsn->jpr_count = njprs;
jsn->jpr_root = (size_t*)calloc(1, sizeof(size_t) * njprs * jsn->levels_max);
memcpy(jsn->jprs, jprs, sizeof(jsonsl_jpr_t) * njprs);
/* Set the initial jump table values */
firstjmp = jsn->jpr_root;
for (ii = 0; ii < njprs; ii++) {
firstjmp[ii] = ii+1;
}
}
JSONSL_API
void jsonsl_jpr_match_state_cleanup(jsonsl_t jsn)
{
if (jsn->jpr_count == 0) {
return;
}
free(jsn->jpr_root);
free(jsn->jprs);
jsn->jprs = NULL;
jsn->jpr_root = NULL;
jsn->jpr_count = 0;
}
/**
* This function should be called exactly once on each element...
* This should also be called in recursive order, since we rely
* on the parent having been initialized for a match.
*
* Since the parent is checked for a match as well, we maintain a 'serial' counter.
* Whenever we traverse an element, we expect the serial to be the same as a global
* integer. If they do not match, we re-initialize the context, and set the serial.
*
* This ensures a type of consistency without having a proactive reset by the
* main lexer itself.
*
*/
JSONSL_API
jsonsl_jpr_t jsonsl_jpr_match_state(jsonsl_t jsn,
struct jsonsl_state_st *state,
const char *key,
size_t nkey,
jsonsl_jpr_match_t *out)
{
struct jsonsl_state_st *parent_state;
jsonsl_jpr_t ret = NULL;
/* Jump and JPR tables for our own state and the parent state */
size_t *jmptable, *pjmptable;
size_t jmp_cur, ii, ourjmpidx;
if (!jsn->jpr_root) {
*out = JSONSL_MATCH_NOMATCH;
return NULL;
}
pjmptable = jsn->jpr_root + (jsn->jpr_count * (state->level-1));
jmptable = pjmptable + jsn->jpr_count;
/* If the parent cannot match, then invalidate it */
if (*pjmptable == 0) {
*jmptable = 0;
*out = JSONSL_MATCH_NOMATCH;
return NULL;
}
parent_state = jsn->stack + state->level - 1;
if (parent_state->type == JSONSL_T_LIST) {
nkey = (size_t) parent_state->nelem;
}
*jmptable = 0;
ourjmpidx = 0;
memset(jmptable, 0, sizeof(int) * jsn->jpr_count);
for (ii = 0; ii < jsn->jpr_count; ii++) {
jmp_cur = pjmptable[ii];
if (jmp_cur) {
jsonsl_jpr_t jpr = jsn->jprs[jmp_cur-1];
*out = jsonsl_jpr_match(jpr,
parent_state->type,
parent_state->level,
key, nkey);
if (*out == JSONSL_MATCH_COMPLETE) {
ret = jpr;
*jmptable = 0;
return ret;
} else if (*out == JSONSL_MATCH_POSSIBLE) {
jmptable[ourjmpidx] = ii+1;
ourjmpidx++;
}
} else {
break;
}
}
if (!*jmptable) {
*out = JSONSL_MATCH_NOMATCH;
}
return NULL;
}
JSONSL_API
const char *jsonsl_strmatchtype(jsonsl_jpr_match_t match)
{
#define X(T,v) \
if ( match == JSONSL_MATCH_##T ) \
return #T;
JSONSL_XMATCH
#undef X
return "<UNKNOWN>";
}
#endif /* JSONSL_WITH_JPR */
static char *
jsonsl__writeutf8(uint32_t pt, char *out)
{
#define ADD_OUTPUT(c) *out = (char)(c); out++;
if (pt < 0x80) {
ADD_OUTPUT(pt);
} else if (pt < 0x800) {
ADD_OUTPUT((pt >> 6) | 0xC0);
ADD_OUTPUT((pt & 0x3F) | 0x80);
} else if (pt < 0x10000) {
ADD_OUTPUT((pt >> 12) | 0xE0);
ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80);
ADD_OUTPUT((pt & 0x3F) | 0x80);
} else {
ADD_OUTPUT((pt >> 18) | 0xF0);
ADD_OUTPUT(((pt >> 12) & 0x3F) | 0x80);
ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80);
ADD_OUTPUT((pt & 0x3F) | 0x80);
}
return out;
#undef ADD_OUTPUT
}
/* Thanks snej (https://github.com/mnunberg/jsonsl/issues/9) */
static int
jsonsl__digit2int(char ch) {
int d = ch - '0';
if ((unsigned) d < 10) {
return d;
}
d = ch - 'a';
if ((unsigned) d < 6) {
return d + 10;
}
d = ch - 'A';
if ((unsigned) d < 6) {
return d + 10;
}
return -1;
}
/* Assume 's' is at least 4 bytes long */
static int
jsonsl__get_uescape_16(const char *s)
{
int ret = 0;
int cur;
#define GET_DIGIT(off) \
cur = jsonsl__digit2int(s[off]); \
if (cur == -1) { return -1; } \
ret |= (cur << (12 - (off * 4)));
GET_DIGIT(0);
GET_DIGIT(1);
GET_DIGIT(2);
GET_DIGIT(3);
#undef GET_DIGIT
return ret;
}
/**
* Utility function to convert escape sequences
*/
JSONSL_API
size_t jsonsl_util_unescape_ex(const char *in,
char *out,
size_t len,
const int toEscape[128],
unsigned *oflags,
jsonsl_error_t *err,
const char **errat)
{
const unsigned char *c = (const unsigned char*)in;
char *begin_p = out;
unsigned oflags_s;
uint16_t last_codepoint = 0;
if (!oflags) {
oflags = &oflags_s;
}
*oflags = 0;
#define UNESCAPE_BAIL(e,offset) \
*err = JSONSL_ERROR_##e; \
if (errat) { \
*errat = (const char*)(c+ (ptrdiff_t)(offset)); \
} \
return 0;
for (; len; len--, c++, out++) {
int uescval;
if (*c != '\\') {
/* Not an escape, so we don't care about this */
goto GT_ASSIGN;
}
if (len < 2) {
UNESCAPE_BAIL(ESCAPE_INVALID, 0);
}
if (!is_allowed_escape(c[1])) {
UNESCAPE_BAIL(ESCAPE_INVALID, 1)
}
if ((toEscape && toEscape[(unsigned char)c[1] & 0x7f] == 0 &&
c[1] != '\\' && c[1] != '"')) {
/* if we don't want to unescape this string, write the escape sequence to the output */
*out++ = *c++;
--len;
goto GT_ASSIGN;
}
if (c[1] != 'u') {
/* simple skip-and-replace using pre-defined maps.
* TODO: should the maps actually reflect the desired
* replacement character in toEscape?
*/
char esctmp = get_escape_equiv(c[1]);
if (esctmp) {
/* Check if there is a corresponding replacement */
*out = esctmp;
} else {
/* Just gobble up the 'reverse-solidus' */
*out = c[1];
}
len--;
c++;
/* do not assign, just continue */
continue;
}
/* next == 'u' */
if (len < 6) {
/* Need at least six characters.. */
UNESCAPE_BAIL(UESCAPE_TOOSHORT, 2);
}
uescval = jsonsl__get_uescape_16((const char *)c + 2);
if (uescval == -1) {
UNESCAPE_BAIL(PERCENT_BADHEX, -1);
}
if (last_codepoint) {
uint16_t w1 = last_codepoint, w2 = (uint16_t)uescval;
uint32_t cp;
if (uescval < 0xDC00 || uescval > 0xDFFF) {
UNESCAPE_BAIL(INVALID_CODEPOINT, -1);
}
cp = (w1 & 0x3FF) << 10;
cp |= (w2 & 0x3FF);
cp += 0x10000;
out = jsonsl__writeutf8(cp, out) - 1;
last_codepoint = 0;
} else if (uescval < 0xD800 || uescval > 0xDFFF) {
*oflags |= JSONSL_SPECIALf_NONASCII;
out = jsonsl__writeutf8(uescval, out) - 1;
} else if (uescval < 0xDC00) {
*oflags |= JSONSL_SPECIALf_NONASCII;
last_codepoint = (uint16_t)uescval;
out--;
} else {
UNESCAPE_BAIL(INVALID_CODEPOINT, 2);
}
/* Post uescape cleanup */
len -= 5; /* Gobble up 5 chars after 'u' */
c += 5;
continue;
/* Only reached by previous branches */
GT_ASSIGN:
*out = *c;
}
if (last_codepoint) {
*err = JSONSL_ERROR_INVALID_CODEPOINT;
return 0;
}
*err = JSONSL_ERROR_SUCCESS;
return out - begin_p;
}
/**
* Character Table definitions.
* These were all generated via srcutil/genchartables.pl
*/
/**
* This table contains the beginnings of non-string
* allowable (bareword) values.
*/
static unsigned short Special_Table[0x100] = {
/* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
/* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2c */
/* 0x2d */ JSONSL_SPECIALf_DASH /* <-> */, /* 0x2d */
/* 0x2e */ 0,0, /* 0x2f */
/* 0x30 */ JSONSL_SPECIALf_ZERO /* <0> */, /* 0x30 */
/* 0x31 */ JSONSL_SPECIALf_UNSIGNED /* <1> */, /* 0x31 */
/* 0x32 */ JSONSL_SPECIALf_UNSIGNED /* <2> */, /* 0x32 */
/* 0x33 */ JSONSL_SPECIALf_UNSIGNED /* <3> */, /* 0x33 */
/* 0x34 */ JSONSL_SPECIALf_UNSIGNED /* <4> */, /* 0x34 */
/* 0x35 */ JSONSL_SPECIALf_UNSIGNED /* <5> */, /* 0x35 */
/* 0x36 */ JSONSL_SPECIALf_UNSIGNED /* <6> */, /* 0x36 */
/* 0x37 */ JSONSL_SPECIALf_UNSIGNED /* <7> */, /* 0x37 */
/* 0x38 */ JSONSL_SPECIALf_UNSIGNED /* <8> */, /* 0x38 */
/* 0x39 */ JSONSL_SPECIALf_UNSIGNED /* <9> */, /* 0x39 */
/* 0x3a */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x48 */
/* 0x49 */ JSONSL__INF_PROXY /* <I> */, /* 0x49 */
/* 0x4a */ 0,0,0,0, /* 0x4d */
/* 0x4e */ JSONSL__NAN_PROXY /* <N> */, /* 0x4e */
/* 0x4f */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x65 */
/* 0x66 */ JSONSL_SPECIALf_FALSE /* <f> */, /* 0x66 */
/* 0x67 */ 0,0, /* 0x68 */
/* 0x69 */ JSONSL__INF_PROXY /* <i> */, /* 0x69 */
/* 0x6a */ 0,0,0,0, /* 0x6d */
/* 0x6e */ JSONSL_SPECIALf_NULL|JSONSL__NAN_PROXY /* <n> */, /* 0x6e */
/* 0x6f */ 0,0,0,0,0, /* 0x73 */
/* 0x74 */ JSONSL_SPECIALf_TRUE /* <t> */, /* 0x74 */
/* 0x75 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x94 */
/* 0x95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb4 */
/* 0xb5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd4 */
/* 0xd5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf4 */
/* 0xf5 */ 0,0,0,0,0,0,0,0,0,0, /* 0xfe */
};
/**
* Contains characters which signal the termination of any of the 'special' bareword
* values.
*/
static int Special_Endings[0x100] = {
/* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */
/* 0x09 */ 1 /* <TAB> */, /* 0x09 */
/* 0x0a */ 1 /* <LF> */, /* 0x0a */
/* 0x0b */ 0,0, /* 0x0c */
/* 0x0d */ 1 /* <CR> */, /* 0x0d */
/* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
/* 0x20 */ 1 /* <SP> */, /* 0x20 */
/* 0x21 */ 0, /* 0x21 */
/* 0x22 */ 1 /* " */, /* 0x22 */
/* 0x23 */ 0,0,0,0,0,0,0,0,0, /* 0x2b */
/* 0x2c */ 1 /* , */, /* 0x2c */
/* 0x2d */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x39 */
/* 0x3a */ 1 /* : */, /* 0x3a */
/* 0x3b */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5a */
/* 0x5b */ 1 /* [ */, /* 0x5b */
/* 0x5c */ 1 /* \ */, /* 0x5c */
/* 0x5d */ 1 /* ] */, /* 0x5d */
/* 0x5e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x7a */
/* 0x7b */ 1 /* { */, /* 0x7b */
/* 0x7c */ 0, /* 0x7c */
/* 0x7d */ 1 /* } */, /* 0x7d */
/* 0x7e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9d */
/* 0x9e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xbd */
/* 0xbe */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xdd */
/* 0xde */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xfd */
/* 0xfe */ 0 /* 0xfe */
};
/**
* This table contains entries for the allowed whitespace as per RFC 4627
*/
static int Allowed_Whitespace[0x100] = {
/* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */
/* 0x09 */ 1 /* <TAB> */, /* 0x09 */
/* 0x0a */ 1 /* <LF> */, /* 0x0a */
/* 0x0b */ 0,0, /* 0x0c */
/* 0x0d */ 1 /* <CR> */, /* 0x0d */
/* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
/* 0x20 */ 1 /* <SP> */, /* 0x20 */
/* 0x21 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 */
/* 0x41 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 */
/* 0x61 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80 */
/* 0x81 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0 */
/* 0xa1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xc0 */
/* 0xc1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xe0 */
/* 0xe1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xfe */
};
static const int String_No_Passthrough[0x100] = {
/* 0x00 */ 1 /* <NUL> */, /* 0x00 */
/* 0x01 */ 1 /* <SOH> */, /* 0x01 */
/* 0x02 */ 1 /* <STX> */, /* 0x02 */
/* 0x03 */ 1 /* <ETX> */, /* 0x03 */
/* 0x04 */ 1 /* <EOT> */, /* 0x04 */
/* 0x05 */ 1 /* <ENQ> */, /* 0x05 */
/* 0x06 */ 1 /* <ACK> */, /* 0x06 */
/* 0x07 */ 1 /* <BEL> */, /* 0x07 */
/* 0x08 */ 1 /* <BS> */, /* 0x08 */
/* 0x09 */ 1 /* <HT> */, /* 0x09 */
/* 0x0a */ 1 /* <LF> */, /* 0x0a */
/* 0x0b */ 1 /* <VT> */, /* 0x0b */
/* 0x0c */ 1 /* <FF> */, /* 0x0c */
/* 0x0d */ 1 /* <CR> */, /* 0x0d */
/* 0x0e */ 1 /* <SO> */, /* 0x0e */
/* 0x0f */ 1 /* <SI> */, /* 0x0f */
/* 0x10 */ 1 /* <DLE> */, /* 0x10 */
/* 0x11 */ 1 /* <DC1> */, /* 0x11 */
/* 0x12 */ 1 /* <DC2> */, /* 0x12 */
/* 0x13 */ 1 /* <DC3> */, /* 0x13 */
/* 0x14 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x21 */
/* 0x22 */ 1 /* <"> */, /* 0x22 */
/* 0x23 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x42 */
/* 0x43 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5b */
/* 0x5c */ 1 /* <\> */, /* 0x5c */
/* 0x5d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x7c */
/* 0x7d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9c */
/* 0x9d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xbc */
/* 0xbd */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xdc */
/* 0xdd */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xfc */
/* 0xfd */ 0,0, /* 0xfe */
};
/**
* Allowable two-character 'common' escapes:
*/
static int Allowed_Escapes[0x100] = {
/* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
/* 0x20 */ 0,0, /* 0x21 */
/* 0x22 */ 1 /* <"> */, /* 0x22 */
/* 0x23 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2e */
/* 0x2f */ 1 /* </> */, /* 0x2f */
/* 0x30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x4f */
/* 0x50 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5b */
/* 0x5c */ 1 /* <\> */, /* 0x5c */
/* 0x5d */ 0,0,0,0,0, /* 0x61 */
/* 0x62 */ 1 /* <b> */, /* 0x62 */
/* 0x63 */ 0,0,0, /* 0x65 */
/* 0x66 */ 1 /* <f> */, /* 0x66 */
/* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */
/* 0x6e */ 1 /* <n> */, /* 0x6e */
/* 0x6f */ 0,0,0, /* 0x71 */
/* 0x72 */ 1 /* <r> */, /* 0x72 */
/* 0x73 */ 0, /* 0x73 */
/* 0x74 */ 1 /* <t> */, /* 0x74 */
/* 0x75 */ 1 /* <u> */, /* 0x75 */
/* 0x76 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x95 */
/* 0x96 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb5 */
/* 0xb6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd5 */
/* 0xd6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf5 */
/* 0xf6 */ 0,0,0,0,0,0,0,0,0, /* 0xfe */
};
/**
* This table contains the _values_ for a given (single) escaped character.
*/
static unsigned char Escape_Equivs[0x100] = {
/* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
/* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x3f */
/* 0x40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5f */
/* 0x60 */ 0,0, /* 0x61 */
/* 0x62 */ 8 /* <b> */, /* 0x62 */
/* 0x63 */ 0,0,0, /* 0x65 */
/* 0x66 */ 12 /* <f> */, /* 0x66 */
/* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */
/* 0x6e */ 10 /* <n> */, /* 0x6e */
/* 0x6f */ 0,0,0, /* 0x71 */
/* 0x72 */ 13 /* <r> */, /* 0x72 */
/* 0x73 */ 0, /* 0x73 */
/* 0x74 */ 9 /* <t> */, /* 0x74 */
/* 0x75 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x94 */
/* 0x95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb4 */
/* 0xb5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd4 */
/* 0xd5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf4 */
/* 0xf5 */ 0,0,0,0,0,0,0,0,0,0 /* 0xfe */
};
/* Definitions of above-declared static functions */
static char get_escape_equiv(unsigned c) {
return Escape_Equivs[c & 0xff];
}
static unsigned extract_special(unsigned c) {
return Special_Table[c & 0xff];
}
static int is_special_end(unsigned c) {
return Special_Endings[c & 0xff];
}
static int is_allowed_whitespace(unsigned c) {
return c == ' ' || Allowed_Whitespace[c & 0xff];
}
static int is_allowed_escape(unsigned c) {
return Allowed_Escapes[c & 0xff];
}
static int is_simple_char(unsigned c) {
return !String_No_Passthrough[c & 0xff];
}
/* Clean up all our macros! */
#undef INCR_METRIC
#undef INCR_GENERIC
#undef INCR_STRINGY_CATCH
#undef CASE_DIGITS
#undef INVOKE_ERROR
#undef STACK_PUSH
#undef STACK_POP_NOPOS
#undef STACK_POP
#undef CALLBACK_AND_POP_NOPOS
#undef CALLBACK_AND_POP
#undef SPECIAL_POP
#undef CUR_CHAR
#undef DO_CALLBACK
#undef ENSURE_HVAL
#undef VERIFY_SPECIAL
#undef STATE_SPECIAL_LENGTH
#undef IS_NORMAL_NUMBER
#undef STATE_NUM_LAST
#undef FASTPARSE_EXHAUSTED
#undef FASTPARSE_BREAK
diff --git a/mongodb-1.13.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h b/mongodb-1.14.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h
rename to mongodb-1.14.0/src/libmongoc/src/libbson/src/jsonsl/jsonsl.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
index e9e6a741..117797f1 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h
@@ -1,221 +1,227 @@
/*
* Copyright 2016 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_APM_PRIVATE_H
#define MONGOC_APM_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-apm.h"
BSON_BEGIN_DECLS
/* forward decl */
struct _mongoc_cmd_t;
struct _mongoc_apm_callbacks_t {
mongoc_apm_command_started_cb_t started;
mongoc_apm_command_succeeded_cb_t succeeded;
mongoc_apm_command_failed_cb_t failed;
mongoc_apm_server_changed_cb_t server_changed;
mongoc_apm_server_opening_cb_t server_opening;
mongoc_apm_server_closed_cb_t server_closed;
mongoc_apm_topology_changed_cb_t topology_changed;
mongoc_apm_topology_opening_cb_t topology_opening;
mongoc_apm_topology_closed_cb_t topology_closed;
mongoc_apm_server_heartbeat_started_cb_t server_heartbeat_started;
mongoc_apm_server_heartbeat_succeeded_cb_t server_heartbeat_succeeded;
mongoc_apm_server_heartbeat_failed_cb_t server_heartbeat_failed;
};
/*
* command monitoring events
*/
struct _mongoc_apm_command_started_t {
bson_t *command;
bool command_owned;
const char *database_name;
const char *command_name;
int64_t request_id;
int64_t operation_id;
const mongoc_host_list_t *host;
uint32_t server_id;
bson_oid_t service_id;
+ int32_t server_connection_id;
void *context;
};
struct _mongoc_apm_command_succeeded_t {
int64_t duration;
bson_t *reply;
bool reply_owned;
const char *command_name;
int64_t request_id;
int64_t operation_id;
const mongoc_host_list_t *host;
uint32_t server_id;
bson_oid_t service_id;
+ int32_t server_connection_id;
void *context;
};
struct _mongoc_apm_command_failed_t {
int64_t duration;
const char *command_name;
const bson_error_t *error;
bson_t *reply;
bool reply_owned;
int64_t request_id;
int64_t operation_id;
const mongoc_host_list_t *host;
uint32_t server_id;
bson_oid_t service_id;
+ int32_t server_connection_id;
void *context;
};
/*
* SDAM monitoring events
*/
struct _mongoc_apm_server_changed_t {
const mongoc_host_list_t *host;
bson_oid_t topology_id;
const mongoc_server_description_t *previous_description;
const mongoc_server_description_t *new_description;
void *context;
};
struct _mongoc_apm_server_opening_t {
const mongoc_host_list_t *host;
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_server_closed_t {
const mongoc_host_list_t *host;
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_topology_changed_t {
bson_oid_t topology_id;
const mongoc_topology_description_t *previous_description;
const mongoc_topology_description_t *new_description;
void *context;
};
struct _mongoc_apm_topology_opening_t {
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_topology_closed_t {
bson_oid_t topology_id;
void *context;
};
struct _mongoc_apm_server_heartbeat_started_t {
const mongoc_host_list_t *host;
void *context;
bool awaited;
};
struct _mongoc_apm_server_heartbeat_succeeded_t {
int64_t duration_usec;
const bson_t *reply;
const mongoc_host_list_t *host;
void *context;
bool awaited;
};
struct _mongoc_apm_server_heartbeat_failed_t {
int64_t duration_usec;
const bson_error_t *error;
const mongoc_host_list_t *host;
void *context;
bool awaited;
};
void
mongoc_apm_command_started_init (mongoc_apm_command_started_t *event,
const bson_t *command,
const char *database_name,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
const bson_oid_t *service_id,
+ int32_t server_connection_id,
bool *is_redacted, /* out */
void *context);
void
mongoc_apm_command_started_init_with_cmd (mongoc_apm_command_started_t *event,
struct _mongoc_cmd_t *cmd,
int64_t request_id,
bool *is_redacted, /* out */
void *context);
void
mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event);
void
mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event,
int64_t duration,
const bson_t *reply,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
const bson_oid_t *service_id,
+ int32_t server_connection_id,
bool force_redaction,
void *context);
void
mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event);
void
mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event,
int64_t duration,
const char *command_name,
const bson_error_t *error,
const bson_t *reply,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
const bson_oid_t *service_id,
+ int32_t server_connection_id,
bool force_redaction,
void *context);
void
mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event);
/**
* @brief Determine whether the given command-related message is a "sensitive
* command."
*
* @param command_name The name of the command being checked
* @param body The body of the command request, reply, or failure.
*/
bool
mongoc_apm_is_sensitive_command_message (const char *command_name,
const bson_t *body);
BSON_END_DECLS
#endif /* MONGOC_APM_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
index 728ca74d..0fb056e7 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c
@@ -1,996 +1,1028 @@
/*
* Copyright 2016 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-util-private.h"
#include "mongoc-apm-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-handshake-private.h"
static bson_oid_t kObjectIdZero = {{0}};
/*
* An Application Performance Management (APM) implementation, complying with
* MongoDB's Command Monitoring Spec:
*
* https://github.com/mongodb/specifications/tree/master/source/command-monitoring
*/
static void
append_documents_from_cmd (const mongoc_cmd_t *cmd,
mongoc_apm_command_started_t *event)
{
if (!cmd->payload || !cmd->payload_size) {
return;
}
if (!event->command_owned) {
event->command = bson_copy (event->command);
event->command_owned = true;
}
_mongoc_cmd_append_payload_as_array (cmd, event->command);
}
/*
* Private initializer / cleanup functions.
*/
static void
mongoc_apm_redact_command (bson_t *command);
static void
mongoc_apm_redact_reply (bson_t *reply);
/*--------------------------------------------------------------------------
*
* mongoc_apm_command_started_init --
*
* Initialises the command started event.
*
* Side effects:
* If provided, is_redacted indicates whether the command document was
* redacted to hide sensitive information.
*
*--------------------------------------------------------------------------
*/
void
mongoc_apm_command_started_init (mongoc_apm_command_started_t *event,
const bson_t *command,
const char *database_name,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
const bson_oid_t *service_id,
+ int32_t server_connection_id,
bool *is_redacted, /* out */
void *context)
{
bson_iter_t iter;
uint32_t len;
const uint8_t *data;
/* Command Monitoring Spec:
*
* In cases where queries or commands are embedded in a $query parameter
* when a read preference is provided, they MUST be unwrapped and the value
* of the $query attribute becomes the filter or the command in the started
* event. The read preference will subsequently be dropped as it is
* considered metadata and metadata is not currently provided in the command
* events.
*/
if (bson_has_field (command, "$readPreference")) {
if (bson_iter_init_find (&iter, command, "$query") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_iter_document (&iter, &len, &data);
event->command = bson_new_from_data (data, len);
event->command_owned = true;
} else {
/* Got $readPreference without $query, probably OP_MSG */
event->command = (bson_t *) command;
event->command_owned = false;
}
} else {
/* discard "const", we promise not to modify "command" */
event->command = (bson_t *) command;
event->command_owned = false;
}
if (mongoc_apm_is_sensitive_command_message (command_name, command)) {
if (!event->command_owned) {
event->command = bson_copy (event->command);
event->command_owned = true;
}
if (is_redacted) {
*is_redacted = true;
}
mongoc_apm_redact_command (event->command);
} else if (is_redacted) {
*is_redacted = false;
}
event->database_name = database_name;
event->command_name = command_name;
event->request_id = request_id;
event->operation_id = operation_id;
event->host = host;
event->server_id = server_id;
event->context = context;
+ event->server_connection_id = server_connection_id;
bson_oid_copy_unsafe (service_id, &event->service_id);
}
/*--------------------------------------------------------------------------
*
* mongoc_apm_command_started_init_with_cmd --
*
* Initialises the command started event from a mongoc_cmd_t.
*
* Side effects:
* If provided, is_redacted indicates whether the command document was
* redacted to hide sensitive information.
*
*--------------------------------------------------------------------------
*/
void
mongoc_apm_command_started_init_with_cmd (mongoc_apm_command_started_t *event,
mongoc_cmd_t *cmd,
int64_t request_id,
bool *is_redacted, /* out */
void *context)
{
- mongoc_apm_command_started_init (event,
- cmd->command,
- cmd->db_name,
- cmd->command_name,
- request_id,
- cmd->operation_id,
- &cmd->server_stream->sd->host,
- cmd->server_stream->sd->id,
- &cmd->server_stream->sd->service_id,
- is_redacted,
- context);
+ mongoc_apm_command_started_init (
+ event,
+ cmd->command,
+ cmd->db_name,
+ cmd->command_name,
+ request_id,
+ cmd->operation_id,
+ &cmd->server_stream->sd->host,
+ cmd->server_stream->sd->id,
+ &cmd->server_stream->sd->service_id,
+ cmd->server_stream->sd->server_connection_id,
+ is_redacted,
+ context);
/* OP_MSG document sequence for insert, update, or delete? */
append_documents_from_cmd (cmd, event);
}
void
mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event)
{
if (event->command_owned) {
bson_destroy (event->command);
}
}
/*--------------------------------------------------------------------------
*
* mongoc_apm_command_succeeded_init --
*
* Initialises the command succeeded event.
*
* Parameters:
* @force_redaction: If true, the reply document is always redacted,
* regardless of whether the command contains sensitive information.
*
*--------------------------------------------------------------------------
*/
void
mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event,
int64_t duration,
const bson_t *reply,
const char *command_name,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
const bson_oid_t *service_id,
+ int32_t server_connection_id,
bool force_redaction,
void *context)
{
BSON_ASSERT (reply);
if (force_redaction ||
mongoc_apm_is_sensitive_command_message (command_name, reply)) {
event->reply = bson_copy (reply);
event->reply_owned = true;
mongoc_apm_redact_reply (event->reply);
} else {
/* discard "const", we promise not to modify "reply" */
event->reply = (bson_t *) reply;
event->reply_owned = false;
}
event->duration = duration;
event->command_name = command_name;
event->request_id = request_id;
event->operation_id = operation_id;
event->host = host;
event->server_id = server_id;
+ event->server_connection_id = server_connection_id;
event->context = context;
bson_oid_copy_unsafe (service_id, &event->service_id);
}
void
mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event)
{
if (event->reply_owned) {
bson_destroy (event->reply);
}
}
/*--------------------------------------------------------------------------
*
* mongoc_apm_command_failed_init --
*
* Initialises the command failed event.
*
* Parameters:
* @force_redaction: If true, the reply document is always redacted,
* regardless of whether the command contains sensitive information.
*
*--------------------------------------------------------------------------
*/
void
mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event,
int64_t duration,
const char *command_name,
const bson_error_t *error,
const bson_t *reply,
int64_t request_id,
int64_t operation_id,
const mongoc_host_list_t *host,
uint32_t server_id,
const bson_oid_t *service_id,
+ int32_t server_connection_id,
bool force_redaction,
void *context)
{
BSON_ASSERT (reply);
if (force_redaction ||
mongoc_apm_is_sensitive_command_message (command_name, reply)) {
event->reply = bson_copy (reply);
event->reply_owned = true;
mongoc_apm_redact_reply (event->reply);
} else {
/* discard "const", we promise not to modify "reply" */
event->reply = (bson_t *) reply;
event->reply_owned = false;
}
event->duration = duration;
event->command_name = command_name;
event->error = error;
event->request_id = request_id;
event->operation_id = operation_id;
event->host = host;
event->server_id = server_id;
+ event->server_connection_id = server_connection_id;
event->context = context;
bson_oid_copy_unsafe (service_id, &event->service_id);
}
void
mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event)
{
if (event->reply_owned) {
bson_destroy (event->reply);
}
}
/*
* event field accessors
*/
/* command-started event fields */
const bson_t *
mongoc_apm_command_started_get_command (
const mongoc_apm_command_started_t *event)
{
return event->command;
}
const char *
mongoc_apm_command_started_get_database_name (
const mongoc_apm_command_started_t *event)
{
return event->database_name;
}
const char *
mongoc_apm_command_started_get_command_name (
const mongoc_apm_command_started_t *event)
{
return event->command_name;
}
int64_t
mongoc_apm_command_started_get_request_id (
const mongoc_apm_command_started_t *event)
{
return event->request_id;
}
int64_t
mongoc_apm_command_started_get_operation_id (
const mongoc_apm_command_started_t *event)
{
return event->operation_id;
}
const mongoc_host_list_t *
mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event)
{
return event->host;
}
uint32_t
mongoc_apm_command_started_get_server_id (
const mongoc_apm_command_started_t *event)
{
return event->server_id;
}
const bson_oid_t *
mongoc_apm_command_started_get_service_id (
const mongoc_apm_command_started_t *event)
{
if (0 == bson_oid_compare (&event->service_id, &kObjectIdZero)) {
/* serviceId is unset. */
return NULL;
}
return &event->service_id;
}
+int32_t
+mongoc_apm_command_started_get_server_connection_id (
+ const mongoc_apm_command_started_t *event)
+{
+ return event->server_connection_id;
+}
+
+
void *
mongoc_apm_command_started_get_context (
const mongoc_apm_command_started_t *event)
{
return event->context;
}
/* command-succeeded event fields */
int64_t
mongoc_apm_command_succeeded_get_duration (
const mongoc_apm_command_succeeded_t *event)
{
return event->duration;
}
const bson_t *
mongoc_apm_command_succeeded_get_reply (
const mongoc_apm_command_succeeded_t *event)
{
return event->reply;
}
const char *
mongoc_apm_command_succeeded_get_command_name (
const mongoc_apm_command_succeeded_t *event)
{
return event->command_name;
}
int64_t
mongoc_apm_command_succeeded_get_request_id (
const mongoc_apm_command_succeeded_t *event)
{
return event->request_id;
}
int64_t
mongoc_apm_command_succeeded_get_operation_id (
const mongoc_apm_command_succeeded_t *event)
{
return event->operation_id;
}
const mongoc_host_list_t *
mongoc_apm_command_succeeded_get_host (
const mongoc_apm_command_succeeded_t *event)
{
return event->host;
}
uint32_t
mongoc_apm_command_succeeded_get_server_id (
const mongoc_apm_command_succeeded_t *event)
{
return event->server_id;
}
const bson_oid_t *
mongoc_apm_command_succeeded_get_service_id (
const mongoc_apm_command_succeeded_t *event)
{
if (0 == bson_oid_compare (&event->service_id, &kObjectIdZero)) {
/* serviceId is unset. */
return NULL;
}
return &event->service_id;
}
+int32_t
+mongoc_apm_command_succeeded_get_server_connection_id (
+ const mongoc_apm_command_succeeded_t *event)
+{
+ return event->server_connection_id;
+}
+
+
void *
mongoc_apm_command_succeeded_get_context (
const mongoc_apm_command_succeeded_t *event)
{
return event->context;
}
/* command-failed event fields */
int64_t
mongoc_apm_command_failed_get_duration (
const mongoc_apm_command_failed_t *event)
{
return event->duration;
}
const char *
mongoc_apm_command_failed_get_command_name (
const mongoc_apm_command_failed_t *event)
{
return event->command_name;
}
void
mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event,
bson_error_t *error)
{
memcpy (error, event->error, sizeof *event->error);
}
const bson_t *
mongoc_apm_command_failed_get_reply (const mongoc_apm_command_failed_t *event)
{
return event->reply;
}
int64_t
mongoc_apm_command_failed_get_request_id (
const mongoc_apm_command_failed_t *event)
{
return event->request_id;
}
int64_t
mongoc_apm_command_failed_get_operation_id (
const mongoc_apm_command_failed_t *event)
{
return event->operation_id;
}
const mongoc_host_list_t *
mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event)
{
return event->host;
}
uint32_t
mongoc_apm_command_failed_get_server_id (
const mongoc_apm_command_failed_t *event)
{
return event->server_id;
}
const bson_oid_t *
mongoc_apm_command_failed_get_service_id (
const mongoc_apm_command_failed_t *event)
{
if (0 == bson_oid_compare (&event->service_id, &kObjectIdZero)) {
/* serviceId is unset. */
return NULL;
}
return &event->service_id;
}
+int32_t
+mongoc_apm_command_failed_get_server_connection_id (
+ const mongoc_apm_command_failed_t *event)
+{
+ return event->server_connection_id;
+}
+
+
void *
mongoc_apm_command_failed_get_context (const mongoc_apm_command_failed_t *event)
{
return event->context;
}
/* server-changed event fields */
const mongoc_host_list_t *
mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event)
{
return event->host;
}
void
mongoc_apm_server_changed_get_topology_id (
const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
const mongoc_server_description_t *
mongoc_apm_server_changed_get_previous_description (
const mongoc_apm_server_changed_t *event)
{
return event->previous_description;
}
const mongoc_server_description_t *
mongoc_apm_server_changed_get_new_description (
const mongoc_apm_server_changed_t *event)
{
return event->new_description;
}
void *
mongoc_apm_server_changed_get_context (const mongoc_apm_server_changed_t *event)
{
return event->context;
}
/* server-opening event fields */
const mongoc_host_list_t *
mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event)
{
return event->host;
}
void
mongoc_apm_server_opening_get_topology_id (
const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_server_opening_get_context (const mongoc_apm_server_opening_t *event)
{
return event->context;
}
/* server-closed event fields */
const mongoc_host_list_t *
mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event)
{
return event->host;
}
void
mongoc_apm_server_closed_get_topology_id (
const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event)
{
return event->context;
}
/* topology-changed event fields */
void
mongoc_apm_topology_changed_get_topology_id (
const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
const mongoc_topology_description_t *
mongoc_apm_topology_changed_get_previous_description (
const mongoc_apm_topology_changed_t *event)
{
return event->previous_description;
}
const mongoc_topology_description_t *
mongoc_apm_topology_changed_get_new_description (
const mongoc_apm_topology_changed_t *event)
{
return event->new_description;
}
void *
mongoc_apm_topology_changed_get_context (
const mongoc_apm_topology_changed_t *event)
{
return event->context;
}
/* topology-opening event field */
void
mongoc_apm_topology_opening_get_topology_id (
const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_topology_opening_get_context (
const mongoc_apm_topology_opening_t *event)
{
return event->context;
}
/* topology-closed event field */
void
mongoc_apm_topology_closed_get_topology_id (
const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id)
{
bson_oid_copy (&event->topology_id, topology_id);
}
void *
mongoc_apm_topology_closed_get_context (
const mongoc_apm_topology_closed_t *event)
{
return event->context;
}
/* heartbeat-started event field */
const mongoc_host_list_t *
mongoc_apm_server_heartbeat_started_get_host (
const mongoc_apm_server_heartbeat_started_t *event)
{
return event->host;
}
void *
mongoc_apm_server_heartbeat_started_get_context (
const mongoc_apm_server_heartbeat_started_t *event)
{
return event->context;
}
bool
mongoc_apm_server_heartbeat_started_get_awaited (
const mongoc_apm_server_heartbeat_started_t *event)
{
return event->awaited;
}
/* heartbeat-succeeded event fields */
int64_t
mongoc_apm_server_heartbeat_succeeded_get_duration (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->duration_usec;
}
const bson_t *
mongoc_apm_server_heartbeat_succeeded_get_reply (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->reply;
}
const mongoc_host_list_t *
mongoc_apm_server_heartbeat_succeeded_get_host (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->host;
}
void *
mongoc_apm_server_heartbeat_succeeded_get_context (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->context;
}
bool
mongoc_apm_server_heartbeat_succeeded_get_awaited (
const mongoc_apm_server_heartbeat_succeeded_t *event)
{
return event->awaited;
}
/* heartbeat-failed event fields */
int64_t
mongoc_apm_server_heartbeat_failed_get_duration (
const mongoc_apm_server_heartbeat_failed_t *event)
{
return event->duration_usec;
}
void
mongoc_apm_server_heartbeat_failed_get_error (
const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error)
{
memcpy (error, event->error, sizeof *event->error);
}
const mongoc_host_list_t *
mongoc_apm_server_heartbeat_failed_get_host (
const mongoc_apm_server_heartbeat_failed_t *event)
{
return event->host;
}
void *
mongoc_apm_server_heartbeat_failed_get_context (
const mongoc_apm_server_heartbeat_failed_t *event)
{
return event->context;
}
bool
mongoc_apm_server_heartbeat_failed_get_awaited (
const mongoc_apm_server_heartbeat_failed_t *event)
{
return event->awaited;
}
/*
* registering callbacks
*/
mongoc_apm_callbacks_t *
mongoc_apm_callbacks_new (void)
{
size_t s = sizeof (mongoc_apm_callbacks_t);
return (mongoc_apm_callbacks_t *) bson_malloc0 (s);
}
void
mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks)
{
bson_free (callbacks);
}
void
mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_started_cb_t cb)
{
callbacks->started = cb;
}
void
mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_succeeded_cb_t cb)
{
callbacks->succeeded = cb;
}
void
mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_failed_cb_t cb)
{
callbacks->failed = cb;
}
void
mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_changed_cb_t cb)
{
callbacks->server_changed = cb;
}
void
mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_opening_cb_t cb)
{
callbacks->server_opening = cb;
}
void
mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_closed_cb_t cb)
{
callbacks->server_closed = cb;
}
void
mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_changed_cb_t cb)
{
callbacks->topology_changed = cb;
}
void
mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_opening_cb_t cb)
{
callbacks->topology_opening = cb;
}
void
mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_closed_cb_t cb)
{
callbacks->topology_closed = cb;
}
void
mongoc_apm_set_server_heartbeat_started_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_started_cb_t cb)
{
callbacks->server_heartbeat_started = cb;
}
void
mongoc_apm_set_server_heartbeat_succeeded_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_succeeded_cb_t cb)
{
callbacks->server_heartbeat_succeeded = cb;
}
void
mongoc_apm_set_server_heartbeat_failed_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_failed_cb_t cb)
{
callbacks->server_heartbeat_failed = cb;
}
static bool
_mongoc_apm_is_sensitive_command_name (const char *command_name)
{
return 0 == strcasecmp (command_name, "authenticate") ||
0 == strcasecmp (command_name, "saslStart") ||
0 == strcasecmp (command_name, "saslContinue") ||
0 == strcasecmp (command_name, "getnonce") ||
0 == strcasecmp (command_name, "createUser") ||
0 == strcasecmp (command_name, "updateUser") ||
0 == strcasecmp (command_name, "copydbgetnonce") ||
0 == strcasecmp (command_name, "copydbsaslstart") ||
0 == strcasecmp (command_name, "copydb");
}
static bool
_mongoc_apm_is_sensitive_hello_message (const char *command_name,
const bson_t *body)
{
const bool is_hello =
(0 == strcasecmp (command_name, "hello") ||
0 == strcasecmp (command_name, HANDSHAKE_CMD_LEGACY_HELLO));
if (!is_hello) {
return false;
}
if (bson_empty (body)) {
/* An empty message body means that it has been redacted */
return true;
} else if (bson_has_field (body, "speculativeAuthenticate")) {
/* "hello" messages are only sensitive if they contain
* 'speculativeAuthenticate' */
return true;
} else {
/* Other "hello" messages are okay */
return false;
}
}
bool
mongoc_apm_is_sensitive_command_message (const char *command_name,
const bson_t *body)
{
BSON_ASSERT (body);
return _mongoc_apm_is_sensitive_command_name (command_name) ||
_mongoc_apm_is_sensitive_hello_message (command_name, body);
}
void
mongoc_apm_redact_command (bson_t *command)
{
BSON_ASSERT (command);
/* Reinit the command to have an empty document */
bson_reinit (command);
}
void
mongoc_apm_redact_reply (bson_t *reply)
{
BSON_ASSERT (reply);
/* Reinit the reply to have an empty document */
bson_reinit (reply);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
index 8bfed99c..7fe95d33 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h
@@ -1,369 +1,378 @@
/*
* Copyright 2015 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_APM_H
#define MONGOC_APM_H
#include <bson/bson.h>
#include "mongoc-macros.h"
#include "mongoc-host-list.h"
#include "mongoc-server-description.h"
#include "mongoc-topology-description.h"
BSON_BEGIN_DECLS
/*
* Application Performance Management (APM) interface, complies with two specs.
* MongoDB's Command Monitoring Spec:
*
* https://github.com/mongodb/specifications/tree/master/source/command-monitoring
*
* MongoDB's Spec for Monitoring Server Discovery and Monitoring (SDAM) events:
*
* https://github.com/mongodb/specifications/tree/master/source/server-discovery-and-monitoring
*
*/
/*
* callbacks to receive APM events
*/
typedef struct _mongoc_apm_callbacks_t mongoc_apm_callbacks_t;
/*
* command monitoring events
*/
typedef struct _mongoc_apm_command_started_t mongoc_apm_command_started_t;
typedef struct _mongoc_apm_command_succeeded_t mongoc_apm_command_succeeded_t;
typedef struct _mongoc_apm_command_failed_t mongoc_apm_command_failed_t;
/*
* SDAM monitoring events
*/
typedef struct _mongoc_apm_server_changed_t mongoc_apm_server_changed_t;
typedef struct _mongoc_apm_server_opening_t mongoc_apm_server_opening_t;
typedef struct _mongoc_apm_server_closed_t mongoc_apm_server_closed_t;
typedef struct _mongoc_apm_topology_changed_t mongoc_apm_topology_changed_t;
typedef struct _mongoc_apm_topology_opening_t mongoc_apm_topology_opening_t;
typedef struct _mongoc_apm_topology_closed_t mongoc_apm_topology_closed_t;
typedef struct _mongoc_apm_server_heartbeat_started_t
mongoc_apm_server_heartbeat_started_t;
typedef struct _mongoc_apm_server_heartbeat_succeeded_t
mongoc_apm_server_heartbeat_succeeded_t;
typedef struct _mongoc_apm_server_heartbeat_failed_t
mongoc_apm_server_heartbeat_failed_t;
/*
* event field accessors
*/
/* command-started event fields */
MONGOC_EXPORT (const bson_t *)
mongoc_apm_command_started_get_command (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_started_get_database_name (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_started_get_command_name (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_started_get_request_id (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_started_get_operation_id (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (uint32_t)
mongoc_apm_command_started_get_server_id (
const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (const bson_oid_t *)
mongoc_apm_command_started_get_service_id (
const mongoc_apm_command_started_t *event);
+MONGOC_EXPORT (int32_t)
+mongoc_apm_command_started_get_server_connection_id (
+ const mongoc_apm_command_started_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_command_started_get_context (
const mongoc_apm_command_started_t *event);
/* command-succeeded event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_command_succeeded_get_duration (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (const bson_t *)
mongoc_apm_command_succeeded_get_reply (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_succeeded_get_command_name (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_succeeded_get_request_id (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_succeeded_get_operation_id (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_command_succeeded_get_host (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (uint32_t)
mongoc_apm_command_succeeded_get_server_id (
const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (const bson_oid_t *)
mongoc_apm_command_succeeded_get_service_id (
const mongoc_apm_command_succeeded_t *event);
+MONGOC_EXPORT (int32_t)
+mongoc_apm_command_succeeded_get_server_connection_id (
+ const mongoc_apm_command_succeeded_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_command_succeeded_get_context (
const mongoc_apm_command_succeeded_t *event);
/* command-failed event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_command_failed_get_duration (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (const char *)
mongoc_apm_command_failed_get_command_name (
const mongoc_apm_command_failed_t *event);
/* retrieve the error by filling out the passed-in "error" struct */
MONGOC_EXPORT (void)
mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event,
bson_error_t *error);
MONGOC_EXPORT (const bson_t *)
mongoc_apm_command_failed_get_reply (const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_failed_get_request_id (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (int64_t)
mongoc_apm_command_failed_get_operation_id (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (uint32_t)
mongoc_apm_command_failed_get_server_id (
const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (const bson_oid_t *)
mongoc_apm_command_failed_get_service_id (
const mongoc_apm_command_failed_t *event);
+MONGOC_EXPORT (int32_t)
+mongoc_apm_command_failed_get_server_connection_id (
+ const mongoc_apm_command_failed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_command_failed_get_context (
const mongoc_apm_command_failed_t *event);
/* server-changed event fields */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_changed_get_topology_id (
const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (const mongoc_server_description_t *)
mongoc_apm_server_changed_get_previous_description (
const mongoc_apm_server_changed_t *event);
MONGOC_EXPORT (const mongoc_server_description_t *)
mongoc_apm_server_changed_get_new_description (
const mongoc_apm_server_changed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_changed_get_context (
const mongoc_apm_server_changed_t *event);
/* server-opening event fields */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_opening_get_topology_id (
const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_server_opening_get_context (
const mongoc_apm_server_opening_t *event);
/* server-closed event fields */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_closed_get_topology_id (
const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event);
/* topology-changed event fields */
MONGOC_EXPORT (void)
mongoc_apm_topology_changed_get_topology_id (
const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (const mongoc_topology_description_t *)
mongoc_apm_topology_changed_get_previous_description (
const mongoc_apm_topology_changed_t *event);
MONGOC_EXPORT (const mongoc_topology_description_t *)
mongoc_apm_topology_changed_get_new_description (
const mongoc_apm_topology_changed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_topology_changed_get_context (
const mongoc_apm_topology_changed_t *event);
/* topology-opening event field */
MONGOC_EXPORT (void)
mongoc_apm_topology_opening_get_topology_id (
const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_topology_opening_get_context (
const mongoc_apm_topology_opening_t *event);
/* topology-closed event field */
MONGOC_EXPORT (void)
mongoc_apm_topology_closed_get_topology_id (
const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id);
MONGOC_EXPORT (void *)
mongoc_apm_topology_closed_get_context (
const mongoc_apm_topology_closed_t *event);
/* heartbeat-started event field */
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_heartbeat_started_get_host (
const mongoc_apm_server_heartbeat_started_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_heartbeat_started_get_context (
const mongoc_apm_server_heartbeat_started_t *event);
MONGOC_EXPORT (bool)
mongoc_apm_server_heartbeat_started_get_awaited (
const mongoc_apm_server_heartbeat_started_t *event);
/* heartbeat-succeeded event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_server_heartbeat_succeeded_get_duration (
const mongoc_apm_server_heartbeat_succeeded_t *event);
MONGOC_EXPORT (const bson_t *)
mongoc_apm_server_heartbeat_succeeded_get_reply (
const mongoc_apm_server_heartbeat_succeeded_t *event);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_heartbeat_succeeded_get_host (
const mongoc_apm_server_heartbeat_succeeded_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_heartbeat_succeeded_get_context (
const mongoc_apm_server_heartbeat_succeeded_t *event);
MONGOC_EXPORT (bool)
mongoc_apm_server_heartbeat_succeeded_get_awaited (
const mongoc_apm_server_heartbeat_succeeded_t *event);
/* heartbeat-failed event fields */
MONGOC_EXPORT (int64_t)
mongoc_apm_server_heartbeat_failed_get_duration (
const mongoc_apm_server_heartbeat_failed_t *event);
MONGOC_EXPORT (void)
mongoc_apm_server_heartbeat_failed_get_error (
const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error);
MONGOC_EXPORT (const mongoc_host_list_t *)
mongoc_apm_server_heartbeat_failed_get_host (
const mongoc_apm_server_heartbeat_failed_t *event);
MONGOC_EXPORT (void *)
mongoc_apm_server_heartbeat_failed_get_context (
const mongoc_apm_server_heartbeat_failed_t *event);
MONGOC_EXPORT (bool)
mongoc_apm_server_heartbeat_failed_get_awaited (
const mongoc_apm_server_heartbeat_failed_t *event);
/*
* callbacks
*/
typedef void (*mongoc_apm_command_started_cb_t) (
const mongoc_apm_command_started_t *event);
typedef void (*mongoc_apm_command_succeeded_cb_t) (
const mongoc_apm_command_succeeded_t *event);
typedef void (*mongoc_apm_command_failed_cb_t) (
const mongoc_apm_command_failed_t *event);
typedef void (*mongoc_apm_server_changed_cb_t) (
const mongoc_apm_server_changed_t *event);
typedef void (*mongoc_apm_server_opening_cb_t) (
const mongoc_apm_server_opening_t *event);
typedef void (*mongoc_apm_server_closed_cb_t) (
const mongoc_apm_server_closed_t *event);
typedef void (*mongoc_apm_topology_changed_cb_t) (
const mongoc_apm_topology_changed_t *event);
typedef void (*mongoc_apm_topology_opening_cb_t) (
const mongoc_apm_topology_opening_t *event);
typedef void (*mongoc_apm_topology_closed_cb_t) (
const mongoc_apm_topology_closed_t *event);
typedef void (*mongoc_apm_server_heartbeat_started_cb_t) (
const mongoc_apm_server_heartbeat_started_t *event);
typedef void (*mongoc_apm_server_heartbeat_succeeded_cb_t) (
const mongoc_apm_server_heartbeat_succeeded_t *event);
typedef void (*mongoc_apm_server_heartbeat_failed_cb_t) (
const mongoc_apm_server_heartbeat_failed_t *event);
/*
* registering callbacks
*/
MONGOC_EXPORT (mongoc_apm_callbacks_t *)
mongoc_apm_callbacks_new (void) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (void)
mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks);
MONGOC_EXPORT (void)
mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_started_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_succeeded_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_command_failed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_changed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_opening_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_closed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_changed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_opening_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks,
mongoc_apm_topology_closed_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_heartbeat_started_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_started_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_heartbeat_succeeded_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_succeeded_cb_t cb);
MONGOC_EXPORT (void)
mongoc_apm_set_server_heartbeat_failed_cb (
mongoc_apm_callbacks_t *callbacks,
mongoc_apm_server_heartbeat_failed_cb_t cb);
BSON_END_DECLS
#endif /* MONGOC_APM_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
index 03c68380..7d495b55 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h
@@ -1,109 +1,110 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_ASYNC_CMD_PRIVATE_H
#define MONGOC_ASYNC_CMD_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-async-private.h"
#include "mongoc-array-private.h"
#include "mongoc-buffer-private.h"
#include "mongoc-rpc-private.h"
#include "mongoc-stream.h"
BSON_BEGIN_DECLS
typedef enum {
MONGOC_ASYNC_CMD_INITIATE,
MONGOC_ASYNC_CMD_SETUP,
MONGOC_ASYNC_CMD_SEND,
MONGOC_ASYNC_CMD_RECV_LEN,
MONGOC_ASYNC_CMD_RECV_RPC,
MONGOC_ASYNC_CMD_ERROR_STATE,
MONGOC_ASYNC_CMD_CANCELED_STATE,
} mongoc_async_cmd_state_t;
typedef struct _mongoc_async_cmd {
mongoc_stream_t *stream;
mongoc_async_t *async;
mongoc_async_cmd_state_t state;
int events;
mongoc_async_cmd_initiate_t initiator;
mongoc_async_cmd_setup_t setup;
void *setup_ctx;
mongoc_async_cmd_cb_t cb;
void *data;
bson_error_t error;
int64_t initiate_delay_ms;
int64_t connect_started;
int64_t cmd_started;
int64_t timeout_msec;
bson_t cmd;
mongoc_buffer_t buffer;
mongoc_array_t array;
mongoc_iovec_t *iovec;
size_t niovec;
size_t bytes_written;
size_t bytes_to_read;
mongoc_rpc_t rpc;
bson_t reply;
bool reply_needs_cleanup;
char *ns;
struct addrinfo *dns_result;
struct _mongoc_async_cmd *next;
struct _mongoc_async_cmd *prev;
} mongoc_async_cmd_t;
mongoc_async_cmd_t *
mongoc_async_cmd_new (mongoc_async_t *async,
mongoc_stream_t *stream,
bool is_setup_done,
struct addrinfo *dns_result,
mongoc_async_cmd_initiate_t initiator,
int64_t initiate_delay_ms,
mongoc_async_cmd_setup_t setup,
void *setup_ctx,
const char *dbname,
const bson_t *cmd,
+ const mongoc_opcode_t cmd_opcode,
mongoc_async_cmd_cb_t cb,
void *cb_data,
int64_t timeout_msec);
void
mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd);
bool
mongoc_async_cmd_run (mongoc_async_cmd_t *acmd);
#ifdef MONGOC_ENABLE_SSL
int
mongoc_async_cmd_tls_setup (mongoc_stream_t *stream,
int *events,
void *ctx,
int32_t timeout_msec,
bson_error_t *error);
#endif
BSON_END_DECLS
#endif /* MONGOC_ASYNC_CMD_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
similarity index 91%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
index c789e263..49b68049 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c
@@ -1,486 +1,507 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-async-cmd-private.h"
#include "mongoc-async-private.h"
#include "mongoc-error.h"
#include "mongoc-opcode.h"
#include "mongoc-rpc-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-server-description-private.h"
#include "mongoc-topology-scanner-private.h"
#include "mongoc-log.h"
#include "utlist.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-stream-tls.h"
#endif
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "async"
typedef mongoc_async_cmd_result_t (*_mongoc_async_cmd_phase_t) (
mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_initiate (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_send (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *cmd);
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *cmd);
static const _mongoc_async_cmd_phase_t gMongocCMDPhases[] = {
_mongoc_async_cmd_phase_initiate,
_mongoc_async_cmd_phase_setup,
_mongoc_async_cmd_phase_send,
_mongoc_async_cmd_phase_recv_len,
_mongoc_async_cmd_phase_recv_rpc,
NULL, /* no callback for MONGOC_ASYNC_CMD_ERROR_STATE */
NULL, /* no callback for MONGOC_ASYNC_CMD_CANCELED_STATE */
};
#ifdef MONGOC_ENABLE_SSL
int
mongoc_async_cmd_tls_setup (mongoc_stream_t *stream,
int *events,
void *ctx,
int32_t timeout_msec,
bson_error_t *error)
{
mongoc_stream_t *tls_stream;
const char *host = (const char *) ctx;
int retry_events = 0;
for (tls_stream = stream; tls_stream->type != MONGOC_STREAM_TLS;
tls_stream = mongoc_stream_get_base_stream (tls_stream)) {
}
#if defined(MONGOC_ENABLE_SSL_OPENSSL) || \
defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL)
/* pass 0 for the timeout to begin / continue non-blocking handshake */
timeout_msec = 0;
#endif
if (mongoc_stream_tls_handshake (
tls_stream, host, timeout_msec, &retry_events, error)) {
return 1;
}
if (retry_events) {
*events = retry_events;
return 0;
}
return -1;
}
#endif
bool
mongoc_async_cmd_run (mongoc_async_cmd_t *acmd)
{
mongoc_async_cmd_result_t result;
int64_t duration_usec;
_mongoc_async_cmd_phase_t phase_callback;
BSON_ASSERT (acmd);
/* if we have successfully connected to the node, call the callback. */
if (acmd->state == MONGOC_ASYNC_CMD_SEND) {
acmd->cb (acmd, MONGOC_ASYNC_CMD_CONNECTED, NULL, 0);
}
phase_callback = gMongocCMDPhases[acmd->state];
if (phase_callback) {
result = phase_callback (acmd);
} else {
result = MONGOC_ASYNC_CMD_ERROR;
}
if (result == MONGOC_ASYNC_CMD_IN_PROGRESS) {
return true;
}
duration_usec = bson_get_monotonic_time () - acmd->cmd_started;
if (result == MONGOC_ASYNC_CMD_SUCCESS) {
acmd->cb (acmd, result, &acmd->reply, duration_usec);
} else {
/* we're in ERROR, TIMEOUT, or CANCELED */
acmd->cb (acmd, result, NULL, duration_usec);
}
mongoc_async_cmd_destroy (acmd);
return false;
}
void
-_mongoc_async_cmd_init_send (mongoc_async_cmd_t *acmd, const char *dbname)
+_mongoc_async_cmd_init_send (const mongoc_opcode_t cmd_opcode,
+ mongoc_async_cmd_t *acmd,
+ const char *dbname)
{
- acmd->ns = bson_strdup_printf ("%s.$cmd", dbname);
-
acmd->rpc.header.msg_len = 0;
acmd->rpc.header.request_id = ++acmd->async->request_id;
acmd->rpc.header.response_to = 0;
- acmd->rpc.header.opcode = MONGOC_OPCODE_QUERY;
- acmd->rpc.query.flags = MONGOC_QUERY_SECONDARY_OK;
- acmd->rpc.query.collection = acmd->ns;
- acmd->rpc.query.skip = 0;
- acmd->rpc.query.n_return = -1;
- acmd->rpc.query.query = bson_get_data (&acmd->cmd);
- acmd->rpc.query.fields = NULL;
+
+ if (MONGOC_OPCODE_QUERY == cmd_opcode) {
+ acmd->ns = bson_strdup_printf ("%s.$cmd", dbname);
+ acmd->rpc.header.opcode = MONGOC_OPCODE_QUERY;
+ acmd->rpc.query.flags = MONGOC_QUERY_SECONDARY_OK;
+ acmd->rpc.query.collection = acmd->ns;
+ acmd->rpc.query.skip = 0;
+ acmd->rpc.query.n_return = -1;
+ acmd->rpc.query.query = bson_get_data (&acmd->cmd);
+ acmd->rpc.query.fields = NULL;
+ }
+
+ if (MONGOC_OPCODE_MSG == cmd_opcode) {
+ acmd->rpc.header.opcode = MONGOC_OPCODE_MSG;
+
+ acmd->rpc.msg.msg_len = 0;
+ acmd->rpc.msg.flags = 0;
+ acmd->rpc.msg.n_sections = 1;
+ acmd->rpc.msg.sections[0].payload_type = 0;
+ acmd->rpc.msg.sections[0].payload.bson_document =
+ bson_get_data (&acmd->cmd);
+ }
/* This will always be hello, which are not allowed to be compressed */
_mongoc_rpc_gather (&acmd->rpc, &acmd->array);
acmd->iovec = (mongoc_iovec_t *) acmd->array.data;
acmd->niovec = acmd->array.len;
_mongoc_rpc_swab_to_le (&acmd->rpc);
acmd->bytes_written = 0;
}
void
_mongoc_async_cmd_state_start (mongoc_async_cmd_t *acmd, bool is_setup_done)
{
if (!acmd->stream) {
acmd->state = MONGOC_ASYNC_CMD_INITIATE;
} else if (acmd->setup && !is_setup_done) {
acmd->state = MONGOC_ASYNC_CMD_SETUP;
} else {
acmd->state = MONGOC_ASYNC_CMD_SEND;
}
acmd->events = POLLOUT;
}
mongoc_async_cmd_t *
mongoc_async_cmd_new (mongoc_async_t *async,
mongoc_stream_t *stream,
bool is_setup_done,
struct addrinfo *dns_result,
mongoc_async_cmd_initiate_t initiator,
int64_t initiate_delay_ms,
mongoc_async_cmd_setup_t setup,
void *setup_ctx,
const char *dbname,
const bson_t *cmd,
+ const mongoc_opcode_t cmd_opcode, /* OP_QUERY or OP_MSG */
mongoc_async_cmd_cb_t cb,
void *cb_data,
int64_t timeout_msec)
{
mongoc_async_cmd_t *acmd;
BSON_ASSERT (cmd);
BSON_ASSERT (dbname);
acmd = (mongoc_async_cmd_t *) bson_malloc0 (sizeof (*acmd));
acmd->async = async;
acmd->dns_result = dns_result;
acmd->timeout_msec = timeout_msec;
acmd->stream = stream;
acmd->initiator = initiator;
acmd->initiate_delay_ms = initiate_delay_ms;
acmd->setup = setup;
acmd->setup_ctx = setup_ctx;
acmd->cb = cb;
acmd->data = cb_data;
acmd->connect_started = bson_get_monotonic_time ();
bson_copy_to (cmd, &acmd->cmd);
+ if (MONGOC_OPCODE_MSG == cmd_opcode) {
+ /* If we're sending an OPCODE_MSG, we need to add the "db" field: */
+ bson_append_utf8 (&acmd->cmd, "$db", 3, "admin", 5);
+ }
+
_mongoc_array_init (&acmd->array, sizeof (mongoc_iovec_t));
_mongoc_buffer_init (&acmd->buffer, NULL, 0, NULL, NULL);
- _mongoc_async_cmd_init_send (acmd, dbname);
+ _mongoc_async_cmd_init_send (cmd_opcode, acmd, dbname);
_mongoc_async_cmd_state_start (acmd, is_setup_done);
async->ncmds++;
DL_APPEND (async->cmds, acmd);
return acmd;
}
void
mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd)
{
BSON_ASSERT (acmd);
DL_DELETE (acmd->async->cmds, acmd);
acmd->async->ncmds--;
bson_destroy (&acmd->cmd);
if (acmd->reply_needs_cleanup) {
bson_destroy (&acmd->reply);
}
_mongoc_array_destroy (&acmd->array);
_mongoc_buffer_destroy (&acmd->buffer);
bson_free (acmd->ns);
bson_free (acmd);
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_initiate (mongoc_async_cmd_t *acmd)
{
acmd->stream = acmd->initiator (acmd);
if (!acmd->stream) {
return MONGOC_ASYNC_CMD_ERROR;
}
/* reset the connect started time after connection starts. */
acmd->connect_started = bson_get_monotonic_time ();
if (acmd->setup) {
acmd->state = MONGOC_ASYNC_CMD_SETUP;
} else {
acmd->state = MONGOC_ASYNC_CMD_SEND;
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *acmd)
{
int retval;
BSON_ASSERT (acmd->timeout_msec < INT32_MAX);
retval = acmd->setup (acmd->stream,
&acmd->events,
acmd->setup_ctx,
(int32_t) acmd->timeout_msec,
&acmd->error);
switch (retval) {
case -1:
return MONGOC_ASYNC_CMD_ERROR;
case 0:
break;
case 1:
acmd->state = MONGOC_ASYNC_CMD_SEND;
acmd->events = POLLOUT;
break;
default:
abort ();
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_send (mongoc_async_cmd_t *acmd)
{
size_t total_bytes = 0;
size_t offset;
ssize_t bytes;
int i;
/* if a continued write, then iovec will be set to a temporary copy */
bool used_temp_iovec = false;
mongoc_iovec_t *iovec = acmd->iovec;
size_t niovec = acmd->niovec;
for (i = 0; i < acmd->niovec; i++) {
total_bytes += acmd->iovec[i].iov_len;
}
if (acmd->bytes_written > 0) {
BSON_ASSERT (acmd->bytes_written < total_bytes);
/* if bytes have been written before, compute the offset in the next
* iovec entry to be written. */
offset = acmd->bytes_written;
/* subtract the lengths of all iovec entries written so far. */
for (i = 0; i < acmd->niovec; i++) {
if (offset < acmd->iovec[i].iov_len) {
break;
}
offset -= acmd->iovec[i].iov_len;
}
BSON_ASSERT (i < acmd->niovec);
/* create a new iovec with the remaining data to be written. */
niovec = acmd->niovec - i;
iovec = bson_malloc (niovec * sizeof (mongoc_iovec_t));
memcpy (iovec, acmd->iovec + i, niovec * sizeof (mongoc_iovec_t));
iovec[0].iov_base = (char *) iovec[0].iov_base + offset;
iovec[0].iov_len -= offset;
used_temp_iovec = true;
}
bytes = mongoc_stream_writev (acmd->stream, iovec, niovec, 0);
if (used_temp_iovec) {
bson_free (iovec);
}
if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
if (bytes < 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to write rpc bytes.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_written += bytes;
if (acmd->bytes_written < total_bytes) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
acmd->state = MONGOC_ASYNC_CMD_RECV_LEN;
acmd->bytes_to_read = 4;
acmd->events = POLLIN;
acmd->cmd_started = bson_get_monotonic_time ();
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *acmd)
{
ssize_t bytes = _mongoc_buffer_try_append_from_stream (
&acmd->buffer, acmd->stream, acmd->bytes_to_read, 0);
uint32_t msg_len;
if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
if (bytes < 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to receive length header from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
if (bytes == 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Server closed connection.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_to_read = (size_t) (acmd->bytes_to_read - bytes);
if (!acmd->bytes_to_read) {
memcpy (&msg_len, acmd->buffer.data, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if (msg_len < 16 || msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE ||
msg_len < acmd->buffer.len) {
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_to_read = msg_len - acmd->buffer.len;
acmd->state = MONGOC_ASYNC_CMD_RECV_RPC;
return _mongoc_async_cmd_phase_recv_rpc (acmd);
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
mongoc_async_cmd_result_t
_mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *acmd)
{
ssize_t bytes = _mongoc_buffer_try_append_from_stream (
&acmd->buffer, acmd->stream, acmd->bytes_to_read, 0);
if (bytes <= 0 && mongoc_stream_should_retry (acmd->stream)) {
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
if (bytes < 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to receive rpc bytes from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
if (bytes == 0) {
bson_set_error (&acmd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Server closed connection.");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->bytes_to_read = (size_t) (acmd->bytes_to_read - bytes);
if (!acmd->bytes_to_read) {
if (!_mongoc_rpc_scatter (
&acmd->rpc, acmd->buffer.data, acmd->buffer.len)) {
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server.");
return MONGOC_ASYNC_CMD_ERROR;
}
if (BSON_UINT32_FROM_LE (acmd->rpc.header.opcode) ==
MONGOC_OPCODE_COMPRESSED) {
uint8_t *buf = NULL;
size_t len =
BSON_UINT32_FROM_LE (acmd->rpc.compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
buf = bson_malloc0 (len);
if (!_mongoc_rpc_decompress (&acmd->rpc, buf, len)) {
bson_free (buf);
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress server reply");
return MONGOC_ASYNC_CMD_ERROR;
}
_mongoc_buffer_destroy (&acmd->buffer);
_mongoc_buffer_init (&acmd->buffer, buf, len, NULL, NULL);
}
_mongoc_rpc_swab_from_le (&acmd->rpc);
if (!_mongoc_rpc_get_first_document (&acmd->rpc, &acmd->reply)) {
bson_set_error (&acmd->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server");
return MONGOC_ASYNC_CMD_ERROR;
}
acmd->reply_needs_cleanup = true;
return MONGOC_ASYNC_CMD_SUCCESS;
}
return MONGOC_ASYNC_CMD_IN_PROGRESS;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
index 4249594c..a5df125f 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h
@@ -1,55 +1,57 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_BULK_OPERATION_PRIVATE_H
#define MONGOC_BULK_OPERATION_PRIVATE_H
#include "mongoc-array-private.h"
#include "mongoc-client.h"
#include "mongoc-write-command-private.h"
BSON_BEGIN_DECLS
struct _mongoc_bulk_operation_t {
char *database;
char *collection;
mongoc_client_t *client;
mongoc_client_session_t *session;
mongoc_write_concern_t *write_concern;
mongoc_bulk_write_flags_t flags;
+ bson_value_t comment;
+ bson_t let;
uint32_t server_id;
mongoc_array_t commands;
mongoc_write_result_t result;
bool executed;
int64_t operation_id;
};
mongoc_bulk_operation_t *
_mongoc_bulk_operation_new (mongoc_client_t *client,
const char *database,
const char *collection,
mongoc_bulk_write_flags_t flags,
const mongoc_write_concern_t *write_concern);
BSON_END_DECLS
#endif /* MONGOC_BULK_OPERATION_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
similarity index 88%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
index 97f498b8..a1b90240 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c
@@ -1,952 +1,1028 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-bulk-operation.h"
#include "mongoc-bulk-operation-private.h"
#include "mongoc-client-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-opts-private.h"
#include "mongoc-write-command-private.h"
/*
* This is the implementation of both write commands and bulk write commands.
* They are all implemented as one contiguous set since we'd like to cut down
* on code duplication here.
*
* This implementation is currently naive.
*
* Some interesting optimizations might be:
*
* - If unordered mode, send operations as we get them instead of waiting
* for execute() to be called. This could save us memcpy()'s too.
* - If there is no acknowledgement desired, keep a count of how many
* replies we need and ask the socket layer to skip that many bytes
* when reading.
* - Try to use iovec to send write commands with subdocuments rather than
* copying them into the write command document.
*/
mongoc_bulk_operation_t *
mongoc_bulk_operation_new (bool ordered)
{
mongoc_bulk_operation_t *bulk;
bulk = (mongoc_bulk_operation_t *) bson_malloc0 (sizeof *bulk);
bulk->flags.bypass_document_validation = false;
bulk->flags.ordered = ordered;
bulk->server_id = 0;
+ bson_init (&bulk->let);
+
_mongoc_array_init (&bulk->commands, sizeof (mongoc_write_command_t));
_mongoc_write_result_init (&bulk->result);
return bulk;
}
mongoc_bulk_operation_t *
_mongoc_bulk_operation_new (
mongoc_client_t *client, /* IN */
const char *database, /* IN */
const char *collection, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
const mongoc_write_concern_t *write_concern) /* IN */
{
mongoc_bulk_operation_t *bulk;
- BSON_ASSERT (client);
- BSON_ASSERT (collection);
+ BSON_ASSERT_PARAM (client);
+ BSON_ASSERT_PARAM (collection);
bulk = mongoc_bulk_operation_new (flags.ordered);
bulk->client = client;
bulk->database = bson_strdup (database);
bulk->collection = bson_strdup (collection);
bulk->write_concern = mongoc_write_concern_copy (write_concern);
bulk->executed = false;
bulk->flags = flags;
bulk->operation_id = ++client->cluster.operation_id;
return bulk;
}
void
mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk) /* IN */
{
mongoc_write_command_t *command;
int i;
if (bulk) {
for (i = 0; i < bulk->commands.len; i++) {
command =
&_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i);
_mongoc_write_command_destroy (command);
}
bson_free (bulk->database);
bson_free (bulk->collection);
+ bson_value_destroy (&bulk->comment);
+ bson_destroy (&bulk->let);
mongoc_write_concern_destroy (bulk->write_concern);
_mongoc_array_destroy (&bulk->commands);
_mongoc_write_result_destroy (&bulk->result);
bson_free (bulk);
}
}
/* already failed, e.g. a bad call to mongoc_bulk_operation_insert? */
#define BULK_EXIT_IF_PRIOR_ERROR \
do { \
if (bulk->result.error.domain) { \
EXIT; \
} \
} while (0)
#define BULK_RETURN_IF_PRIOR_ERROR \
do { \
if (bulk->result.error.domain) { \
if (error != &bulk->result.error) { \
bson_set_error (error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"Bulk operation is invalid from prior error: %s", \
bulk->result.error.message); \
}; \
return false; \
}; \
} while (0)
-bool
+static bool
_mongoc_bulk_operation_remove_with_opts (
mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const mongoc_bulk_remove_opts_t *remove_opts,
int32_t limit,
bson_error_t *error) /* OUT */
{
mongoc_write_command_t command = {0};
mongoc_write_command_t *last;
+ bson_t cmd_opts = BSON_INITIALIZER;
bson_t opts;
bool has_collation;
bool ret = false;
bool has_delete_hint;
ENTRY;
- BSON_ASSERT (bulk);
- BSON_ASSERT (selector);
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (selector);
bson_init (&opts);
/* allow "limit" in opts, but it must be the correct limit */
if (remove_opts->limit != limit) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid \"limit\" in opts: %" PRId32 "."
" The value must be %" PRId32 ", or omitted.",
remove_opts->limit,
limit);
GOTO (done);
}
bson_append_int32 (&opts, "limit", 5, limit);
has_collation = !bson_empty (&remove_opts->collation);
if (has_collation) {
bson_append_document (&opts, "collation", 9, &remove_opts->collation);
}
has_delete_hint = !!(remove_opts->hint.value_type);
if (has_delete_hint) {
bson_append_value (&opts, "hint", 4, &remove_opts->hint);
}
if (bulk->commands.len) {
last = &_mongoc_array_index (
&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1);
if (last->type == MONGOC_WRITE_COMMAND_DELETE) {
last->flags.has_collation |= has_collation;
last->flags.has_delete_hint |= has_delete_hint;
last->flags.has_multi_write |= (remove_opts->limit == 0);
_mongoc_write_command_delete_append (last, selector, &opts);
ret = true;
GOTO (done);
}
}
+ if (bulk->comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (&cmd_opts, "comment", 7, &bulk->comment);
+ }
+
+ if (!bson_empty (&bulk->let)) {
+ bson_append_document (&cmd_opts, "let", 3, &bulk->let);
+ }
+
_mongoc_write_command_init_delete (
- &command, selector, NULL, &opts, bulk->flags, bulk->operation_id);
+ &command, selector, &cmd_opts, &opts, bulk->flags, bulk->operation_id);
command.flags.has_collation = has_collation;
command.flags.has_delete_hint = has_delete_hint;
command.flags.has_multi_write = (remove_opts->limit == 0);
_mongoc_array_append_val (&bulk->commands, command);
ret = true;
done:
+ bson_destroy (&cmd_opts);
bson_destroy (&opts);
RETURN (ret);
}
bool
mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_remove_one_opts_t remove_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_remove_one_opts_parse (
bulk->client, opts, &remove_opts, error)) {
_mongoc_bulk_remove_one_opts_cleanup (&remove_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_remove_with_opts (
bulk, selector, &remove_opts.remove, 1, error);
_mongoc_bulk_remove_one_opts_cleanup (&remove_opts);
RETURN (ret);
}
bool
mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_remove_many_opts_t remove_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_remove_many_opts_parse (
bulk->client, opts, &remove_opts, error)) {
_mongoc_bulk_remove_many_opts_cleanup (&remove_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_remove_with_opts (
bulk, selector, &remove_opts.remove, 0, error);
_mongoc_bulk_remove_many_opts_cleanup (&remove_opts);
RETURN (ret);
}
void
mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, /* IN */
const bson_t *selector) /* IN */
{
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
if (!mongoc_bulk_operation_remove_many_with_opts (
bulk, selector, NULL, error)) {
MONGOC_WARNING ("%s", error->message);
}
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
void
mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, /* IN */
const bson_t *selector) /* IN */
{
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
if (!mongoc_bulk_operation_remove_one_with_opts (
bulk, selector, NULL, error)) {
MONGOC_WARNING ("%s", error->message);
}
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
void
mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk,
const bson_t *selector)
{
ENTRY;
mongoc_bulk_operation_remove (bulk, selector);
EXIT;
}
void
mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector)
{
ENTRY;
mongoc_bulk_operation_remove_one (bulk, selector);
EXIT;
}
void
mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk,
const bson_t *document)
{
ENTRY;
- BSON_ASSERT (bulk);
- BSON_ASSERT (document);
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (document);
if (!mongoc_bulk_operation_insert_with_opts (
bulk, document, NULL /* opts */, &bulk->result.error)) {
MONGOC_WARNING ("%s", bulk->result.error.message);
}
EXIT;
}
bool
mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *document,
const bson_t *opts,
bson_error_t *error)
{
mongoc_bulk_insert_opts_t insert_opts;
mongoc_write_command_t command = {0};
mongoc_write_command_t *last;
+ bson_t cmd_opts = BSON_INITIALIZER;
bool ret = false;
ENTRY;
- BSON_ASSERT (bulk);
- BSON_ASSERT (document);
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (document);
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_insert_opts_parse (
bulk->client, opts, &insert_opts, error)) {
GOTO (done);
}
if (!_mongoc_validate_new_document (document, insert_opts.validate, error)) {
GOTO (done);
}
+ /* Note: mongoc_bulk_insert_opts_t specifies allow_extra=False, so there is
+ * no reason to concatenate cmd_opts with &insert_opts.extra. */
+
if (bulk->commands.len) {
last = &_mongoc_array_index (
&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1);
if (last->type == MONGOC_WRITE_COMMAND_INSERT) {
_mongoc_write_command_insert_append (last, document);
ret = true;
GOTO (done);
}
}
+ if (bulk->comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (&cmd_opts, "comment", 7, &bulk->comment);
+ }
+
_mongoc_write_command_init_insert (
- &command, document, &insert_opts.extra, bulk->flags, bulk->operation_id);
+ &command, document, &cmd_opts, bulk->flags, bulk->operation_id);
_mongoc_array_append_val (&bulk->commands, command);
ret = true;
done:
_mongoc_bulk_insert_opts_cleanup (&insert_opts);
+ bson_destroy (&cmd_opts);
+
RETURN (ret);
}
static void
_mongoc_bulk_operation_update_append (
mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const mongoc_bulk_update_opts_t *update_opts,
const bson_t *array_filters,
const bson_t *extra_opts)
{
mongoc_write_command_t command = {0};
mongoc_write_command_t *last;
+ bson_t cmd_opts = BSON_INITIALIZER;
bson_t opts;
bool has_collation;
bool has_array_filters;
bool has_update_hint;
bson_init (&opts);
bson_append_bool (&opts, "upsert", 6, update_opts->upsert);
bson_append_bool (&opts, "multi", 5, update_opts->multi);
has_array_filters = !bson_empty0 (array_filters);
if (has_array_filters) {
bson_append_array (&opts, "arrayFilters", 12, array_filters);
}
has_collation = !bson_empty (&update_opts->collation);
if (has_collation) {
bson_append_document (&opts, "collation", 9, &update_opts->collation);
}
has_update_hint = !!(update_opts->hint.value_type);
if (has_update_hint) {
bson_append_value (&opts, "hint", 4, &update_opts->hint);
}
if (extra_opts) {
bson_concat (&opts, extra_opts);
}
if (bulk->commands.len) {
last = &_mongoc_array_index (
&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1);
if (last->type == MONGOC_WRITE_COMMAND_UPDATE) {
last->flags.has_array_filters |= has_array_filters;
last->flags.has_collation |= has_collation;
last->flags.has_update_hint |= has_update_hint;
last->flags.has_multi_write |= update_opts->multi;
_mongoc_write_command_update_append (last, selector, document, &opts);
- bson_destroy (&opts);
- return;
+ GOTO (done);
}
}
- _mongoc_write_command_init_update (
- &command, selector, document, &opts, bulk->flags, bulk->operation_id);
+ if (bulk->comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (&cmd_opts, "comment", 7, &bulk->comment);
+ }
+
+ if (!bson_empty (&bulk->let)) {
+ bson_append_document (&cmd_opts, "let", 3, &bulk->let);
+ }
+
+ _mongoc_write_command_init_update (&command,
+ selector,
+ document,
+ &cmd_opts,
+ &opts,
+ bulk->flags,
+ bulk->operation_id);
command.flags.has_array_filters = has_array_filters;
command.flags.has_collation = has_collation;
command.flags.has_update_hint = has_update_hint;
command.flags.has_multi_write = update_opts->multi;
_mongoc_array_append_val (&bulk->commands, command);
+
+done:
+ bson_destroy (&cmd_opts);
bson_destroy (&opts);
}
static bool
_mongoc_bulk_operation_update_with_opts (
mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const mongoc_bulk_update_opts_t *update_opts,
const bson_t *array_filters,
const bson_t *extra_opts,
bool multi,
bson_error_t *error) /* OUT */
{
ENTRY;
- BSON_ASSERT (bulk);
- BSON_ASSERT (selector);
- BSON_ASSERT (document);
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (selector);
+ BSON_ASSERT_PARAM (document);
if (!_mongoc_validate_update (document, update_opts->validate, error)) {
RETURN (false);
}
/* allow "multi" in opts, but it must be the correct multi */
if (update_opts->multi != multi) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid \"multi\" in opts: %s."
" The value must be %s, or omitted.",
update_opts->multi ? "true" : "false",
multi ? "true" : "false");
RETURN (false);
}
_mongoc_bulk_operation_update_append (
bulk, selector, document, update_opts, array_filters, extra_opts);
RETURN (true);
}
bool
mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_update_one_opts_t update_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_update_one_opts_parse (
bulk->client, opts, &update_opts, error)) {
_mongoc_bulk_update_one_opts_cleanup (&update_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_update_with_opts (bulk,
selector,
document,
&update_opts.update,
&update_opts.arrayFilters,
&update_opts.extra,
false /* multi */,
error);
_mongoc_bulk_update_one_opts_cleanup (&update_opts);
RETURN (ret);
}
bool
mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_update_many_opts_t update_opts;
bool ret;
ENTRY;
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_update_many_opts_parse (
bulk->client, opts, &update_opts, error)) {
_mongoc_bulk_update_many_opts_cleanup (&update_opts);
RETURN (false);
}
ret = _mongoc_bulk_operation_update_with_opts (bulk,
selector,
document,
&update_opts.update,
&update_opts.arrayFilters,
&update_opts.extra,
true /* multi */,
error);
_mongoc_bulk_update_many_opts_cleanup (&update_opts);
RETURN (ret);
}
void
mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert)
{
bson_t opts;
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
bson_init (&opts);
if (upsert) {
BSON_APPEND_BOOL (&opts, "upsert", upsert);
}
if (!mongoc_bulk_operation_update_many_with_opts (
bulk, selector, document, &opts, error)) {
MONGOC_WARNING ("%s", error->message);
}
bson_destroy (&opts);
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
void
mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert)
{
bson_t opts;
bson_error_t *error = &bulk->result.error;
ENTRY;
BULK_EXIT_IF_PRIOR_ERROR;
bson_init (&opts);
BSON_APPEND_BOOL (&opts, "upsert", upsert);
if (!mongoc_bulk_operation_update_one_with_opts (
bulk, selector, document, &opts, error)) {
MONGOC_WARNING ("%s", error->message);
}
bson_destroy (&opts);
if (error->domain) {
MONGOC_WARNING ("%s", error->message);
}
EXIT;
}
bool
mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error) /* OUT */
{
mongoc_bulk_replace_one_opts_t repl_opts;
mongoc_bulk_update_opts_t *update_opts = &repl_opts.update;
bool ret = false;
ENTRY;
- BSON_ASSERT (bulk);
- BSON_ASSERT (selector);
- BSON_ASSERT (document);
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (selector);
+ BSON_ASSERT_PARAM (document);
BULK_RETURN_IF_PRIOR_ERROR;
if (!_mongoc_bulk_replace_one_opts_parse (
bulk->client, opts, &repl_opts, error)) {
GOTO (done);
}
if (!_mongoc_validate_replace (document, update_opts->validate, error)) {
GOTO (done);
}
/* allow "multi" in opts, but it must be the correct multi */
if (update_opts->multi) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid \"multi\": true in opts for"
" mongoc_bulk_operation_replace_one_with_opts."
" The value must be true, or omitted.");
GOTO (done);
}
_mongoc_bulk_operation_update_append (
bulk, selector, document, update_opts, NULL, &repl_opts.extra);
ret = true;
done:
_mongoc_bulk_replace_one_opts_cleanup (&repl_opts);
RETURN (ret);
}
void
mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert)
{
bson_t opts = BSON_INITIALIZER;
bson_error_t *error = &bulk->result.error;
ENTRY;
BSON_APPEND_BOOL (&opts, "upsert", upsert);
if (!mongoc_bulk_operation_replace_one_with_opts (
bulk, selector, document, &opts, error)) {
MONGOC_WARNING ("%s", error->message);
}
bson_destroy (&opts);
EXIT;
}
uint32_t
mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */
bson_t *reply, /* OUT */
bson_error_t *error) /* OUT */
{
mongoc_cluster_t *cluster;
mongoc_write_command_t *command;
mongoc_server_stream_t *server_stream;
bool ret;
uint32_t offset = 0;
int i;
ENTRY;
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
if (!bulk->client) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"mongoc_bulk_operation_execute() requires a client "
"and one has not been set.");
GOTO (err);
}
cluster = &bulk->client->cluster;
if (bulk->executed) {
_mongoc_write_result_destroy (&bulk->result);
_mongoc_write_result_init (&bulk->result);
}
bulk->executed = true;
if (!bulk->database) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"mongoc_bulk_operation_execute() requires a database "
"and one has not been set.");
GOTO (err);
} else if (!bulk->collection) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"mongoc_bulk_operation_execute() requires a collection "
"and one has not been set.");
GOTO (err);
}
/* error stored by functions like mongoc_bulk_operation_insert that
* can't report errors immediately */
if (bulk->result.error.domain) {
if (error) {
memcpy (error, &bulk->result.error, sizeof (bson_error_t));
}
GOTO (err);
}
if (!bulk->commands.len) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot do an empty bulk write");
GOTO (err);
}
for (i = 0; i < bulk->commands.len; i++) {
if (bulk->server_id) {
server_stream =
mongoc_cluster_stream_for_server (cluster,
bulk->server_id,
true /* reconnect_ok */,
bulk->session,
reply,
error);
} else {
server_stream = mongoc_cluster_stream_for_writes (
cluster, bulk->session, reply, error);
}
if (!server_stream) {
/* stream_for_server and stream_for_writes initialize reply on error */
RETURN (false);
}
command =
&_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i);
_mongoc_write_command_execute (command,
bulk->client,
server_stream,
bulk->database,
bulk->collection,
bulk->write_concern,
offset,
bulk->session,
&bulk->result);
bulk->server_id = server_stream->sd->id;
/* If a retryable error occurred and a new primary was selected, use it in
* subsequent commands. */
if (bulk->result.retry_server_id) {
bulk->server_id = bulk->result.retry_server_id;
}
if (bulk->result.failed &&
(bulk->flags.ordered || bulk->result.must_stop)) {
mongoc_server_stream_cleanup (server_stream);
GOTO (cleanup);
}
offset += command->n_documents;
mongoc_server_stream_cleanup (server_stream);
}
cleanup:
_mongoc_bson_init_if_set (reply);
ret = MONGOC_WRITE_RESULT_COMPLETE (&bulk->result,
bulk->client->error_api_version,
bulk->write_concern,
MONGOC_ERROR_COMMAND /* err domain */,
reply,
error);
RETURN (ret ? bulk->server_id : 0);
err:
_mongoc_bson_init_if_set (reply);
RETURN (false);
}
void
mongoc_bulk_operation_set_write_concern (
mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern)
{
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
if (bulk->write_concern) {
mongoc_write_concern_destroy (bulk->write_concern);
}
if (write_concern) {
bulk->write_concern = mongoc_write_concern_copy (write_concern);
} else {
bulk->write_concern = mongoc_write_concern_new ();
}
}
const mongoc_write_concern_t *
mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk)
{
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
return bulk->write_concern;
}
void
mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk,
const char *database)
{
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
if (bulk->database) {
bson_free (bulk->database);
}
bulk->database = bson_strdup (database);
}
void
mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk,
const char *collection)
{
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
if (bulk->collection) {
bson_free (bulk->collection);
}
bulk->collection = bson_strdup (collection);
}
void
mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client)
{
- BSON_ASSERT (bulk);
- BSON_ASSERT (client);
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (client);
if (bulk->session) {
BSON_ASSERT (bulk->session->client == client);
}
bulk->client = (mongoc_client_t *) client;
/* if you call set_client, bulk was likely made by mongoc_bulk_operation_new,
* not mongoc_collection_create_bulk_operation_with_opts(), so operation_id
* is 0. */
if (!bulk->operation_id) {
bulk->operation_id = ++bulk->client->cluster.operation_id;
}
}
void
mongoc_bulk_operation_set_client_session (
mongoc_bulk_operation_t *bulk,
struct _mongoc_client_session_t *client_session)
{
- BSON_ASSERT (bulk);
- BSON_ASSERT (client_session);
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (client_session);
if (bulk->client) {
BSON_ASSERT (bulk->client == client_session->client);
}
bulk->session = client_session;
}
uint32_t
mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk)
{
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
return bulk->server_id;
}
void
mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk,
uint32_t server_id)
{
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
bulk->server_id = server_id;
}
void
mongoc_bulk_operation_set_bypass_document_validation (
mongoc_bulk_operation_t *bulk, bool bypass)
{
- BSON_ASSERT (bulk);
+ BSON_ASSERT_PARAM (bulk);
bulk->flags.bypass_document_validation = bypass;
}
+
+
+void
+mongoc_bulk_operation_set_comment (mongoc_bulk_operation_t *bulk,
+ const bson_value_t *comment)
+{
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (comment);
+ BSON_ASSERT (comment->value_type != BSON_TYPE_EOD);
+
+ /* This method cannot be called after appending operations, as the CRUD spec
+ * states the option should apply to all commands. Since commands are
+ * initialized as operations are added, allowing "comment" to be changed at
+ * any time could violate that contract. */
+ BSON_ASSERT (bulk->commands.len == 0);
+
+ bson_value_destroy (&bulk->comment);
+ bson_value_copy (comment, &bulk->comment);
+}
+
+
+void
+mongoc_bulk_operation_set_let (mongoc_bulk_operation_t *bulk, const bson_t *let)
+{
+ BSON_ASSERT_PARAM (bulk);
+ BSON_ASSERT_PARAM (let);
+
+ /* This method cannot be called after appending operations, as the CRUD spec
+ * states the option should apply to all commands (excluding insert). Since
+ * commands are initialized as operations are added, allowing "let" to be
+ * changed at any time could violate that contract. */
+ BSON_ASSERT (bulk->commands.len == 0);
+
+ bson_destroy (&bulk->let);
+ bson_copy_to (let, &bulk->let);
+}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
index 85c1adfa..515bfb2f 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h
@@ -1,154 +1,160 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_BULK_OPERATION_H
#define MONGOC_BULK_OPERATION_H
#include <bson/bson.h>
#include "mongoc-macros.h"
#include "mongoc-write-concern.h"
/* ordered, bypass_document_validation, has_collation, multi */
#define MONGOC_BULK_WRITE_FLAGS_INIT \
{ \
true, false, 0 \
}
BSON_BEGIN_DECLS
/* forward decl */
struct _mongoc_client_session_t;
typedef struct _mongoc_bulk_operation_t mongoc_bulk_operation_t;
typedef struct _mongoc_bulk_write_flags_t mongoc_bulk_write_flags_t;
MONGOC_EXPORT (void)
mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk);
MONGOC_EXPORT (uint32_t)
mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk,
bson_t *reply,
bson_error_t *error);
MONGOC_EXPORT (void)
mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk,
const bson_t *selector)
BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove);
MONGOC_EXPORT (void)
mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector)
BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove_one);
MONGOC_EXPORT (void)
mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk,
const bson_t *document);
MONGOC_EXPORT (bool)
mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *document,
const bson_t *opts,
bson_error_t *error); /* OUT */
MONGOC_EXPORT (void)
mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk,
const bson_t *selector);
MONGOC_EXPORT (bool)
mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *opts,
bson_error_t *error); /* OUT */
MONGOC_EXPORT (void)
mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector);
MONGOC_EXPORT (bool)
mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *opts,
bson_error_t *error); /* OUT */
MONGOC_EXPORT (void)
mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert);
MONGOC_EXPORT (bool)
mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error); /* OUT */
MONGOC_EXPORT (void)
mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert);
MONGOC_EXPORT (bool)
mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error); /* OUT */
MONGOC_EXPORT (void)
mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
bool upsert);
MONGOC_EXPORT (bool)
mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk,
const bson_t *selector,
const bson_t *document,
const bson_t *opts,
bson_error_t *error); /* OUT */
MONGOC_EXPORT (void)
mongoc_bulk_operation_set_bypass_document_validation (
mongoc_bulk_operation_t *bulk, bool bypass);
+MONGOC_EXPORT (void)
+mongoc_bulk_operation_set_comment (mongoc_bulk_operation_t *bulk,
+ const bson_value_t *comment);
+MONGOC_EXPORT (void)
+mongoc_bulk_operation_set_let (mongoc_bulk_operation_t *bulk,
+ const bson_t *let);
/*
* The following functions are really only useful by language bindings and
* those wanting to replay a bulk operation to a number of clients or
* collections.
*/
MONGOC_EXPORT (mongoc_bulk_operation_t *)
mongoc_bulk_operation_new (bool ordered) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (void)
mongoc_bulk_operation_set_write_concern (
mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern);
MONGOC_EXPORT (void)
mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk,
const char *database);
MONGOC_EXPORT (void)
mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk,
const char *collection);
MONGOC_EXPORT (void)
mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client);
MONGOC_EXPORT (void)
mongoc_bulk_operation_set_client_session (
mongoc_bulk_operation_t *bulk,
struct _mongoc_client_session_t *client_session);
/* These names include the term "hint" for backward compatibility, should be
* mongoc_bulk_operation_get_server_id, mongoc_bulk_operation_set_server_id. */
MONGOC_EXPORT (void)
mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk,
uint32_t server_id);
MONGOC_EXPORT (uint32_t)
mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk);
MONGOC_EXPORT (const mongoc_write_concern_t *)
mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk);
BSON_END_DECLS
#endif /* MONGOC_BULK_OPERATION_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
index b8147e36..c0f774a3 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h
@@ -1,85 +1,86 @@
/*
* Copyright 2017-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CHANGE_STREAM_PRIVATE_H
#define MONGOC_CHANGE_STREAM_PRIVATE_H
#include "mongoc-change-stream.h"
#include "mongoc-client-session.h"
#include "mongoc-collection.h"
#include "mongoc-cursor.h"
#include "mongoc-opts-private.h"
#include "mongoc-opts-helpers-private.h"
typedef enum {
MONGOC_CHANGE_STREAM_COLLECTION,
MONGOC_CHANGE_STREAM_DATABASE,
MONGOC_CHANGE_STREAM_CLIENT
} mongoc_change_stream_type_t;
struct _mongoc_change_stream_t {
mongoc_change_stream_opts_t opts;
mongoc_timestamp_t operation_time;
bson_t pipeline_to_append;
bson_t resume_token;
bson_t *full_document;
+ bson_t *full_document_before_change;
bson_error_t err;
bson_t err_doc;
mongoc_cursor_t *cursor;
mongoc_client_t *client;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_change_stream_type_t change_stream_type;
char *db;
char *coll;
int64_t max_await_time_ms;
int32_t batch_size;
bool has_returned_results;
/* Track whether the change stream has resumed after an error, as this
* determines how we construct an initial or resuming aggregate command. */
bool resumed;
mongoc_client_session_t *implicit_session;
/* The max_wire_version of the server the change stream is tied to. */
uint32_t max_wire_version;
};
mongoc_change_stream_t *
_mongoc_change_stream_new_from_collection (const mongoc_collection_t *coll,
const bson_t *pipeline,
const bson_t *opts);
mongoc_change_stream_t *
_mongoc_change_stream_new_from_database (const mongoc_database_t *db,
const bson_t *pipeline,
const bson_t *opts);
mongoc_change_stream_t *
_mongoc_change_stream_new_from_client (mongoc_client_t *client,
const bson_t *pipeline,
const bson_t *opts);
#endif /* MONGOC_CHANGE_STREAM_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
similarity index 96%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
index 2daba263..6a7f3706 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c
@@ -1,669 +1,688 @@
/*
* Copyright 2017-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongoc-cluster-private.h"
#include "mongoc-change-stream-private.h"
#include "mongoc-collection-private.h"
#include "mongoc-client-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-cursor-private.h"
#include "mongoc-database-private.h"
#include "mongoc-error.h"
#include "mongoc-error-private.h"
#define CHANGE_STREAM_ERR(_str) \
bson_set_error (&stream->err, \
MONGOC_ERROR_CURSOR, \
MONGOC_ERROR_BSON, \
"Could not set " _str);
/* the caller knows either a client or server error has occurred.
* `reply` contains the server reply or an empty document. */
static bool
_is_resumable_error (mongoc_change_stream_t *stream, const bson_t *reply)
{
bson_error_t error = {0};
/* Change Streams Spec resumable criteria: "any error encountered which is
* not a server error (e.g. a timeout error or network error)" */
if (bson_empty (reply)) {
return true;
}
if (_mongoc_cmd_check_ok (reply, MONGOC_ERROR_API_VERSION_2, &error)) {
return true;
}
if (error.code == MONGOC_SERVER_ERR_CURSOR_NOT_FOUND) {
return true;
}
if (stream->max_wire_version >= WIRE_VERSION_4_4) {
return mongoc_error_has_label (reply, "ResumableChangeStreamError");
}
switch (error.code) {
case MONGOC_SERVER_ERR_HOSTUNREACHABLE:
case MONGOC_SERVER_ERR_HOSTNOTFOUND:
case MONGOC_SERVER_ERR_NETWORKTIMEOUT:
case MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS:
case MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN:
case MONGOC_SERVER_ERR_EXCEEDEDTIMELIMIT:
case MONGOC_SERVER_ERR_SOCKETEXCEPTION:
case MONGOC_SERVER_ERR_NOTPRIMARY:
case MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN:
case MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE:
case MONGOC_SERVER_ERR_NOTPRIMARYNOSECONDARYOK:
case MONGOC_SERVER_ERR_NOTPRIMARYORSECONDARY:
case MONGOC_SERVER_ERR_STALESHARDVERSION:
case MONGOC_SERVER_ERR_STALEEPOCH:
case MONGOC_SERVER_ERR_STALECONFIG:
case MONGOC_SERVER_ERR_RETRYCHANGESTREAM:
case MONGOC_SERVER_ERR_FAILEDTOSATISFYREADPREFERENCE:
return true;
default:
return false;
}
}
static void
_set_resume_token (mongoc_change_stream_t *stream, const bson_t *resume_token)
{
BSON_ASSERT (stream);
BSON_ASSERT (resume_token);
bson_destroy (&stream->resume_token);
bson_copy_to (resume_token, &stream->resume_token);
}
/* construct the aggregate command in cmd. looks like one of the following:
* for a collection change stream:
* { aggregate: collname, pipeline: [], cursor: { batchSize: x } }
* for a database change stream:
* { aggregate: 1, pipeline: [], cursor: { batchSize: x } }
* for a client change stream:
* { aggregate: 1, pipeline: [{$changeStream: {allChangesForCluster: true}}],
* cursor: { batchSize: x } }
*/
static void
_make_command (mongoc_change_stream_t *stream, bson_t *command)
{
bson_iter_t iter;
bson_t change_stream_stage; /* { $changeStream: <change_stream_doc> } */
bson_t change_stream_doc;
bson_t pipeline;
bson_t cursor_doc;
if (stream->change_stream_type == MONGOC_CHANGE_STREAM_COLLECTION) {
bson_append_utf8 (
command, "aggregate", 9, stream->coll, (int) strlen (stream->coll));
} else {
bson_append_int32 (command, "aggregate", 9, 1);
}
bson_append_array_begin (command, "pipeline", 8, &pipeline);
/* append the $changeStream stage. */
bson_append_document_begin (&pipeline, "0", 1, &change_stream_stage);
bson_append_document_begin (
&change_stream_stage, "$changeStream", 13, &change_stream_doc);
- bson_concat (&change_stream_doc, stream->full_document);
+ if (stream->full_document) {
+ bson_concat (&change_stream_doc, stream->full_document);
+ }
+ if (stream->full_document_before_change) {
+ bson_concat (&change_stream_doc, stream->full_document_before_change);
+ }
if (stream->resumed) {
/* Change stream spec: Resume Process */
/* If there is a cached resumeToken: */
if (!bson_empty (&stream->resume_token)) {
/* If the ChangeStream was started with startAfter
and has yet to return a result document: */
if (!bson_empty (&stream->opts.startAfter) &&
!stream->has_returned_results) {
/* The driver MUST set startAfter to the cached resumeToken */
BSON_APPEND_DOCUMENT (
&change_stream_doc, "startAfter", &stream->resume_token);
} else {
/* The driver MUST set resumeAfter to the cached resumeToken */
BSON_APPEND_DOCUMENT (
&change_stream_doc, "resumeAfter", &stream->resume_token);
}
} else if (!_mongoc_timestamp_empty (&stream->operation_time) &&
stream->max_wire_version >= WIRE_VERSION_4_0) {
/* Else if there is no cached resumeToken and the ChangeStream
has a saved operation time and the max wire version is >= 7,
the driver MUST set startAtOperationTime */
_mongoc_timestamp_append (&stream->operation_time,
&change_stream_doc,
"startAtOperationTime");
}
} else {
/* Change streams spec: "startAtOperationTime, resumeAfter, and startAfter
* are all mutually exclusive; if any two are set, the server will return
* an error. Drivers MUST NOT throw a custom error, and MUST defer to the
* server error." */
if (!bson_empty (&stream->opts.resumeAfter)) {
BSON_APPEND_DOCUMENT (
&change_stream_doc, "resumeAfter", &stream->opts.resumeAfter);
/* Update the cached resume token */
_set_resume_token (stream, &stream->opts.resumeAfter);
}
if (!bson_empty (&stream->opts.startAfter)) {
BSON_APPEND_DOCUMENT (
&change_stream_doc, "startAfter", &stream->opts.startAfter);
/* Update the cached resume token (take precedence over resumeAfter) */
_set_resume_token (stream, &stream->opts.startAfter);
}
if (!_mongoc_timestamp_empty (&stream->operation_time)) {
_mongoc_timestamp_append (&stream->operation_time,
&change_stream_doc,
"startAtOperationTime");
}
}
if (stream->change_stream_type == MONGOC_CHANGE_STREAM_CLIENT) {
bson_append_bool (&change_stream_doc, "allChangesForCluster", 20, true);
}
bson_append_document_end (&change_stream_stage, &change_stream_doc);
bson_append_document_end (&pipeline, &change_stream_stage);
/* Append user pipeline if it exists */
if (bson_iter_init_find (&iter, &stream->pipeline_to_append, "pipeline") &&
BSON_ITER_HOLDS_ARRAY (&iter)) {
bson_iter_t child_iter;
uint32_t key_int = 1;
char buf[16];
const char *key_str;
BSON_ASSERT (bson_iter_recurse (&iter, &child_iter));
while (bson_iter_next (&child_iter)) {
/* the user pipeline may consist of invalid stages or non-documents.
* append anyway, and rely on the server error. */
size_t keyLen =
bson_uint32_to_string (key_int, &key_str, buf, sizeof (buf));
bson_append_value (
&pipeline, key_str, (int) keyLen, bson_iter_value (&child_iter));
++key_int;
}
}
bson_append_array_end (command, &pipeline);
/* Add batch size if needed */
bson_append_document_begin (command, "cursor", 6, &cursor_doc);
if (stream->batch_size > 0) {
bson_append_int32 (&cursor_doc, "batchSize", 9, stream->batch_size);
}
bson_append_document_end (command, &cursor_doc);
}
/*---------------------------------------------------------------------------
*
* _make_cursor --
*
* Construct and send the aggregate command and create the resulting
* cursor. On error, stream->cursor remains NULL, otherwise it is
* created and must be destroyed.
*
* Return:
* False on error and sets stream->err.
*
*--------------------------------------------------------------------------
*/
static bool
_make_cursor (mongoc_change_stream_t *stream)
{
mongoc_client_session_t *cs = NULL;
bson_t command_opts;
bson_t command; /* { aggregate: "coll", pipeline: [], ... } */
bson_t reply;
bson_t getmore_opts = BSON_INITIALIZER;
bson_iter_t iter;
mongoc_server_stream_t *server_stream;
BSON_ASSERT (stream);
BSON_ASSERT (!stream->cursor);
bson_init (&command);
bson_copy_to (&(stream->opts.extra), &command_opts);
+ if (stream->opts.comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (&command_opts, "comment", 7, &stream->opts.comment);
+ bson_append_value (&getmore_opts, "comment", 7, &stream->opts.comment);
+ }
+
if (bson_iter_init_find (&iter, &command_opts, "sessionId")) {
if (!_mongoc_client_session_from_iter (
stream->client, &iter, &cs, &stream->err)) {
goto cleanup;
}
} else if (stream->implicit_session) {
/* If an implicit session was created before, and this cursor is now
* being recreated after resuming, then use the same session as before. */
cs = stream->implicit_session;
if (!mongoc_client_session_append (cs, &command_opts, &stream->err)) {
goto cleanup;
}
} else {
/* Create an implicit session. This session lsid must be the same for the
* agg command and the subsequent getMores. Thus, this implicit session is
* passed as if it were an explicit session to
* mongoc_client_read_command_with_opts and
* _mongoc_cursor_change_stream_new, but it is still implicit and its
* lifetime is owned by this change_stream_t. */
mongoc_session_opt_t *session_opts;
session_opts = mongoc_session_opts_new ();
mongoc_session_opts_set_causal_consistency (session_opts, false);
/* returns NULL if sessions aren't supported. ignore errors. */
cs = mongoc_client_start_session (stream->client, session_opts, NULL);
stream->implicit_session = cs;
mongoc_session_opts_destroy (session_opts);
if (cs &&
!mongoc_client_session_append (cs, &command_opts, &stream->err)) {
goto cleanup;
}
}
if (cs && !mongoc_client_session_append (cs, &getmore_opts, &stream->err)) {
goto cleanup;
}
server_stream =
mongoc_cluster_stream_for_reads (&stream->client->cluster,
stream->read_prefs,
cs,
&reply,
/* Not aggregate-with-write */ false,
&stream->err);
if (!server_stream) {
bson_destroy (&stream->err_doc);
bson_copy_to (&reply, &stream->err_doc);
bson_destroy (&reply);
goto cleanup;
}
bson_append_int32 (&command_opts, "serverId", 8, server_stream->sd->id);
bson_append_int32 (&getmore_opts, "serverId", 8, server_stream->sd->id);
stream->max_wire_version = server_stream->sd->max_wire_version;
mongoc_server_stream_cleanup (server_stream);
if (stream->read_concern && !bson_has_field (&command_opts, "readConcern")) {
mongoc_read_concern_append (stream->read_concern, &command_opts);
}
_make_command (stream, &command);
/* even though serverId has already been set, still pass the read prefs.
* they are necessary for OP_MSG if sending to a secondary. */
if (!mongoc_client_read_command_with_opts (stream->client,
stream->db,
&command,
stream->read_prefs,
&command_opts,
&reply,
&stream->err)) {
bson_destroy (&stream->err_doc);
bson_copy_to (&reply, &stream->err_doc);
bson_destroy (&reply);
goto cleanup;
}
bson_append_bool (
&getmore_opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true);
bson_append_bool (&getmore_opts,
MONGOC_CURSOR_AWAIT_DATA,
MONGOC_CURSOR_AWAIT_DATA_LEN,
true);
/* maxTimeMS is only appended to getMores if these are set in cursor opts. */
if (stream->max_await_time_ms > 0) {
bson_append_int64 (&getmore_opts,
MONGOC_CURSOR_MAX_AWAIT_TIME_MS,
MONGOC_CURSOR_MAX_AWAIT_TIME_MS_LEN,
stream->max_await_time_ms);
}
if (stream->batch_size > 0) {
bson_append_int32 (&getmore_opts,
MONGOC_CURSOR_BATCH_SIZE,
MONGOC_CURSOR_BATCH_SIZE_LEN,
stream->batch_size);
}
/* steals reply. */
stream->cursor =
_mongoc_cursor_change_stream_new (stream->client, &reply, &getmore_opts);
if (mongoc_cursor_error (stream->cursor, NULL)) {
goto cleanup;
}
/* Change stream spec: "When aggregate or getMore returns: If an empty batch
* was returned and a postBatchResumeToken was included, cache it." */
if (_mongoc_cursor_change_stream_end_of_batch (stream->cursor) &&
_mongoc_cursor_change_stream_has_post_batch_resume_token (
stream->cursor)) {
_set_resume_token (
stream,
_mongoc_cursor_change_stream_get_post_batch_resume_token (
stream->cursor));
}
/* Change stream spec: startAtOperationTime */
if (bson_empty (&stream->opts.resumeAfter) &&
bson_empty (&stream->opts.startAfter) &&
_mongoc_timestamp_empty (&stream->operation_time) &&
stream->max_wire_version >= WIRE_VERSION_4_0 &&
bson_empty (&stream->resume_token) &&
bson_iter_init_find (
&iter,
_mongoc_cursor_change_stream_get_reply (stream->cursor),
"operationTime") &&
BSON_ITER_HOLDS_TIMESTAMP (&iter)) {
_mongoc_timestamp_set_from_bson (&stream->operation_time, &iter);
}
cleanup:
bson_destroy (&command);
bson_destroy (&command_opts);
bson_destroy (&getmore_opts);
return stream->err.code == 0;
}
/*---------------------------------------------------------------------------
*
* _change_stream_init --
*
* Called after @stream has the collection name, database name, read
* preferences, and read concern set. Creates the change streams
* cursor.
*
*--------------------------------------------------------------------------
*/
void
_change_stream_init (mongoc_change_stream_t *stream,
const bson_t *pipeline,
const bson_t *opts)
{
BSON_ASSERT (pipeline);
stream->max_await_time_ms = -1;
stream->batch_size = -1;
bson_init (&stream->pipeline_to_append);
bson_init (&stream->resume_token);
bson_init (&stream->err_doc);
if (!_mongoc_change_stream_opts_parse (
stream->client, opts, &stream->opts, &stream->err)) {
return;
}
- stream->full_document = BCON_NEW ("fullDocument", stream->opts.fullDocument);
+ if (stream->opts.fullDocument) {
+ stream->full_document =
+ BCON_NEW ("fullDocument", stream->opts.fullDocument);
+ }
+
+ if (stream->opts.fullDocumentBeforeChange) {
+ stream->full_document_before_change = BCON_NEW (
+ "fullDocumentBeforeChange", stream->opts.fullDocumentBeforeChange);
+ }
_mongoc_timestamp_set (&stream->operation_time,
&stream->opts.startAtOperationTime);
stream->batch_size = stream->opts.batchSize;
stream->max_await_time_ms = stream->opts.maxAwaitTimeMS;
/* Accept two forms of user pipeline:
* 1. A document like: { "pipeline": [...] }
* 2. An array-like document: { "0": {}, "1": {}, ... }
* If the passed pipeline is invalid, we pass it along and let the server
* error instead.
*/
if (!bson_empty (pipeline)) {
bson_iter_t iter;
if (bson_iter_init_find (&iter, pipeline, "pipeline") &&
BSON_ITER_HOLDS_ARRAY (&iter)) {
if (!BSON_APPEND_VALUE (&stream->pipeline_to_append,
"pipeline",
bson_iter_value (&iter))) {
CHANGE_STREAM_ERR ("pipeline");
}
} else {
if (!BSON_APPEND_ARRAY (
&stream->pipeline_to_append, "pipeline", pipeline)) {
CHANGE_STREAM_ERR ("pipeline");
}
}
}
if (stream->err.code == 0) {
(void) _make_cursor (stream);
}
}
mongoc_change_stream_t *
_mongoc_change_stream_new_from_collection (const mongoc_collection_t *coll,
const bson_t *pipeline,
const bson_t *opts)
{
mongoc_change_stream_t *stream;
BSON_ASSERT (coll);
stream =
(mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t));
stream->db = bson_strdup (coll->db);
stream->coll = bson_strdup (coll->collection);
stream->read_prefs = mongoc_read_prefs_copy (coll->read_prefs);
stream->read_concern = mongoc_read_concern_copy (coll->read_concern);
stream->client = coll->client;
stream->change_stream_type = MONGOC_CHANGE_STREAM_COLLECTION;
_change_stream_init (stream, pipeline, opts);
return stream;
}
mongoc_change_stream_t *
_mongoc_change_stream_new_from_database (const mongoc_database_t *db,
const bson_t *pipeline,
const bson_t *opts)
{
mongoc_change_stream_t *stream;
BSON_ASSERT (db);
stream =
(mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t));
stream->db = bson_strdup (db->name);
stream->coll = NULL;
stream->read_prefs = mongoc_read_prefs_copy (db->read_prefs);
stream->read_concern = mongoc_read_concern_copy (db->read_concern);
stream->client = db->client;
stream->change_stream_type = MONGOC_CHANGE_STREAM_DATABASE;
_change_stream_init (stream, pipeline, opts);
return stream;
}
mongoc_change_stream_t *
_mongoc_change_stream_new_from_client (mongoc_client_t *client,
const bson_t *pipeline,
const bson_t *opts)
{
mongoc_change_stream_t *stream;
BSON_ASSERT (client);
stream =
(mongoc_change_stream_t *) bson_malloc0 (sizeof (mongoc_change_stream_t));
stream->db = bson_strdup ("admin");
stream->coll = NULL;
stream->read_prefs = mongoc_read_prefs_copy (client->read_prefs);
stream->read_concern = mongoc_read_concern_copy (client->read_concern);
stream->client = client;
stream->change_stream_type = MONGOC_CHANGE_STREAM_CLIENT;
_change_stream_init (stream, pipeline, opts);
return stream;
}
const bson_t *
mongoc_change_stream_get_resume_token (mongoc_change_stream_t *stream)
{
if (!bson_empty (&stream->resume_token)) {
return &stream->resume_token;
}
return NULL;
}
bool
mongoc_change_stream_next (mongoc_change_stream_t *stream, const bson_t **bson)
{
bson_iter_t iter;
bson_t doc_resume_token;
uint32_t len;
const uint8_t *data;
bool ret = false;
BSON_ASSERT (stream);
BSON_ASSERT (bson);
if (stream->err.code != 0) {
goto end;
}
BSON_ASSERT (stream->cursor);
if (!mongoc_cursor_next (stream->cursor, bson)) {
const bson_t *err_doc;
bson_error_t err;
bool resumable = false;
if (!mongoc_cursor_error_document (stream->cursor, &err, &err_doc)) {
/* no error occurred, just no documents left. */
goto end;
}
resumable = _is_resumable_error (stream, err_doc);
while (resumable) {
/* recreate the cursor. */
mongoc_cursor_destroy (stream->cursor);
stream->cursor = NULL;
stream->resumed = true;
if (!_make_cursor (stream)) {
goto end;
}
if (mongoc_cursor_next (stream->cursor, bson)) {
break;
}
if (!mongoc_cursor_error_document (stream->cursor, &err, &err_doc)) {
goto end;
}
if (err_doc) {
resumable = _is_resumable_error (stream, err_doc);
} else {
resumable = false;
}
}
if (!resumable) {
stream->err = err;
bson_destroy (&stream->err_doc);
bson_copy_to (err_doc, &stream->err_doc);
goto end;
}
}
/* we have received documents, either from the first call to next or after a
* resume. */
stream->has_returned_results = true;
if (!bson_iter_init_find (&iter, *bson, "_id") ||
!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (&stream->err,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CHANGE_STREAM_NO_RESUME_TOKEN,
"Cannot provide resume functionality when the resume "
"token is missing");
goto end;
}
/* copy the resume token. */
bson_iter_document (&iter, &len, &data);
BSON_ASSERT (bson_init_static (&doc_resume_token, data, len));
_set_resume_token (stream, &doc_resume_token);
/* clear out the operation time, since we no longer need it to resume. */
_mongoc_timestamp_clear (&stream->operation_time);
ret = true;
end:
/* Change stream spec: Updating the Cached Resume Token */
if (stream->cursor && !mongoc_cursor_error (stream->cursor, NULL) &&
_mongoc_cursor_change_stream_end_of_batch (stream->cursor) &&
_mongoc_cursor_change_stream_has_post_batch_resume_token (
stream->cursor)) {
_set_resume_token (
stream,
_mongoc_cursor_change_stream_get_post_batch_resume_token (
stream->cursor));
}
/* Driver Sessions Spec: "When an implicit session is associated with a
* cursor for use with getMore operations, the session MUST be returned to
* the pool immediately following a getMore operation that indicates that the
* cursor has been exhausted." */
if (stream->implicit_session) {
/* if creating the change stream cursor errored, it may be null. */
if (!stream->cursor || stream->cursor->cursor_id == 0) {
mongoc_client_session_destroy (stream->implicit_session);
stream->implicit_session = NULL;
}
}
return ret;
}
bool
mongoc_change_stream_error_document (const mongoc_change_stream_t *stream,
bson_error_t *err,
const bson_t **bson)
{
BSON_ASSERT (stream);
if (stream->err.code != 0) {
if (err) {
*err = stream->err;
}
if (bson) {
*bson = &stream->err_doc;
}
return true;
}
if (bson) {
*bson = NULL;
}
return false;
}
void
mongoc_change_stream_destroy (mongoc_change_stream_t *stream)
{
if (!stream) {
return;
}
bson_destroy (&stream->pipeline_to_append);
bson_destroy (&stream->resume_token);
bson_destroy (stream->full_document);
+ bson_destroy (stream->full_document_before_change);
bson_destroy (&stream->err_doc);
_mongoc_change_stream_opts_cleanup (&stream->opts);
mongoc_cursor_destroy (stream->cursor);
mongoc_client_session_destroy (stream->implicit_session);
mongoc_read_prefs_destroy (stream->read_prefs);
mongoc_read_concern_destroy (stream->read_concern);
bson_free (stream->db);
bson_free (stream->coll);
bson_free (stream);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
index 379cb62d..56aaaf7c 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h
@@ -1,249 +1,256 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLIENT_PRIVATE_H
#define MONGOC_CLIENT_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-apm-private.h"
#include "mongoc-buffer-private.h"
#include "mongoc-client.h"
#include "mongoc-cluster-private.h"
#include "mongoc-config.h"
#include "mongoc-host-list.h"
#include "mongoc-read-prefs.h"
#include "mongoc-rpc-private.h"
#include "mongoc-opcode.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-ssl.h"
#endif
#include "mongoc-stream.h"
#include "mongoc-topology-private.h"
#include "mongoc-write-concern.h"
#include "mongoc-crypt-private.h"
BSON_BEGIN_DECLS
/* Range of wire protocol versions this driver supports. Bumping
* WIRE_VERSION_MAX must be accompanied by an update to
* `_mongoc_wire_version_to_server_version`. */
#define WIRE_VERSION_MIN 6 /* a.k.a. minWireVersion */
-#define WIRE_VERSION_MAX 15 /* a.k.a. maxWireVersion */
+#define WIRE_VERSION_MAX 17 /* a.k.a. maxWireVersion */
/* first version that supported "find" and "getMore" commands */
#define WIRE_VERSION_FIND_CMD 4
/* first version with "killCursors" command */
#define WIRE_VERSION_KILLCURSORS_CMD 4
/* first version when findAndModify accepts writeConcern */
#define WIRE_VERSION_FAM_WRITE_CONCERN 4
/* first version to support readConcern */
#define WIRE_VERSION_READ_CONCERN 4
/* first version to support maxStalenessSeconds */
#define WIRE_VERSION_MAX_STALENESS 5
/* first version to support writeConcern */
#define WIRE_VERSION_CMD_WRITE_CONCERN 5
/* first version to support collation */
#define WIRE_VERSION_COLLATION 5
/* first version to support server-side errors for unsupported hint options */
#define WIRE_VERSION_HINT_SERVER_SIDE_ERROR 5
/* first version to support OP_MSG */
#define WIRE_VERSION_OP_MSG 6
/* first version to support array filters for "update" command */
#define WIRE_VERSION_ARRAY_FILTERS 6
/* first version to support retryable reads */
#define WIRE_VERSION_RETRY_READS 6
/* first version to support retryable writes */
#define WIRE_VERSION_RETRY_WRITES 6
/* version corresponding to server 4.0 release */
#define WIRE_VERSION_4_0 7
/* first version to support hint for "update" command */
#define WIRE_VERSION_UPDATE_HINT 8
/* version corresponding to server 4.2 release */
#define WIRE_VERSION_4_2 8
/* version corresponding to client side field level encryption support. */
#define WIRE_VERSION_CSE 8
/* first version to throw server-side errors for unsupported hint in
* "findAndModify" command */
#define WIRE_VERSION_FIND_AND_MODIFY_HINT_SERVER_SIDE_ERROR 8
/* first version to support hint for "delete" command */
#define WIRE_VERSION_DELETE_HINT 9
/* first version to support hint for "findAndModify" command */
#define WIRE_VERSION_FIND_AND_MODIFY_HINT 9
/* version corresponding to server 4.4 release */
#define WIRE_VERSION_4_4 9
/* version corresponding to retryable writes error label */
#define WIRE_VERSION_RETRYABLE_WRITE_ERROR_LABEL 9
/* first version to support server hedged reads */
#define WIRE_VERSION_HEDGED_READS 9
/* first version to support estimatedDocumentCount with collStats */
#define WIRE_VERSION_4_9 12
/* version corresponding to server 5.0 release */
#define WIRE_VERSION_5_0 13
/* first version to support snapshot reads */
#define WIRE_VERSION_SNAPSHOT_READS 13
/* version corresponding to server 5.1 release */
#define WIRE_VERSION_5_1 14
struct _mongoc_collection_t;
struct _mongoc_client_t {
mongoc_uri_t *uri;
mongoc_cluster_t cluster;
bool in_exhaust;
bool is_pooled;
mongoc_stream_initiator_t initiator;
void *initiator_data;
#ifdef MONGOC_ENABLE_SSL
bool use_ssl;
mongoc_ssl_opt_t ssl_opts;
#endif
mongoc_topology_t *topology;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_write_concern_t *write_concern;
mongoc_apm_callbacks_t apm_callbacks;
void *apm_context;
int32_t error_api_version;
bool error_api_set;
mongoc_server_api_t *api;
/* mongoc_client_session_t's in use, to look up lsids and clusterTimes */
mongoc_set_t *client_sessions;
unsigned int csid_rand_seed;
uint32_t generation;
};
/* Defines whether _mongoc_client_command_with_opts() is acting as a read
* command helper for a command like "distinct", or a write command helper for
* a command like "createRole", or both, like "aggregate" with "$out".
*/
typedef enum {
MONGOC_CMD_RAW = 0,
MONGOC_CMD_READ = 1,
MONGOC_CMD_WRITE = 2,
MONGOC_CMD_RW = 3,
} mongoc_command_mode_t;
BSON_STATIC_ASSERT2 (mongoc_cmd_rw,
MONGOC_CMD_RW == (MONGOC_CMD_READ | MONGOC_CMD_WRITE));
/* TODO (CDRIVER-4052): Move MONGOC_RR_DEFAULT_BUFFER_SIZE and
* _mongoc_client_get_rr to mongoc-topology-private.h or in a separate file.
* There is no reason these should be in mongoc-client. */
#define MONGOC_RR_DEFAULT_BUFFER_SIZE 1024
bool
_mongoc_client_get_rr (const char *hostname,
mongoc_rr_type_t rr_type,
mongoc_rr_data_t *rr_data,
size_t initial_buffer_size,
bson_error_t *error);
mongoc_client_t *
_mongoc_client_new_from_topology (mongoc_topology_t *topology);
bool
_mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
mongoc_apm_callbacks_t *callbacks,
void *context);
mongoc_stream_t *
mongoc_client_default_stream_initiator (const mongoc_uri_t *uri,
const mongoc_host_list_t *host,
void *user_data,
bson_error_t *error);
mongoc_stream_t *
_mongoc_client_create_stream (mongoc_client_t *client,
const mongoc_host_list_t *host,
bson_error_t *error);
bool
_mongoc_client_recv (mongoc_client_t *client,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error);
void
_mongoc_client_kill_cursor (mongoc_client_t *client,
uint32_t server_id,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs);
bool
_mongoc_client_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
mongoc_command_mode_t mode,
const bson_t *opts,
mongoc_query_flags_t flags,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
mongoc_read_concern_t *default_rc,
mongoc_write_concern_t *default_wc,
bson_t *reply,
bson_error_t *error);
mongoc_server_session_t *
_mongoc_client_pop_server_session (mongoc_client_t *client,
bson_error_t *error);
bool
_mongoc_client_lookup_session (const mongoc_client_t *client,
uint32_t client_session_id,
mongoc_client_session_t **cs,
bson_error_t *error);
void
_mongoc_client_unregister_session (mongoc_client_t *client,
mongoc_client_session_t *session);
void
_mongoc_client_push_server_session (mongoc_client_t *client,
mongoc_server_session_t *server_session);
void
_mongoc_client_end_sessions (mongoc_client_t *client);
mongoc_stream_t *
mongoc_client_connect_tcp (int32_t connecttimeoutms,
const mongoc_host_list_t *host,
bson_error_t *error);
mongoc_stream_t *
mongoc_client_connect (bool buffered,
bool use_ssl,
void *ssl_opts_void,
const mongoc_uri_t *uri,
const mongoc_host_list_t *host,
bson_error_t *error);
+
+
+/* Returns true if a versioned server API has been selected,
+ * otherwise returns false. */
+bool
+mongoc_client_uses_server_api (const mongoc_client_t *client);
+
BSON_END_DECLS
#endif /* MONGOC_CLIENT_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
similarity index 66%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
index 9b86b66f..8eb2ea07 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c
@@ -1,1732 +1,2564 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WIN32
#include <sys/wait.h>
#include <signal.h>
#endif
#include "mongoc.h"
#include "mongoc-client-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-topology-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
/*--------------------------------------------------------------------------
* Auto Encryption options.
*--------------------------------------------------------------------------
*/
struct _mongoc_auto_encryption_opts_t {
/* keyvault_client and keyvault_client_pool are not owned and must outlive
* auto encrypted client/pool. */
mongoc_client_t *keyvault_client;
mongoc_client_pool_t *keyvault_client_pool;
char *keyvault_db;
char *keyvault_coll;
bson_t *kms_providers;
bson_t *tls_opts;
bson_t *schema_map;
+ bson_t *encrypted_fields_map;
bool bypass_auto_encryption;
+ bool bypass_query_analysis;
bson_t *extra;
};
mongoc_auto_encryption_opts_t *
mongoc_auto_encryption_opts_new (void)
{
return bson_malloc0 (sizeof (mongoc_auto_encryption_opts_t));
}
void
mongoc_auto_encryption_opts_destroy (mongoc_auto_encryption_opts_t *opts)
{
if (!opts) {
return;
}
bson_destroy (opts->extra);
bson_destroy (opts->kms_providers);
bson_destroy (opts->schema_map);
+ bson_destroy (opts->encrypted_fields_map);
bson_free (opts->keyvault_db);
bson_free (opts->keyvault_coll);
bson_destroy (opts->tls_opts);
bson_free (opts);
}
void
mongoc_auto_encryption_opts_set_keyvault_client (
mongoc_auto_encryption_opts_t *opts, mongoc_client_t *client)
{
if (!opts) {
return;
}
/* Does not own. */
opts->keyvault_client = client;
}
void
mongoc_auto_encryption_opts_set_keyvault_client_pool (
mongoc_auto_encryption_opts_t *opts, mongoc_client_pool_t *pool)
{
if (!opts) {
return;
}
/* Does not own. */
opts->keyvault_client_pool = pool;
}
void
mongoc_auto_encryption_opts_set_keyvault_namespace (
mongoc_auto_encryption_opts_t *opts, const char *db, const char *coll)
{
if (!opts) {
return;
}
bson_free (opts->keyvault_db);
opts->keyvault_db = NULL;
opts->keyvault_db = bson_strdup (db);
bson_free (opts->keyvault_coll);
opts->keyvault_coll = NULL;
opts->keyvault_coll = bson_strdup (coll);
}
void
mongoc_auto_encryption_opts_set_kms_providers (
mongoc_auto_encryption_opts_t *opts, const bson_t *providers)
{
if (!opts) {
return;
}
bson_destroy (opts->kms_providers);
opts->kms_providers = NULL;
if (providers) {
opts->kms_providers = bson_copy (providers);
}
}
/* _bson_copy_or_null returns a copy of @bson or NULL if @bson is NULL */
static bson_t *
_bson_copy_or_null (const bson_t *bson)
{
if (bson) {
return bson_copy (bson);
}
return NULL;
}
void
mongoc_auto_encryption_opts_set_tls_opts (mongoc_auto_encryption_opts_t *opts,
const bson_t *tls_opts)
{
if (!opts) {
return;
}
bson_destroy (opts->tls_opts);
opts->tls_opts = _bson_copy_or_null (tls_opts);
}
void
mongoc_auto_encryption_opts_set_schema_map (mongoc_auto_encryption_opts_t *opts,
const bson_t *schema_map)
{
if (!opts) {
return;
}
bson_destroy (opts->schema_map);
opts->schema_map = NULL;
if (schema_map) {
opts->schema_map = bson_copy (schema_map);
}
}
+void
+mongoc_auto_encryption_opts_set_encrypted_fields_map (
+ mongoc_auto_encryption_opts_t *opts, const bson_t *encrypted_fields_map)
+{
+ if (!opts) {
+ return;
+ }
+ bson_destroy (opts->encrypted_fields_map);
+ opts->encrypted_fields_map = NULL;
+ if (encrypted_fields_map) {
+ opts->encrypted_fields_map = bson_copy (encrypted_fields_map);
+ }
+}
+
void
mongoc_auto_encryption_opts_set_bypass_auto_encryption (
mongoc_auto_encryption_opts_t *opts, bool bypass_auto_encryption)
{
if (!opts) {
return;
}
opts->bypass_auto_encryption = bypass_auto_encryption;
}
+void
+mongoc_auto_encryption_opts_set_bypass_query_analysis (
+ mongoc_auto_encryption_opts_t *opts, bool bypass_query_analysis)
+{
+ if (!opts) {
+ return;
+ }
+ opts->bypass_query_analysis = bypass_query_analysis;
+}
+
void
mongoc_auto_encryption_opts_set_extra (mongoc_auto_encryption_opts_t *opts,
const bson_t *extra)
{
if (!opts) {
return;
}
bson_destroy (opts->extra);
opts->extra = NULL;
if (extra) {
opts->extra = bson_copy (extra);
}
}
/*--------------------------------------------------------------------------
* Client Encryption options.
*--------------------------------------------------------------------------
*/
struct _mongoc_client_encryption_opts_t {
mongoc_client_t *keyvault_client;
char *keyvault_db;
char *keyvault_coll;
bson_t *kms_providers;
bson_t *tls_opts;
};
mongoc_client_encryption_opts_t *
mongoc_client_encryption_opts_new (void)
{
return bson_malloc0 (sizeof (mongoc_client_encryption_opts_t));
}
void
mongoc_client_encryption_opts_destroy (mongoc_client_encryption_opts_t *opts)
{
if (!opts) {
return;
}
bson_free (opts->keyvault_db);
bson_free (opts->keyvault_coll);
bson_destroy (opts->kms_providers);
bson_destroy (opts->tls_opts);
bson_free (opts);
}
void
mongoc_client_encryption_opts_set_keyvault_client (
mongoc_client_encryption_opts_t *opts, mongoc_client_t *keyvault_client)
{
if (!opts) {
return;
}
opts->keyvault_client = keyvault_client;
}
void
mongoc_client_encryption_opts_set_keyvault_namespace (
mongoc_client_encryption_opts_t *opts, const char *db, const char *coll)
{
if (!opts) {
return;
}
bson_free (opts->keyvault_db);
opts->keyvault_db = NULL;
opts->keyvault_db = bson_strdup (db);
bson_free (opts->keyvault_coll);
opts->keyvault_coll = NULL;
opts->keyvault_coll = bson_strdup (coll);
}
void
mongoc_client_encryption_opts_set_kms_providers (
mongoc_client_encryption_opts_t *opts, const bson_t *kms_providers)
{
if (!opts) {
return;
}
bson_destroy (opts->kms_providers);
opts->kms_providers = NULL;
if (kms_providers) {
opts->kms_providers = bson_copy (kms_providers);
}
}
void
mongoc_client_encryption_opts_set_tls_opts (
mongoc_client_encryption_opts_t *opts, const bson_t *tls_opts)
{
if (!opts) {
return;
}
bson_destroy (opts->tls_opts);
opts->tls_opts = _bson_copy_or_null (tls_opts);
}
/*--------------------------------------------------------------------------
* Data key options.
*--------------------------------------------------------------------------
*/
struct _mongoc_client_encryption_datakey_opts_t {
bson_t *masterkey;
char **keyaltnames;
uint32_t keyaltnames_count;
+ uint8_t *keymaterial;
+ uint32_t keymaterial_len;
};
mongoc_client_encryption_datakey_opts_t *
mongoc_client_encryption_datakey_opts_new (void)
{
return bson_malloc0 (sizeof (mongoc_client_encryption_datakey_opts_t));
}
static void
_clear_datakey_keyaltnames (mongoc_client_encryption_datakey_opts_t *opts)
{
if (opts->keyaltnames) {
int i;
for (i = 0; i < opts->keyaltnames_count; i++) {
bson_free (opts->keyaltnames[i]);
}
bson_free (opts->keyaltnames);
opts->keyaltnames = NULL;
opts->keyaltnames_count = 0;
}
}
void
mongoc_client_encryption_datakey_opts_destroy (
mongoc_client_encryption_datakey_opts_t *opts)
{
if (!opts) {
return;
}
bson_destroy (opts->masterkey);
_clear_datakey_keyaltnames (opts);
+ bson_free (opts->keymaterial);
bson_free (opts);
}
void
mongoc_client_encryption_datakey_opts_set_masterkey (
mongoc_client_encryption_datakey_opts_t *opts, const bson_t *masterkey)
{
if (!opts) {
return;
}
bson_destroy (opts->masterkey);
opts->masterkey = NULL;
if (masterkey) {
opts->masterkey = bson_copy (masterkey);
}
}
void
mongoc_client_encryption_datakey_opts_set_keyaltnames (
mongoc_client_encryption_datakey_opts_t *opts,
char **keyaltnames,
uint32_t keyaltnames_count)
{
int i;
if (!opts) {
return;
}
/* Free all first (if any have been set before). */
_clear_datakey_keyaltnames (opts);
BSON_ASSERT (!opts->keyaltnames);
if (keyaltnames_count) {
opts->keyaltnames = bson_malloc (sizeof (char *) * keyaltnames_count);
for (i = 0; i < keyaltnames_count; i++) {
opts->keyaltnames[i] = bson_strdup (keyaltnames[i]);
}
opts->keyaltnames_count = keyaltnames_count;
}
}
+void
+mongoc_client_encryption_datakey_opts_set_keymaterial (
+ mongoc_client_encryption_datakey_opts_t *opts,
+ const uint8_t *data,
+ uint32_t len)
+{
+ if (!opts) {
+ return;
+ }
+
+ if (opts->keymaterial) {
+ bson_free (opts->keymaterial);
+ }
+
+ opts->keymaterial = bson_malloc (len);
+ memcpy (opts->keymaterial, data, len);
+ opts->keymaterial_len = len;
+}
+
/*--------------------------------------------------------------------------
* Explicit Encryption options.
*--------------------------------------------------------------------------
*/
struct _mongoc_client_encryption_encrypt_opts_t {
bson_value_t keyid;
char *algorithm;
char *keyaltname;
+ struct {
+ int64_t value;
+ bool set;
+ } contention_factor;
+ char *query_type;
};
mongoc_client_encryption_encrypt_opts_t *
mongoc_client_encryption_encrypt_opts_new (void)
{
return bson_malloc0 (sizeof (mongoc_client_encryption_encrypt_opts_t));
}
void
mongoc_client_encryption_encrypt_opts_destroy (
mongoc_client_encryption_encrypt_opts_t *opts)
{
if (!opts) {
return;
}
bson_value_destroy (&opts->keyid);
bson_free (opts->algorithm);
bson_free (opts->keyaltname);
+ bson_free (opts->query_type);
bson_free (opts);
}
void
mongoc_client_encryption_encrypt_opts_set_keyid (
mongoc_client_encryption_encrypt_opts_t *opts, const bson_value_t *keyid)
{
if (!opts) {
return;
}
bson_value_destroy (&opts->keyid);
memset (&opts->keyid, 0, sizeof (opts->keyid));
if (keyid) {
bson_value_copy (keyid, &opts->keyid);
}
}
void
mongoc_client_encryption_encrypt_opts_set_keyaltname (
mongoc_client_encryption_encrypt_opts_t *opts, const char *keyaltname)
{
if (!opts) {
return;
}
bson_free (opts->keyaltname);
opts->keyaltname = NULL;
opts->keyaltname = bson_strdup (keyaltname);
}
void
mongoc_client_encryption_encrypt_opts_set_algorithm (
mongoc_client_encryption_encrypt_opts_t *opts, const char *algorithm)
{
if (!opts) {
return;
}
bson_free (opts->algorithm);
opts->algorithm = NULL;
opts->algorithm = bson_strdup (algorithm);
}
+void
+mongoc_client_encryption_encrypt_opts_set_contention_factor (
+ mongoc_client_encryption_encrypt_opts_t *opts, int64_t contention_factor)
+{
+ if (!opts) {
+ return;
+ }
+ opts->contention_factor.value = contention_factor;
+ opts->contention_factor.set = true;
+}
+
+void
+mongoc_client_encryption_encrypt_opts_set_query_type (
+ mongoc_client_encryption_encrypt_opts_t *opts, const char *query_type)
+{
+ if (!opts) {
+ return;
+ }
+ bson_free (opts->query_type);
+ opts->query_type = query_type ? bson_strdup (query_type) : NULL;
+}
+
+/*--------------------------------------------------------------------------
+ * RewrapManyDataKeyResult.
+ *--------------------------------------------------------------------------
+ */
+struct _mongoc_client_encryption_rewrap_many_datakey_result_t {
+ bson_t bulk_write_result;
+};
+
+mongoc_client_encryption_rewrap_many_datakey_result_t *
+mongoc_client_encryption_rewrap_many_datakey_result_new (void)
+{
+ mongoc_client_encryption_rewrap_many_datakey_result_t *const res =
+ bson_malloc0 (
+ sizeof (mongoc_client_encryption_rewrap_many_datakey_result_t));
+
+ bson_init (&res->bulk_write_result);
+
+ return res;
+}
+
+void
+mongoc_client_encryption_rewrap_many_datakey_result_destroy (
+ mongoc_client_encryption_rewrap_many_datakey_result_t *result)
+{
+ if (!result) {
+ return;
+ }
+
+ bson_destroy (&result->bulk_write_result);
+ bson_free (result);
+}
+
+const bson_t *
+mongoc_client_encryption_rewrap_many_datakey_result_get_bulk_write_result (
+ mongoc_client_encryption_rewrap_many_datakey_result_t *result)
+{
+ if (!result) {
+ return NULL;
+ }
+
+ /* bulkWriteResult may be empty if no result of a bulk write operation has
+ * been assigned to it. Treat as equivalent to an unset optional state. */
+ if (bson_empty (&result->bulk_write_result)) {
+ return NULL;
+ }
+
+ return &result->bulk_write_result;
+}
+
#ifndef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
static bool
_disabled_error (bson_error_t *error)
{
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"libmongoc is not built with support for Client-Side Field "
"Level Encryption. Configure with "
"ENABLE_CLIENT_SIDE_ENCRYPTION=ON.");
return false;
}
bool
_mongoc_cse_auto_encrypt (mongoc_client_t *client,
const mongoc_cmd_t *cmd,
mongoc_cmd_t *encrypted_cmd,
bson_t *encrypted,
bson_error_t *error)
{
bson_init (encrypted);
return _disabled_error (error);
}
bool
_mongoc_cse_auto_decrypt (mongoc_client_t *client,
const char *db_name,
const bson_t *reply,
bson_t *decrypted,
bson_error_t *error)
{
bson_init (decrypted);
return _disabled_error (error);
}
bool
_mongoc_cse_client_enable_auto_encryption (
mongoc_client_t *client,
mongoc_auto_encryption_opts_t *opts /* may be NULL */,
bson_error_t *error)
{
return _disabled_error (error);
}
bool
_mongoc_cse_client_pool_enable_auto_encryption (
mongoc_topology_t *topology,
mongoc_auto_encryption_opts_t *opts /* may be NULL */,
bson_error_t *error)
{
return _disabled_error (error);
}
bool
mongoc_client_encryption_create_datakey (
mongoc_client_encryption_t *client_encryption,
const char *kms_provider,
mongoc_client_encryption_datakey_opts_t *opts,
bson_value_t *keyid,
bson_error_t *error)
{
if (keyid) {
memset (keyid, 0, sizeof (*keyid));
}
return _disabled_error (error);
}
+bool
+mongoc_client_encryption_rewrap_many_datakey (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_t *filter,
+ const char *provider,
+ const bson_t *master_key,
+ mongoc_client_encryption_rewrap_many_datakey_result_t *result,
+ bson_error_t *error)
+{
+ return _disabled_error (error);
+}
+
+
+bool
+mongoc_client_encryption_delete_key (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ bson_t *reply,
+ bson_error_t *error)
+{
+ _mongoc_bson_init_if_set (reply);
+ return _disabled_error (error);
+}
+
+
+bool
+mongoc_client_encryption_get_key (mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ _mongoc_bson_init_if_set (key_doc);
+ return _disabled_error (error);
+}
+
+
+mongoc_cursor_t *
+mongoc_client_encryption_get_keys (
+ mongoc_client_encryption_t *client_encryption, bson_error_t *error)
+{
+ _disabled_error (error);
+ return NULL;
+}
+
+
+bool
+mongoc_client_encryption_add_key_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ _mongoc_bson_init_if_set (key_doc);
+ return _disabled_error (error);
+}
+
+
+bool
+mongoc_client_encryption_remove_key_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ _mongoc_bson_init_if_set (key_doc);
+ return _disabled_error (error);
+}
+
+
+bool
+mongoc_client_encryption_get_key_by_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ _mongoc_bson_init_if_set (key_doc);
+ return _disabled_error (error);
+}
+
+
MONGOC_EXPORT (mongoc_client_encryption_t *)
mongoc_client_encryption_new (mongoc_client_encryption_opts_t *opts,
bson_error_t *error)
{
_disabled_error (error);
return NULL;
}
void
mongoc_client_encryption_destroy (mongoc_client_encryption_t *client_encryption)
{
}
bool
mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,
const bson_value_t *value,
mongoc_client_encryption_encrypt_opts_t *opts,
bson_value_t *ciphertext,
bson_error_t *error)
{
if (ciphertext) {
memset (ciphertext, 0, sizeof (*ciphertext));
}
return _disabled_error (error);
}
bool
mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption,
const bson_value_t *ciphertext,
bson_value_t *value,
bson_error_t *error)
{
if (value) {
memset (value, 0, sizeof (*value));
}
return _disabled_error (error);
}
bool
_mongoc_cse_is_enabled (mongoc_client_t *client)
{
return false;
}
#else
/*--------------------------------------------------------------------------
*
* _prep_for_auto_encryption --
* If @cmd contains a type=1 payload (document sequence), convert it into
* a type=0 payload (array payload). See OP_MSG spec for details.
* Place the command BSON that should be encrypted into @out.
*
* Post-conditions:
* @out is initialized and set to the full payload. If @cmd did not include
* a type=1 payload, @out is statically initialized. Caller must not modify
* @out after, but must call bson_destroy.
*
* --------------------------------------------------------------------------
*/
static void
_prep_for_auto_encryption (const mongoc_cmd_t *cmd, bson_t *out)
{
/* If there is no type=1 payload, return the command unchanged. */
if (!cmd->payload || !cmd->payload_size) {
bson_init_static (out, bson_get_data (cmd->command), cmd->command->len);
return;
}
/* Otherwise, append the type=1 payload as an array. */
bson_copy_to (cmd->command, out);
_mongoc_cmd_append_payload_as_array (cmd, out);
}
/* Return the mongocryptd client to use on a client with automatic encryption
* enabled.
* If @client_encrypted is single-threaded, use the client to mongocryptd.
* If @client_encrypted is multi-threaded, use the client pool to mongocryptd.
*/
mongoc_client_t *
_get_mongocryptd_client (mongoc_client_t *client_encrypted)
{
if (client_encrypted->topology->single_threaded) {
return client_encrypted->topology->mongocryptd_client;
}
return mongoc_client_pool_pop (
client_encrypted->topology->mongocryptd_client_pool);
}
void
_release_mongocryptd_client (mongoc_client_t *client_encrypted,
mongoc_client_t *mongocryptd_client)
{
if (!mongocryptd_client) {
return;
}
if (!client_encrypted->topology->single_threaded) {
mongoc_client_pool_push (
client_encrypted->topology->mongocryptd_client_pool,
mongocryptd_client);
}
}
/* Return the key vault collection to use on a client with automatic encryption
* enabled.
* If no custom key vault client/pool is set, create a collection from the
* @client_encrypted itself.
* If @client_encrypted is single-threaded, use the client to mongocryptd to
* create the collection.
* If @client_encrypted is multi-threaded, use the client pool to mongocryptd
* to create the collection.
*/
mongoc_collection_t *
_get_keyvault_coll (mongoc_client_t *client_encrypted)
{
+ mongoc_write_concern_t *const wc = mongoc_write_concern_new ();
+ mongoc_read_concern_t *const rc = mongoc_read_concern_new ();
+
mongoc_client_t *keyvault_client;
const char *db;
const char *coll;
+ mongoc_collection_t *res = NULL;
db = client_encrypted->topology->keyvault_db;
coll = client_encrypted->topology->keyvault_coll;
if (client_encrypted->topology->single_threaded) {
if (client_encrypted->topology->keyvault_client) {
keyvault_client = client_encrypted->topology->keyvault_client;
} else {
keyvault_client = client_encrypted;
}
} else {
if (client_encrypted->topology->keyvault_client_pool) {
keyvault_client = mongoc_client_pool_pop (
client_encrypted->topology->keyvault_client_pool);
} else {
keyvault_client = client_encrypted;
}
}
- return mongoc_client_get_collection (keyvault_client, db, coll);
+
+ res = mongoc_client_get_collection (keyvault_client, db, coll);
+
+ mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY);
+ mongoc_collection_set_write_concern (res, wc);
+
+ mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY);
+ mongoc_collection_set_read_concern (res, rc);
+
+ mongoc_write_concern_destroy (wc);
+ mongoc_read_concern_destroy (rc);
+
+ return res;
}
void
_release_keyvault_coll (mongoc_client_t *client_encrypted,
mongoc_collection_t *keyvault_coll)
{
mongoc_client_t *keyvault_client;
if (!keyvault_coll) {
return;
}
keyvault_client = keyvault_coll->client;
mongoc_collection_destroy (keyvault_coll);
if (!client_encrypted->topology->single_threaded &&
client_encrypted->topology->keyvault_client_pool) {
mongoc_client_pool_push (client_encrypted->topology->keyvault_client_pool,
keyvault_client);
}
}
static bool
_spawn_mongocryptd (const char *mongocryptd_spawn_path,
const bson_t *mongocryptd_spawn_args,
bson_error_t *error);
/*--------------------------------------------------------------------------
*
* _mongoc_cse_auto_encrypt --
*
* Perform automatic encryption if enabled.
*
* Return:
* True on success, false on error.
*
* Pre-conditions:
* CSE is enabled on client or its associated client pool.
*
* Post-conditions:
* If return false, @error is set. @encrypted is always initialized.
* @encrypted_cmd is set to the mongoc_cmd_t to send, which may refer
* to @encrypted.
* If automatic encryption was bypassed, @encrypted is set to an empty
* document, but @encrypted_cmd is a copy of @cmd. Caller must always
* bson_destroy @encrypted.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cse_auto_encrypt (mongoc_client_t *client_encrypted,
const mongoc_cmd_t *cmd,
mongoc_cmd_t *encrypted_cmd,
bson_t *encrypted,
bson_error_t *error)
{
bool ret = false;
bson_t cmd_bson = BSON_INITIALIZER;
bson_t *result = NULL;
bson_iter_t iter;
mongoc_client_t *mongocryptd_client = NULL;
mongoc_collection_t *keyvault_coll = NULL;
bool retried = false;
ENTRY;
bson_init (encrypted);
if (client_encrypted->topology->bypass_auto_encryption) {
memcpy (encrypted_cmd, cmd, sizeof (mongoc_cmd_t));
bson_destroy (&cmd_bson);
RETURN (true);
}
if (cmd->server_stream->sd->max_wire_version < WIRE_VERSION_CSE) {
bson_set_error (
error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"%s",
"Auto-encryption requires a minimum MongoDB version of 4.2");
GOTO (fail);
}
/* Construct the command we're sending to libmongocrypt. If cmd includes a
* type 1 payload, convert it to a type 0 payload. */
bson_destroy (&cmd_bson);
_prep_for_auto_encryption (cmd, &cmd_bson);
keyvault_coll = _get_keyvault_coll (client_encrypted);
mongocryptd_client = _get_mongocryptd_client (client_encrypted);
retry:
bson_destroy (encrypted);
if (!_mongoc_crypt_auto_encrypt (client_encrypted->topology->crypt,
keyvault_coll,
mongocryptd_client,
client_encrypted,
cmd->db_name,
&cmd_bson,
encrypted,
error)) {
/* From the Client-Side Encryption spec: If spawning is necessary, the
* driver MUST spawn mongocryptd whenever server selection on the
* MongoClient to mongocryptd fails. If the MongoClient fails to connect
* after spawning, the server selection error is propagated to the user.
*/
if (!client_encrypted->topology->mongocryptd_bypass_spawn &&
error->domain == MONGOC_ERROR_SERVER_SELECTION && !retried) {
if (!_spawn_mongocryptd (
client_encrypted->topology->mongocryptd_spawn_path,
client_encrypted->topology->mongocryptd_spawn_args,
error)) {
GOTO (fail);
}
/* Respawn and retry. */
memset (error, 0, sizeof (*error));
retried = true;
GOTO (retry);
}
GOTO (fail);
}
/* Re-append $db if encryption stripped it. */
if (!bson_iter_init_find (&iter, encrypted, "$db")) {
BSON_APPEND_UTF8 (encrypted, "$db", cmd->db_name);
}
/* Create the modified cmd_t. */
memcpy (encrypted_cmd, cmd, sizeof (mongoc_cmd_t));
/* Modify the mongoc_cmd_t and clear the payload, since
* _mongoc_cse_auto_encrypt converted the payload into an embedded array. */
encrypted_cmd->payload = NULL;
encrypted_cmd->payload_size = 0;
encrypted_cmd->command = encrypted;
ret = true;
fail:
bson_destroy (result);
bson_destroy (&cmd_bson);
_release_mongocryptd_client (client_encrypted, mongocryptd_client);
_release_keyvault_coll (client_encrypted, keyvault_coll);
RETURN (ret);
}
/*--------------------------------------------------------------------------
*
* _mongoc_cse_auto_decrypt --
*
* Perform automatic decryption.
*
* Return:
* True on success, false on error.
*
* Pre-conditions:
* FLE is enabled on client or its associated client pool.
*
* Post-conditions:
* If return false, @error is set. @decrypted is always initialized.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cse_auto_decrypt (mongoc_client_t *client_encrypted,
const char *db_name,
const bson_t *reply,
bson_t *decrypted,
bson_error_t *error)
{
bool ret = false;
mongoc_collection_t *keyvault_coll = NULL;
ENTRY;
keyvault_coll = _get_keyvault_coll (client_encrypted);
if (!_mongoc_crypt_auto_decrypt (client_encrypted->topology->crypt,
keyvault_coll,
reply,
decrypted,
error)) {
GOTO (fail);
}
ret = true;
fail:
_release_keyvault_coll (client_encrypted, keyvault_coll);
RETURN (ret);
}
static void
_uri_construction_error (bson_error_t *error)
{
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"Error constructing URI to mongocryptd");
}
#ifdef _WIN32
static bool
_do_spawn (const char *path, char **args, bson_error_t *error)
{
bson_string_t *command;
char **arg;
PROCESS_INFORMATION process_information;
STARTUPINFO startup_info;
/* Construct the full command, quote path and arguments. */
command = bson_string_new ("");
bson_string_append (command, "\"");
if (path) {
bson_string_append (command, path);
}
bson_string_append (command, "mongocryptd.exe");
bson_string_append (command, "\"");
/* skip the "mongocryptd" first arg. */
arg = args + 1;
while (*arg) {
bson_string_append (command, " \"");
bson_string_append (command, *arg);
bson_string_append (command, "\"");
arg++;
}
ZeroMemory (&process_information, sizeof (process_information));
ZeroMemory (&startup_info, sizeof (startup_info));
startup_info.cb = sizeof (startup_info);
if (!CreateProcessA (NULL,
command->str,
NULL,
NULL,
false /* inherit descriptors */,
DETACHED_PROCESS /* FLAGS */,
NULL /* environment */,
NULL /* current directory */,
&startup_info,
&process_information)) {
long lastError = GetLastError ();
LPSTR message = NULL;
FormatMessageA (
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastError,
0,
(LPSTR) &message,
0,
NULL);
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"failed to spawn mongocryptd: %s",
message);
LocalFree (message);
bson_string_free (command, true);
return false;
}
bson_string_free (command, true);
return true;
}
#else
+
/*--------------------------------------------------------------------------
*
* _do_spawn --
*
* Spawn process defined by arg[0] on POSIX systems.
*
* Note, if mongocryptd fails to spawn (due to not being found on the path),
* an error is not reported and true is returned. Users will get an error
* later, upon first attempt to use mongocryptd.
*
* These comments refer to three distinct processes: parent, child, and
* mongocryptd.
* - parent is initial calling process
* - child is the first forked child. It fork-execs mongocryptd then
* terminates. This makes mongocryptd an orphan, making it immediately
* adopted by the init process.
* - mongocryptd is the final background daemon (grandchild process).
*
* Return:
* False if an error definitely occurred. Returns true if no reportable
* error occurred (though an error may have occurred in starting
* mongocryptd, resulting in the process not running).
*
* Arguments:
* args - A NULL terminated list of arguments. The first argument MUST
* be the name of the process to execute, and the last argument MUST be
* NULL.
*
* Post-conditions:
* If return false, @error is set.
*
*--------------------------------------------------------------------------
*/
static bool
_do_spawn (const char *path, char **args, bson_error_t *error)
{
pid_t pid;
int fd;
char *to_exec;
+ // String allocation must be done up-front, as allocation is not fork-safe.
+ if (path) {
+ to_exec = bson_strdup_printf ("%s%s", path, args[0]);
+ } else {
+ to_exec = bson_strdup (args[0]);
+ }
+
/* Fork. The child will terminate immediately (after fork-exec'ing
* mongocryptd). This orphans mongocryptd, and allows parent to wait on
* child. */
pid = fork ();
if (pid < 0) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"failed to fork (errno=%d) '%s'",
errno,
strerror (errno));
+ bson_free (to_exec);
return false;
} else if (pid > 0) {
int child_status;
/* Child will spawn mongocryptd and immediately terminate to turn
* mongocryptd into an orphan. */
if (waitpid (pid, &child_status, 0 /* options */) < 0) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"failed to wait for child (errno=%d) '%s'",
errno,
strerror (errno));
+ bson_free (to_exec);
return false;
}
/* parent is done at this point, return. */
+ bson_free (to_exec);
return true;
}
/* We're no longer in the parent process. Errors encountered result in an
* exit.
* Note, we're not logging here, because that would require the user's log
* callback to be fork-safe.
*/
/* Start a new session for the child, so it is not bound to the current
* session (e.g. terminal session). */
if (setsid () < 0) {
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
/* Fork again. Child terminates so mongocryptd gets orphaned and immedately
* adopted by init. */
signal (SIGHUP, SIG_IGN);
pid = fork ();
if (pid < 0) {
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
} else if (pid > 0) {
/* Child terminates immediately. */
- exit (EXIT_SUCCESS);
+ _exit (EXIT_SUCCESS);
}
/* If we later decide to change the working directory for the pid file path,
* possibly change the process's working directory with chdir like: `chdir
* (default_pid_path)`. Currently pid file ends up in application's working
* directory. */
/* Set the user file creation mask to zero. */
umask (0);
/* Close and reopen stdin. */
fd = open ("/dev/null", O_RDONLY);
if (fd < 0) {
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
dup2 (fd, STDIN_FILENO);
close (fd);
/* Close and reopen stdout. */
fd = open ("/dev/null", O_WRONLY);
if (fd < 0) {
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
if (dup2 (fd, STDOUT_FILENO) < 0 || close (fd) < 0) {
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
/* Close and reopen stderr. */
fd = open ("/dev/null", O_RDWR);
if (fd < 0) {
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
if (dup2 (fd, STDERR_FILENO) < 0 || close (fd) < 0) {
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
- if (path) {
- to_exec = bson_strdup_printf ("%s%s", path, args[0]);
- } else {
- to_exec = bson_strdup (args[0]);
- }
if (execvp (to_exec, args) < 0) {
/* Need to exit. */
- exit (EXIT_FAILURE);
+ _exit (EXIT_FAILURE);
}
/* Will never execute. */
return false;
}
#endif
/*--------------------------------------------------------------------------
*
* _spawn_mongocryptd --
*
* Attempt to spawn mongocryptd as a background process.
*
* Return:
* False if an error definitely occurred. Returns true if no reportable
* error occurred (though an error may have occurred in starting
* mongocryptd, resulting in the process not running).
*
* Arguments:
* mongocryptd_spawn_path May be NULL, otherwise the path to mongocryptd.
* mongocryptd_spawn_args May be NULL, otherwise a bson_iter_t to the
* value "mongocryptdSpawnArgs" in AutoEncryptionOpts.extraOptions
* (see spec).
*
* Post-conditions:
* If return false, @error is set.
*
*--------------------------------------------------------------------------
*/
static bool
_spawn_mongocryptd (const char *mongocryptd_spawn_path,
const bson_t *mongocryptd_spawn_args,
bson_error_t *error)
{
char **args = NULL;
bson_iter_t iter;
bool passed_idle_shutdown_timeout_secs = false;
int num_args = 2; /* for leading "mongocrypt" and trailing NULL */
int i;
bool ret;
/* iterate once to get length and validate all are strings */
if (mongocryptd_spawn_args) {
bson_iter_init (&iter, mongocryptd_spawn_args);
while (bson_iter_next (&iter)) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"invalid argument for mongocryptd, must be string");
return false;
}
/* Check if the arg starts with --idleShutdownTimeoutSecs= or is equal
* to --idleShutdownTimeoutSecs */
if (0 == strncmp ("--idleShutdownTimeoutSecs=",
bson_iter_utf8 (&iter, NULL),
26) ||
0 == strcmp ("--idleShutdownTimeoutSecs",
bson_iter_utf8 (&iter, NULL))) {
passed_idle_shutdown_timeout_secs = true;
}
num_args++;
}
}
if (!passed_idle_shutdown_timeout_secs) {
/* add one more */
num_args++;
}
args = (char **) bson_malloc (sizeof (char *) * num_args);
i = 0;
args[i++] = "mongocryptd";
if (mongocryptd_spawn_args) {
bson_iter_init (&iter, mongocryptd_spawn_args);
while (bson_iter_next (&iter)) {
args[i++] = (char *) bson_iter_utf8 (&iter, NULL);
}
}
if (!passed_idle_shutdown_timeout_secs) {
args[i++] = "--idleShutdownTimeoutSecs=60";
}
BSON_ASSERT (i == num_args - 1);
args[i++] = NULL;
ret = _do_spawn (mongocryptd_spawn_path, args, error);
bson_free (args);
return ret;
}
static bool
_parse_extra (const bson_t *extra,
mongoc_topology_t *topology,
mongoc_uri_t **uri,
bson_error_t *error)
{
bson_iter_t iter;
bool ret = false;
ENTRY;
*uri = NULL;
if (extra) {
if (bson_iter_init_find (&iter, extra, "mongocryptdBypassSpawn")) {
if (!BSON_ITER_HOLDS_BOOL (&iter)) {
bson_set_error (
error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Expected bool for option 'mongocryptdBypassSpawn'");
GOTO (fail);
}
topology->mongocryptd_bypass_spawn = bson_iter_bool (&iter);
}
if (bson_iter_init_find (&iter, extra, "mongocryptdSpawnPath")) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
bson_set_error (
error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Expected string for option 'mongocryptdSpawnPath'");
GOTO (fail);
}
topology->mongocryptd_spawn_path =
bson_strdup (bson_iter_utf8 (&iter, NULL));
}
if (bson_iter_init_find (&iter, extra, "mongocryptdSpawnArgs")) {
uint32_t array_len;
const uint8_t *array_data;
if (!BSON_ITER_HOLDS_ARRAY (&iter)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Expected array for option 'mongocryptdSpawnArgs'");
GOTO (fail);
}
bson_iter_array (&iter, &array_len, &array_data);
topology->mongocryptd_spawn_args =
bson_new_from_data (array_data, array_len);
}
if (bson_iter_init_find (&iter, extra, "mongocryptdURI")) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Expected string for option 'mongocryptdURI'");
GOTO (fail);
}
*uri = mongoc_uri_new_with_error (bson_iter_utf8 (&iter, NULL), error);
if (!*uri) {
GOTO (fail);
}
}
+
+ if (bson_iter_init_find (&iter, extra, "cryptSharedLibPath")) {
+ if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
+ "Expected a string for 'cryptSharedLibPath'");
+ GOTO (fail);
+ }
+ size_t len;
+ const char *ptr = bson_iter_utf8_unsafe (&iter, &len);
+ bson_free (topology->clientSideEncryption.autoOptions.extraOptions
+ .cryptSharedLibPath);
+ topology->clientSideEncryption.autoOptions.extraOptions
+ .cryptSharedLibPath = bson_strdup (ptr);
+ }
+
+ if (bson_iter_init_find (&iter, extra, "cryptSharedLibRequired")) {
+ if (!BSON_ITER_HOLDS_BOOL (&iter)) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
+ "Expected a bool for 'cryptSharedLibRequired'");
+ GOTO (fail);
+ }
+ topology->clientSideEncryption.autoOptions.extraOptions
+ .cryptSharedLibRequired = bson_iter_bool_unsafe (&iter);
+ }
}
if (!*uri) {
*uri = mongoc_uri_new_with_error ("mongodb://localhost:27020", error);
if (!*uri) {
GOTO (fail);
}
if (!mongoc_uri_set_option_as_int32 (
*uri, MONGOC_URI_SERVERSELECTIONTIMEOUTMS, 10000)) {
_uri_construction_error (error);
GOTO (fail);
}
}
ret = true;
fail:
RETURN (ret);
}
bool
_mongoc_cse_client_enable_auto_encryption (mongoc_client_t *client,
mongoc_auto_encryption_opts_t *opts,
bson_error_t *error)
{
bool ret = false;
mongoc_uri_t *mongocryptd_uri = NULL;
ENTRY;
BSON_ASSERT (client);
if (!client->topology->single_threaded) {
bson_set_error (
error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Automatic encryption on pooled clients must be set on the pool");
GOTO (fail);
}
if (!opts) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Auto encryption options required");
GOTO (fail);
}
if (opts->keyvault_client_pool) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"The key vault client pool only applies to a client "
"pool, not a single threaded client");
GOTO (fail);
}
if (opts->keyvault_client &&
!opts->keyvault_client->topology->single_threaded) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"The key vault client must be single threaded, not be "
"from a client pool");
GOTO (fail);
}
/* Check for required options */
if (!opts->keyvault_db || !opts->keyvault_coll) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Key vault namespace option required");
GOTO (fail);
}
if (!opts->kms_providers) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"KMS providers option required");
GOTO (fail);
}
if (client->topology->cse_state != MONGOC_CSE_DISABLED) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"Automatic encryption already set");
GOTO (fail);
} else {
client->topology->cse_state = MONGOC_CSE_ENABLED;
}
if (!_parse_extra (opts->extra, client->topology, &mongocryptd_uri, error)) {
GOTO (fail);
}
- client->topology->crypt = _mongoc_crypt_new (
- opts->kms_providers, opts->schema_map, opts->tls_opts, error);
+ client->topology->crypt =
+ _mongoc_crypt_new (opts->kms_providers,
+ opts->schema_map,
+ opts->encrypted_fields_map,
+ opts->tls_opts,
+ client->topology->clientSideEncryption.autoOptions
+ .extraOptions.cryptSharedLibPath,
+ client->topology->clientSideEncryption.autoOptions
+ .extraOptions.cryptSharedLibRequired,
+ opts->bypass_auto_encryption,
+ opts->bypass_query_analysis,
+ error);
if (!client->topology->crypt) {
GOTO (fail);
}
client->topology->bypass_auto_encryption = opts->bypass_auto_encryption;
+ client->topology->bypass_query_analysis = opts->bypass_query_analysis;
- if (!client->topology->bypass_auto_encryption) {
+ if (!client->topology->bypass_auto_encryption &&
+ !client->topology->bypass_query_analysis) {
if (!client->topology->mongocryptd_bypass_spawn) {
if (!_spawn_mongocryptd (client->topology->mongocryptd_spawn_path,
client->topology->mongocryptd_spawn_args,
error)) {
GOTO (fail);
}
}
/* By default, single threaded clients set serverSelectionTryOnce to
* true, which means server selection fails if a topology scan fails
* the first time (i.e. it will not make repeat attempts until
* serverSelectionTimeoutMS expires). Override this, since the first
* attempt to connect to mongocryptd may fail when spawning, as it
* takes some time for mongocryptd to listen on sockets. */
if (!mongoc_uri_set_option_as_bool (
mongocryptd_uri, MONGOC_URI_SERVERSELECTIONTRYONCE, false)) {
_uri_construction_error (error);
GOTO (fail);
}
client->topology->mongocryptd_client =
mongoc_client_new_from_uri (mongocryptd_uri);
if (!client->topology->mongocryptd_client) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"Unable to create client to mongocryptd");
GOTO (fail);
}
/* Similarly, single threaded clients will by default wait for 5 second
* cooldown period after failing to connect to a server before making
* another attempt. Meaning if the first attempt to mongocryptd fails
* to connect, then the user observes a 5 second delay. This is not
* configurable in the URI, so override. */
_mongoc_topology_bypass_cooldown (
client->topology->mongocryptd_client->topology);
/* Also, since single threaded server selection can foreseeably take
* connectTimeoutMS (which by default is longer than 10 seconds), reduce
* this as well. */
if (!mongoc_uri_set_option_as_int32 (
mongocryptd_uri, MONGOC_URI_CONNECTTIMEOUTMS, 10000)) {
_uri_construction_error (error);
GOTO (fail);
}
}
client->topology->keyvault_db = bson_strdup (opts->keyvault_db);
client->topology->keyvault_coll = bson_strdup (opts->keyvault_coll);
if (opts->keyvault_client) {
client->topology->keyvault_client = opts->keyvault_client;
}
+ if (opts->encrypted_fields_map) {
+ client->topology->encrypted_fields_map =
+ bson_copy (opts->encrypted_fields_map);
+ }
+
ret = true;
fail:
mongoc_uri_destroy (mongocryptd_uri);
RETURN (ret);
}
bool
_mongoc_cse_client_pool_enable_auto_encryption (
mongoc_topology_t *topology,
mongoc_auto_encryption_opts_t *opts,
bson_error_t *error)
{
bool setup_okay = false;
mongoc_uri_t *mongocryptd_uri = NULL;
mongoc_topology_cse_state_t prev_cse_state = MONGOC_CSE_STARTING;
BSON_ASSERT (topology);
if (!opts) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Auto encryption options required");
GOTO (fail);
}
if (opts->keyvault_client) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"The key vault client only applies to a single threaded "
"client not a client pool. Set a key vault client pool");
GOTO (fail);
}
/* Check for required options */
if (!opts->keyvault_db || !opts->keyvault_coll) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Key vault namespace option required");
GOTO (fail);
}
if (!opts->kms_providers) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"KMS providers option required");
GOTO (fail);
}
prev_cse_state =
bson_atomic_int_compare_exchange_strong ((int *) &topology->cse_state,
MONGOC_CSE_DISABLED,
MONGOC_CSE_STARTING,
bson_memory_order_acquire);
while (prev_cse_state == MONGOC_CSE_STARTING) {
/* Another thread is starting client-side encryption. It may take some
* time to start, but don't continue until it is finished. */
bson_thrd_yield ();
prev_cse_state =
bson_atomic_int_compare_exchange_strong ((int *) &topology->cse_state,
MONGOC_CSE_DISABLED,
MONGOC_CSE_STARTING,
bson_memory_order_acquire);
}
if (prev_cse_state == MONGOC_CSE_ENABLED) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"Automatic encryption already set");
GOTO (fail);
}
/* We just set the CSE state from DISABLED to STARTING. Start it up now. */
if (!_parse_extra (opts->extra, topology, &mongocryptd_uri, error)) {
GOTO (fail);
}
- topology->crypt = _mongoc_crypt_new (
- opts->kms_providers, opts->schema_map, opts->tls_opts, error);
+ topology->crypt =
+ _mongoc_crypt_new (opts->kms_providers,
+ opts->schema_map,
+ opts->encrypted_fields_map,
+ opts->tls_opts,
+ topology->clientSideEncryption.autoOptions.extraOptions
+ .cryptSharedLibPath,
+ topology->clientSideEncryption.autoOptions.extraOptions
+ .cryptSharedLibRequired,
+ opts->bypass_auto_encryption,
+ opts->bypass_query_analysis,
+ error);
if (!topology->crypt) {
GOTO (fail);
}
topology->bypass_auto_encryption = opts->bypass_auto_encryption;
+ topology->bypass_query_analysis = opts->bypass_query_analysis;
- if (!topology->bypass_auto_encryption) {
+ if (!topology->bypass_auto_encryption && !topology->bypass_query_analysis) {
if (!topology->mongocryptd_bypass_spawn) {
if (!_spawn_mongocryptd (topology->mongocryptd_spawn_path,
topology->mongocryptd_spawn_args,
error)) {
GOTO (fail);
}
}
topology->mongocryptd_client_pool =
mongoc_client_pool_new (mongocryptd_uri);
if (!topology->mongocryptd_client_pool) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"Unable to create client pool to mongocryptd");
GOTO (fail);
}
}
topology->keyvault_db = bson_strdup (opts->keyvault_db);
topology->keyvault_coll = bson_strdup (opts->keyvault_coll);
if (opts->keyvault_client_pool) {
topology->keyvault_client_pool = opts->keyvault_client_pool;
}
+ if (opts->encrypted_fields_map) {
+ topology->encrypted_fields_map = bson_copy (opts->encrypted_fields_map);
+ }
+
setup_okay = true;
BSON_ASSERT (prev_cse_state == MONGOC_CSE_DISABLED);
fail:
if (prev_cse_state == MONGOC_CSE_DISABLED) {
/* We need to set the new CSE state. */
mongoc_topology_cse_state_t new_state =
setup_okay ? MONGOC_CSE_ENABLED : MONGOC_CSE_DISABLED;
bson_atomic_int_exchange (
(int *) &topology->cse_state, new_state, bson_memory_order_release);
}
mongoc_uri_destroy (mongocryptd_uri);
RETURN (setup_okay);
}
struct _mongoc_client_encryption_t {
_mongoc_crypt_t *crypt;
mongoc_collection_t *keyvault_coll;
bson_t *kms_providers;
};
mongoc_client_encryption_t *
mongoc_client_encryption_new (mongoc_client_encryption_opts_t *opts,
bson_error_t *error)
{
mongoc_client_encryption_t *client_encryption = NULL;
bool success = false;
mongoc_write_concern_t *wc = NULL;
+ mongoc_read_concern_t *rc = NULL;
/* Check for required options */
if (!opts || !opts->keyvault_client || !opts->keyvault_db ||
!opts->keyvault_coll) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Key vault client and namespace option required");
goto fail;
}
if (!opts->kms_providers) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"KMS providers option required");
goto fail;
}
client_encryption = bson_malloc0 (sizeof (*client_encryption));
client_encryption->keyvault_coll = mongoc_client_get_collection (
opts->keyvault_client, opts->keyvault_db, opts->keyvault_coll);
wc = mongoc_write_concern_new ();
- mongoc_write_concern_set_wmajority (wc, 1000);
+ mongoc_write_concern_set_w (wc, MONGOC_WRITE_CONCERN_W_MAJORITY);
mongoc_collection_set_write_concern (client_encryption->keyvault_coll, wc);
+ rc = mongoc_read_concern_new ();
+ mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY);
+ mongoc_collection_set_read_concern (client_encryption->keyvault_coll, rc);
client_encryption->kms_providers = bson_copy (opts->kms_providers);
- client_encryption->crypt = _mongoc_crypt_new (
- opts->kms_providers, NULL /* schema_map */, opts->tls_opts, error);
+ client_encryption->crypt =
+ _mongoc_crypt_new (opts->kms_providers,
+ NULL /* schema_map */,
+ NULL /* encrypted_fields_map */,
+ opts->tls_opts,
+ NULL /* No crypt_shared path */,
+ false /* crypt_shared not requried */,
+ true, /* bypassAutoEncryption (We are explicit) */
+ false /* bypass_query_analysis. Not applicable. */,
+ error);
if (!client_encryption->crypt) {
goto fail;
}
success = true;
fail:
mongoc_write_concern_destroy (wc);
+ mongoc_read_concern_destroy (rc);
if (!success) {
mongoc_client_encryption_destroy (client_encryption);
return NULL;
}
return client_encryption;
}
void
mongoc_client_encryption_destroy (mongoc_client_encryption_t *client_encryption)
{
if (!client_encryption) {
return;
}
_mongoc_crypt_destroy (client_encryption->crypt);
mongoc_collection_destroy (client_encryption->keyvault_coll);
bson_destroy (client_encryption->kms_providers);
bson_free (client_encryption);
}
+static bool
+_coll_has_write_concern_majority (const mongoc_collection_t *coll)
+{
+ const mongoc_write_concern_t *const wc =
+ mongoc_collection_get_write_concern (coll);
+ return wc && mongoc_write_concern_get_wmajority (wc);
+}
+
+static bool
+_coll_has_read_concern_majority (const mongoc_collection_t *coll)
+{
+ const mongoc_read_concern_t *const rc =
+ mongoc_collection_get_read_concern (coll);
+ const char *const level = rc ? mongoc_read_concern_get_level (rc) : NULL;
+ return level && strcmp (level, MONGOC_READ_CONCERN_LEVEL_MAJORITY) == 0;
+}
+
bool
mongoc_client_encryption_create_datakey (
mongoc_client_encryption_t *client_encryption,
const char *kms_provider,
mongoc_client_encryption_datakey_opts_t *opts,
bson_value_t *keyid,
bson_error_t *error)
{
bool ret = false;
bson_t datakey = BSON_INITIALIZER;
bson_t insert_opts = BSON_INITIALIZER;
ENTRY;
+ BSON_ASSERT_PARAM (client_encryption);
+
+ BSON_ASSERT (
+ _coll_has_write_concern_majority (client_encryption->keyvault_coll));
+
if (!opts) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"required 'opts' unset");
GOTO (fail);
}
/* reset, so it is safe for caller to call bson_value_destroy on error or
* success. */
if (keyid) {
keyid->value_type = BSON_TYPE_EOD;
}
bson_destroy (&datakey);
if (!_mongoc_crypt_create_datakey (client_encryption->crypt,
kms_provider,
opts->masterkey,
opts->keyaltnames,
opts->keyaltnames_count,
+ opts->keymaterial,
+ opts->keymaterial_len,
&datakey,
error)) {
GOTO (fail);
}
- /* Insert the data key with write concern majority */
if (!mongoc_collection_insert_one (client_encryption->keyvault_coll,
&datakey,
NULL /* opts */,
NULL /* reply */,
error)) {
GOTO (fail);
}
if (keyid) {
bson_iter_t iter;
const bson_value_t *id_value;
if (!bson_iter_init_find (&iter, &datakey, "_id")) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"data key not did not contain _id");
GOTO (fail);
} else if (!BSON_ITER_HOLDS_BINARY (&iter)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"data key _id does not contain binary");
GOTO (fail);
} else {
id_value = bson_iter_value (&iter);
bson_value_copy (id_value, keyid);
}
}
ret = true;
fail:
bson_destroy (&insert_opts);
bson_destroy (&datakey);
RETURN (ret);
}
+bool
+mongoc_client_encryption_rewrap_many_datakey (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_t *filter,
+ const char *provider,
+ const bson_t *master_key,
+ mongoc_client_encryption_rewrap_many_datakey_result_t *result,
+ bson_error_t *error)
+{
+ bson_t keys = BSON_INITIALIZER;
+ bson_t local_result = BSON_INITIALIZER;
+ bson_t *const bulk_write_result =
+ result ? &result->bulk_write_result : &local_result;
+ mongoc_bulk_operation_t *bulk = NULL;
+ bson_iter_t iter;
+ bool ret = false;
+
+ ENTRY;
+
+ BSON_ASSERT_PARAM (client_encryption);
+
+ BSON_ASSERT (
+ _coll_has_read_concern_majority (client_encryption->keyvault_coll));
+ BSON_ASSERT (
+ _coll_has_write_concern_majority (client_encryption->keyvault_coll));
+
+ bson_reinit (bulk_write_result);
+
+ if (!_mongoc_crypt_rewrap_many_datakey (client_encryption->crypt,
+ client_encryption->keyvault_coll,
+ filter,
+ provider,
+ master_key,
+ &keys,
+ error)) {
+ GOTO (fail);
+ }
+
+ /* No keys rewrapped, no key documents to update. */
+ if (bson_empty (&keys)) {
+ bson_destroy (&keys);
+ bson_destroy (&local_result);
+ return true;
+ }
+
+ bulk = mongoc_collection_create_bulk_operation_with_opts (
+ client_encryption->keyvault_coll, NULL);
+
+ BSON_ASSERT (bulk);
+
+ if (!bson_iter_init_find (&iter, &keys, "v")) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "result did not contain expected field 'v'");
+ GOTO (fail);
+ }
+
+ if (!BSON_ITER_HOLDS_ARRAY (&iter)) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "result did not return an array as expected");
+ GOTO (fail);
+ }
+
+ BSON_ASSERT (bson_iter_recurse (&iter, &iter));
+
+ while (bson_iter_next (&iter)) {
+ const uint8_t *data = NULL;
+ uint32_t len = 0u;
+ bson_t key;
+ bson_iter_t key_iter;
+ bson_subtype_t subtype;
+ bson_t selector = BSON_INITIALIZER;
+ bson_t document = BSON_INITIALIZER;
+ bool doc_success = false;
+
+ bson_iter_document (&iter, &len, &data);
+
+ if (!data || !bson_init_static (&key, data, len)) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "element is not a valid BSON document");
+ goto doc_done;
+ }
+
+ /* Find _id and use as selector. */
+ {
+ if (!bson_iter_init_find (&key_iter, &key, "_id")) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "could not find _id in key document");
+ goto doc_done;
+ }
+
+ bson_iter_binary (&key_iter, &subtype, &len, &data);
+
+ if (!data || subtype != BSON_SUBTYPE_UUID) {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "expected _id in key document to be a UUID");
+ goto doc_done;
+ }
+
+ BSON_ASSERT (bson_append_iter (&selector, "_id", 3, &key_iter));
+ }
+
+ /* Find and include potentially updated fields. */
+ {
+ bson_t child;
+
+ BSON_ASSERT (BSON_APPEND_DOCUMENT_BEGIN (&document, "$set", &child));
+ {
+ if (bson_iter_init_find (&key_iter, &key, "masterKey")) {
+ BSON_ASSERT (
+ bson_append_iter (&child, "masterKey", -1, &key_iter));
+ }
+
+ if (bson_iter_init_find (&key_iter, &key, "keyMaterial")) {
+ BSON_ASSERT (
+ bson_append_iter (&child, "keyMaterial", -1, &key_iter));
+ }
+ }
+ BSON_ASSERT (bson_append_document_end (&document, &child));
+ }
+
+ /* Update updateDate field. */
+ BCON_APPEND (
+ &document, "$currentDate", "{", "updateDate", BCON_BOOL (true), "}");
+
+ if (!mongoc_bulk_operation_update_one_with_opts (
+ bulk, &selector, &document, NULL, error)) {
+ goto doc_done;
+ }
+
+ doc_success = true;
+
+ doc_done:
+ bson_destroy (&key);
+ bson_destroy (&selector);
+ bson_destroy (&document);
+
+ if (!doc_success) {
+ GOTO (fail);
+ }
+ }
+
+ if (!mongoc_bulk_operation_execute (bulk, bulk_write_result, error)) {
+ GOTO (fail);
+ }
+
+ ret = true;
+
+fail:
+ bson_destroy (&keys);
+ bson_destroy (&local_result);
+ mongoc_bulk_operation_destroy (bulk);
+
+ RETURN (ret);
+}
+
+bool
+mongoc_client_encryption_delete_key (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ bson_t *reply,
+ bson_error_t *error)
+{
+ bool ret = false;
+ bson_t selector = BSON_INITIALIZER;
+
+ ENTRY;
+
+ BSON_ASSERT_PARAM (client_encryption);
+ BSON_ASSERT_PARAM (keyid);
+
+ BSON_ASSERT (
+ _coll_has_write_concern_majority (client_encryption->keyvault_coll));
+
+ BSON_ASSERT (keyid->value_type == BSON_TYPE_BINARY);
+ BSON_ASSERT (keyid->value.v_binary.subtype == BSON_SUBTYPE_UUID);
+ BSON_ASSERT (keyid->value.v_binary.data_len > 0u);
+
+ BSON_ASSERT (BSON_APPEND_BINARY (&selector,
+ "_id",
+ keyid->value.v_binary.subtype,
+ keyid->value.v_binary.data,
+ keyid->value.v_binary.data_len));
+
+ ret = mongoc_collection_delete_one (
+ client_encryption->keyvault_coll, &selector, NULL, reply, error);
+
+ bson_destroy (&selector);
+
+ RETURN (ret);
+}
+
+bool
+mongoc_client_encryption_get_key (mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ bson_t filter = BSON_INITIALIZER;
+ mongoc_cursor_t *cursor = NULL;
+ bool ret = false;
+
+ ENTRY;
+
+ BSON_ASSERT_PARAM (client_encryption);
+ BSON_ASSERT_PARAM (keyid);
+
+ BSON_ASSERT (keyid->value_type == BSON_TYPE_BINARY);
+ BSON_ASSERT (keyid->value.v_binary.subtype == BSON_SUBTYPE_UUID);
+ BSON_ASSERT (keyid->value.v_binary.data_len > 0u);
+
+ BSON_ASSERT (BSON_APPEND_BINARY (&filter,
+ "_id",
+ keyid->value.v_binary.subtype,
+ keyid->value.v_binary.data,
+ keyid->value.v_binary.data_len));
+
+ BSON_ASSERT (
+ _coll_has_read_concern_majority (client_encryption->keyvault_coll));
+
+ _mongoc_bson_init_if_set (key_doc);
+
+ cursor = mongoc_collection_find_with_opts (
+ client_encryption->keyvault_coll, &filter, NULL, NULL);
+
+ ret = !mongoc_cursor_error (cursor, error);
+
+ if (ret && key_doc) {
+ const bson_t *bson = NULL;
+
+ if (mongoc_cursor_next (cursor, &bson)) {
+ bson_copy_to (bson, key_doc);
+ } else if (mongoc_cursor_error (cursor, error)) {
+ ret = false;
+ }
+ }
+
+ bson_destroy (&filter);
+ mongoc_cursor_destroy (cursor);
+
+ RETURN (ret);
+}
+
+mongoc_cursor_t *
+mongoc_client_encryption_get_keys (
+ mongoc_client_encryption_t *client_encryption, bson_error_t *error)
+{
+ mongoc_cursor_t *cursor = NULL;
+ bson_t filter = BSON_INITIALIZER;
+
+ ENTRY;
+
+ BSON_ASSERT_PARAM (client_encryption);
+
+ BSON_ASSERT (
+ _coll_has_read_concern_majority (client_encryption->keyvault_coll));
+
+ /* If an error occurred, user should query cursor error. */
+ cursor = mongoc_collection_find_with_opts (
+ client_encryption->keyvault_coll, &filter, NULL, NULL);
+
+ bson_destroy (&filter);
+
+ RETURN (cursor);
+}
+
+bool
+mongoc_client_encryption_add_key_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ mongoc_find_and_modify_opts_t *const opts =
+ mongoc_find_and_modify_opts_new ();
+ bson_t query = BSON_INITIALIZER;
+ bool ret = false;
+ bson_t local_reply;
+
+ ENTRY;
+
+ BSON_ASSERT_PARAM (client_encryption);
+ BSON_ASSERT_PARAM (keyid);
+ BSON_ASSERT_PARAM (keyaltname);
+
+ BSON_ASSERT (
+ _coll_has_read_concern_majority (client_encryption->keyvault_coll));
+ BSON_ASSERT (
+ _coll_has_write_concern_majority (client_encryption->keyvault_coll));
+
+ BSON_ASSERT (keyid->value_type == BSON_TYPE_BINARY);
+ BSON_ASSERT (keyid->value.v_binary.subtype == BSON_SUBTYPE_UUID);
+ BSON_ASSERT (keyid->value.v_binary.data_len > 0u);
+
+ BSON_ASSERT (BSON_APPEND_BINARY (&query,
+ "_id",
+ keyid->value.v_binary.subtype,
+ keyid->value.v_binary.data,
+ keyid->value.v_binary.data_len));
+
+ _mongoc_bson_init_if_set (key_doc);
+
+ {
+ bson_t *const update = BCON_NEW (
+ "$addToSet", "{", "keyAltNames", BCON_UTF8 (keyaltname), "}");
+ BSON_ASSERT (mongoc_find_and_modify_opts_set_update (opts, update));
+ bson_destroy (update);
+ }
+
+ ret = mongoc_collection_find_and_modify_with_opts (
+ client_encryption->keyvault_coll, &query, opts, &local_reply, error);
+
+ if (ret && key_doc) {
+ bson_iter_t iter;
+
+ if (bson_iter_init_find (&iter, &local_reply, "value")) {
+ const bson_value_t *const value = bson_iter_value (&iter);
+
+ if (value->value_type == BSON_TYPE_DOCUMENT) {
+ bson_t bson;
+ BSON_ASSERT (bson_init_static (
+ &bson, value->value.v_doc.data, value->value.v_doc.data_len));
+ bson_copy_to (&bson, key_doc);
+ bson_destroy (&bson);
+ } else if (value->value_type == BSON_TYPE_NULL) {
+ bson_t bson = BSON_INITIALIZER;
+ bson_copy_to (&bson, key_doc);
+ bson_destroy (&bson);
+ } else {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "expected field value to be a document or null");
+ ret = false;
+ }
+ }
+ }
+
+ mongoc_find_and_modify_opts_destroy (opts);
+ bson_destroy (&query);
+ bson_destroy (&local_reply);
+
+ RETURN (ret);
+}
+
+bool
+mongoc_client_encryption_remove_key_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ bson_t query = BSON_INITIALIZER;
+ bool ret = false;
+ bson_t local_reply;
+
+ ENTRY;
+
+ BSON_ASSERT_PARAM (client_encryption);
+ BSON_ASSERT_PARAM (keyid);
+ BSON_ASSERT_PARAM (keyaltname);
+
+ BSON_ASSERT (
+ _coll_has_write_concern_majority (client_encryption->keyvault_coll));
+
+ BSON_ASSERT (keyid->value_type == BSON_TYPE_BINARY);
+ BSON_ASSERT (keyid->value.v_binary.subtype == BSON_SUBTYPE_UUID);
+ BSON_ASSERT (keyid->value.v_binary.data_len > 0u);
+
+ BSON_ASSERT (BSON_APPEND_BINARY (&query,
+ "_id",
+ keyid->value.v_binary.subtype,
+ keyid->value.v_binary.data,
+ keyid->value.v_binary.data_len));
+
+ _mongoc_bson_init_if_set (key_doc);
+
+
+ {
+ mongoc_find_and_modify_opts_t *const opts =
+ mongoc_find_and_modify_opts_new ();
+
+ /* clang-format off */
+ bson_t *const update = BCON_NEW (
+ "0", "{",
+ "$set", "{",
+ "keyAltNames", "{",
+ "$cond", "[",
+ "{",
+ "$eq", "[", "$keyAltNames", "[", keyaltname, "]", "]",
+ "}",
+ "$$REMOVE",
+ "{",
+ "$filter", "{",
+ "input", "$keyAltNames",
+ "cond", "{",
+ "$ne", "[", "$$this", keyaltname, "]",
+ "}",
+ "}",
+ "}",
+ "]",
+ "}",
+ "}",
+ "}");
+ /* clang-format on */
+
+ BSON_ASSERT (mongoc_find_and_modify_opts_set_update (opts, update));
+
+ ret = mongoc_collection_find_and_modify_with_opts (
+ client_encryption->keyvault_coll, &query, opts, &local_reply, error);
+
+ bson_destroy (update);
+ mongoc_find_and_modify_opts_destroy (opts);
+ }
+
+ if (ret && key_doc) {
+ bson_iter_t iter;
+
+ if (bson_iter_init_find (&iter, &local_reply, "value")) {
+ const bson_value_t *const value = bson_iter_value (&iter);
+
+ if (value->value_type == BSON_TYPE_DOCUMENT) {
+ bson_t bson;
+ BSON_ASSERT (bson_init_static (
+ &bson, value->value.v_doc.data, value->value.v_doc.data_len));
+ bson_copy_to (&bson, key_doc);
+ bson_destroy (&bson);
+ } else if (value->value_type == BSON_TYPE_NULL) {
+ bson_t bson = BSON_INITIALIZER;
+ bson_copy_to (&bson, key_doc);
+ bson_destroy (&bson);
+ } else {
+ bson_set_error (error,
+ MONGOC_ERROR_CLIENT,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "expected field value to be a document or null");
+ ret = false;
+ }
+ }
+ }
+
+ bson_destroy (&query);
+ bson_destroy (&local_reply);
+
+ RETURN (ret);
+}
+
+bool
+mongoc_client_encryption_get_key_by_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error)
+{
+ bson_t filter = BSON_INITIALIZER;
+ mongoc_cursor_t *cursor = NULL;
+ bool ret = false;
+
+ ENTRY;
+
+ BSON_ASSERT_PARAM (client_encryption);
+ BSON_ASSERT_PARAM (keyaltname);
+
+ BSON_ASSERT (
+ _coll_has_write_concern_majority (client_encryption->keyvault_coll));
+
+ BSON_ASSERT (BSON_APPEND_UTF8 (&filter, "keyAltNames", keyaltname));
+
+ _mongoc_bson_init_if_set (key_doc);
+
+ cursor = mongoc_collection_find_with_opts (
+ client_encryption->keyvault_coll, &filter, NULL, NULL);
+
+ ret = !mongoc_cursor_error (cursor, error);
+
+ if (ret && key_doc) {
+ const bson_t *bson = NULL;
+
+ if (mongoc_cursor_next (cursor, &bson)) {
+ bson_copy_to (bson, key_doc);
+ } else if (mongoc_cursor_error (cursor, error)) {
+ ret = false;
+ }
+ }
+
+ bson_destroy (&filter);
+ mongoc_cursor_destroy (cursor);
+
+ RETURN (ret);
+}
+
bool
mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,
const bson_value_t *value,
mongoc_client_encryption_encrypt_opts_t *opts,
bson_value_t *ciphertext,
bson_error_t *error)
{
bool ret = false;
ENTRY;
BSON_ASSERT (client_encryption);
if (!ciphertext) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"required 'ciphertext' unset");
GOTO (fail);
}
/* reset, so it is safe for caller to call bson_value_destroy on error or
* success. */
ciphertext->value_type = BSON_TYPE_EOD;
if (!opts) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"required 'opts' unset");
GOTO (fail);
}
- if (!_mongoc_crypt_explicit_encrypt (client_encryption->crypt,
- client_encryption->keyvault_coll,
- opts->algorithm,
- &opts->keyid,
- opts->keyaltname,
- value,
- ciphertext,
- error)) {
+ if (!_mongoc_crypt_explicit_encrypt (
+ client_encryption->crypt,
+ client_encryption->keyvault_coll,
+ opts->algorithm,
+ &opts->keyid,
+ opts->keyaltname,
+ opts->query_type,
+ opts->contention_factor.set ? &opts->contention_factor.value : NULL,
+ value,
+ ciphertext,
+ error)) {
GOTO (fail);
}
ret = true;
fail:
RETURN (ret);
}
bool
mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption,
const bson_value_t *ciphertext,
bson_value_t *value,
bson_error_t *error)
{
bool ret = false;
ENTRY;
BSON_ASSERT (client_encryption);
if (!value) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"required 'value' unset");
GOTO (fail);
}
/* reset, so it is safe for caller to call bson_value_destroy on error or
* success. */
value->value_type = BSON_TYPE_EOD;
if (ciphertext->value_type != BSON_TYPE_BINARY ||
ciphertext->value.v_binary.subtype != BSON_SUBTYPE_ENCRYPTED) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"ciphertext must be BSON binary subtype 6");
GOTO (fail);
}
if (!_mongoc_crypt_explicit_decrypt (client_encryption->crypt,
client_encryption->keyvault_coll,
ciphertext,
value,
error)) {
GOTO (fail);
}
ret = true;
fail:
RETURN (ret);
}
bool
_mongoc_cse_is_enabled (mongoc_client_t *client)
{
while (1) {
mongoc_topology_cse_state_t state = bson_atomic_int_fetch (
(int *) &client->topology->cse_state, bson_memory_order_relaxed);
if (state != MONGOC_CSE_STARTING) {
return state == MONGOC_CSE_ENABLED;
}
/* CSE is starting up. Wait until that succeeds or fails. */
bson_thrd_yield ();
}
}
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
similarity index 66%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
index c79ca7d8..e0c68713 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h
@@ -1,172 +1,264 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLIENT_SIDE_ENCRYPTION_H
#define MONGOC_CLIENT_SIDE_ENCRYPTION_H
#include <bson/bson.h>
/* Forward declare */
struct _mongoc_client_t;
struct _mongoc_client_pool_t;
+struct _mongoc_cursor_t;
#define MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM \
"AEAD_AES_256_CBC_HMAC_SHA_512-Random"
#define MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC \
"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+#define MONGOC_ENCRYPT_ALGORITHM_INDEXED "Indexed"
+#define MONGOC_ENCRYPT_ALGORITHM_UNINDEXED "Unindexed"
+
+#define MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY "equality"
+
BSON_BEGIN_DECLS
typedef struct _mongoc_auto_encryption_opts_t mongoc_auto_encryption_opts_t;
MONGOC_EXPORT (mongoc_auto_encryption_opts_t *)
mongoc_auto_encryption_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_destroy (mongoc_auto_encryption_opts_t *opts);
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_keyvault_client (
mongoc_auto_encryption_opts_t *opts, struct _mongoc_client_t *client);
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_keyvault_client_pool (
mongoc_auto_encryption_opts_t *opts, struct _mongoc_client_pool_t *pool);
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_keyvault_namespace (
mongoc_auto_encryption_opts_t *opts, const char *db, const char *coll);
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_kms_providers (
mongoc_auto_encryption_opts_t *opts, const bson_t *kms_providers);
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_tls_opts (mongoc_auto_encryption_opts_t *opts,
const bson_t *tls_opts);
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_schema_map (mongoc_auto_encryption_opts_t *opts,
const bson_t *schema_map);
+MONGOC_EXPORT (void)
+mongoc_auto_encryption_opts_set_encrypted_fields_map (
+ mongoc_auto_encryption_opts_t *opts, const bson_t *encrypted_fields_map);
+
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_bypass_auto_encryption (
mongoc_auto_encryption_opts_t *opts, bool bypass_auto_encryption);
+MONGOC_EXPORT (void)
+mongoc_auto_encryption_opts_set_bypass_query_analysis (
+ mongoc_auto_encryption_opts_t *opts, bool bypass_query_analysis);
+
MONGOC_EXPORT (void)
mongoc_auto_encryption_opts_set_extra (mongoc_auto_encryption_opts_t *opts,
const bson_t *extra);
typedef struct _mongoc_client_encryption_opts_t mongoc_client_encryption_opts_t;
typedef struct _mongoc_client_encryption_t mongoc_client_encryption_t;
typedef struct _mongoc_client_encryption_encrypt_opts_t
mongoc_client_encryption_encrypt_opts_t;
typedef struct _mongoc_client_encryption_datakey_opts_t
mongoc_client_encryption_datakey_opts_t;
+typedef struct _mongoc_client_encryption_rewrap_many_datakey_result_t
+ mongoc_client_encryption_rewrap_many_datakey_result_t;
MONGOC_EXPORT (mongoc_client_encryption_opts_t *)
mongoc_client_encryption_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (void)
mongoc_client_encryption_opts_destroy (mongoc_client_encryption_opts_t *opts);
MONGOC_EXPORT (void)
mongoc_client_encryption_opts_set_keyvault_client (
mongoc_client_encryption_opts_t *opts,
struct _mongoc_client_t *keyvault_client);
MONGOC_EXPORT (void)
mongoc_client_encryption_opts_set_keyvault_namespace (
mongoc_client_encryption_opts_t *opts, const char *db, const char *coll);
MONGOC_EXPORT (void)
mongoc_client_encryption_opts_set_kms_providers (
mongoc_client_encryption_opts_t *opts, const bson_t *kms_providers);
MONGOC_EXPORT (void)
mongoc_client_encryption_opts_set_tls_opts (
mongoc_client_encryption_opts_t *opts, const bson_t *tls_opts);
+MONGOC_EXPORT (mongoc_client_encryption_rewrap_many_datakey_result_t *)
+mongoc_client_encryption_rewrap_many_datakey_result_new (void)
+ BSON_GNUC_WARN_UNUSED_RESULT;
+
+MONGOC_EXPORT (void)
+mongoc_client_encryption_rewrap_many_datakey_result_destroy (
+ mongoc_client_encryption_rewrap_many_datakey_result_t *result);
+
+MONGOC_EXPORT (const bson_t *)
+mongoc_client_encryption_rewrap_many_datakey_result_get_bulk_write_result (
+ mongoc_client_encryption_rewrap_many_datakey_result_t *result)
+ BSON_GNUC_WARN_UNUSED_RESULT;
+
MONGOC_EXPORT (mongoc_client_encryption_t *)
mongoc_client_encryption_new (mongoc_client_encryption_opts_t *opts,
bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (void)
mongoc_client_encryption_destroy (
mongoc_client_encryption_t *client_encryption);
MONGOC_EXPORT (bool)
mongoc_client_encryption_create_datakey (
mongoc_client_encryption_t *client_encryption,
const char *kms_provider,
mongoc_client_encryption_datakey_opts_t *opts,
bson_value_t *keyid,
bson_error_t *error);
+MONGOC_EXPORT (bool)
+mongoc_client_encryption_rewrap_many_datakey (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_t *filter,
+ const char *provider,
+ const bson_t *master_key,
+ mongoc_client_encryption_rewrap_many_datakey_result_t *result,
+ bson_error_t *error);
+
+MONGOC_EXPORT (bool)
+mongoc_client_encryption_delete_key (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ bson_t *reply,
+ bson_error_t *error);
+
+MONGOC_EXPORT (bool)
+mongoc_client_encryption_get_key (mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ bson_t *key_doc,
+ bson_error_t *error);
+
+MONGOC_EXPORT (struct _mongoc_cursor_t *)
+mongoc_client_encryption_get_keys (
+ mongoc_client_encryption_t *client_encryption, bson_error_t *error);
+
+MONGOC_EXPORT (bool)
+mongoc_client_encryption_add_key_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error);
+
+MONGOC_EXPORT (bool)
+mongoc_client_encryption_remove_key_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const bson_value_t *keyid,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error);
+
+MONGOC_EXPORT (bool)
+mongoc_client_encryption_get_key_by_alt_name (
+ mongoc_client_encryption_t *client_encryption,
+ const char *keyaltname,
+ bson_t *key_doc,
+ bson_error_t *error);
+
MONGOC_EXPORT (bool)
mongoc_client_encryption_encrypt (mongoc_client_encryption_t *client_encryption,
const bson_value_t *value,
mongoc_client_encryption_encrypt_opts_t *opts,
bson_value_t *ciphertext,
bson_error_t *error);
MONGOC_EXPORT (bool)
mongoc_client_encryption_decrypt (mongoc_client_encryption_t *client_encryption,
const bson_value_t *ciphertext,
bson_value_t *value,
bson_error_t *error);
MONGOC_EXPORT (mongoc_client_encryption_encrypt_opts_t *)
mongoc_client_encryption_encrypt_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_destroy (
mongoc_client_encryption_encrypt_opts_t *opts);
MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_set_keyid (
mongoc_client_encryption_encrypt_opts_t *opts, const bson_value_t *keyid);
MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_set_keyaltname (
mongoc_client_encryption_encrypt_opts_t *opts, const char *keyaltname);
MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_set_algorithm (
mongoc_client_encryption_encrypt_opts_t *opts, const char *algorithm);
+MONGOC_EXPORT (void)
+mongoc_client_encryption_encrypt_opts_set_contention_factor (
+ mongoc_client_encryption_encrypt_opts_t *opts, int64_t contention_factor);
+
+MONGOC_EXPORT (void)
+mongoc_client_encryption_encrypt_opts_set_query_type (
+ mongoc_client_encryption_encrypt_opts_t *opts, const char *query_type);
+
MONGOC_EXPORT (mongoc_client_encryption_datakey_opts_t *)
mongoc_client_encryption_datakey_opts_new (void) BSON_GNUC_WARN_UNUSED_RESULT;
MONGOC_EXPORT (void)
mongoc_client_encryption_datakey_opts_destroy (
mongoc_client_encryption_datakey_opts_t *opts);
MONGOC_EXPORT (void)
mongoc_client_encryption_datakey_opts_set_masterkey (
mongoc_client_encryption_datakey_opts_t *opts, const bson_t *masterkey);
MONGOC_EXPORT (void)
mongoc_client_encryption_datakey_opts_set_keyaltnames (
mongoc_client_encryption_datakey_opts_t *opts,
char **keyaltnames,
uint32_t keyaltnames_count);
+MONGOC_EXPORT (void)
+mongoc_client_encryption_datakey_opts_set_keymaterial (
+ mongoc_client_encryption_datakey_opts_t *opts,
+ const uint8_t *data,
+ uint32_t len);
+
BSON_END_DECLS
#endif /* MONGOC_CLIENT_SIDE_ENCRYPTION_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
index 46a3c504..457c841a 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c
@@ -1,3168 +1,3177 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongoc-config.h"
#ifdef MONGOC_HAVE_DNSAPI
/* for DnsQuery_UTF8 */
#include <Windows.h>
#include <WinDNS.h>
#include <ws2tcpip.h>
#else
#if defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH)
#include <netdb.h>
#include <netinet/tcp.h>
#include <arpa/nameser.h>
#include <resolv.h>
#define BSON_INSIDE
#include <bson/bson-string.h>
#undef BSON_INSIDE
#endif
#endif
#include "mongoc-client-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-collection-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-database-private.h"
#include "mongoc-gridfs-private.h"
#include "mongoc-error.h"
#include "mongoc-error-private.h"
#include "mongoc-log.h"
#include "mongoc-queue-private.h"
#include "mongoc-socket.h"
#include "mongoc-stream-buffered.h"
#include "mongoc-stream-socket.h"
#include "mongoc-thread-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-util-private.h"
#include "mongoc-set-private.h"
#include "mongoc-log.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-change-stream-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-cursor-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-stream-tls.h"
#include "mongoc-ssl-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-opts-private.h"
#endif
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "client"
static void
_mongoc_client_op_killcursors (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection);
static void
_mongoc_client_killcursors_command (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs);
#define DNS_ERROR(_msg, ...) \
do { \
bson_set_error (error, \
MONGOC_ERROR_STREAM, \
MONGOC_ERROR_STREAM_NAME_RESOLUTION, \
_msg, \
__VA_ARGS__); \
GOTO (done); \
} while (0)
#ifdef MONGOC_HAVE_DNSAPI
typedef bool (*mongoc_rr_callback_t) (const char *hostname,
PDNS_RECORD pdns,
mongoc_rr_data_t *rr_data,
bson_error_t *error);
static bool
srv_callback (const char *hostname,
PDNS_RECORD pdns,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
mongoc_host_list_t new_host;
if (rr_data && rr_data->hosts) {
_mongoc_host_list_remove_host (
&(rr_data->hosts), pdns->Data.SRV.pNameTarget, pdns->Data.SRV.wPort);
}
if (!_mongoc_host_list_from_hostport_with_err (
&new_host, pdns->Data.SRV.pNameTarget, pdns->Data.SRV.wPort, error)) {
return false;
}
_mongoc_host_list_upsert (&rr_data->hosts, &new_host);
return true;
}
/* rr_data is unused, but here to match srv_callback signature */
static bool
txt_callback (const char *hostname,
PDNS_RECORD pdns,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
DWORD i;
bson_string_t *txt;
txt = bson_string_new (NULL);
for (i = 0; i < pdns->Data.TXT.dwStringCount; i++) {
bson_string_append (txt, pdns->Data.TXT.pStringArray[i]);
}
rr_data->txt_record_opts = bson_strdup (txt->str);
bson_string_free (txt, true);
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_get_rr_dnsapi --
*
* Fetch SRV or TXT resource records using the Windows DNS API and
* put results in @rr_data.
*
* Returns:
* Success or failure.
*
* For an SRV lookup, returns false if there is any error.
*
* For TXT lookup, ignores any error fetching the resource record and
* always returns true.
*
* Side effects:
* @error is set if there is a failure.
* @rr_data->hosts may be set if querying SRV. Caller must destroy.
* @rr_data->txt_record_opts may be set if querying TXT. Caller must
* free.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_get_rr_dnsapi (const char *hostname,
mongoc_rr_type_t rr_type,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
const char *rr_type_name;
WORD nst;
mongoc_rr_callback_t callback;
PDNS_RECORD pdns = NULL;
DNS_STATUS res;
LPVOID lpMsgBuf = NULL;
bool dns_success;
bool callback_success = true;
int i;
ENTRY;
if (rr_type == MONGOC_RR_SRV) {
/* return true only if DNS succeeds */
dns_success = false;
rr_type_name = "SRV";
nst = DNS_TYPE_SRV;
callback = srv_callback;
} else {
/* return true whether or not DNS succeeds */
dns_success = true;
rr_type_name = "TXT";
nst = DNS_TYPE_TEXT;
callback = txt_callback;
}
res = DnsQuery_UTF8 (hostname,
nst,
DNS_QUERY_BYPASS_CACHE,
NULL /* IP Address */,
&pdns,
0 /* reserved */);
if (res) {
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
if (FormatMessage (flags,
0,
res,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
0)) {
DNS_ERROR ("Failed to look up %s record \"%s\": %s",
rr_type_name,
hostname,
(char *) lpMsgBuf);
}
DNS_ERROR ("Failed to look up %s record \"%s\": Unknown error",
rr_type_name,
hostname);
}
if (!pdns) {
DNS_ERROR ("No %s records for \"%s\"", rr_type_name, hostname);
}
i = 0;
do {
/* DnsQuery can return additional records not of the requested type */
if ((rr_type == MONGOC_RR_TXT && pdns->wType == DNS_TYPE_TEXT) ||
(rr_type == MONGOC_RR_SRV && pdns->wType == DNS_TYPE_SRV)) {
if (i > 0 && rr_type == MONGOC_RR_TXT) {
/* Initial DNS Seedlist Discovery Spec: a client "MUST raise an
error when multiple TXT records are encountered". */
callback_success = false;
DNS_ERROR ("Multiple TXT records for \"%s\"", hostname);
}
if (rr_data) {
if ((i == 0) || (pdns->dwTtl < rr_data->min_ttl)) {
rr_data->min_ttl = pdns->dwTtl;
}
}
if (!callback (hostname, pdns, rr_data, error)) {
callback_success = false;
GOTO (done);
}
i++;
}
pdns = pdns->pNext;
} while (pdns);
rr_data->count = i;
if (i == 0) {
DNS_ERROR ("No matching %s records for \"%s\"", rr_type_name, hostname);
}
dns_success = true;
done:
if (pdns) {
DnsRecordListFree (pdns, DnsFreeRecordList);
}
if (lpMsgBuf) {
LocalFree (lpMsgBuf);
}
RETURN (dns_success && callback_success);
}
#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH))
typedef bool (*mongoc_rr_callback_t) (const char *hostname,
ns_msg *ns_answer,
ns_rr *rr,
mongoc_rr_data_t *rr_data,
bson_error_t *error);
static const char *
_mongoc_hstrerror (int code)
{
switch (code) {
case HOST_NOT_FOUND:
return "The specified host is unknown.";
case NO_ADDRESS:
return "The requested name is valid but does not have an IP address.";
case NO_RECOVERY:
return "A nonrecoverable name server error occurred.";
case TRY_AGAIN:
return "A temporary error occurred on an authoritative name server. Try "
"again later.";
default:
return "An unknown error occurred.";
}
}
static bool
srv_callback (const char *hostname,
ns_msg *ns_answer,
ns_rr *rr,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
const uint8_t *data;
char name[1024];
uint16_t port;
int size;
bool ret = false;
mongoc_host_list_t new_host;
data = ns_rr_rdata (*rr);
/* memcpy the network endian port before converting to host endian. we cannot
* cast (data + 4) directly as a uint16_t*, because it may not align on an
* 2-byte boundary. */
memcpy (&port, data + 4, sizeof (port));
port = ntohs (port);
size = dn_expand (ns_msg_base (*ns_answer),
ns_msg_end (*ns_answer),
data + 6,
name,
sizeof (name));
if (size < 1) {
DNS_ERROR ("Invalid record in SRV answer for \"%s\": \"%s\"",
hostname,
_mongoc_hstrerror (h_errno));
}
if (!_mongoc_host_list_from_hostport_with_err (
&new_host, name, port, error)) {
GOTO (done);
}
_mongoc_host_list_upsert (&rr_data->hosts, &new_host);
ret = true;
done:
return ret;
}
static bool
txt_callback (const char *hostname,
ns_msg *ns_answer,
ns_rr *rr,
mongoc_rr_data_t *rr_data,
bson_error_t *error)
{
char s[256];
const uint8_t *data;
bson_string_t *txt;
uint16_t pos, total;
uint8_t len;
bool ret = false;
total = (uint16_t) ns_rr_rdlen (*rr);
if (total < 1 || total > 255) {
DNS_ERROR ("Invalid TXT record size %hu for \"%s\"", total, hostname);
}
/* a TXT record has one or more strings, each up to 255 chars, each is
* prefixed by its length as 1 byte. thus endianness doesn't matter. */
txt = bson_string_new (NULL);
pos = 0;
data = ns_rr_rdata (*rr);
while (pos < total) {
memcpy (&len, data + pos, sizeof (uint8_t));
pos++;
bson_strncpy (s, (const char *) (data + pos), (size_t) len + 1);
bson_string_append (txt, s);
pos += len;
}
rr_data->txt_record_opts = bson_strdup (txt->str);
bson_string_free (txt, true);
ret = true;
done:
return ret;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_get_rr_search --
*
* Fetch SRV or TXT resource records using libresolv and put results in
* @rr_data.
*
* Returns:
* Success or failure.
*
* For an SRV lookup, returns false if there is any error.
*
* For TXT lookup, ignores any error fetching the resource record and
* always returns true.
*
* Side effects:
* @error is set if there is a failure.
* @rr_data->hosts may be set if querying SRV. Caller must destroy.
* @rr_data->txt_record_opts may be set if querying TXT. Caller must
* free.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_get_rr_search (const char *hostname,
mongoc_rr_type_t rr_type,
mongoc_rr_data_t *rr_data,
size_t initial_buffer_size,
bson_error_t *error)
{
#ifdef MONGOC_HAVE_RES_NSEARCH
struct __res_state state = {0};
#endif
int size = 0;
unsigned char *search_buf = NULL;
size_t buffer_size = initial_buffer_size;
ns_msg ns_answer;
int n;
int i;
const char *rr_type_name;
ns_type nst;
mongoc_rr_callback_t callback;
ns_rr resource_record;
bool dns_success;
bool callback_success = true;
int num_matching_records;
uint32_t ttl;
ENTRY;
if (rr_type == MONGOC_RR_SRV) {
/* return true only if DNS succeeds */
dns_success = false;
rr_type_name = "SRV";
nst = ns_t_srv;
callback = srv_callback;
} else {
/* return true whether or not DNS succeeds */
dns_success = true;
rr_type_name = "TXT";
nst = ns_t_txt;
callback = txt_callback;
}
do {
if (search_buf) {
bson_free (search_buf);
/* increase buffer size by the previous response size. This ensures
* that even if a subsequent response is larger, we'll still be able
* to fit it in the response buffer */
buffer_size = buffer_size + size;
}
search_buf = (unsigned char *) bson_malloc (buffer_size);
BSON_ASSERT (search_buf);
#ifdef MONGOC_HAVE_RES_NSEARCH
/* thread-safe */
res_ninit (&state);
size =
res_nsearch (&state, hostname, ns_c_in, nst, search_buf, buffer_size);
#elif defined(MONGOC_HAVE_RES_SEARCH)
size = res_search (hostname, ns_c_in, nst, search_buf, buffer_size);
#endif
if (size < 0) {
DNS_ERROR ("Failed to look up %s record \"%s\": %s",
rr_type_name,
hostname,
_mongoc_hstrerror (h_errno));
}
} while (size >= buffer_size);
if (ns_initparse (search_buf, size, &ns_answer)) {
DNS_ERROR ("Invalid %s answer for \"%s\"", rr_type_name, hostname);
}
n = ns_msg_count (ns_answer, ns_s_an);
if (!n) {
DNS_ERROR ("No %s records for \"%s\"", rr_type_name, hostname);
}
rr_data->count = n;
num_matching_records = 0;
for (i = 0; i < n; i++) {
if (ns_parserr (&ns_answer, ns_s_an, i, &resource_record)) {
DNS_ERROR ("Invalid record %d of %s answer for \"%s\": \"%s\"",
i,
rr_type_name,
hostname,
_mongoc_hstrerror (h_errno));
}
/* Skip records that don't match the ones we requested. CDRIVER-3628 shows
* that we can receive records that were not requested. */
if (rr_type == MONGOC_RR_TXT) {
if (ns_rr_type (resource_record) != ns_t_txt) {
continue;
}
} else if (rr_type == MONGOC_RR_SRV) {
if (ns_rr_type (resource_record) != ns_t_srv) {
continue;
}
}
if (num_matching_records > 0 && rr_type == MONGOC_RR_TXT) {
/* Initial DNS Seedlist Discovery Spec: a client "MUST raise an error
* when multiple TXT records are encountered". */
callback_success = false;
DNS_ERROR ("Multiple TXT records for \"%s\"", hostname);
}
num_matching_records++;
ttl = ns_rr_ttl (resource_record);
if ((i == 0) || (ttl < rr_data->min_ttl)) {
rr_data->min_ttl = ttl;
}
if (!callback (hostname, &ns_answer, &resource_record, rr_data, error)) {
callback_success = false;
GOTO (done);
}
}
if (num_matching_records == 0) {
DNS_ERROR ("No matching %s records for \"%s\"", rr_type_name, hostname);
}
dns_success = true;
done:
bson_free (search_buf);
#ifdef MONGOC_HAVE_RES_NDESTROY
/* defined on BSD/Darwin, and only if MONGOC_HAVE_RES_NSEARCH is defined */
res_ndestroy (&state);
#elif defined(MONGOC_HAVE_RES_NCLOSE)
/* defined on Linux, and only if MONGOC_HAVE_RES_NSEARCH is defined */
res_nclose (&state);
#endif
RETURN (dns_success && callback_success);
}
#endif
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_get_rr --
*
* Fetch an SRV or TXT resource record and update put results in
* @rr_data.
*
* See RFCs 1464 and 2782, MongoDB's "Initial DNS Seedlist Discovery"
* spec, and MongoDB's "Polling SRV Records for Mongos Discovery"
* spec.
*
* Returns:
* Success or failure.
*
* Side effects:
* @error is set if there is a failure. Errors fetching TXT are
* ignored.
* @rr_data->hosts may be set if querying SRV. Caller must destroy.
* @rr_data->txt_record_opts may be set if querying TXT. Caller must
* free.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_get_rr (const char *hostname,
mongoc_rr_type_t rr_type,
mongoc_rr_data_t *rr_data,
size_t initial_buffer_size,
bson_error_t *error)
{
BSON_ASSERT (rr_data);
#ifdef MONGOC_HAVE_DNSAPI
return _mongoc_get_rr_dnsapi (hostname, rr_type, rr_data, error);
#elif (defined(MONGOC_HAVE_RES_NSEARCH) || defined(MONGOC_HAVE_RES_SEARCH))
return _mongoc_get_rr_search (
hostname, rr_type, rr_data, initial_buffer_size, error);
#else
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"libresolv unavailable, cannot use mongodb+srv URI");
return false;
#endif
}
#undef DNS_ERROR
/*
*--------------------------------------------------------------------------
*
* mongoc_client_connect_tcp --
*
* Connect to a host using a TCP socket.
*
* This will be performed synchronously and return a mongoc_stream_t
* that can be used to connect with the remote host.
*
* Returns:
* A newly allocated mongoc_stream_t if successful; otherwise
* NULL and @error is set.
*
* Side effects:
* @error is set if return value is NULL.
*
*--------------------------------------------------------------------------
*/
mongoc_stream_t *
mongoc_client_connect_tcp (int32_t connecttimeoutms,
const mongoc_host_list_t *host,
bson_error_t *error)
{
mongoc_socket_t *sock = NULL;
struct addrinfo hints;
struct addrinfo *result, *rp;
int64_t expire_at;
char portstr[8];
int s;
ENTRY;
BSON_ASSERT (connecttimeoutms);
BSON_ASSERT (host);
bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
memset (&hints, 0, sizeof hints);
hints.ai_family = host->family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
TRACE ("DNS lookup for %s", host->host);
s = getaddrinfo (host->host, portstr, &hints, &result);
if (s != 0) {
mongoc_counter_dns_failure_inc ();
TRACE ("Failed to resolve %s", host->host);
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"Failed to resolve %s",
host->host);
RETURN (NULL);
}
mongoc_counter_dns_success_inc ();
for (rp = result; rp; rp = rp->ai_next) {
/*
* Create a new non-blocking socket.
*/
if (!(sock = mongoc_socket_new (
rp->ai_family, rp->ai_socktype, rp->ai_protocol))) {
continue;
}
/*
* Try to connect to the peer.
*/
expire_at = bson_get_monotonic_time () + (connecttimeoutms * 1000L);
if (0 !=
mongoc_socket_connect (
sock, rp->ai_addr, (mongoc_socklen_t) rp->ai_addrlen, expire_at)) {
mongoc_socket_destroy (sock);
sock = NULL;
continue;
}
break;
}
if (!sock) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"Failed to connect to target host: %s",
host->host_and_port);
freeaddrinfo (result);
RETURN (NULL);
}
freeaddrinfo (result);
return mongoc_stream_socket_new (sock);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_connect_unix --
*
* Connect to a MongoDB server using a UNIX domain socket.
*
* Returns:
* A newly allocated mongoc_stream_t if successful; otherwise
* NULL and @error is set.
*
* Side effects:
* @error is set if return value is NULL.
*
*--------------------------------------------------------------------------
*/
static mongoc_stream_t *
mongoc_client_connect_unix (const mongoc_host_list_t *host, bson_error_t *error)
{
#ifdef _WIN32
ENTRY;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"UNIX domain sockets not supported on win32.");
RETURN (NULL);
#else
struct sockaddr_un saddr;
mongoc_socket_t *sock;
mongoc_stream_t *ret = NULL;
ENTRY;
BSON_ASSERT (host);
memset (&saddr, 0, sizeof saddr);
saddr.sun_family = AF_UNIX;
bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0);
if (sock == NULL) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to create socket.");
RETURN (NULL);
}
if (-1 == mongoc_socket_connect (
sock, (struct sockaddr *) &saddr, sizeof saddr, -1)) {
mongoc_socket_destroy (sock);
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"Failed to connect to UNIX domain socket.");
RETURN (NULL);
}
ret = mongoc_stream_socket_new (sock);
RETURN (ret);
#endif
}
mongoc_stream_t *
mongoc_client_connect (bool buffered,
bool use_ssl,
void *ssl_opts_void,
const mongoc_uri_t *uri,
const mongoc_host_list_t *host,
bson_error_t *error)
{
mongoc_stream_t *base_stream = NULL;
int32_t connecttimeoutms;
BSON_ASSERT (uri);
BSON_ASSERT (host);
#ifndef MONGOC_ENABLE_SSL
if (ssl_opts_void || mongoc_uri_get_tls (uri)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER,
"TLS is not enabled in this build of mongo-c-driver.");
return NULL;
}
#endif
connecttimeoutms = mongoc_uri_get_option_as_int32 (
uri, MONGOC_URI_CONNECTTIMEOUTMS, MONGOC_DEFAULT_CONNECTTIMEOUTMS);
switch (host->family) {
case AF_UNSPEC:
#if defined(AF_INET6)
case AF_INET6:
#endif
case AF_INET:
base_stream = mongoc_client_connect_tcp (connecttimeoutms, host, error);
break;
case AF_UNIX:
base_stream = mongoc_client_connect_unix (host, error);
break;
default:
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_INVALID_TYPE,
"Invalid address family: 0x%02x",
host->family);
break;
}
#ifdef MONGOC_ENABLE_SSL
if (base_stream) {
mongoc_ssl_opt_t *ssl_opts;
const char *mechanism;
ssl_opts = (mongoc_ssl_opt_t *) ssl_opts_void;
mechanism = mongoc_uri_get_auth_mechanism (uri);
if (use_ssl || (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) {
mongoc_stream_t *original = base_stream;
base_stream = mongoc_stream_tls_new_with_hostname (
base_stream, host->host, ssl_opts, true);
if (!base_stream) {
mongoc_stream_destroy (original);
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed initialize TLS state.");
return NULL;
}
if (!mongoc_stream_tls_handshake_block (
base_stream, host->host, connecttimeoutms, error)) {
mongoc_stream_destroy (base_stream);
return NULL;
}
}
}
#endif
if (!base_stream) {
return NULL;
}
if (buffered) {
return mongoc_stream_buffered_new (base_stream, 1024);
}
return base_stream;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_default_stream_initiator --
*
* A mongoc_stream_initiator_t that will handle the various type
* of supported sockets by MongoDB including TCP and UNIX.
*
* Language binding authors may want to implement an alternate
* version of this method to use their native stream format.
*
* Returns:
* A mongoc_stream_t if successful; otherwise NULL and @error is set.
*
* Side effects:
* @error is set if return value is NULL.
*
*--------------------------------------------------------------------------
*/
mongoc_stream_t *
mongoc_client_default_stream_initiator (const mongoc_uri_t *uri,
const mongoc_host_list_t *host,
void *user_data,
bson_error_t *error)
{
void *ssl_opts_void = NULL;
bool use_ssl = false;
#ifdef MONGOC_ENABLE_SSL
mongoc_client_t *client = (mongoc_client_t *) user_data;
use_ssl = client->use_ssl;
ssl_opts_void = (void *) &client->ssl_opts;
#endif
return mongoc_client_connect (
true, use_ssl, ssl_opts_void, uri, host, error);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_create_stream --
*
* INTERNAL API
*
* This function is used by the mongoc_cluster_t to initiate a
* new stream. This is done because cluster is private API and
* those using mongoc_client_t may need to override this process.
*
* This function calls the default initiator for new streams.
*
* Returns:
* A newly allocated mongoc_stream_t if successful; otherwise
* NULL and @error is set.
*
* Side effects:
* @error is set if return value is NULL.
*
*--------------------------------------------------------------------------
*/
mongoc_stream_t *
_mongoc_client_create_stream (mongoc_client_t *client,
const mongoc_host_list_t *host,
bson_error_t *error)
{
BSON_ASSERT (client);
BSON_ASSERT (host);
return client->initiator (client->uri, host, client->initiator_data, error);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_recv --
*
* Receives a RPC from a remote MongoDB cluster node.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is set if return value is false.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_recv (mongoc_client_t *client,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
BSON_ASSERT (client);
BSON_ASSERT (rpc);
BSON_ASSERT (buffer);
BSON_ASSERT (server_stream);
return mongoc_cluster_try_recv (
&client->cluster, rpc, buffer, server_stream, error);
}
mongoc_client_t *
mongoc_client_new (const char *uri_string)
{
mongoc_client_t *client;
mongoc_uri_t *uri;
bson_error_t error = {0};
if (!uri_string) {
uri_string = "mongodb://127.0.0.1/";
}
if (!(uri = mongoc_uri_new_with_error (uri_string, &error))) {
/* Log URI errors as a warning for consistency with mongoc_uri_new */
MONGOC_WARNING ("Error parsing URI: '%s'", error.message);
return NULL;
}
if (!(client = mongoc_client_new_from_uri_with_error (uri, &error))) {
MONGOC_ERROR ("%s", error.message);
}
mongoc_uri_destroy (uri);
return client;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_ssl_opts
*
* set ssl opts for a client
*
* Returns:
* Nothing
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
#ifdef MONGOC_ENABLE_SSL
/* Only called internally. Caller must ensure opts->internal is valid. */
void
_mongoc_client_set_internal_tls_opts (mongoc_client_t *client,
_mongoc_internal_tls_opts_t *internal)
{
if (!client->use_ssl) {
return;
}
client->ssl_opts.internal =
bson_malloc (sizeof (_mongoc_internal_tls_opts_t));
memcpy (client->ssl_opts.internal,
internal,
sizeof (_mongoc_internal_tls_opts_t));
}
void
mongoc_client_set_ssl_opts (mongoc_client_t *client,
const mongoc_ssl_opt_t *opts)
{
BSON_ASSERT (client);
BSON_ASSERT (opts);
_mongoc_ssl_opts_cleanup (&client->ssl_opts,
false /* don't free internal opts */);
client->use_ssl = true;
_mongoc_ssl_opts_copy_to (
opts, &client->ssl_opts, false /* don't overwrite internal opts */);
if (client->topology->single_threaded) {
mongoc_topology_scanner_set_ssl_opts (client->topology->scanner,
&client->ssl_opts);
}
}
#endif
mongoc_client_t *
mongoc_client_new_from_uri (const mongoc_uri_t *uri)
{
mongoc_client_t *client;
bson_error_t error = {0};
if (!(client = mongoc_client_new_from_uri_with_error (uri, &error))) {
MONGOC_ERROR ("%s", error.message);
}
return client;
}
mongoc_client_t *
mongoc_client_new_from_uri_with_error (const mongoc_uri_t *uri,
bson_error_t *error)
{
mongoc_client_t *client;
mongoc_topology_t *topology;
ENTRY;
BSON_ASSERT (uri);
#ifndef MONGOC_ENABLE_SSL
if (mongoc_uri_get_tls (uri)) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Can't create SSL client, SSL not enabled in this build.");
RETURN (NULL);
}
#endif
topology = mongoc_topology_new (uri, true);
if (!topology->valid) {
if (error) {
memcpy (error, &topology->scanner->error, sizeof (bson_error_t));
}
mongoc_topology_destroy (topology);
RETURN (NULL);
}
client = _mongoc_client_new_from_topology (topology);
BSON_ASSERT (client);
RETURN (client);
}
/* precondition: topology is valid */
mongoc_client_t *
_mongoc_client_new_from_topology (mongoc_topology_t *topology)
{
mongoc_client_t *client;
const mongoc_read_prefs_t *read_prefs;
const mongoc_read_concern_t *read_concern;
const mongoc_write_concern_t *write_concern;
const char *appname;
BSON_ASSERT (topology);
BSON_ASSERT (topology->valid);
client = (mongoc_client_t *) bson_malloc0 (sizeof *client);
client->uri = mongoc_uri_copy (topology->uri);
client->initiator = mongoc_client_default_stream_initiator;
client->initiator_data = client;
client->topology = topology;
client->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY;
client->error_api_set = false;
client->client_sessions = mongoc_set_new (8, NULL, NULL);
client->csid_rand_seed = (unsigned int) bson_get_monotonic_time ();
write_concern = mongoc_uri_get_write_concern (client->uri);
client->write_concern = mongoc_write_concern_copy (write_concern);
read_concern = mongoc_uri_get_read_concern (client->uri);
client->read_concern = mongoc_read_concern_copy (read_concern);
read_prefs = mongoc_uri_get_read_prefs_t (client->uri);
client->read_prefs = mongoc_read_prefs_copy (read_prefs);
appname =
mongoc_uri_get_option_as_utf8 (client->uri, MONGOC_URI_APPNAME, NULL);
if (appname && client->topology->single_threaded) {
/* the appname should have already been validated */
BSON_ASSERT (mongoc_client_set_appname (client, appname));
}
mongoc_cluster_init (&client->cluster, client->uri, client);
#ifdef MONGOC_ENABLE_SSL
client->use_ssl = false;
if (mongoc_uri_get_tls (client->uri)) {
mongoc_ssl_opt_t ssl_opt = {0};
_mongoc_internal_tls_opts_t internal_tls_opts = {0};
_mongoc_ssl_opts_from_uri (&ssl_opt, &internal_tls_opts, client->uri);
/* sets use_ssl = true */
mongoc_client_set_ssl_opts (client, &ssl_opt);
_mongoc_client_set_internal_tls_opts (client, &internal_tls_opts);
}
#endif
mongoc_counter_clients_active_inc ();
return client;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_destroy --
*
* Destroys a mongoc_client_t and cleans up all resources associated
* with the client instance.
*
* Returns:
* None.
*
* Side effects:
* @client is destroyed.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_destroy (mongoc_client_t *client)
{
if (client) {
if (client->topology->single_threaded) {
_mongoc_client_end_sessions (client);
mongoc_topology_destroy (client->topology);
}
mongoc_write_concern_destroy (client->write_concern);
mongoc_read_concern_destroy (client->read_concern);
mongoc_read_prefs_destroy (client->read_prefs);
mongoc_cluster_destroy (&client->cluster);
mongoc_uri_destroy (client->uri);
mongoc_set_destroy (client->client_sessions);
mongoc_server_api_destroy (client->api);
#ifdef MONGOC_ENABLE_SSL
_mongoc_ssl_opts_cleanup (&client->ssl_opts, true);
#endif
bson_free (client);
mongoc_counter_clients_active_dec ();
mongoc_counter_clients_disposed_inc ();
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_uri --
*
* Fetch the URI used for @client.
*
* Returns:
* A mongoc_uri_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_uri_t *
mongoc_client_get_uri (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->uri;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_start_session --
*
* Creates a structure to communicate in a session over @client.
*
* This structure should be freed when the caller is done with it
* using mongoc_client_session_destroy().
*
* Returns:
* A newly allocated mongoc_client_session_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_client_session_t *
mongoc_client_start_session (mongoc_client_t *client,
const mongoc_session_opt_t *opts,
bson_error_t *error)
{
mongoc_server_session_t *ss;
mongoc_client_session_t *cs;
uint32_t csid;
ENTRY;
ss = _mongoc_client_pop_server_session (client, error);
if (!ss) {
RETURN (NULL);
}
/* get a random internal id for the session, retrying on collision */
do {
csid = (uint32_t) _mongoc_rand_simple (&client->csid_rand_seed);
} while (mongoc_set_get (client->client_sessions, csid));
/* causal consistency and snapshot cannot both be set. */
if (opts && mongoc_session_opts_get_causal_consistency (opts) &&
mongoc_session_opts_get_snapshot (opts)) {
bson_set_error (
error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_SESSION_FAILURE,
"Only one of causal consistency and snapshot can be enabled.");
_mongoc_client_push_server_session (client, ss);
RETURN (NULL);
}
cs = _mongoc_client_session_new (client, ss, opts, csid);
/* remember session so if we see its client_session_id in a command, we can
* find its lsid and clusterTime */
mongoc_set_add (client->client_sessions, csid, cs);
RETURN (cs);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_database --
*
* Fetches a newly allocated database structure to communicate with
* a database over @client.
*
* @database should be a db name such as "test".
*
* This structure should be freed when the caller is done with it
* using mongoc_database_destroy().
*
* Returns:
* A newly allocated mongoc_database_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
mongoc_client_get_database (mongoc_client_t *client, const char *name)
{
BSON_ASSERT (client);
BSON_ASSERT (name);
return _mongoc_database_new (client,
name,
client->read_prefs,
client->read_concern,
client->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_default_database --
*
* Get the database named in the MongoDB connection URI, or NULL
* if none was specified in the URI.
*
* This structure should be freed when the caller is done with it
* using mongoc_database_destroy().
*
* Returns:
* A newly allocated mongoc_database_t or NULL.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
mongoc_client_get_default_database (mongoc_client_t *client)
{
const char *db;
BSON_ASSERT (client);
db = mongoc_uri_get_database (client->uri);
if (db) {
return mongoc_client_get_database (client, db);
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_collection --
*
* This function returns a newly allocated collection structure.
*
* @db should be the name of the database, such as "test".
* @collection should be the name of the collection such as "test".
*
* The above would result in the namespace "test.test".
*
* You should free this structure when you are done with it using
* mongoc_collection_destroy().
*
* Returns:
* A newly allocated mongoc_collection_t that should be freed with
* mongoc_collection_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_collection_t *
mongoc_client_get_collection (mongoc_client_t *client,
const char *db,
const char *collection)
{
BSON_ASSERT (client);
BSON_ASSERT (db);
BSON_ASSERT (collection);
return _mongoc_collection_new (client,
db,
collection,
client->read_prefs,
client->read_concern,
client->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_gridfs --
*
* This function returns a newly allocated collection structure.
*
* @db should be the name of the database, such as "test".
*
* @prefix optional prefix for GridFS collection names, or NULL. Default
* is "fs", thus the default collection names for GridFS are "fs.files"
* and "fs.chunks".
*
* Returns:
* A newly allocated mongoc_gridfs_t that should be freed with
* mongoc_gridfs_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_gridfs_t *
mongoc_client_get_gridfs (mongoc_client_t *client,
const char *db,
const char *prefix,
bson_error_t *error)
{
BSON_ASSERT (client);
BSON_ASSERT (db);
if (!prefix) {
prefix = "fs";
}
return _mongoc_gridfs_new (client, db, prefix, error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_write_concern --
*
* Fetches the default write concern for @client.
*
* Returns:
* A mongoc_write_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_write_concern_t *
mongoc_client_get_write_concern (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->write_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_write_concern --
*
* Sets the default write concern for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_set_write_concern (mongoc_client_t *client,
const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT (client);
if (write_concern != client->write_concern) {
if (client->write_concern) {
mongoc_write_concern_destroy (client->write_concern);
}
client->write_concern = write_concern
? mongoc_write_concern_copy (write_concern)
: mongoc_write_concern_new ();
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_read_concern --
*
* Fetches the default read concern for @client.
*
* Returns:
* A mongoc_read_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_concern_t *
mongoc_client_get_read_concern (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->read_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_read_concern --
*
* Sets the default read concern for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_set_read_concern (mongoc_client_t *client,
const mongoc_read_concern_t *read_concern)
{
BSON_ASSERT (client);
if (read_concern != client->read_concern) {
if (client->read_concern) {
mongoc_read_concern_destroy (client->read_concern);
}
client->read_concern = read_concern
? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_get_read_prefs --
*
* Fetch the default read preferences for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_prefs_t *
mongoc_client_get_read_prefs (const mongoc_client_t *client)
{
BSON_ASSERT (client);
return client->read_prefs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_set_read_prefs --
*
* Set the default read preferences for @client.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_set_read_prefs (mongoc_client_t *client,
const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT (client);
if (read_prefs != client->read_prefs) {
if (client->read_prefs) {
mongoc_read_prefs_destroy (client->read_prefs);
}
client->read_prefs = read_prefs
? mongoc_read_prefs_copy (read_prefs)
: mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
}
}
mongoc_cursor_t *
mongoc_client_command (mongoc_client_t *client,
const char *db_name,
mongoc_query_flags_t flags,
uint32_t skip,
uint32_t limit,
uint32_t batch_size,
const bson_t *query,
const bson_t *fields,
const mongoc_read_prefs_t *read_prefs)
{
char *ns = NULL;
mongoc_cursor_t *cursor;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (query);
/*
* Allow a caller to provide a fully qualified namespace
*/
if (NULL == strstr (db_name, "$cmd")) {
ns = bson_strdup_printf ("%s.$cmd", db_name);
db_name = ns;
}
cursor =
_mongoc_cursor_cmd_deprecated_new (client, db_name, query, read_prefs);
bson_free (ns);
return cursor;
}
static bool
_mongoc_client_retryable_write_command_with_stream (
mongoc_client_t *client,
mongoc_cmd_parts_t *parts,
mongoc_server_stream_t *server_stream,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *retry_server_stream = NULL;
bson_iter_t txn_number_iter;
bool is_retryable = true;
bool ret;
ENTRY;
BSON_ASSERT (parts->is_retryable_write);
/* increment the transaction number for the first attempt of each retryable
* write command */
BSON_ASSERT (bson_iter_init_find (
&txn_number_iter, parts->assembled.command, "txnNumber"));
bson_iter_overwrite_int64 (
&txn_number_iter, ++parts->assembled.session->server_session->txn_number);
retry:
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts->assembled, reply, error);
_mongoc_write_error_handle_labels (
ret, error, reply, server_stream->sd->max_wire_version);
if (is_retryable) {
_mongoc_write_error_update_if_unsupported_storage_engine (
ret, error, reply);
}
/* If a retryable error is encountered and the write is retryable, select
* a new writable stream and retry. If server selection fails or the selected
* server does not support retryable writes, fall through and allow the
* original error to be reported. */
if (is_retryable &&
_mongoc_write_error_get_type (reply) == MONGOC_WRITE_ERR_RETRY) {
bson_error_t ignored_error;
/* each write command may be retried at most once */
is_retryable = false;
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
retry_server_stream = mongoc_cluster_stream_for_writes (
&client->cluster, parts->assembled.session, NULL, &ignored_error);
if (retry_server_stream && retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_WRITES) {
parts->assembled.server_stream = retry_server_stream;
bson_destroy (reply);
GOTO (retry);
}
}
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
if (ret && error) {
/* if a retry succeeded, clear the initial error */
memset (error, 0, sizeof (bson_error_t));
}
RETURN (ret);
}
static bool
_mongoc_client_retryable_read_command_with_stream (
mongoc_client_t *client,
mongoc_cmd_parts_t *parts,
mongoc_server_stream_t *server_stream,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *retry_server_stream = NULL;
bool is_retryable = true;
bool ret;
bson_t reply_local;
if (reply == NULL) {
reply = &reply_local;
}
ENTRY;
BSON_ASSERT (parts->is_retryable_read);
retry:
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts->assembled, reply, error);
/* If a retryable error is encountered and the read is retryable, select
* a new readable stream and retry. If server selection fails or the selected
* server does not support retryable reads, fall through and allow the
* original error to be reported. */
if (is_retryable && _mongoc_read_error_get_type (ret, error, reply) ==
MONGOC_READ_ERR_RETRY) {
bson_error_t ignored_error;
/* each read command may be retried at most once */
is_retryable = false;
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
retry_server_stream =
mongoc_cluster_stream_for_reads (&client->cluster,
parts->read_prefs,
parts->assembled.session,
NULL,
/* Not aggregate-with-write */ false,
&ignored_error);
if (retry_server_stream && retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_READS) {
parts->assembled.server_stream = retry_server_stream;
bson_destroy (reply);
GOTO (retry);
}
}
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
if (ret && error) {
/* if a retry succeeded, clear the initial error */
memset (error, 0, sizeof (bson_error_t));
}
RETURN (ret);
}
static bool
_mongoc_client_command_with_stream (mongoc_client_t *client,
mongoc_cmd_parts_t *parts,
const mongoc_read_prefs_t *read_prefs,
mongoc_server_stream_t *server_stream,
bson_t *reply,
bson_error_t *error)
{
ENTRY;
parts->assembled.operation_id = ++client->cluster.operation_id;
if (!mongoc_cmd_parts_assemble (parts, server_stream, error)) {
_mongoc_bson_init_if_set (reply);
return false;
};
if (parts->is_retryable_write) {
RETURN (_mongoc_client_retryable_write_command_with_stream (
client, parts, server_stream, reply, error));
}
if (parts->is_retryable_read) {
RETURN (_mongoc_client_retryable_read_command_with_stream (
client, parts, server_stream, reply, error));
}
RETURN (mongoc_cluster_run_command_monitored (
&client->cluster, &parts->assembled, reply, error));
}
bool
mongoc_client_command_simple (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
mongoc_cluster_t *cluster;
mongoc_server_stream_t *server_stream = NULL;
mongoc_cmd_parts_t parts;
bool ret;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (command);
if (!_mongoc_read_prefs_validate (read_prefs, error)) {
RETURN (false);
}
cluster = &client->cluster;
mongoc_cmd_parts_init (&parts, client, db_name, MONGOC_QUERY_NONE, command);
parts.read_prefs = read_prefs;
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
server_stream =
mongoc_cluster_stream_for_reads (cluster,
read_prefs,
NULL,
reply,
/* Not aggregate-with-write */ false,
error);
if (server_stream) {
ret = _mongoc_client_command_with_stream (
client, &parts, read_prefs, server_stream, reply, error);
} else {
/* reply initialized by mongoc_cluster_stream_for_reads */
ret = false;
}
mongoc_cmd_parts_cleanup (&parts);
mongoc_server_stream_cleanup (server_stream);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_command_with_opts --
*
* Execute a command on the server. If mode is MONGOC_CMD_READ or
* MONGOC_CMD_RW, then read concern is applied from @opts, or else from
* @default_rc, and read preferences are applied from @user_prefs, or else
* from @default_prefs. If mode is MONGOC_CMD_WRITE or MONGOC_CMD_RW, then
* write concern is applied from @opts if present, or else @default_wc.
*
* If mode is MONGOC_CMD_RAW, then read concern and write concern are
* applied from @opts only. Read preferences are applied from
* @user_prefs.
*
* The mongoc_client_t's read preference, read concern, and write concern
* are *NOT* applied.
*
* Returns:
* Success or failure.
* A write concern timeout or write concern error is considered a failure.
*
* Side effects:
* @reply is always initialized.
* @error is filled out if the command fails.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
mongoc_command_mode_t mode,
const bson_t *opts,
mongoc_query_flags_t flags,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
mongoc_read_concern_t *default_rc,
mongoc_write_concern_t *default_wc,
bson_t *reply,
bson_error_t *error)
{
mongoc_read_write_opts_t read_write_opts;
mongoc_cmd_parts_t parts;
const char *command_name;
const mongoc_read_prefs_t *prefs = COALESCE (user_prefs, default_prefs);
mongoc_server_stream_t *server_stream = NULL;
mongoc_cluster_t *cluster;
mongoc_client_session_t *cs;
bson_t reply_local;
bson_t *reply_ptr;
int32_t wire_version;
int32_t wc_wire_version;
bool reply_initialized = false;
bool ret = false;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (command);
command_name = _mongoc_get_command_name (command);
cluster = &client->cluster;
reply_ptr = reply ? reply : &reply_local;
mongoc_cmd_parts_init (&parts, client, db_name, flags, command);
parts.is_read_command = (mode & MONGOC_CMD_READ);
parts.is_write_command = (mode & MONGOC_CMD_WRITE);
if (!_mongoc_read_write_opts_parse (client, opts, &read_write_opts, error)) {
GOTO (done);
}
cs = read_write_opts.client_session;
if (!command_name) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Empty command document");
GOTO (done);
}
if (_mongoc_client_session_in_txn (read_write_opts.client_session)) {
if ((mode == MONGOC_CMD_READ || mode == MONGOC_CMD_RAW) &&
!IS_PREF_PRIMARY (user_prefs)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Read preference in a transaction must be primary");
GOTO (done);
}
if (!bson_empty (&read_write_opts.readConcern)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set read concern after starting transaction");
GOTO (done);
}
if (read_write_opts.writeConcern &&
strcmp (command_name, "commitTransaction") != 0 &&
strcmp (command_name, "abortTransaction") != 0) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
GOTO (done);
}
}
if (mode == MONGOC_CMD_READ || mode == MONGOC_CMD_RAW) {
/* NULL read pref is ok */
if (!_mongoc_read_prefs_validate (prefs, error)) {
GOTO (done);
}
parts.read_prefs = prefs;
} else {
/* this is a command that writes */
prefs = NULL;
}
if (read_write_opts.serverId) {
/* "serverId" passed in opts */
server_stream =
mongoc_cluster_stream_for_server (cluster,
read_write_opts.serverId,
true /* reconnect ok */,
cs,
reply_ptr,
error);
if (server_stream && server_stream->sd->type != MONGOC_SERVER_MONGOS) {
parts.user_query_flags |= MONGOC_QUERY_SECONDARY_OK;
}
} else if (parts.is_write_command) {
server_stream =
mongoc_cluster_stream_for_writes (cluster, cs, reply_ptr, error);
} else {
server_stream =
mongoc_cluster_stream_for_reads (cluster,
prefs,
cs,
reply_ptr,
/* Not aggregate-with-write */ false,
error);
}
if (!server_stream) {
/* stream_for_reads/writes/server has initialized reply */
reply_initialized = true;
GOTO (done);
}
wire_version = server_stream->sd->max_wire_version;
if (!mongoc_cmd_parts_append_read_write (
&parts, &read_write_opts, wire_version, error)) {
GOTO (done);
}
if (mode & MONGOC_CMD_WRITE) {
wc_wire_version = !strcasecmp (command_name, "findandmodify")
? WIRE_VERSION_FAM_WRITE_CONCERN
: WIRE_VERSION_CMD_WRITE_CONCERN;
if (read_write_opts.write_concern_owned &&
wire_version < wc_wire_version) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"\"%s\" command does not support writeConcern with "
"wire version %d, wire version %d is required",
command_name,
wire_version,
wc_wire_version);
GOTO (done);
}
/* use default write concern unless it's in opts */
if (!mongoc_write_concern_is_default (default_wc) &&
!read_write_opts.write_concern_owned &&
wire_version >= wc_wire_version) {
if (!mongoc_cmd_parts_set_write_concern (
&parts, default_wc, wire_version, error)) {
GOTO (done);
}
}
}
/* use default read concern for read command, unless it's in opts */
if ((mode & MONGOC_CMD_READ) && bson_empty (&read_write_opts.readConcern)) {
if (!mongoc_cmd_parts_set_read_concern (
&parts, default_rc, wire_version, error)) {
GOTO (done);
}
}
ret = _mongoc_client_command_with_stream (
client, &parts, user_prefs, server_stream, reply_ptr, error);
reply_initialized = true;
if (ret && (mode & MONGOC_CMD_WRITE)) {
ret = !_mongoc_parse_wc_err (reply_ptr, error);
}
done:
if (reply_ptr == &reply_local) {
if (reply_initialized) {
bson_destroy (reply_ptr);
}
} else if (!reply_initialized) {
_mongoc_bson_init_if_set (reply);
}
if (server_stream) {
mongoc_server_stream_cleanup (server_stream);
}
mongoc_cmd_parts_cleanup (&parts);
_mongoc_read_write_opts_cleanup (&read_write_opts);
RETURN (ret);
}
bool
mongoc_client_read_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_READ,
opts,
MONGOC_QUERY_NONE,
read_prefs,
client->read_prefs,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_write_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL,
client->read_prefs,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_read_write_command_with_opts (
mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs /* IGNORED */,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_RW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
client->read_prefs,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_command_with_opts (mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (client,
db_name,
command,
MONGOC_CMD_RAW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
NULL,
client->read_concern,
client->write_concern,
reply,
error);
}
bool
mongoc_client_command_simple_with_server_id (
mongoc_client_t *client,
const char *db_name,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
uint32_t server_id,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *server_stream;
mongoc_cmd_parts_t parts;
bool ret;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (db_name);
BSON_ASSERT (command);
if (!_mongoc_read_prefs_validate (read_prefs, error)) {
RETURN (false);
}
server_stream = mongoc_cluster_stream_for_server (
&client->cluster, server_id, true /* reconnect ok */, NULL, reply, error);
if (server_stream) {
mongoc_cmd_parts_init (
&parts, client, db_name, MONGOC_QUERY_NONE, command);
parts.read_prefs = read_prefs;
ret = _mongoc_client_command_with_stream (
client, &parts, read_prefs, server_stream, reply, error);
mongoc_cmd_parts_cleanup (&parts);
mongoc_server_stream_cleanup (server_stream);
RETURN (ret);
} else {
/* stream_for_server initialized reply */
RETURN (false);
}
}
static void
_mongoc_client_prepare_killcursors_command (int64_t cursor_id,
const char *collection,
bson_t *command)
{
bson_t child;
bson_append_utf8 (command, "killCursors", 11, collection, -1);
bson_append_array_begin (command, "cursors", 7, &child);
bson_append_int64 (&child, "0", 1, cursor_id);
bson_append_array_end (command, &child);
}
void
_mongoc_client_kill_cursor (mongoc_client_t *client,
uint32_t server_id,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs)
{
mongoc_server_stream_t *server_stream;
ENTRY;
BSON_ASSERT (client);
BSON_ASSERT (cursor_id);
/* don't attempt reconnect if server unavailable, and ignore errors */
server_stream = mongoc_cluster_stream_for_server (
&client->cluster, server_id, false /* reconnect_ok */, NULL, NULL, NULL);
if (!server_stream) {
return;
}
if (db && collection &&
server_stream->sd->max_wire_version >= WIRE_VERSION_KILLCURSORS_CMD) {
_mongoc_client_killcursors_command (
&client->cluster, server_stream, cursor_id, db, collection, cs);
} else {
_mongoc_client_op_killcursors (&client->cluster,
server_stream,
cursor_id,
operation_id,
db,
collection);
}
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
static void
_mongoc_client_monitor_op_killcursors (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection)
{
bson_t doc;
mongoc_client_t *client;
mongoc_apm_command_started_t event;
ENTRY;
client = cluster->client;
if (!client->apm_callbacks.started) {
return;
}
bson_init (&doc);
_mongoc_client_prepare_killcursors_command (cursor_id, collection, &doc);
mongoc_apm_command_started_init (&event,
&doc,
db,
"killCursors",
cluster->request_id,
operation_id,
&server_stream->sd->host,
server_stream->sd->id,
&server_stream->sd->service_id,
+ server_stream->sd->server_connection_id,
NULL,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
bson_destroy (&doc);
EXIT;
}
static void
_mongoc_client_monitor_op_killcursors_succeeded (
mongoc_cluster_t *cluster,
int64_t duration,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id)
{
mongoc_client_t *client;
bson_t doc;
bson_t cursors_unknown;
mongoc_apm_command_succeeded_t event;
ENTRY;
client = cluster->client;
if (!client->apm_callbacks.succeeded) {
EXIT;
}
/* fake server reply to killCursors command: {ok: 1, cursorsUnknown: [42]} */
bson_init (&doc);
bson_append_int32 (&doc, "ok", 2, 1);
bson_append_array_begin (&doc, "cursorsUnknown", 14, &cursors_unknown);
bson_append_int64 (&cursors_unknown, "0", 1, cursor_id);
bson_append_array_end (&doc, &cursors_unknown);
mongoc_apm_command_succeeded_init (&event,
duration,
&doc,
"killCursors",
cluster->request_id,
operation_id,
&server_stream->sd->host,
server_stream->sd->id,
&server_stream->sd->service_id,
+ server_stream->sd->server_connection_id,
false,
client->apm_context);
client->apm_callbacks.succeeded (&event);
mongoc_apm_command_succeeded_cleanup (&event);
bson_destroy (&doc);
}
static void
_mongoc_client_monitor_op_killcursors_failed (
mongoc_cluster_t *cluster,
int64_t duration,
mongoc_server_stream_t *server_stream,
const bson_error_t *error,
int64_t operation_id)
{
mongoc_client_t *client;
bson_t doc;
mongoc_apm_command_failed_t event;
ENTRY;
client = cluster->client;
if (!client->apm_callbacks.failed) {
EXIT;
}
/* fake server reply to killCursors command: {ok: 0} */
bson_init (&doc);
bson_append_int32 (&doc, "ok", 2, 0);
mongoc_apm_command_failed_init (&event,
duration,
"killCursors",
error,
&doc,
cluster->request_id,
operation_id,
&server_stream->sd->host,
server_stream->sd->id,
&server_stream->sd->service_id,
+ server_stream->sd->server_connection_id,
false,
client->apm_context);
client->apm_callbacks.failed (&event);
mongoc_apm_command_failed_cleanup (&event);
bson_destroy (&doc);
}
static void
_mongoc_client_op_killcursors (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
int64_t operation_id,
const char *db,
const char *collection)
{
int64_t started;
mongoc_rpc_t rpc = {{0}};
bson_error_t error;
bool has_ns;
bool r;
/* called by old mongoc_client_kill_cursor without db/collection? */
has_ns = (db && collection);
started = bson_get_monotonic_time ();
++cluster->request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = cluster->request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_KILL_CURSORS;
rpc.kill_cursors.zero = 0;
rpc.kill_cursors.cursors = &cursor_id;
rpc.kill_cursors.n_cursors = 1;
if (has_ns) {
_mongoc_client_monitor_op_killcursors (
cluster, server_stream, cursor_id, operation_id, db, collection);
}
r = mongoc_cluster_legacy_rpc_sendv_to_server (
cluster, &rpc, server_stream, &error);
if (has_ns) {
if (r) {
_mongoc_client_monitor_op_killcursors_succeeded (
cluster,
bson_get_monotonic_time () - started,
server_stream,
cursor_id,
operation_id);
} else {
_mongoc_client_monitor_op_killcursors_failed (
cluster,
bson_get_monotonic_time () - started,
server_stream,
&error,
operation_id);
}
}
}
static void
_mongoc_client_killcursors_command (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
int64_t cursor_id,
const char *db,
const char *collection,
mongoc_client_session_t *cs)
{
bson_t command = BSON_INITIALIZER;
mongoc_cmd_parts_t parts;
ENTRY;
_mongoc_client_prepare_killcursors_command (cursor_id, collection, &command);
mongoc_cmd_parts_init (
&parts, cluster->client, db, MONGOC_QUERY_SECONDARY_OK, &command);
parts.assembled.operation_id = ++cluster->operation_id;
mongoc_cmd_parts_set_session (&parts, cs);
if (mongoc_cmd_parts_assemble (&parts, server_stream, NULL)) {
/* Find, getMore And killCursors Commands Spec: "The result from the
* killCursors command MAY be safely ignored."
*/
(void) mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, NULL, NULL);
}
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&command);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_kill_cursor --
*
* Destroy a cursor on the server.
*
* NOTE: this is only reliable when connected to a single mongod or
* mongos. If connected to a replica set, the driver attempts to
* kill the cursor on the primary. If connected to multiple mongoses
* the kill-cursors message is sent to a *random* mongos.
*
* If no primary, mongos, or standalone server is known, return
* without attempting to reconnect.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id)
{
mongoc_topology_t *const topology =
BSON_ASSERT_PTR_INLINE (client)->topology;
mongoc_server_description_t const *selected_server;
mongoc_read_prefs_t *read_prefs;
bson_error_t error;
uint32_t server_id = 0;
mc_shared_tpld td = mc_tpld_take_ref (topology);
read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
if (!mongoc_topology_compatible (td.ptr, NULL, &error)) {
MONGOC_ERROR ("Could not kill cursor: %s", error.message);
mc_tpld_drop_ref (&td);
mongoc_read_prefs_destroy (read_prefs);
return;
}
/* see if there's a known writable server - do no I/O or retries */
selected_server =
mongoc_topology_description_select (td.ptr,
MONGOC_SS_WRITE,
read_prefs,
NULL /* chosen read mode */,
topology->local_threshold_msec);
if (selected_server) {
server_id = selected_server->id;
}
if (server_id) {
_mongoc_client_kill_cursor (client,
server_id,
cursor_id,
0 /* operation_id */,
NULL /* db */,
NULL /* collection */,
NULL /* session */);
} else {
MONGOC_INFO ("No server available for mongoc_client_kill_cursor");
}
mongoc_read_prefs_destroy (read_prefs);
mc_tpld_drop_ref (&td);
}
char **
mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error)
{
return mongoc_client_get_database_names_with_opts (client, NULL, error);
}
char **
mongoc_client_get_database_names_with_opts (mongoc_client_t *client,
const bson_t *opts,
bson_error_t *error)
{
bson_iter_t iter;
const char *name;
char **ret = NULL;
int i = 0;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t cmd = BSON_INITIALIZER;
BSON_ASSERT (client);
BSON_APPEND_INT32 (&cmd, "listDatabases", 1);
BSON_APPEND_BOOL (&cmd, "nameOnly", true);
/* ignore client read prefs */
cursor = _mongoc_cursor_array_new (client, "admin", &cmd, opts, "databases");
bson_destroy (&cmd);
while (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init (&iter, doc) && bson_iter_find (&iter, "name") &&
BSON_ITER_HOLDS_UTF8 (&iter) &&
(name = bson_iter_utf8 (&iter, NULL))) {
ret = (char **) bson_realloc (ret, sizeof (char *) * (i + 2));
ret[i] = bson_strdup (name);
ret[++i] = NULL;
}
}
if (!ret && !mongoc_cursor_error (cursor, error)) {
ret = (char **) bson_malloc0 (sizeof (void *));
}
mongoc_cursor_destroy (cursor);
return ret;
}
mongoc_cursor_t *
mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error)
{
/* existing bug in this deprecated API: error pointer is unused */
return mongoc_client_find_databases_with_opts (client, NULL);
}
mongoc_cursor_t *
mongoc_client_find_databases_with_opts (mongoc_client_t *client,
const bson_t *opts)
{
bson_t cmd = BSON_INITIALIZER;
mongoc_cursor_t *cursor;
BSON_ASSERT (client);
BSON_APPEND_INT32 (&cmd, "listDatabases", 1);
cursor = _mongoc_cursor_array_new (client, "admin", &cmd, opts, "databases");
bson_destroy (&cmd);
return cursor;
}
int32_t
mongoc_client_get_max_message_size (mongoc_client_t *client) /* IN */
{
BSON_ASSERT (client);
return mongoc_cluster_get_max_msg_size (&client->cluster);
}
int32_t
mongoc_client_get_max_bson_size (mongoc_client_t *client) /* IN */
{
BSON_ASSERT (client);
return mongoc_cluster_get_max_bson_obj_size (&client->cluster);
}
bool
mongoc_client_get_server_status (mongoc_client_t *client, /* IN */
mongoc_read_prefs_t *read_prefs, /* IN */
bson_t *reply, /* OUT */
bson_error_t *error) /* OUT */
{
bson_t cmd = BSON_INITIALIZER;
bool ret = false;
BSON_ASSERT (client);
BSON_APPEND_INT32 (&cmd, "serverStatus", 1);
ret = mongoc_client_command_simple (
client, "admin", &cmd, read_prefs, reply, error);
bson_destroy (&cmd);
return ret;
}
void
mongoc_client_set_stream_initiator (mongoc_client_t *client,
mongoc_stream_initiator_t initiator,
void *user_data)
{
BSON_ASSERT (client);
if (!initiator) {
initiator = mongoc_client_default_stream_initiator;
user_data = client;
} else {
MONGOC_DEBUG ("Using custom stream initiator.");
}
client->initiator = initiator;
client->initiator_data = user_data;
if (client->topology->single_threaded) {
mongoc_topology_scanner_set_stream_initiator (
client->topology->scanner, initiator, user_data);
}
}
bool
_mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
mongoc_apm_callbacks_t *callbacks,
void *context)
{
if (callbacks) {
memcpy (
&client->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
} else {
memset (&client->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t));
}
client->apm_context = context;
/* A client pool sets APM callbacks for the entire pool. */
if (client->topology->single_threaded) {
mongoc_topology_set_apm_callbacks (
client->topology,
/* We are safe to modify the shared_descr directly, since we are
* single-threaded */
mc_tpld_unsafe_get_mutable (client->topology),
callbacks,
context);
}
return true;
}
bool
mongoc_client_set_apm_callbacks (mongoc_client_t *client,
mongoc_apm_callbacks_t *callbacks,
void *context)
{
if (!client->topology->single_threaded) {
MONGOC_ERROR ("Cannot set callbacks on a pooled client, use "
"mongoc_client_pool_set_apm_callbacks");
return false;
}
return _mongoc_client_set_apm_callbacks_private (client, callbacks, context);
}
mongoc_server_description_t *
mongoc_client_get_server_description (mongoc_client_t *client,
uint32_t server_id)
{
mongoc_server_description_t *ret;
mc_shared_tpld td = mc_tpld_take_ref (client->topology);
mongoc_server_description_t const *sd =
mongoc_topology_description_server_by_id_const (
td.ptr, server_id, NULL /* <- the error info isn't useful */);
ret = mongoc_server_description_new_copy (sd);
mc_tpld_drop_ref (&td);
return ret;
}
mongoc_server_description_t **
mongoc_client_get_server_descriptions (const mongoc_client_t *client,
size_t *n /* OUT */)
{
mc_shared_tpld td =
mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (client)->topology);
mongoc_server_description_t **const sds =
mongoc_topology_description_get_servers (td.ptr,
BSON_ASSERT_PTR_INLINE (n));
mc_tpld_drop_ref (&td);
return sds;
}
void
mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds,
size_t n)
{
size_t i;
for (i = 0; i < n; ++i) {
mongoc_server_description_destroy (sds[i]);
}
bson_free (sds);
}
mongoc_server_description_t *
mongoc_client_select_server (mongoc_client_t *client,
bool for_writes,
const mongoc_read_prefs_t *prefs,
bson_error_t *error)
{
mongoc_ss_optype_t optype = for_writes ? MONGOC_SS_WRITE : MONGOC_SS_READ;
mongoc_server_description_t *sd;
if (for_writes && prefs) {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"Cannot use read preferences with for_writes = true");
return NULL;
}
if (!_mongoc_read_prefs_validate (prefs, error)) {
return NULL;
}
sd = mongoc_topology_select (
client->topology, optype, prefs, NULL /* chosen read mode */, error);
if (!sd) {
return NULL;
}
if (mongoc_cluster_check_interval (&client->cluster, sd->id)) {
/* check not required, or it succeeded */
return sd;
}
/* check failed, retry once */
mongoc_server_description_destroy (sd);
sd = mongoc_topology_select (
client->topology, optype, prefs, NULL /* chosen read mode */, error);
if (sd) {
return sd;
}
return NULL;
}
bool
mongoc_client_set_error_api (mongoc_client_t *client, int32_t version)
{
if (!client->topology->single_threaded) {
MONGOC_ERROR ("Cannot set Error API Version on a pooled client, use "
"mongoc_client_pool_set_error_api");
return false;
}
if (version != MONGOC_ERROR_API_VERSION_LEGACY &&
version != MONGOC_ERROR_API_VERSION_2) {
MONGOC_ERROR ("Unsupported Error API Version: %" PRId32, version);
return false;
}
if (client->error_api_set) {
MONGOC_ERROR ("Can only set Error API Version once");
return false;
}
client->error_api_version = version;
client->error_api_set = true;
return true;
}
bool
mongoc_client_set_appname (mongoc_client_t *client, const char *appname)
{
if (!client->topology->single_threaded) {
MONGOC_ERROR ("Cannot call set_appname on a client from a pool");
return false;
}
return _mongoc_topology_set_appname (client->topology, appname);
}
mongoc_server_session_t *
_mongoc_client_pop_server_session (mongoc_client_t *client, bson_error_t *error)
{
return _mongoc_topology_pop_server_session (client->topology, error);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_client_lookup_session --
*
* Retrieve a mongoc_client_session_t associated with @client_session_id.
* Use this to find the "lsid" and "$clusterTime" to send in the server
* command.
*
* Returns:
* True on success, false on error and @error is set. Will return false
* if the session is from an outdated client generation, a holdover
* from before a call to mongoc_client_reset.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_client_lookup_session (const mongoc_client_t *client,
uint32_t client_session_id,
mongoc_client_session_t **cs /* OUT */,
bson_error_t *error /* OUT */)
{
ENTRY;
*cs = mongoc_set_get (client->client_sessions, client_session_id);
if (*cs) {
RETURN (true);
}
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid sessionId");
RETURN (false);
}
void
_mongoc_client_unregister_session (mongoc_client_t *client,
mongoc_client_session_t *session)
{
mongoc_set_rm (client->client_sessions, session->client_session_id);
}
void
_mongoc_client_push_server_session (mongoc_client_t *client,
mongoc_server_session_t *server_session)
{
_mongoc_topology_push_server_session (client->topology, server_session);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_client_end_sessions --
*
* End all server sessions in the topology's server session pool.
* Don't block long: if server selection or connecting fails, quit.
*
* The server session pool becomes invalid, but may not be empty.
* Destroy the topology after this without using any sessions.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_client_end_sessions (mongoc_client_t *client)
{
mongoc_topology_t *t = client->topology;
mongoc_read_prefs_t *prefs;
bson_error_t error;
uint32_t server_id;
bson_t cmd;
mongoc_server_stream_t *stream;
mongoc_cmd_parts_t parts;
mongoc_cluster_t *cluster = &client->cluster;
bool r;
while (!mongoc_server_session_pool_is_empty (t->session_pool)) {
prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED);
server_id = mongoc_topology_select_server_id (
t, MONGOC_SS_READ, prefs, NULL /* chosen read mode */, &error);
mongoc_read_prefs_destroy (prefs);
if (!server_id) {
MONGOC_WARNING ("Couldn't send \"endSessions\": %s", error.message);
return;
}
stream = mongoc_cluster_stream_for_server (
cluster, server_id, false /* reconnect_ok */, NULL, NULL, &error);
if (!stream) {
MONGOC_WARNING ("Couldn't send \"endSessions\": %s", error.message);
return;
}
/* end sessions in chunks */
while (_mongoc_topology_end_sessions_cmd (t, &cmd)) {
mongoc_cmd_parts_init (
&parts, client, "admin", MONGOC_QUERY_SECONDARY_OK, &cmd);
parts.assembled.operation_id = ++cluster->operation_id;
parts.prohibit_lsid = true;
r = mongoc_cmd_parts_assemble (&parts, stream, &error);
if (!r) {
MONGOC_WARNING ("Couldn't construct \"endSessions\" command: %s",
error.message);
} else {
r = mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, NULL, &error);
if (!r) {
MONGOC_WARNING ("Couldn't send \"endSessions\": %s",
error.message);
}
}
mongoc_cmd_parts_cleanup (&parts);
if (!mongoc_cluster_stream_valid (cluster, stream)) {
/* The stream was invalidated as a result of a network error, so we
* stop sending commands. */
break;
}
bson_destroy (&cmd);
}
bson_destroy (&cmd);
mongoc_server_stream_cleanup (stream);
}
}
void
mongoc_client_reset (mongoc_client_t *client)
{
BSON_ASSERT (client);
client->generation++;
/* Client sessions are owned and destroyed by the user, but we keep
local pointers to them for reference. On reset, clear our local
set without destroying the sessions or calling endSessions.
client_sessions has no dtor, so it won't destroy its items.
Destroying the local cache of client sessions here ensures they
cannot be used by future operations--lookup for them will fail. */
mongoc_set_destroy (client->client_sessions);
client->client_sessions = mongoc_set_new (8, NULL, NULL);
/* Server sessions are owned by us, so we clear the pool on reset. */
mongoc_server_session_pool_clear (client->topology->session_pool);
}
mongoc_change_stream_t *
mongoc_client_watch (mongoc_client_t *client,
const bson_t *pipeline,
const bson_t *opts)
{
return _mongoc_change_stream_new_from_client (client, pipeline, opts);
}
bool
mongoc_client_enable_auto_encryption (mongoc_client_t *client,
mongoc_auto_encryption_opts_t *opts,
bson_error_t *error)
{
if (!client->topology->single_threaded) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Cannot enable auto encryption on a pooled client, use "
"mongoc_client_pool_enable_auto_encryption");
return false;
}
return _mongoc_cse_client_enable_auto_encryption (client, opts, error);
}
bool
mongoc_client_set_server_api (mongoc_client_t *client,
const mongoc_server_api_t *api,
bson_error_t *error)
{
BSON_ASSERT_PARAM (client);
BSON_ASSERT_PARAM (api);
if (client->is_pooled) {
bson_set_error (
error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_API_FROM_POOL,
"Cannot set server api on a client checked out from a pool");
return false;
}
- if (client->api) {
+ if (mongoc_client_uses_server_api (client)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_API_ALREADY_SET,
"Cannot set server api more than once per client");
return false;
}
client->api = mongoc_server_api_copy (api);
_mongoc_topology_scanner_set_server_api (client->topology->scanner, api);
return true;
}
mongoc_server_description_t *
mongoc_client_get_handshake_description (mongoc_client_t *client,
uint32_t server_id,
bson_t *opts,
bson_error_t *error)
{
mongoc_server_stream_t *server_stream;
mongoc_server_description_t *sd;
server_stream = mongoc_cluster_stream_for_server (&client->cluster,
server_id,
true /* reconnect */,
NULL /* client session */,
NULL /* reply */,
error);
if (!server_stream) {
return NULL;
}
sd = mongoc_server_description_new_copy (server_stream->sd);
mongoc_server_stream_cleanup (server_stream);
return sd;
}
+
+bool
+mongoc_client_uses_server_api (const mongoc_client_t *client)
+{
+ return mongoc_topology_uses_server_api (client->topology);
+}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c
index 17f0853b..80d31208 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c
@@ -1,1018 +1,1018 @@
/*
* Copyright 2020-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* All interaction with kms_message is limited to this file. */
#include "common-b64-private.h"
#include "mongoc-cluster-aws-private.h"
#include "mongoc-client-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-rand-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-util-private.h"
#include "mongoc-http-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "aws_auth"
#define AUTH_ERROR_AND_FAIL(...) \
do { \
bson_set_error (error, \
MONGOC_ERROR_CLIENT, \
MONGOC_ERROR_CLIENT_AUTHENTICATE, \
__VA_ARGS__); \
goto fail; \
} while (0)
#ifdef MONGOC_ENABLE_MONGODB_AWS_AUTH
#include "kms_message/kms_message.h"
/*
* Run a single command on a stream.
*
* On success, returns true.
* On failure, returns false and sets error.
* reply is always initialized.
*/
static bool
_run_command (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_t *command,
bson_t *reply,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
mongoc_server_stream_t *server_stream;
bool ret;
mc_shared_tpld td =
mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (cluster)->client->topology);
mongoc_cmd_parts_init (&parts,
cluster->client,
"$external",
MONGOC_QUERY_NONE /* unused for OP_MSG */,
command);
/* Drivers must not append session ids to auth commands per sessions spec. */
parts.prohibit_lsid = true;
server_stream = _mongoc_cluster_create_server_stream (td.ptr, sd, stream);
mc_tpld_drop_ref (&td);
ret = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, reply, error);
mongoc_server_stream_cleanup (server_stream);
return ret;
}
/*
* Utility function to parse out a server reply's payload.
*
* Given a server reply like { ok: 1, payload: <BSON data>, ... } parse out the
* payload into a bson_t.
* On success, returns true.
* On failure, returns false and sets error.
* payload is always initialized.
*/
static bool
_sasl_reply_parse_payload_as_bson (const bson_t *reply,
bson_t *payload,
bson_error_t *error)
{
bson_iter_t iter;
bson_subtype_t payload_subtype;
const uint8_t *payload_data;
uint32_t payload_len;
bool ret = false;
bson_init (payload);
if (!bson_iter_init_find (&iter, reply, "payload") ||
!BSON_ITER_HOLDS_BINARY (&iter)) {
AUTH_ERROR_AND_FAIL ("server reply did not contain binary payload");
}
bson_iter_binary (&iter, &payload_subtype, &payload_len, &payload_data);
if (payload_subtype != BSON_SUBTYPE_BINARY) {
AUTH_ERROR_AND_FAIL ("server reply contained unexpected binary subtype");
}
bson_destroy (payload);
if (!bson_init_static (payload, payload_data, payload_len)) {
AUTH_ERROR_AND_FAIL ("server payload is invalid BSON");
}
ret = true;
fail:
return ret;
}
/*
* Send an HTTP request and get a response.
* On success, returns true.
* On failure, returns false and sets error.
* headers is a \r\n delimitted list of headers (or an empty string).
* http_response_body is always set, and must be freed.
* http_response_headers is always set, and must be freed. This may be used for
* error reporting since the response headers should not include sensitive
* credentials.
*/
static bool
_send_http_request (const char *ip,
int port,
const char *method,
const char *path,
const char *headers,
char **http_response_body,
char **http_response_headers,
bson_error_t *error)
{
mongoc_http_request_t req;
mongoc_http_response_t res;
const int socket_timeout_ms = 10000;
bool ret;
*http_response_body = NULL;
*http_response_headers = NULL;
_mongoc_http_request_init (&req);
_mongoc_http_response_init (&res);
req.host = ip;
req.port = port;
req.method = method;
req.path = path;
req.extra_headers = headers;
ret = _mongoc_http_send (&req,
socket_timeout_ms,
false /* use_tls */,
NULL /* ssl_opts */,
&res,
error);
if (ret) {
*http_response_headers = bson_strndup (res.headers, res.headers_len);
*http_response_body = (char *) bson_malloc0 (res.body_len + 1);
memcpy (*http_response_body, res.body, res.body_len);
}
_mongoc_http_response_cleanup (&res);
return ret;
}
static bool
_creds_empty (_mongoc_aws_credentials_t *creds)
{
return creds->access_key_id == NULL && creds->secret_access_key == NULL &&
creds->session_token == NULL;
}
/*
* Helper to validate and possibly set credentials.
*
* On success, returns true.
* On failure, returns false and sets error.
* Caller should use _creds_empty to determine whether credentials have been
* set.
*/
static bool
_validate_and_set_creds (const char *access_key_id,
const char *secret_access_key,
const char *session_token,
_mongoc_aws_credentials_t *creds,
bson_error_t *error)
{
bool has_access_key_id = access_key_id && strlen (access_key_id) != 0;
bool has_secret_access_key =
secret_access_key && strlen (secret_access_key) != 0;
bool has_session_token = session_token && strlen (session_token) != 0;
bool ret = false;
/* Check for invalid combinations of URI parameters. */
if (has_access_key_id && !has_secret_access_key) {
AUTH_ERROR_AND_FAIL (
"ACCESS_KEY_ID is set, but SECRET_ACCESS_KEY is missing");
}
if (!has_access_key_id && has_secret_access_key) {
AUTH_ERROR_AND_FAIL (
"SECRET_ACCESS_KEY is set, but ACCESS_KEY_ID is missing");
}
if (!has_access_key_id && !has_secret_access_key && has_session_token) {
AUTH_ERROR_AND_FAIL ("AWS_SESSION_TOKEN is set, but ACCESS_KEY_ID and "
"SECRET_ACCESS_KEY are missing");
}
creds->access_key_id = bson_strdup (access_key_id);
creds->secret_access_key = bson_strdup (secret_access_key);
creds->session_token = session_token ? bson_strdup (session_token) : NULL;
ret = true;
fail:
return ret;
}
/*
* Validate and possibly set credentials.
*
* On success, returns true.
* On failure, returns false and sets error.
* Caller should use _creds_empty to determine whether credentials have been
* set.
*/
static bool
_obtain_creds_from_uri (_mongoc_aws_credentials_t *creds,
mongoc_uri_t *uri,
bson_error_t *error)
{
bool ret = false;
bson_t auth_mechanism_props;
const char *uri_session_token = NULL;
if (mongoc_uri_get_mechanism_properties (uri, &auth_mechanism_props)) {
bson_iter_t iter;
if (bson_iter_init_find_case (
&iter, &auth_mechanism_props, "AWS_SESSION_TOKEN") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
uri_session_token = bson_iter_utf8 (&iter, NULL);
}
}
if (!_validate_and_set_creds (mongoc_uri_get_username (uri),
mongoc_uri_get_password (uri),
uri_session_token,
creds,
error)) {
goto fail;
}
ret = true;
fail:
return ret;
}
static bool
_obtain_creds_from_env (_mongoc_aws_credentials_t *creds, bson_error_t *error)
{
bool ret = false;
char *env_access_key_id = NULL;
char *env_secret_access_key = NULL;
char *env_session_token = NULL;
/* Check environment variables. */
env_access_key_id = _mongoc_getenv ("AWS_ACCESS_KEY_ID");
env_secret_access_key = _mongoc_getenv ("AWS_SECRET_ACCESS_KEY");
env_session_token = _mongoc_getenv ("AWS_SESSION_TOKEN");
if (!_validate_and_set_creds (env_access_key_id,
env_secret_access_key,
env_session_token,
creds,
error)) {
goto fail;
}
ret = true;
fail:
bson_free (env_access_key_id);
bson_free (env_secret_access_key);
bson_free (env_session_token);
return ret;
}
static bool
_obtain_creds_from_ecs (_mongoc_aws_credentials_t *creds, bson_error_t *error)
{
bool ret = false;
char *http_response_headers = NULL;
char *http_response_body = NULL;
char *relative_ecs_uri = NULL;
bson_t *response_json = NULL;
bson_iter_t iter;
const char *ecs_access_key_id = NULL;
const char *ecs_secret_access_key = NULL;
const char *ecs_session_token = NULL;
bson_error_t http_error;
relative_ecs_uri = _mongoc_getenv ("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI");
if (!relative_ecs_uri || strlen (relative_ecs_uri) == 0) {
bson_free (relative_ecs_uri);
return true;
}
if (!_send_http_request ("169.254.170.2",
80,
"GET",
relative_ecs_uri,
"",
&http_response_body,
&http_response_headers,
&http_error)) {
AUTH_ERROR_AND_FAIL ("failed to contact ECS link local server: %s",
http_error.message);
}
response_json = bson_new_from_json (
(const uint8_t *) http_response_body, strlen (http_response_body), error);
if (!response_json) {
AUTH_ERROR_AND_FAIL ("invalid JSON in ECS response. Response headers: %s",
http_response_headers);
}
if (bson_iter_init_find_case (&iter, response_json, "AccessKeyId") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
ecs_access_key_id = bson_iter_utf8 (&iter, NULL);
}
if (bson_iter_init_find_case (&iter, response_json, "SecretAccessKey") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
ecs_secret_access_key = bson_iter_utf8 (&iter, NULL);
}
if (bson_iter_init_find_case (&iter, response_json, "Token") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
ecs_session_token = bson_iter_utf8 (&iter, NULL);
}
if (!_validate_and_set_creds (ecs_access_key_id,
ecs_secret_access_key,
ecs_session_token,
creds,
error)) {
goto fail;
}
ret = true;
fail:
bson_destroy (response_json);
bson_free (http_response_headers);
bson_free (http_response_body);
bson_free (relative_ecs_uri);
return ret;
}
static bool
_obtain_creds_from_ec2 (_mongoc_aws_credentials_t *creds, bson_error_t *error)
{
bool ret = false;
char *http_response_headers = NULL;
char *http_response_body = NULL;
char *token_header = NULL;
char *token = NULL;
char *role_name = NULL;
char *relative_ecs_uri = NULL;
char *path_with_role = NULL;
bson_t *response_json = NULL;
bson_iter_t iter;
const char *ec2_access_key_id = NULL;
const char *ec2_secret_access_key = NULL;
const char *ec2_session_token = NULL;
bson_error_t http_error;
const char *ip = "169.254.169.254";
/* Get the token. */
if (!_send_http_request (ip,
80,
"PUT",
"/latest/api/token",
"X-aws-ec2-metadata-token-ttl-seconds: 30\r\n",
&token,
&http_response_headers,
&http_error)) {
AUTH_ERROR_AND_FAIL ("failed to contact EC2 link local server: %s",
http_error.message);
}
if (0 == strlen (token)) {
AUTH_ERROR_AND_FAIL (
"unable to retrieve token from EC2 metadata. Headers: %s",
http_response_headers);
}
bson_free (http_response_headers);
http_response_headers = NULL;
token_header =
bson_strdup_printf ("X-aws-ec2-metadata-token: %s\r\n", token);
/* Get the role name. */
if (!_send_http_request (ip,
80,
"GET",
"/latest/meta-data/iam/security-credentials/",
token_header,
&role_name,
&http_response_headers,
&http_error)) {
AUTH_ERROR_AND_FAIL ("failed to contact EC2 link local server: %s",
http_error.message);
}
if (0 == strlen (role_name)) {
AUTH_ERROR_AND_FAIL (
"unable to retrieve role_name from EC2 metadata. Headers: %s",
http_response_headers);
}
/* Get the creds. */
path_with_role = bson_strdup_printf (
"/latest/meta-data/iam/security-credentials/%s", role_name);
bson_free (http_response_headers);
http_response_headers = NULL;
if (!_send_http_request (ip,
80,
"GET",
path_with_role,
token_header,
&http_response_body,
&http_response_headers,
&http_error)) {
AUTH_ERROR_AND_FAIL ("failed to contact EC2 link local server: %s",
http_error.message);
}
response_json = bson_new_from_json (
(const uint8_t *) http_response_body, strlen (http_response_body), error);
if (!response_json) {
AUTH_ERROR_AND_FAIL ("invalid JSON in EC2 response. Response headers: %s",
http_response_headers);
}
if (bson_iter_init_find_case (&iter, response_json, "AccessKeyId") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
ec2_access_key_id = bson_iter_utf8 (&iter, NULL);
}
if (bson_iter_init_find_case (&iter, response_json, "SecretAccessKey") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
ec2_secret_access_key = bson_iter_utf8 (&iter, NULL);
}
if (bson_iter_init_find_case (&iter, response_json, "Token") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
ec2_session_token = bson_iter_utf8 (&iter, NULL);
}
if (!_validate_and_set_creds (ec2_access_key_id,
ec2_secret_access_key,
ec2_session_token,
creds,
error)) {
goto fail;
}
ret = true;
fail:
bson_destroy (response_json);
bson_free (http_response_headers);
bson_free (http_response_body);
bson_free (token);
bson_free (role_name);
bson_free (token_header);
bson_free (relative_ecs_uri);
bson_free (path_with_role);
return ret;
}
/*
* Attempt to obtain AWS credentials.
*
* Credentials may be passed in multiple ways. The precedence is as follows:
* 1. Username/password in the URI (and authMechanismProperty for session token)
* 2. From environment variables.
* 3. From querying the ECS local HTTP server.
* 4. From querying the EC2 local HTTP server.
*
* On success, returns true.
* On failure, returns false and sets error.
*/
bool
_mongoc_aws_credentials_obtain (mongoc_uri_t *uri,
_mongoc_aws_credentials_t *creds,
bson_error_t *error)
{
bool ret = false;
creds->access_key_id = NULL;
creds->secret_access_key = NULL;
creds->session_token = NULL;
TRACE ("%s", "checking URI for credentials");
if (!_obtain_creds_from_uri (creds, uri, error)) {
goto fail;
}
if (!_creds_empty (creds)) {
goto succeed;
}
TRACE ("%s", "checking environment variables for credentials");
if (!_obtain_creds_from_env (creds, error)) {
goto fail;
}
if (!_creds_empty (creds)) {
goto succeed;
}
TRACE ("%s", "checking ECS metadata for credentials");
if (!_obtain_creds_from_ecs (creds, error)) {
goto fail;
}
if (!_creds_empty (creds)) {
goto succeed;
}
TRACE ("%s", "checking EC2 metadata for credentials");
if (!_obtain_creds_from_ec2 (creds, error)) {
goto fail;
}
if (!_creds_empty (creds)) {
goto succeed;
}
AUTH_ERROR_AND_FAIL ("unable to get credentials\n");
succeed:
ret = true;
fail:
return ret;
}
void
_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds)
{
bson_free (creds->access_key_id);
bson_free (creds->secret_access_key);
bson_free (creds->session_token);
}
/*
* Validate the STS host returned by the server and derive the region.
*
* On success, returns true.
* On failure, returns false and sets error.
* region is always set and must be freed by caller.
*/
bool
_mongoc_validate_and_derive_region (char *sts_fqdn,
uint32_t sts_fqdn_len,
char **region,
bson_error_t *error)
{
bool ret = false;
char *ptr;
char *ptr_prev;
char *second_part = NULL;
/* Default to us-east-1. */
*region = bson_strdup ("us-east-1");
/* Drivers must also validate that the host is greater than 0 and less than
* or equal to 255 bytes per RFC 1035 */
if (sts_fqdn_len == 0) {
AUTH_ERROR_AND_FAIL ("invalid STS host: empty");
}
if (sts_fqdn_len > 255) {
AUTH_ERROR_AND_FAIL ("invalid STS host: too large");
}
/* If sts.amazonaws.com, then use default region. */
if (0 == bson_strcasecmp ("sts.amazonaws.com", sts_fqdn)) {
goto succeed;
}
/* Drivers MUST reject FQDN names with empty labels, e.g., "abc..def" */
ptr_prev = sts_fqdn;
ptr = strstr (sts_fqdn, ".");
if (ptr) {
second_part = ptr + 1;
}
if (0 == ptr - sts_fqdn) {
AUTH_ERROR_AND_FAIL ("invalid STS host: empty part");
}
while (ptr) {
if (1 == ptr - ptr_prev) {
AUTH_ERROR_AND_FAIL ("invalid STS host: empty part");
}
ptr_prev = ptr;
ptr = strstr (ptr + 1, ".");
}
if (strlen (ptr_prev + 1) == 0) {
AUTH_ERROR_AND_FAIL ("invalid STS host: empty part");
}
if (second_part) {
char *second_part_end;
second_part_end = strstr (second_part, ".");
bson_free (*region);
if (!second_part_end) {
*region = bson_strdup (second_part);
} else {
*region = bson_strndup (second_part, second_part_end - second_part);
}
}
succeed:
ret = true;
fail:
return ret;
}
/* --------------------------------------------------------------------------
* Step 1
* --------------------------------------------------------------------------
* Client sends BSON payload:
* {
* "r": <32 byte client nonce>,
* "p": 110
* }
* Server responds with BSON payload:
* {
* "s": <32 byte client nonce + 32 byte server nonce>,
* "h": <domain name of STS service>
* }
*
* Payloads are wrapped in SASL commands. The command a client sends is like:
* { "saslStart": 1, "mechanism": "MONGODB-AWS", "payload": <BSON payload> }
* And similar for server responses:
* { "ok": 1, "conversationId": 1, "done": false, "payload": <BSON payload> }
*
* On success, returns true.
* On failure, returns false and sets error.
* --------------------------------------------------------------------------
*/
static bool
_client_first (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
uint8_t *server_nonce,
char **sts_fqdn,
char **region,
int *conv_id,
bson_error_t *error)
{
bool ret = false;
uint8_t client_nonce[32];
bson_t client_payload = BSON_INITIALIZER;
bson_t client_command = BSON_INITIALIZER;
bson_t server_payload = BSON_INITIALIZER;
bson_t server_reply = BSON_INITIALIZER;
bson_iter_t iter;
bson_subtype_t reply_nonce_subtype;
const uint8_t *reply_nonce_data;
uint32_t reply_nonce_len;
uint32_t sts_fqdn_len;
/* Reset out params. */
memset (server_nonce, 0, 32);
*sts_fqdn = NULL;
*region = NULL;
*conv_id = 0;
#ifdef MONGOC_ENABLE_CRYPTO
/* Generate secure random nonce. */
if (!_mongoc_rand_bytes (client_nonce, 32)) {
AUTH_ERROR_AND_FAIL ("Could not generate client nonce");
}
#else
AUTH_ERROR_AND_FAIL ("libmongoc requires a cryptography library (libcrypto, "
"Common Crypto, or cng) to support MONGODB-AWS");
#endif
BCON_APPEND (&client_payload,
"r",
BCON_BIN (BSON_SUBTYPE_BINARY, client_nonce, 32),
"p",
BCON_INT32 (110));
BCON_APPEND (&client_command,
"saslStart",
BCON_INT32 (1),
"mechanism",
"MONGODB-AWS",
"payload",
BCON_BIN (BSON_SUBTYPE_BINARY,
bson_get_data (&client_payload),
client_payload.len));
bson_destroy (&server_reply);
if (!_run_command (
cluster, stream, sd, &client_command, &server_reply, error)) {
goto fail;
}
*conv_id = _mongoc_cluster_get_conversation_id (&server_reply);
if (!*conv_id) {
AUTH_ERROR_AND_FAIL ("server reply did not contain conversationId");
}
bson_destroy (&server_payload);
if (!_sasl_reply_parse_payload_as_bson (
&server_reply, &server_payload, error)) {
goto fail;
}
if (!bson_iter_init_find (&iter, &server_payload, "h") ||
!BSON_ITER_HOLDS_UTF8 (&iter)) {
AUTH_ERROR_AND_FAIL ("server payload did not contain string STS FQDN");
}
*sts_fqdn = bson_strdup (bson_iter_utf8 (&iter, &sts_fqdn_len));
if (!_mongoc_validate_and_derive_region (
*sts_fqdn, sts_fqdn_len, region, error)) {
goto fail;
}
if (!bson_iter_init_find (&iter, &server_payload, "s") ||
!BSON_ITER_HOLDS_BINARY (&iter)) {
AUTH_ERROR_AND_FAIL ("server payload did not contain nonce");
}
bson_iter_binary (
&iter, &reply_nonce_subtype, &reply_nonce_len, &reply_nonce_data);
if (reply_nonce_len != 64) {
AUTH_ERROR_AND_FAIL ("server reply nonce was not 64 bytes");
}
if (0 != memcmp (reply_nonce_data, client_nonce, 32)) {
AUTH_ERROR_AND_FAIL (
"server reply nonce prefix did not match client nonce");
}
/* Drivers MUST error on any additional fields */
bson_iter_init (&iter, &server_payload);
while (bson_iter_next (&iter)) {
const char *field;
field = bson_iter_key (&iter);
if (0 == strcmp (field, "h")) {
continue;
}
if (0 == strcmp (field, "s")) {
continue;
}
AUTH_ERROR_AND_FAIL ("unexpected field from server's reply: %s", field);
}
memcpy (server_nonce, reply_nonce_data, 64);
ret = true;
fail:
bson_destroy (&client_payload);
bson_destroy (&client_command);
bson_destroy (&server_reply);
bson_destroy (&server_payload);
return ret;
}
#define KMS_REQUEST_ADD_HEADER(key, value) \
do { \
if (!kms_request_add_header_field (request, key, value)) { \
AUTH_ERROR_AND_FAIL ("Failed to add header '%s'", key); \
} \
} while (0)
#define KMS_REQUEST_SET(fn, name, value) \
do { \
if (!fn (request, value)) { \
AUTH_ERROR_AND_FAIL ("Failed to set %s", name); \
} \
} while (0)
/* --------------------------------------------------------------------------
* Step 2
* --------------------------------------------------------------------------
* Client sends BSON payload:
* {
* "a": <signed headers>,
* "d": <current date in UTC>
* "t": <optional security token>
* }
*
* Server responds with final result.
*
* On success, returns true.
* On failure, returns false and sets error.
* --------------------------------------------------------------------------
*/
static bool
_client_second (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
_mongoc_aws_credentials_t *creds,
const uint8_t *server_nonce,
const char *sts_fqdn,
const char *region,
int conv_id,
bson_error_t *error)
{
bool ret = false;
kms_request_t *request = NULL;
char *signature = NULL;
const char *date = NULL;
const size_t server_nonce_str_len =
- COMMON_PREFIX (bson_b64_ntop_calculate_target_size (64));
+ mcommon_b64_ntop_calculate_target_size (64);
char *server_nonce_str = NULL;
const char *body = "Action=GetCallerIdentity&Version=2011-06-15";
bson_t client_payload = BSON_INITIALIZER;
bson_t client_command = BSON_INITIALIZER;
bson_t server_reply = BSON_INITIALIZER;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
BSON_ASSERT (sd);
BSON_ASSERT (creds);
BSON_ASSERT (server_nonce);
BSON_ASSERT (sts_fqdn);
BSON_ASSERT (conv_id);
BSON_ASSERT (creds->access_key_id);
BSON_ASSERT (creds->secret_access_key);
server_nonce_str = bson_malloc (server_nonce_str_len);
request = kms_request_new ("POST", "/", NULL);
if (kms_request_get_error (request)) {
AUTH_ERROR_AND_FAIL ("Failed to create new KMS request: %s",
kms_request_get_error (request));
}
- if (COMMON_PREFIX (bson_b64_ntop) (
+ if (mcommon_b64_ntop (
server_nonce, 64, server_nonce_str, server_nonce_str_len) == -1) {
AUTH_ERROR_AND_FAIL ("Failed to parse server nonce");
}
if (!kms_request_append_payload (request, body, -1)) {
AUTH_ERROR_AND_FAIL ("Failed to append payload");
}
KMS_REQUEST_SET (
kms_request_set_access_key_id, "access key ID", creds->access_key_id);
KMS_REQUEST_SET (
kms_request_set_secret_key, "secret key", creds->secret_access_key);
KMS_REQUEST_SET (kms_request_set_date, "date", NULL /* use current time */);
KMS_REQUEST_SET (kms_request_set_region, "region", region);
KMS_REQUEST_SET (kms_request_set_service, "service", "sts");
KMS_REQUEST_ADD_HEADER ("Content-Type", "application/x-www-form-urlencoded");
KMS_REQUEST_ADD_HEADER ("Host", sts_fqdn);
KMS_REQUEST_ADD_HEADER ("X-MongoDB-Server-Nonce", server_nonce_str);
KMS_REQUEST_ADD_HEADER ("X-MongoDB-GS2-CB-Flag", "n");
if (creds->session_token) {
KMS_REQUEST_ADD_HEADER ("X-Amz-Security-Token", creds->session_token);
}
signature = kms_request_get_signature (request);
if (kms_request_get_error (request)) {
AUTH_ERROR_AND_FAIL ("Failed to get signature: %s",
kms_request_get_error (request));
}
date = kms_request_get_canonical_header (request, "X-Amz-Date");
if (kms_request_get_error (request)) {
AUTH_ERROR_AND_FAIL ("Failed to get canonical header: %s",
kms_request_get_error (request));
}
BCON_APPEND (
&client_payload, "a", BCON_UTF8 (signature), "d", BCON_UTF8 (date));
if (creds->session_token) {
BCON_APPEND (&client_payload, "t", BCON_UTF8 (creds->session_token));
}
BCON_APPEND (&client_command,
"saslContinue",
BCON_INT32 (1),
"conversationId",
BCON_INT32 (conv_id),
"payload",
BCON_BIN (BSON_SUBTYPE_BINARY,
bson_get_data (&client_payload),
client_payload.len));
bson_destroy (&server_reply);
if (!_run_command (
cluster, stream, sd, &client_command, &server_reply, error)) {
goto fail;
}
ret = true;
fail:
bson_destroy (&client_payload);
bson_destroy (&client_command);
bson_destroy (&server_reply);
kms_request_destroy (request);
free (signature);
bson_free (server_nonce_str);
return ret;
}
bool
_mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
bool ret = false;
uint8_t server_nonce[64];
char *sts_fqdn = NULL;
char *region = NULL;
int conv_id = 0;
_mongoc_aws_credentials_t creds = {0};
if (!_mongoc_aws_credentials_obtain (cluster->client->uri, &creds, error)) {
goto fail;
}
if (!_client_first (cluster,
stream,
sd,
server_nonce,
&sts_fqdn,
&region,
&conv_id,
error)) {
goto fail;
}
if (!_client_second (cluster,
stream,
sd,
&creds,
server_nonce,
sts_fqdn,
region,
conv_id,
error)) {
goto fail;
}
ret = true;
fail:
_mongoc_aws_credentials_cleanup (&creds);
bson_free (sts_fqdn);
bson_free (region);
return ret;
}
#else
bool
_mongoc_cluster_auth_node_aws (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
AUTH_ERROR_AND_FAIL ("AWS auth not supported, configure libmongoc with "
"ENABLE_MONGODB_AWS_AUTH=ON");
fail:
return false;
}
bool
_mongoc_aws_credentials_obtain (mongoc_uri_t *uri,
_mongoc_aws_credentials_t *creds,
bson_error_t *error)
{
AUTH_ERROR_AND_FAIL ("AWS auth not supported, configure libmongoc with "
"ENABLE_MONGODB_AWS_AUTH=ON");
fail:
return false;
}
void
_mongoc_aws_credentials_cleanup (_mongoc_aws_credentials_t *creds)
{
return;
}
bool
_mongoc_validate_and_derive_region (char *sts_fqdn,
uint32_t sts_fqdn_len,
char **region,
bson_error_t *error)
{
AUTH_ERROR_AND_FAIL ("AWS auth not supported, configure libmongoc with "
"ENABLE_MONGODB_AWS_AUTH=ON");
fail:
return false;
}
#endif /* MONGOC_ENABLE_MONGODB_AWS_AUTH */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
index 675102f9..e8452231 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h
@@ -1,234 +1,239 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CLUSTER_PRIVATE_H
#define MONGOC_CLUSTER_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-array-private.h"
#include "mongoc-buffer-private.h"
#include "mongoc-config.h"
#include "mongoc-client.h"
#include "mongoc-list-private.h"
#include "mongoc-opcode.h"
#include "mongoc-rpc-private.h"
#include "mongoc-server-stream-private.h"
#include "mongoc-set-private.h"
#include "mongoc-stream.h"
#include "mongoc-topology-private.h"
#include "mongoc-topology-description-private.h"
#include "mongoc-write-concern.h"
#include "mongoc-scram-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-crypto-private.h"
BSON_BEGIN_DECLS
typedef struct _mongoc_cluster_node_t {
mongoc_stream_t *stream;
char *connection_address;
/* handshake_sd is a server description created from the handshake on the
* stream. */
mongoc_server_description_t *handshake_sd;
} mongoc_cluster_node_t;
typedef struct _mongoc_cluster_t {
int64_t operation_id;
uint32_t request_id;
uint32_t sockettimeoutms;
uint32_t socketcheckintervalms;
mongoc_uri_t *uri;
unsigned requires_auth : 1;
mongoc_client_t *client;
mongoc_set_t *nodes;
mongoc_array_t iov;
mongoc_scram_cache_t *scram_cache;
} mongoc_cluster_t;
void
mongoc_cluster_init (mongoc_cluster_t *cluster,
const mongoc_uri_t *uri,
void *client);
void
mongoc_cluster_destroy (mongoc_cluster_t *cluster);
void
mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, uint32_t id);
int32_t
mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster);
int32_t
mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster);
size_t
_mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov,
size_t iovcnt,
int skip,
char *buffer);
bool
mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id);
bool
mongoc_cluster_legacy_rpc_sendv_to_server (
mongoc_cluster_t *cluster,
mongoc_rpc_t *rpcs,
mongoc_server_stream_t *server_stream,
bson_error_t *error);
bool
mongoc_cluster_try_recv (mongoc_cluster_t *cluster,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error);
/**
* @brief Obtain a server stream appropriate for read operations on the
* cluster.
*
* Returns a new stream (that must be freed) or NULL and sets an error via
* `error`.
*
* @note The returned stream must be released via
* `mongoc_server_stream_cleanup`.
*
* @note May add nodes and/or update the cluster's topology.
*/
mongoc_server_stream_t *
mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster,
const mongoc_read_prefs_t *read_prefs,
mongoc_client_session_t *cs,
bson_t *reply,
bool is_aggr_with_write,
bson_error_t *error);
/**
* @brief Obtain a server stream appropriate for write operations on the
* cluster.
*
* Returns a new stream (that must be freed) or NULL and sets an error via
* `error`.
*
* @note The returned stream must be released via `mongoc_server_stream_cleanup`
*
* @note May add nodes and/or update the cluster's topology.
*/
mongoc_server_stream_t *
mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error);
/**
* @brief Obtain a server stream associated with the cluster node associated
* with the given server ID.
*
* Returns a new server stream (that must be freed) or NULL and sets `error`.
*
* @param server_id The ID of a server in the cluster topology.
* @param reconnect_ok If `true`, the server exists in the topology but is not
* connected, then attempt to reconnect with the server. If `false`, then only
* create a stream if the server is connected and ready.
*
* @note The returned stream must be released via `mongoc_server_stream_cleanup`
*
* @note May update the cluster's topology.
*/
mongoc_server_stream_t *
mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error);
bool
mongoc_cluster_stream_valid (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream);
bool
mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error);
bool
mongoc_cluster_run_command_parts (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
mongoc_cmd_parts_t *parts,
bson_t *reply,
bson_error_t *error);
bool
mongoc_cluster_run_command_private (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error);
void
_mongoc_cluster_build_sasl_start (bson_t *cmd,
const char *mechanism,
const char *buf,
uint32_t buflen);
void
_mongoc_cluster_build_sasl_continue (bson_t *cmd,
int conv_id,
const char *buf,
uint32_t buflen);
int
_mongoc_cluster_get_conversation_id (const bson_t *reply);
mongoc_server_stream_t *
_mongoc_cluster_create_server_stream (const mongoc_topology_description_t *td,
const mongoc_server_description_t *sd,
mongoc_stream_t *stream);
bool
_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri,
const mongoc_ssl_opt_t *ssl_opts,
bson_t *cmd /* OUT */,
bson_error_t *error /* OUT */);
+/* Returns true if a versioned server API has been selected,
+ * otherwise returns false. */
+bool
+mongoc_cluster_uses_server_api (const mongoc_cluster_t *cluster);
+
#ifdef MONGOC_ENABLE_CRYPTO
void
_mongoc_cluster_init_scram (const mongoc_cluster_t *cluster,
mongoc_scram_t *scram,
mongoc_crypto_hash_algorithm_t algo);
bool
_mongoc_cluster_get_auth_cmd_scram (mongoc_crypto_hash_algorithm_t algo,
mongoc_scram_t *scram,
bson_t *cmd /* OUT */,
bson_error_t *error /* OUT */);
#endif /* MONGOC_ENABLE_CRYPTO */
BSON_END_DECLS
#endif /* MONGOC_CLUSTER_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
index 82cfe44d..ff3f7714 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c
@@ -1,3560 +1,3591 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-config.h"
#include <string.h>
#include "mongoc-cluster-private.h"
#include "mongoc-client-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-config.h"
#include "mongoc-error.h"
#include "mongoc-flags-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-log.h"
#include "mongoc-cluster-sasl-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-ssl.h"
#include "mongoc-ssl-private.h"
#include "mongoc-stream-tls.h"
#endif
#include "common-b64-private.h"
#include "mongoc-scram-private.h"
#include "mongoc-set-private.h"
#include "mongoc-socket.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-socket.h"
#include "mongoc-stream-tls.h"
#include "mongoc-thread-private.h"
#include "mongoc-topology-private.h"
#include "mongoc-topology-background-monitoring-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-rpc-private.h"
#include "mongoc-compression-private.h"
#include "mongoc-cmd-private.h"
#include "utlist.h"
#include "mongoc-handshake-private.h"
#include "mongoc-cluster-aws-private.h"
#include "mongoc-error-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "cluster"
#define CHECK_CLOSED_DURATION_MSEC 1000
#define IS_NOT_COMMAND(_name) (!!strcasecmp (cmd->command_name, _name))
static mongoc_server_stream_t *
_cluster_fetch_stream_single (mongoc_cluster_t *cluster,
const mongoc_topology_description_t *td,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error);
static mongoc_server_stream_t *
_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster,
const mongoc_topology_description_t *td,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error);
static bool
mongoc_cluster_run_opmsg (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error);
static void
_bson_error_message_printf (bson_error_t *error, const char *format, ...)
BSON_GNUC_PRINTF (2, 3);
static void
_handle_not_primary_error (mongoc_cluster_t *cluster,
const mongoc_server_stream_t *server_stream,
const bson_t *reply)
{
uint32_t server_id;
server_id = server_stream->sd->id;
if (_mongoc_topology_handle_app_error (cluster->client->topology,
server_id,
true /* handshake complete */,
MONGOC_SDAM_APP_ERROR_COMMAND,
reply,
NULL,
server_stream->sd->max_wire_version,
server_stream->sd->generation,
&server_stream->sd->service_id)) {
mongoc_cluster_disconnect_node (cluster, server_id);
}
}
/* Called when a network error occurs on an application socket.
*/
static void
_handle_network_error (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
bool handshake_complete,
const bson_error_t *why)
{
mongoc_topology_t *topology;
uint32_t server_id;
_mongoc_sdam_app_error_type_t type;
BSON_ASSERT (server_stream);
ENTRY;
topology = cluster->client->topology;
server_id = server_stream->sd->id;
type = MONGOC_SDAM_APP_ERROR_NETWORK;
if (mongoc_stream_timed_out (server_stream->stream)) {
type = MONGOC_SDAM_APP_ERROR_TIMEOUT;
}
_mongoc_topology_handle_app_error (topology,
server_id,
handshake_complete,
type,
NULL,
why,
server_stream->sd->max_wire_version,
server_stream->sd->generation,
&server_stream->sd->service_id);
/* Always disconnect the current connection on network error. */
mongoc_cluster_disconnect_node (cluster, server_id);
EXIT;
}
size_t
_mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov,
size_t iovcnt,
int skip,
char *buffer)
{
int n;
size_t buffer_offset = 0;
int total_iov_len = 0;
int difference = 0;
for (n = 0; n < iovcnt; n++) {
total_iov_len += iov[n].iov_len;
if (total_iov_len <= skip) {
continue;
}
/* If this iovec starts before the skip, and takes the total count
* beyond the skip, we need to figure out the portion of the iovec
* we should skip passed */
if (total_iov_len - iov[n].iov_len < skip) {
difference = skip - (total_iov_len - iov[n].iov_len);
} else {
difference = 0;
}
memcpy (buffer + buffer_offset,
((char *) iov[n].iov_base) + difference,
iov[n].iov_len - difference);
buffer_offset += iov[n].iov_len - difference;
}
return buffer_offset;
}
/* Allows caller to safely overwrite error->message with a formatted string,
* even if the formatted string includes original error->message. */
static void
_bson_error_message_printf (bson_error_t *error, const char *format, ...)
{
va_list args;
char error_message[sizeof error->message];
if (error) {
va_start (args, format);
bson_vsnprintf (error_message, sizeof error->message, format, args);
va_end (args);
bson_strncpy (error->message, error_message, sizeof error->message);
}
}
#define RUN_CMD_ERR_DECORATE \
do { \
_bson_error_message_printf ( \
error, \
"Failed to send \"%s\" command with database \"%s\": %s", \
cmd->command_name, \
cmd->db_name, \
error->message); \
} while (0)
#define RUN_CMD_ERR(_domain, _code, ...) \
do { \
bson_set_error (error, _domain, _code, __VA_ARGS__); \
RUN_CMD_ERR_DECORATE; \
} while (0)
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_opquery --
*
* Internal function to run a command on a given stream. @error and
* @reply are optional out-pointers.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set and should ALWAYS be released with bson_destroy().
* On failure, @error is filled out. If this was a network error
* and server_id is nonzero, the cluster disconnects from the server.
*
*--------------------------------------------------------------------------
*/
static bool
mongoc_cluster_run_command_opquery (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
int32_t compressor_id,
bson_t *reply,
bson_error_t *error)
{
const size_t reply_header_size = sizeof (mongoc_rpc_reply_header_t);
uint8_t reply_header_buf[sizeof (mongoc_rpc_reply_header_t)];
uint8_t *reply_buf; /* reply body */
mongoc_rpc_t rpc; /* sent to server */
bson_t reply_local;
bson_t *reply_ptr;
char *cmd_ns;
uint32_t request_id;
int32_t msg_len;
size_t doc_len;
bool ret = false;
char *output = NULL;
mongoc_stream_t *stream;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (cmd);
BSON_ASSERT (cmd->server_stream);
stream = cmd->server_stream->stream;
/*
* setup
*/
reply_ptr = reply ? reply : &reply_local;
bson_init (reply_ptr);
error->code = 0;
/*
* prepare the request
*/
_mongoc_array_clear (&cluster->iov);
cmd_ns = bson_strdup_printf ("%s.$cmd", cmd->db_name);
request_id = ++cluster->request_id;
_mongoc_rpc_prep_command (&rpc, cmd_ns, cmd);
rpc.header.request_id = request_id;
_mongoc_rpc_gather (&rpc, &cluster->iov);
_mongoc_rpc_swab_to_le (&rpc);
if (compressor_id != -1 && IS_NOT_COMMAND (HANDSHAKE_CMD_LEGACY_HELLO) &&
IS_NOT_COMMAND ("hello") && IS_NOT_COMMAND ("saslstart") &&
IS_NOT_COMMAND ("saslcontinue") && IS_NOT_COMMAND ("getnonce") &&
IS_NOT_COMMAND ("authenticate") && IS_NOT_COMMAND ("createuser") &&
IS_NOT_COMMAND ("updateuser")) {
output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error);
if (output == NULL) {
GOTO (done);
}
}
if (cluster->client->in_exhaust) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"A cursor derived from this client is in exhaust.");
GOTO (done);
}
/*
* send and receive
*/
if (!_mongoc_stream_writev_full (stream,
cluster->iov.data,
cluster->iov.len,
cluster->sockettimeoutms,
error)) {
_handle_network_error (
cluster, cmd->server_stream, true /* handshake complete */, error);
/* add info about the command to writev_full's error message */
RUN_CMD_ERR_DECORATE;
GOTO (done);
}
if (reply_header_size != mongoc_stream_read (stream,
&reply_header_buf,
reply_header_size,
reply_header_size,
cluster->sockettimeoutms)) {
RUN_CMD_ERR (MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"socket error or timeout");
_handle_network_error (
cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
memcpy (&msg_len, reply_header_buf, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if ((msg_len < reply_header_size) ||
(msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE)) {
_handle_network_error (
cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
if (!_mongoc_rpc_scatter_reply_header_only (
&rpc, reply_header_buf, reply_header_size)) {
_handle_network_error (
cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
doc_len = (size_t) msg_len - reply_header_size;
if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) {
bson_t tmp = BSON_INITIALIZER;
uint8_t *buf = NULL;
size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
reply_buf = bson_malloc0 (msg_len);
memcpy (reply_buf, reply_header_buf, reply_header_size);
if (doc_len != mongoc_stream_read (stream,
reply_buf + reply_header_size,
doc_len,
doc_len,
cluster->sockettimeoutms)) {
RUN_CMD_ERR (MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"socket error or timeout");
_handle_network_error (
cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
if (!_mongoc_rpc_scatter (&rpc, reply_buf, msg_len)) {
GOTO (done);
}
buf = bson_malloc0 (len);
if (!_mongoc_rpc_decompress (&rpc, buf, len)) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress server reply");
bson_free (reply_buf);
bson_free (buf);
GOTO (done);
}
_mongoc_rpc_swab_from_le (&rpc);
if (!_mongoc_rpc_get_first_document (&rpc, &tmp)) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Corrupt compressed OP_QUERY reply from server");
bson_free (reply_buf);
bson_free (buf);
GOTO (done);
}
bson_copy_to (&tmp, reply_ptr);
bson_free (reply_buf);
bson_free (buf);
} else if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_REPLY &&
BSON_UINT32_FROM_LE (rpc.reply_header.n_returned) == 1) {
reply_buf = bson_reserve_buffer (reply_ptr, (uint32_t) doc_len);
BSON_ASSERT (reply_buf);
if (doc_len != mongoc_stream_read (stream,
(void *) reply_buf,
doc_len,
doc_len,
cluster->sockettimeoutms)) {
RUN_CMD_ERR (MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"socket error or timeout");
_handle_network_error (
cluster, cmd->server_stream, true /* handshake complete */, error);
GOTO (done);
}
_mongoc_rpc_swab_from_le (&rpc);
} else {
GOTO (done);
}
if (!_mongoc_cmd_check_ok (
reply_ptr, cluster->client->error_api_version, error)) {
GOTO (done);
}
ret = true;
done:
if (!ret && error->code == 0) {
/* generic error */
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server.");
}
if (reply_ptr == &reply_local) {
bson_destroy (reply_ptr);
}
bson_free (output);
bson_free (cmd_ns);
RETURN (ret);
}
bool
_in_sharded_txn (const mongoc_client_session_t *session)
{
return session && _mongoc_client_session_in_txn_or_ending (session) &&
_mongoc_topology_get_type (session->client->topology) ==
MONGOC_TOPOLOGY_SHARDED;
}
static void
_handle_txn_error_labels (bool cmd_ret,
const bson_error_t *cmd_err,
const mongoc_cmd_t *cmd,
bson_t *reply)
{
if (!cmd->is_txn_finish) {
return;
}
_mongoc_write_error_handle_labels (
cmd_ret, cmd_err, reply, cmd->server_stream->sd->max_wire_version);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_monitored --
*
* Internal function to run a command on a given stream.
* @error and @reply are optional out-pointers.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* If the client's APM callbacks are set, they are executed.
* @reply is set and should ALWAYS be released with bson_destroy().
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error)
{
bool retval;
uint32_t request_id = ++cluster->request_id;
uint32_t server_id;
mongoc_apm_callbacks_t *callbacks;
mongoc_apm_command_started_t started_event;
mongoc_apm_command_succeeded_t succeeded_event;
mongoc_apm_command_failed_t failed_event;
int64_t started = bson_get_monotonic_time ();
const mongoc_server_stream_t *server_stream;
bson_t reply_local;
bson_error_t error_local;
int32_t compressor_id;
bson_iter_t iter;
bson_t encrypted = BSON_INITIALIZER;
bson_t decrypted = BSON_INITIALIZER;
mongoc_cmd_t encrypted_cmd;
bool is_redacted = false;
server_stream = cmd->server_stream;
server_id = server_stream->sd->id;
compressor_id = mongoc_server_description_compressor_id (server_stream->sd);
callbacks = &cluster->client->apm_callbacks;
if (!reply) {
reply = &reply_local;
}
if (!error) {
error = &error_local;
}
if (_mongoc_cse_is_enabled (cluster->client)) {
bson_destroy (&encrypted);
retval = _mongoc_cse_auto_encrypt (
cluster->client, cmd, &encrypted_cmd, &encrypted, error);
cmd = &encrypted_cmd;
if (!retval) {
bson_init (reply);
goto fail_no_events;
}
}
if (callbacks->started) {
mongoc_apm_command_started_init_with_cmd (&started_event,
cmd,
request_id,
&is_redacted,
cluster->client->apm_context);
callbacks->started (&started_event);
mongoc_apm_command_started_cleanup (&started_event);
}
- if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
+ if (mongoc_cluster_uses_server_api (cluster) ||
+ server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error);
} else {
retval = mongoc_cluster_run_command_opquery (
cluster, cmd, compressor_id, reply, error);
}
- if (_mongoc_cse_is_enabled (cluster->client)) {
- bson_destroy (&decrypted);
- retval = _mongoc_cse_auto_decrypt (
- cluster->client, cmd->db_name, reply, &decrypted, error);
- bson_destroy (reply);
- bson_steal (reply, &decrypted);
- bson_init (&decrypted);
- if (!retval) {
- goto fail_no_events;
- }
- }
-
if (retval && callbacks->succeeded) {
bson_t fake_reply = BSON_INITIALIZER;
/*
* Unacknowledged writes must provide a CommandSucceededEvent with an
* {ok: 1} reply.
* https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes
*/
if (!cmd->is_acknowledged) {
bson_append_int32 (&fake_reply, "ok", 2, 1);
}
- mongoc_apm_command_succeeded_init (&succeeded_event,
- bson_get_monotonic_time () - started,
- cmd->is_acknowledged ? reply
- : &fake_reply,
- cmd->command_name,
- request_id,
- cmd->operation_id,
- &server_stream->sd->host,
- server_id,
- &server_stream->sd->service_id,
- is_redacted,
- cluster->client->apm_context);
+ mongoc_apm_command_succeeded_init (
+ &succeeded_event,
+ bson_get_monotonic_time () - started,
+ cmd->is_acknowledged ? reply : &fake_reply,
+ cmd->command_name,
+ request_id,
+ cmd->operation_id,
+ &server_stream->sd->host,
+ server_id,
+ &server_stream->sd->service_id,
+ server_stream->sd->server_connection_id,
+ is_redacted,
+ cluster->client->apm_context);
callbacks->succeeded (&succeeded_event);
mongoc_apm_command_succeeded_cleanup (&succeeded_event);
bson_destroy (&fake_reply);
}
if (!retval && callbacks->failed) {
mongoc_apm_command_failed_init (&failed_event,
bson_get_monotonic_time () - started,
cmd->command_name,
error,
reply,
request_id,
cmd->operation_id,
&server_stream->sd->host,
server_id,
&server_stream->sd->service_id,
+ server_stream->sd->server_connection_id,
is_redacted,
cluster->client->apm_context);
callbacks->failed (&failed_event);
mongoc_apm_command_failed_cleanup (&failed_event);
}
+ if (retval && _mongoc_cse_is_enabled (cluster->client)) {
+ bson_destroy (&decrypted);
+ retval = _mongoc_cse_auto_decrypt (
+ cluster->client, cmd->db_name, reply, &decrypted, error);
+ bson_destroy (reply);
+ bson_steal (reply, &decrypted);
+ bson_init (&decrypted);
+ if (!retval) {
+ goto fail_no_events;
+ }
+ }
+
_handle_not_primary_error (cluster, server_stream, reply);
_handle_txn_error_labels (retval, error, cmd, reply);
if (retval && _in_sharded_txn (cmd->session) &&
bson_iter_init_find (&iter, reply, "recoveryToken")) {
bson_destroy (cmd->session->recovery_token);
if (BSON_ITER_HOLDS_DOCUMENT (&iter)) {
cmd->session->recovery_token =
bson_new_from_data (bson_iter_value (&iter)->value.v_doc.data,
bson_iter_value (&iter)->value.v_doc.data_len);
} else {
MONGOC_ERROR ("Malformed recovery token from server");
cmd->session->recovery_token = NULL;
}
}
fail_no_events:
if (reply == &reply_local) {
bson_destroy (&reply_local);
}
bson_destroy (&encrypted);
bson_destroy (&decrypted);
_mongoc_topology_update_last_used (cluster->client->topology, server_id);
return retval;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_private --
*
* Internal function to run a command on a given stream.
* @error and @reply are optional out-pointers.
* The client's APM callbacks are not executed.
* Automatic encryption/decryption is not performed.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set and should ALWAYS be released with bson_destroy().
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_run_command_private (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error)
{
bool retval;
const mongoc_server_stream_t *server_stream;
bson_t reply_local;
bson_error_t error_local;
if (!error) {
error = &error_local;
}
+ /* If NULL was passed, we use our local variable as a temporary sink: */
if (!reply) {
reply = &reply_local;
}
+
server_stream = cmd->server_stream;
- if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
+
+ if (mongoc_cluster_uses_server_api (cluster) ||
+ server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
retval = mongoc_cluster_run_opmsg (cluster, cmd, reply, error);
} else {
retval =
mongoc_cluster_run_command_opquery (cluster, cmd, -1, reply, error);
}
+
_handle_not_primary_error (cluster, server_stream, reply);
+
if (reply == &reply_local) {
bson_destroy (&reply_local);
}
_mongoc_topology_update_last_used (cluster->client->topology,
server_stream->sd->id);
return retval;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_run_command_parts --
*
* Internal function to assemble command parts and run a command
* on a given stream. @error and @reply are optional out-pointers.
* The client's APM callbacks are not executed.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set and should ALWAYS be released with bson_destroy().
* mongoc_cmd_parts_cleanup will be always be called on parts. The
* caller should *not* call cleanup on the parts.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_run_command_parts (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream,
mongoc_cmd_parts_t *parts,
bson_t *reply,
bson_error_t *error)
{
bool ret;
if (!mongoc_cmd_parts_assemble (parts, server_stream, error)) {
_mongoc_bson_init_if_set (reply);
mongoc_cmd_parts_cleanup (parts);
return false;
}
ret = mongoc_cluster_run_command_private (
cluster, &parts->assembled, reply, error);
mongoc_cmd_parts_cleanup (parts);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* _stream_run_hello --
*
* Run a hello command on the given stream. If
* @negotiate_sasl_supported_mechs is true, then saslSupportedMechs is
* added to the hello command.
*
* Returns:
* A mongoc_server_description_t you must destroy or NULL. If the call
* failed its error is set and its type is MONGOC_SERVER_UNKNOWN.
*
*--------------------------------------------------------------------------
*/
static mongoc_server_description_t *
_stream_run_hello (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const char *address,
uint32_t server_id,
bool negotiate_sasl_supported_mechs,
mongoc_scram_cache_t *scram_cache,
mongoc_scram_t *scram,
bson_t *speculative_auth_response /* OUT */,
bson_error_t *error)
{
- bson_t command; /* Initialized by dup_handshake below */
+ bson_t handshake_command; /* Initialized by dup_handshake below */
mongoc_cmd_t hello_cmd;
bson_t reply;
int64_t start;
int64_t rtt_msec;
mongoc_server_description_t empty_sd;
mongoc_server_description_t *ret_handshake_sd;
mongoc_server_stream_t *server_stream;
bool r;
bson_iter_t iter;
mongoc_ssl_opt_t *ssl_opts = NULL;
mc_shared_tpld td =
mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (cluster)->client->topology);
ENTRY;
BSON_ASSERT (stream);
- _mongoc_topology_dup_handshake_cmd (cluster->client->topology, &command);
+ _mongoc_topology_dup_handshake_cmd (cluster->client->topology,
+ &handshake_command);
if (cluster->requires_auth && speculative_auth_response) {
#ifdef MONGOC_ENABLE_SSL
ssl_opts = &cluster->client->ssl_opts;
#endif
_mongoc_topology_scanner_add_speculative_authentication (
- &command, cluster->uri, ssl_opts, scram_cache, scram);
+ &handshake_command, cluster->uri, ssl_opts, scram_cache, scram);
}
if (negotiate_sasl_supported_mechs) {
- _mongoc_handshake_append_sasl_supported_mechs (cluster->uri, &command);
+ _mongoc_handshake_append_sasl_supported_mechs (cluster->uri,
+ &handshake_command);
}
start = bson_get_monotonic_time ();
/* TODO CDRIVER-3654: do not use a mongoc_server_stream here.
* Instead, use a plain stream. If a network error occurs, check the cluster
* node's generation (which is the generation of the created connection) to
* determine if the error should be handled.
* The current behavior may double invalidate.
- * If a network error occurs in mongoc_cluster_run_command_private below,
+ * If a network error occurs in mongoc_cluster_run_command_private below,
* that invalidates (thinking the error is a post-handshake network error).
* Then _mongoc_cluster_stream_for_server also handles the error, and
* invalidates again.
*/
mongoc_server_description_init (&empty_sd, address, server_id);
server_stream =
_mongoc_cluster_create_server_stream (td.ptr, &empty_sd, stream);
+
mongoc_server_description_cleanup (&empty_sd);
- /* Always use OP_QUERY for the handshake, regardless of whether the last
- * known hello indicates the server supports a newer wire protocol.
- */
+ /* Set up the shared parts of the mongo_cmd_t, which will later be converted
+ to either an op_msg or op_query: */
memset (&hello_cmd, 0, sizeof (hello_cmd));
+
+
hello_cmd.db_name = "admin";
- hello_cmd.command = &command;
- hello_cmd.command_name = _mongoc_get_command_name (&command);
- hello_cmd.query_flags = MONGOC_QUERY_SECONDARY_OK;
+ hello_cmd.command = &handshake_command;
+ hello_cmd.command_name = _mongoc_get_command_name (&handshake_command);
hello_cmd.server_stream = server_stream;
+ hello_cmd.is_acknowledged = true;
+
+ /* Use OP_QUERY for the handshake, unless the user has specified an
+ * API version; the correct hello_cmd has already been selected: */
+ if (!mongoc_cluster_uses_server_api (cluster)) {
+ /* Complete OPCODE_QUERY setup: */
+ hello_cmd.query_flags = MONGOC_QUERY_SECONDARY_OK;
+ } else {
+ /* We're using OP_MSG, and require some additional doctoring: */
+ bson_append_utf8 (&handshake_command, "$db", 3, "admin", 5);
+ }
+
if (!mongoc_cluster_run_command_private (
cluster, &hello_cmd, &reply, error)) {
if (negotiate_sasl_supported_mechs) {
if (bson_iter_init_find (&iter, &reply, "ok") &&
!bson_iter_as_bool (&iter)) {
/* hello response returned ok: 0. According to auth spec: "If the
* hello of the MongoDB Handshake fails with an error, drivers
* MUST treat this an authentication error." */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
}
}
mongoc_server_stream_cleanup (server_stream);
ret_handshake_sd = NULL;
goto done;
}
rtt_msec = (bson_get_monotonic_time () - start) / 1000;
ret_handshake_sd = (mongoc_server_description_t *) bson_malloc0 (
sizeof (mongoc_server_description_t));
mongoc_server_description_init (ret_handshake_sd, address, server_id);
/* send the error from run_command IN to handle_hello */
mongoc_server_description_handle_hello (
ret_handshake_sd, &reply, rtt_msec, error);
if (cluster->requires_auth && speculative_auth_response) {
_mongoc_topology_scanner_parse_speculative_authentication (
&reply, speculative_auth_response);
}
/* Note: This call will render our copy of the topology description to be
* stale */
r = _mongoc_topology_update_from_handshake (cluster->client->topology,
ret_handshake_sd);
if (!r) {
mongoc_server_description_reset (ret_handshake_sd);
bson_set_error (&ret_handshake_sd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"\"%s\" removed from topology",
address);
}
mongoc_server_stream_cleanup (server_stream);
done:
- bson_destroy (&command);
+ bson_destroy (&handshake_command);
bson_destroy (&reply);
mc_tpld_drop_ref (&td);
RETURN (ret_handshake_sd);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_run_hello --
*
* Run an initial hello command for the given node and handle result.
*
* Returns:
* mongoc_server_description_t on success, NULL otherwise.
* the mongoc_server_description_t MUST BE DESTROYED BY THE CALLER.
*
* Side effects:
* Makes a blocking I/O call, updates cluster->topology->description
* with hello result.
*
*--------------------------------------------------------------------------
*/
static mongoc_server_description_t *
_cluster_run_hello (mongoc_cluster_t *cluster,
mongoc_cluster_node_t *node,
uint32_t server_id,
mongoc_scram_cache_t *scram_cache,
mongoc_scram_t *scram /* OUT */,
bson_t *speculative_auth_response /* OUT */,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t *sd;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (node);
BSON_ASSERT (node->stream);
sd = _stream_run_hello (cluster,
node->stream,
node->connection_address,
server_id,
_mongoc_uri_requires_auth_negotiation (cluster->uri),
scram_cache,
scram,
speculative_auth_response,
error);
if (!sd) {
return NULL;
}
if (sd->type == MONGOC_SERVER_UNKNOWN) {
memcpy (error, &sd->error, sizeof (bson_error_t));
mongoc_server_description_destroy (sd);
return NULL;
}
return sd;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_build_basic_auth_digest --
*
* Computes the Basic Authentication digest using the credentials
* configured for @cluster and the @nonce provided.
*
* The result should be freed by the caller using bson_free() when
* they are finished with it.
*
* Returns:
* A newly allocated string containing the digest.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static char *
_mongoc_cluster_build_basic_auth_digest (mongoc_cluster_t *cluster,
const char *nonce)
{
const char *username;
const char *password;
char *password_digest;
char *password_md5;
char *digest_in;
char *ret;
ENTRY;
/*
* The following generates the digest to be used for basic authentication
* with a MongoDB server. More information on the format can be found
* at the following location:
*
* http://docs.mongodb.org/meta-driver/latest/legacy/
* implement-authentication-in-driver/
*/
BSON_ASSERT (cluster);
BSON_ASSERT (cluster->uri);
username = mongoc_uri_get_username (cluster->uri);
password = mongoc_uri_get_password (cluster->uri);
password_digest = bson_strdup_printf ("%s:mongo:%s", username, password);
password_md5 = _mongoc_hex_md5 (password_digest);
digest_in = bson_strdup_printf ("%s%s%s", nonce, username, password_md5);
ret = _mongoc_hex_md5 (digest_in);
bson_free (digest_in);
bson_free (password_md5);
bson_free (password_digest);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node_cr --
*
* Performs authentication of @node using the credentials provided
* when configuring the @cluster instance.
*
* This is the Challenge-Response mode of authentication.
*
* Returns:
* true if authentication was successful; otherwise false and
* @error is set.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_node_cr (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
bson_iter_t iter;
const char *auth_source;
bson_t command;
bson_t reply;
char *digest;
char *nonce;
bool ret;
mongoc_server_stream_t *server_stream;
mc_shared_tpld td;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
if (!(auth_source = mongoc_uri_get_auth_source (cluster->uri)) ||
(*auth_source == '\0')) {
auth_source = "admin";
}
/*
* To authenticate a node using basic authentication, we need to first
* get the nonce from the server. We use that to hash our password which
* is sent as a reply to the server. If everything went good we get a
* success notification back from the server.
*/
/*
* Execute the getnonce command to fetch the nonce used for generating
* md5 digest of our password information.
*/
bson_init (&command);
bson_append_int32 (&command, "getnonce", 8, 1);
mongoc_cmd_parts_init (&parts,
cluster->client,
auth_source,
MONGOC_QUERY_SECONDARY_OK,
&command);
parts.prohibit_lsid = true;
td = mc_tpld_take_ref (cluster->client->topology);
server_stream = _mongoc_cluster_create_server_stream (td.ptr, sd, stream);
mc_tpld_drop_ref (&td);
if (!mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, &reply, error)) {
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&command);
bson_destroy (&reply);
RETURN (false);
}
bson_destroy (&command);
if (!bson_iter_init_find_case (&iter, &reply, "nonce")) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_GETNONCE,
"Invalid reply from getnonce");
bson_destroy (&reply);
RETURN (false);
}
/*
* Build our command to perform the authentication.
*/
nonce = bson_iter_dup_utf8 (&iter, NULL);
digest = _mongoc_cluster_build_basic_auth_digest (cluster, nonce);
bson_init (&command);
bson_append_int32 (&command, "authenticate", 12, 1);
bson_append_utf8 (
&command, "user", 4, mongoc_uri_get_username (cluster->uri), -1);
bson_append_utf8 (&command, "nonce", 5, nonce, -1);
bson_append_utf8 (&command, "key", 3, digest, -1);
bson_destroy (&reply);
bson_free (nonce);
bson_free (digest);
/*
* Execute the authenticate command. mongoc_cluster_run_command_private
* checks for {ok: 1} in the response.
*/
mongoc_cmd_parts_init (&parts,
cluster->client,
auth_source,
MONGOC_QUERY_SECONDARY_OK,
&command);
parts.prohibit_lsid = true;
ret = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, &reply, error);
if (!ret) {
/* error->message is already set */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
}
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&command);
bson_destroy (&reply);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node_plain --
*
* Perform SASL PLAIN authentication for @node. We do this manually
* instead of using the SASL module because it is rather simplistic.
*
* Returns:
* true if successful; otherwise false and error is set.
*
* Side effects:
* error may be set.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_node_plain (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
char buf[4096];
int buflen = 0;
const char *username;
const char *password;
bson_t b = BSON_INITIALIZER;
bson_t reply;
size_t len;
char *str;
bool ret;
mongoc_server_stream_t *server_stream;
mc_shared_tpld td;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
username = mongoc_uri_get_username (cluster->uri);
if (!username) {
username = "";
}
password = mongoc_uri_get_password (cluster->uri);
if (!password) {
password = "";
}
str = bson_strdup_printf ("%c%s%c%s", '\0', username, '\0', password);
len = strlen (username) + strlen (password) + 2;
- buflen = COMMON_PREFIX (
- bson_b64_ntop ((const uint8_t *) str, len, buf, sizeof buf));
+ buflen = mcommon_b64_ntop ((const uint8_t *) str, len, buf, sizeof buf);
bson_free (str);
if (buflen == -1) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"failed base64 encoding message");
return false;
}
BSON_APPEND_INT32 (&b, "saslStart", 1);
BSON_APPEND_UTF8 (&b, "mechanism", "PLAIN");
bson_append_utf8 (&b, "payload", 7, (const char *) buf, buflen);
BSON_APPEND_INT32 (&b, "autoAuthorize", 1);
mongoc_cmd_parts_init (
&parts, cluster->client, "$external", MONGOC_QUERY_SECONDARY_OK, &b);
parts.prohibit_lsid = true;
td = mc_tpld_take_ref (cluster->client->topology);
server_stream = _mongoc_cluster_create_server_stream (td.ptr, sd, stream);
mc_tpld_drop_ref (&td);
ret = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, &reply, error);
mongoc_server_stream_cleanup (server_stream);
if (!ret) {
/* error->message is already set */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
}
bson_destroy (&b);
bson_destroy (&reply);
return ret;
}
bool
_mongoc_cluster_get_auth_cmd_x509 (const mongoc_uri_t *uri,
const mongoc_ssl_opt_t *ssl_opts,
bson_t *cmd /* OUT */,
bson_error_t *error /* OUT */)
{
#ifndef MONGOC_ENABLE_SSL
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The MONGODB-X509 authentication mechanism requires "
"libmongoc built with ENABLE_SSL");
return false;
#else
const char *username_from_uri = NULL;
char *username_from_subject = NULL;
BSON_ASSERT (uri);
username_from_uri = mongoc_uri_get_username (uri);
if (username_from_uri) {
TRACE ("%s", "X509: got username from URI");
} else {
if (!ssl_opts || !ssl_opts->pem_file) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"cannot determine username for "
"X-509 authentication.");
return false;
}
username_from_subject =
mongoc_ssl_extract_subject (ssl_opts->pem_file, ssl_opts->pem_pwd);
if (!username_from_subject) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"No username provided for X509 authentication.");
return false;
}
TRACE ("%s", "X509: got username from certificate");
}
bson_init (cmd);
BSON_APPEND_INT32 (cmd, "authenticate", 1);
BSON_APPEND_UTF8 (cmd, "mechanism", "MONGODB-X509");
BSON_APPEND_UTF8 (cmd,
"user",
username_from_uri ? username_from_uri
: username_from_subject);
bson_free (username_from_subject);
return true;
#endif
}
static bool
_mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
#ifndef MONGOC_ENABLE_SSL
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The MONGODB-X509 authentication mechanism requires "
"libmongoc built with ENABLE_SSL");
return false;
#else
mongoc_cmd_parts_t parts;
bson_t cmd;
bson_t reply;
bool ret;
mongoc_server_stream_t *server_stream;
mc_shared_tpld td;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
if (!_mongoc_cluster_get_auth_cmd_x509 (
cluster->uri, &cluster->client->ssl_opts, &cmd, error)) {
return false;
}
mongoc_cmd_parts_init (
&parts, cluster->client, "$external", MONGOC_QUERY_SECONDARY_OK, &cmd);
parts.prohibit_lsid = true;
td = mc_tpld_take_ref (cluster->client->topology);
server_stream = _mongoc_cluster_create_server_stream (td.ptr, sd, stream);
mc_tpld_drop_ref (&td);
ret = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, &reply, error);
mongoc_server_stream_cleanup (server_stream);
if (!ret) {
/* error->message is already set */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
}
bson_destroy (&cmd);
bson_destroy (&reply);
return ret;
#endif
}
+bool
+mongoc_cluster_uses_server_api (const mongoc_cluster_t *cluster)
+{
+ return mongoc_client_uses_server_api (cluster->client);
+}
+
#ifdef MONGOC_ENABLE_CRYPTO
void
_mongoc_cluster_init_scram (const mongoc_cluster_t *cluster,
mongoc_scram_t *scram,
mongoc_crypto_hash_algorithm_t algo)
{
_mongoc_uri_init_scram (cluster->uri, scram, algo);
/* Apply previously cached SCRAM secrets if available */
if (cluster->scram_cache) {
_mongoc_scram_set_cache (scram, cluster->scram_cache);
}
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_get_auth_cmd_scram --
*
* Generates the saslStart command for scram authentication. Used
* during explicit authentication as well as speculative
* authentication during hello.
*
*
* Returns:
* true if the command could be generated, false otherwise
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cluster_get_auth_cmd_scram (mongoc_crypto_hash_algorithm_t algo,
mongoc_scram_t *scram,
bson_t *cmd /* OUT */,
bson_error_t *error /* OUT */)
{
uint8_t buf[4096] = {0};
uint32_t buflen = 0;
bson_t options;
if (!_mongoc_scram_step (
scram, buf, buflen, buf, sizeof buf, &buflen, error)) {
return false;
}
BSON_ASSERT (scram->step == 1);
bson_init (cmd);
BSON_APPEND_INT32 (cmd, "saslStart", 1);
if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_1) {
BSON_APPEND_UTF8 (cmd, "mechanism", "SCRAM-SHA-1");
} else if (algo == MONGOC_CRYPTO_ALGORITHM_SHA_256) {
BSON_APPEND_UTF8 (cmd, "mechanism", "SCRAM-SHA-256");
} else {
BSON_ASSERT (false);
}
bson_append_binary (cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen);
BSON_APPEND_INT32 (cmd, "autoAuthorize", 1);
BSON_APPEND_DOCUMENT_BEGIN (cmd, "options", &options);
BSON_APPEND_BOOL (&options, "skipEmptyExchange", true);
bson_append_document_end (cmd, &options);
bson_destroy (&options);
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_run_scram_command --
*
* Runs a scram authentication command, handling auth_source and
* errors during the command.
*
*
* Returns:
* true if the command was successful, false otherwise
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_run_scram_command (
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const mongoc_server_description_t *handshake_sd,
const bson_t *cmd,
bson_t *reply,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
mongoc_server_stream_t *server_stream;
const char *auth_source;
mc_shared_tpld td =
mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (cluster)->client->topology);
if (!(auth_source = mongoc_uri_get_auth_source (cluster->uri)) ||
(*auth_source == '\0')) {
auth_source = "admin";
}
mongoc_cmd_parts_init (
&parts, cluster->client, auth_source, MONGOC_QUERY_SECONDARY_OK, cmd);
parts.prohibit_lsid = true;
server_stream =
_mongoc_cluster_create_server_stream (td.ptr, handshake_sd, stream);
mc_tpld_drop_ref (&td);
if (!mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, reply, error)) {
mongoc_server_stream_cleanup (server_stream);
bson_destroy (reply);
/* error->message is already set */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
return false;
}
mongoc_server_stream_cleanup (server_stream);
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_scram_start --
*
* Starts scram authentication by generating and sending the saslStart
* command. The conversation can then be resumed using
* _mongoc_cluster_auth_scram_continue.
*
*
* Returns:
* true if the saslStart command was successful, false otherwise
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_scram_start (
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const mongoc_server_description_t *handshake_sd,
mongoc_crypto_hash_algorithm_t algo,
mongoc_scram_t *scram,
bson_t *reply,
bson_error_t *error)
{
bson_t cmd;
BSON_ASSERT (scram->step == 0);
if (!_mongoc_cluster_get_auth_cmd_scram (algo, scram, &cmd, error)) {
/* error->message is already set */
error->domain = MONGOC_ERROR_CLIENT;
error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
return false;
}
if (!_mongoc_cluster_run_scram_command (
cluster, stream, handshake_sd, &cmd, reply, error)) {
bson_destroy (&cmd);
return false;
}
bson_destroy (&cmd);
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_scram_handle_reply --
*
* Handles replies from _mongoc_cluster_run_scram_command. The @done
* argument will be set to true if the scram conversation was
* completed successfully.
*
*
* Returns:
* true if the reply was handled successfully, false if there was an
* error. Note that the return value itself does not indicate whether
* authentication was completed successfully.
*
* Side effects:
* @error is set on failure. @done, @conv_id, @buf, and @buflen are
* set for use in the next scram step.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_scram_handle_reply (mongoc_scram_t *scram,
const bson_t *reply,
bool *done /* OUT */,
int *conv_id /* OUT */,
uint8_t *buf /* OUT */,
uint32_t bufmax,
uint32_t *buflen /* OUT */,
bson_error_t *error)
{
bson_iter_t iter;
bson_subtype_t btype;
const char *tmpstr;
BSON_ASSERT (scram);
if (bson_iter_init_find (&iter, reply, "done") &&
bson_iter_as_bool (&iter)) {
if (scram->step < 2) {
/* Prior to step 2, we haven't even received server proof. */
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Incorrect step for 'done'");
return false;
}
*done = true;
if (scram->step >= 3) {
return true;
}
}
if (!bson_iter_init_find (&iter, reply, "conversationId") ||
!BSON_ITER_HOLDS_INT32 (&iter) ||
!(*conv_id = bson_iter_int32 (&iter)) ||
!bson_iter_init_find (&iter, reply, "payload") ||
!BSON_ITER_HOLDS_BINARY (&iter)) {
const char *errmsg = "Received invalid SCRAM reply from MongoDB server.";
MONGOC_DEBUG ("SCRAM: authentication failed");
if (bson_iter_init_find (&iter, reply, "errmsg") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
errmsg = bson_iter_utf8 (&iter, NULL);
}
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"%s",
errmsg);
return false;
}
bson_iter_binary (&iter, &btype, buflen, (const uint8_t **) &tmpstr);
if (*buflen > bufmax) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"SCRAM reply from MongoDB is too large.");
return false;
}
memcpy (buf, tmpstr, *buflen);
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_scram_continue --
*
* Continues the scram conversation from the reply to a saslStart
* command, either sent explicitly or received through speculative
* authentication during hello.
*
*
* Returns:
* true if authenticated. false on failure and @error is set.
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_scram_continue (
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const mongoc_server_description_t *handshake_sd,
mongoc_scram_t *scram,
const bson_t *sasl_start_reply,
bson_error_t *error)
{
bson_t cmd;
uint8_t buf[4096] = {0};
uint32_t buflen = 0;
int conv_id = 0;
bool done = false;
bson_t reply_local;
if (!_mongoc_cluster_scram_handle_reply (scram,
sasl_start_reply,
&done,
&conv_id,
buf,
sizeof buf,
&buflen,
error)) {
return false;
}
for (;;) {
if (!_mongoc_scram_step (
scram, buf, buflen, buf, sizeof buf, &buflen, error)) {
return false;
}
if (done && (scram->step >= 3)) {
break;
}
bson_init (&cmd);
BSON_APPEND_INT32 (&cmd, "saslContinue", 1);
BSON_APPEND_INT32 (&cmd, "conversationId", conv_id);
bson_append_binary (&cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen);
TRACE ("SCRAM: authenticating (step %d)", scram->step);
if (!_mongoc_cluster_run_scram_command (
cluster, stream, handshake_sd, &cmd, &reply_local, error)) {
bson_destroy (&cmd);
return false;
}
bson_destroy (&cmd);
if (!_mongoc_cluster_scram_handle_reply (scram,
&reply_local,
&done,
&conv_id,
buf,
sizeof buf,
&buflen,
error)) {
bson_destroy (&reply_local);
return false;
}
bson_destroy (&reply_local);
if (done && (scram->step >= 3)) {
break;
}
}
TRACE ("%s", "SCRAM: authenticated");
/* Save cached SCRAM secrets for future use */
if (cluster->scram_cache) {
_mongoc_scram_cache_destroy (cluster->scram_cache);
}
cluster->scram_cache = _mongoc_scram_get_cache (scram);
return true;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node_scram --
*
* Invokes scram authentication by sending a saslStart command and
* handling all replies.
*
*
* Returns:
* true if authenticated. false on failure and @error is set.
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_node_scram (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *handshake_sd,
mongoc_crypto_hash_algorithm_t algo,
bson_error_t *error)
{
mongoc_scram_t scram;
bool ret = false;
bson_t reply;
BSON_ASSERT (cluster);
_mongoc_cluster_init_scram (cluster, &scram, algo);
if (!_mongoc_cluster_auth_scram_start (
cluster, stream, handshake_sd, algo, &scram, &reply, error)) {
goto failure;
}
if (!_mongoc_cluster_auth_scram_continue (
cluster, stream, handshake_sd, &scram, &reply, error)) {
bson_destroy (&reply);
goto failure;
}
TRACE ("%s", "SCRAM: authenticated");
ret = true;
bson_destroy (&reply);
failure:
_mongoc_scram_destroy (&scram);
return ret;
}
#endif
static bool
_mongoc_cluster_auth_node_scram_sha_1 (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
#ifndef MONGOC_ENABLE_CRYPTO
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The SCRAM_SHA_1 authentication mechanism requires "
"libmongoc built with ENABLE_SSL");
return false;
#else
return _mongoc_cluster_auth_node_scram (
cluster, stream, sd, MONGOC_CRYPTO_ALGORITHM_SHA_1, error);
#endif
}
static bool
_mongoc_cluster_auth_node_scram_sha_256 (mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
bson_error_t *error)
{
#ifndef MONGOC_ENABLE_CRYPTO
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"The SCRAM_SHA_256 authentication mechanism requires "
"libmongoc built with ENABLE_SSL");
return false;
#else
return _mongoc_cluster_auth_node_scram (
cluster, stream, sd, MONGOC_CRYPTO_ALGORITHM_SHA_256, error);
#endif
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cluster_auth_node --
*
* Authenticate a cluster node depending on the required mechanism.
*
* Returns:
* true if authenticated. false on failure and @error is set.
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
static bool
_mongoc_cluster_auth_node (
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *sd,
const mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs,
bson_error_t *error)
{
bool ret = false;
const char *mechanism;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (stream);
mechanism = mongoc_uri_get_auth_mechanism (cluster->uri);
if (!mechanism) {
if (sasl_supported_mechs->scram_sha_256) {
/* Auth spec: "If SCRAM-SHA-256 is present in the list of mechanisms,
* then it MUST be used as the default; otherwise, SCRAM-SHA-1 MUST be
* used as the default, regardless of whether SCRAM-SHA-1 is in the
* list. Drivers MUST NOT attempt to use any other mechanism (e.g.
* PLAIN) as the default." [...] "If saslSupportedMechs is not present
* in the hello results for mechanism negotiation, then SCRAM-SHA-1
* MUST be used when talking to servers >= 3.0." */
mechanism = "SCRAM-SHA-256";
} else {
mechanism = "SCRAM-SHA-1";
}
}
if (0 == strcasecmp (mechanism, "MONGODB-CR")) {
ret = _mongoc_cluster_auth_node_cr (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "MONGODB-X509")) {
ret = _mongoc_cluster_auth_node_x509 (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "SCRAM-SHA-1")) {
ret = _mongoc_cluster_auth_node_scram_sha_1 (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "SCRAM-SHA-256")) {
ret =
_mongoc_cluster_auth_node_scram_sha_256 (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "GSSAPI")) {
ret = _mongoc_cluster_auth_node_sasl (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "PLAIN")) {
ret = _mongoc_cluster_auth_node_plain (cluster, stream, sd, error);
} else if (0 == strcasecmp (mechanism, "MONGODB-AWS")) {
ret = _mongoc_cluster_auth_node_aws (cluster, stream, sd, error);
} else {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Unknown authentication mechanism \"%s\".",
mechanism);
}
if (!ret) {
mongoc_counter_auth_failure_inc ();
MONGOC_DEBUG ("Authentication failed: %s", error->message);
} else {
mongoc_counter_auth_success_inc ();
TRACE ("%s", "Authentication succeeded");
}
RETURN (ret);
}
/*
* Close the connection associated with this server.
*
* Called when a network error occurs, or to close connection tied to an exhaust
* cursor.
* If the cluster is pooled, removes the node from cluster's set of nodes.
* WARNING: pointers to a disconnected mongoc_cluster_node_t or its stream are
* now invalid, be careful of dangling pointers.
*/
void
mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, uint32_t server_id)
{
mongoc_topology_t *topology = cluster->client->topology;
ENTRY;
if (topology->single_threaded) {
mongoc_topology_scanner_node_t *scanner_node;
scanner_node =
mongoc_topology_scanner_get_node (topology->scanner, server_id);
/* might never actually have connected */
if (scanner_node && scanner_node->stream) {
mongoc_topology_scanner_node_disconnect (scanner_node, true);
}
} else {
mongoc_set_rm (cluster->nodes, server_id);
}
EXIT;
}
static void
_mongoc_cluster_node_destroy (mongoc_cluster_node_t *node)
{
/* Failure, or Replica Set reconfigure without this node */
mongoc_stream_failed (node->stream);
bson_free (node->connection_address);
mongoc_server_description_destroy (node->handshake_sd);
bson_free (node);
}
static void
_mongoc_cluster_node_dtor (void *data_, void *ctx_)
{
mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) data_;
_mongoc_cluster_node_destroy (node);
}
static mongoc_cluster_node_t *
_mongoc_cluster_node_new (mongoc_stream_t *stream,
const char *connection_address)
{
mongoc_cluster_node_t *node;
if (!stream) {
return NULL;
}
node = (mongoc_cluster_node_t *) bson_malloc0 (sizeof *node);
node->stream = stream;
node->connection_address = bson_strdup (connection_address);
+ /* Note that the node->sd field is set to NULL by bson_malloc0(),
+ rather than being explicitly initialized. */
+
return node;
}
static bool
_mongoc_cluster_finish_speculative_auth (
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
mongoc_server_description_t *handshake_sd,
bson_t *speculative_auth_response,
mongoc_scram_t *scram,
bson_error_t *error)
{
const char *mechanism =
_mongoc_topology_scanner_get_speculative_auth_mechanism (cluster->uri);
bool ret = false;
bool auth_handled = false;
BSON_ASSERT (handshake_sd);
BSON_ASSERT (speculative_auth_response);
if (!mechanism) {
return false;
}
if (bson_empty (speculative_auth_response)) {
return false;
}
#ifdef MONGOC_ENABLE_SSL
if (strcasecmp (mechanism, "MONGODB-X509") == 0) {
/* For X509, a successful hello with speculativeAuthenticate field
* indicates successful auth */
ret = true;
auth_handled = true;
}
#endif
#ifdef MONGOC_ENABLE_CRYPTO
if (strcasecmp (mechanism, "SCRAM-SHA-1") == 0 ||
strcasecmp (mechanism, "SCRAM-SHA-256") == 0) {
/* Don't attempt authentication if scram objects have advanced past
* saslStart */
if (scram->step != 1) {
return false;
}
auth_handled = true;
ret = _mongoc_cluster_auth_scram_continue (cluster,
stream,
handshake_sd,
scram,
speculative_auth_response,
error);
}
#endif
if (auth_handled) {
if (!ret) {
mongoc_counter_auth_failure_inc ();
MONGOC_DEBUG ("Speculative authentication failed: %s", error->message);
} else {
mongoc_counter_auth_success_inc ();
TRACE ("%s", "Speculative authentication succeeded");
}
}
bson_reinit (speculative_auth_response);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_add_node --
*
* Add a new node to this cluster for the given server description.
*
* NOTE: does NOT check if this server is already in the cluster.
*
* Returns:
* A stream connected to the server, or NULL on failure.
*
* Side effects:
* Adds a cluster node, or sets error on failure.
*
*--------------------------------------------------------------------------
*/
static mongoc_cluster_node_t *
_cluster_add_node (mongoc_cluster_t *cluster,
const mongoc_topology_description_t *td,
uint32_t server_id,
bson_error_t *error /* OUT */)
{
mongoc_host_list_t *host = NULL;
mongoc_cluster_node_t *cluster_node = NULL;
mongoc_stream_t *stream;
mongoc_server_description_t *handshake_sd;
mongoc_handshake_sasl_supported_mechs_t sasl_supported_mechs;
mongoc_scram_t scram = {0};
bson_t speculative_auth_response = BSON_INITIALIZER;
ENTRY;
BSON_ASSERT (!cluster->client->topology->single_threaded);
host = _mongoc_topology_host_by_id (td, server_id, error);
if (!host) {
GOTO (error);
}
TRACE ("Adding new server to cluster: %s", host->host_and_port);
stream = _mongoc_client_create_stream (cluster->client, host, error);
if (!stream) {
MONGOC_WARNING (
"Failed connection to %s (%s)", host->host_and_port, error->message);
GOTO (error);
/* TODO CDRIVER-3654: if this is a non-timeout network error and the
* generation is not stale, mark the server unknown and increment the
* generation. */
}
/* take critical fields from a fresh hello */
cluster_node = _mongoc_cluster_node_new (stream, host->host_and_port);
handshake_sd = _cluster_run_hello (cluster,
cluster_node,
server_id,
cluster->scram_cache,
&scram,
&speculative_auth_response,
error);
if (!handshake_sd) {
GOTO (error);
}
_mongoc_handshake_parse_sasl_supported_mechs (
&handshake_sd->last_hello_response, &sasl_supported_mechs);
if (cluster->requires_auth) {
/* Complete speculative authentication */
bool is_auth =
_mongoc_cluster_finish_speculative_auth (cluster,
stream,
handshake_sd,
&speculative_auth_response,
&scram,
error);
if (!is_auth && !_mongoc_cluster_auth_node (cluster,
cluster_node->stream,
handshake_sd,
&sasl_supported_mechs,
error)) {
MONGOC_WARNING ("Failed authentication to %s (%s)",
host->host_and_port,
error->message);
mongoc_server_description_destroy (handshake_sd);
GOTO (error);
}
}
/* Transfer ownership of the server description into the cluster node. */
cluster_node->handshake_sd = handshake_sd;
/* Copy the latest connection pool generation.
* TODO (CDRIVER-4078) do not store the generation counter on the server
* description */
handshake_sd->generation = _mongoc_topology_get_connection_pool_generation (
td, server_id, &handshake_sd->service_id);
bson_destroy (&speculative_auth_response);
mongoc_set_add (cluster->nodes, server_id, cluster_node);
_mongoc_host_list_destroy_all (host);
#ifdef MONGOC_ENABLE_CRYPTO
_mongoc_scram_destroy (&scram);
#endif
RETURN (cluster_node);
error:
bson_destroy (&speculative_auth_response);
_mongoc_host_list_destroy_all (host); /* null ok */
#ifdef MONGOC_ENABLE_CRYPTO
_mongoc_scram_destroy (&scram);
#endif
if (cluster_node) {
_mongoc_cluster_node_destroy (cluster_node); /* also destroys stream */
}
RETURN (NULL);
}
static void
node_not_found (const mongoc_topology_description_t *td,
uint32_t server_id,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t const *sd;
if (!error) {
return;
}
sd = mongoc_topology_description_server_by_id_const (td, server_id, error);
if (!sd) {
return;
}
if (sd->error.code) {
memcpy (error, &sd->error, sizeof *error);
} else {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"Could not find node %s",
sd->host.host_and_port);
}
}
static void
stream_not_found (const mongoc_topology_description_t *td,
uint32_t server_id,
const char *connection_address,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t const *sd;
sd = mongoc_topology_description_server_by_id_const (td, server_id, error);
if (error) {
if (sd && sd->error.code) {
memcpy (error, &sd->error, sizeof *error);
} else {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"Could not find stream for node %s",
connection_address);
}
}
}
static mongoc_server_stream_t *
_try_get_server_stream (mongoc_cluster_t *cluster,
const mongoc_topology_description_t *td,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error)
{
if (cluster->client->topology->single_threaded) {
/* in the single-threaded use case we share topology's streams */
return _cluster_fetch_stream_single (
cluster, td, server_id, reconnect_ok, error);
} else {
return _cluster_fetch_stream_pooled (
cluster, td, server_id, reconnect_ok, error);
}
}
mongoc_server_stream_t *
_mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
const mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error /* OUT */)
{
mongoc_topology_t *const topology =
BSON_ASSERT_PTR_INLINE (cluster)->client->topology;
mongoc_server_stream_t *ret_server_stream;
bson_error_t err_local;
/* if fetch_stream fails we need a place to receive error details and pass
* them to mongoc_topology_description_invalidate_server. */
bson_error_t *err_ptr = error ? error : &err_local;
mc_tpld_modification tdmod;
mc_shared_tpld td;
ENTRY;
td = mc_tpld_take_ref (topology);
ret_server_stream = _try_get_server_stream (
cluster, td.ptr, server_id, reconnect_ok, err_ptr);
if (!ret_server_stream) {
/* TODO CDRIVER-3654. A null server stream could be due to:
* 1. Network error during handshake.
* 2. Failure to retrieve server description (if it was removed from
* topology).
* 3. Auth error during handshake.
* Only (1) should mark the server unknown and clear the pool.
* Network errors should be checked at a lower layer than this, when an
* operation on a stream fails, and should take the connection generation
* into account.
*/
/* Update the topology */
tdmod = mc_tpld_modify_begin (topology);
/* Add a transient transaction label if applicable. */
_mongoc_bson_init_with_transient_txn_error (cs, reply);
/* When establishing a new connection in load balanced mode, drivers MUST
* NOT perform SDAM error handling for any errors that occur before the
* MongoDB Handshake. */
if (tdmod.new_td->type == MONGOC_TOPOLOGY_LOAD_BALANCED) {
mc_tpld_modify_drop (tdmod);
ret_server_stream = NULL;
goto done;
}
mongoc_topology_description_invalidate_server (
tdmod.new_td, server_id, err_ptr);
mongoc_cluster_disconnect_node (cluster, server_id);
/* This is not load balanced mode, so there are no service IDs associated
* with connections. Pass kZeroServiceId to clear the entire connection
* pool to this server. */
_mongoc_topology_description_clear_connection_pool (
tdmod.new_td, server_id, &kZeroServiceId);
if (!topology->single_threaded) {
_mongoc_topology_background_monitoring_cancel_check (topology,
server_id);
}
mc_tpld_modify_commit (tdmod);
ret_server_stream = NULL;
goto done;
}
/* If this is a load balanced topology and the server stream does not have a
* service id, disconnect and return an error. */
if (td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED) {
if (!mongoc_server_description_has_service_id (ret_server_stream->sd)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_LOAD_BALANCER,
"Driver attempted to initialize in load balancing "
"mode, but the server does not support this mode.");
mongoc_server_stream_cleanup (ret_server_stream);
mongoc_cluster_disconnect_node (cluster, server_id);
_mongoc_bson_init_if_set (reply);
ret_server_stream = NULL;
goto done;
}
}
done:
mc_tpld_drop_ref (&td);
RETURN (ret_server_stream);
}
mongoc_server_stream_t *
mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
uint32_t server_id,
bool reconnect_ok,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *server_stream = NULL;
bson_error_t err_local = {0};
ENTRY;
BSON_ASSERT (cluster);
if (cs && cs->server_id && cs->server_id != server_id) {
_mongoc_bson_init_if_set (reply);
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_SERVER_SELECTION_INVALID_ID,
"Requested server id does not matched pinned server id");
RETURN (NULL);
}
if (!error) {
error = &err_local;
}
server_stream = _mongoc_cluster_stream_for_server (
cluster, server_id, reconnect_ok, cs, reply, error);
-
if (_in_sharded_txn (cs)) {
_mongoc_client_session_pin (cs, server_id);
} else {
/* Transactions Spec: Additionally, any non-transaction operation using
* a pinned ClientSession MUST unpin the session and the operation MUST
* perform normal server selection. */
if (cs && !_mongoc_client_session_in_txn_or_ending (cs)) {
_mongoc_client_session_unpin (cs);
}
}
RETURN (server_stream);
}
static mongoc_server_stream_t *
_cluster_fetch_stream_single (mongoc_cluster_t *cluster,
const mongoc_topology_description_t *td,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error /* OUT */)
{
mongoc_server_description_t *handshake_sd;
mongoc_topology_scanner_node_t *scanner_node;
char *address;
scanner_node = mongoc_topology_scanner_get_node (
cluster->client->topology->scanner, server_id);
/* This could happen if a user explicitly passes a bad server id. */
if (!scanner_node) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Could not find server with id: %d",
server_id);
return NULL;
}
/* Retired scanner nodes are removed at the end of a scan. If the node was
* retired, that would indicate a bug. */
if (scanner_node->retired) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Unexpected, selecting server marked for removal: %s",
scanner_node->host.host_and_port);
return NULL;
}
if (scanner_node->stream) {
handshake_sd =
mongoc_server_description_new_copy (scanner_node->handshake_sd);
} else {
if (!reconnect_ok) {
stream_not_found (
td, server_id, scanner_node->host.host_and_port, error);
return NULL;
}
/* save the scanner node address in case it is removed during the scan. */
address = bson_strdup (scanner_node->host.host_and_port);
_mongoc_topology_do_blocking_scan (cluster->client->topology, error);
if (error->code) {
bson_free (address);
return NULL;
}
scanner_node = mongoc_topology_scanner_get_node (
cluster->client->topology->scanner, server_id);
if (!scanner_node || !scanner_node->stream) {
stream_not_found (td, server_id, address, error);
bson_free (address);
return NULL;
}
bson_free (address);
handshake_sd =
mongoc_server_description_new_copy (scanner_node->handshake_sd);
}
if (handshake_sd->type == MONGOC_SERVER_UNKNOWN) {
*error = handshake_sd->error;
mongoc_server_description_destroy (handshake_sd);
return NULL;
}
/* stream open but not auth'ed: first use since connect or reconnect */
if (cluster->requires_auth && !scanner_node->has_auth) {
/* Complete speculative authentication */
bool has_speculative_auth = _mongoc_cluster_finish_speculative_auth (
cluster,
scanner_node->stream,
handshake_sd,
&scanner_node->speculative_auth_response,
&scanner_node->scram,
&handshake_sd->error);
#ifdef MONGOC_ENABLE_CRYPTO
_mongoc_scram_destroy (&scanner_node->scram);
#endif
if (!scanner_node->stream) {
*error = handshake_sd->error;
mongoc_server_description_destroy (handshake_sd);
return NULL;
}
if (!has_speculative_auth &&
!_mongoc_cluster_auth_node (cluster,
scanner_node->stream,
handshake_sd,
&scanner_node->sasl_supported_mechs,
&handshake_sd->error)) {
*error = handshake_sd->error;
mongoc_server_description_destroy (handshake_sd);
return NULL;
}
scanner_node->has_auth = true;
}
/* Copy the latest connection pool generation.
* TODO (CDRIVER-4078) do not store the generation counter on the server
* description */
handshake_sd->generation = _mongoc_topology_get_connection_pool_generation (
td, server_id, &handshake_sd->service_id);
return mongoc_server_stream_new (td, handshake_sd, scanner_node->stream);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_stream_valid --
*
* Internal function to determine if @server_stream is valid and
* associated with the given cluster.
*
* Returns:
* true if @server_stream is not NULL, hasn't been freed or changed;
* otherwise false.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_stream_valid (mongoc_cluster_t *cluster,
mongoc_server_stream_t *server_stream)
{
mongoc_server_stream_t *tmp_stream = NULL;
mongoc_topology_t *topology =
BSON_ASSERT_PTR_INLINE (cluster)->client->topology;
const mongoc_server_description_t *sd;
bool ret = false;
bson_error_t error;
mc_shared_tpld td = mc_tpld_take_ref (topology);
if (!server_stream) {
goto done;
}
tmp_stream = mongoc_cluster_stream_for_server (
cluster, server_stream->sd->id, false, NULL, NULL, NULL);
if (!tmp_stream || tmp_stream->stream != server_stream->stream) {
/* stream was freed, or has changed. */
goto done;
}
/* Check that the server stream is still valid for the given server, and that
* the server is still registered. */
sd = mongoc_topology_description_server_by_id_const (
td.ptr, server_stream->sd->id, &error);
if (!sd ||
server_stream->sd->generation <
_mongoc_topology_get_connection_pool_generation (
td.ptr, server_stream->sd->id, &server_stream->sd->service_id)) {
/* No server description, or the pool has been cleared. */
goto done;
}
ret = true;
done:
mc_tpld_drop_ref (&td);
mongoc_server_stream_cleanup (tmp_stream);
return ret;
}
mongoc_server_stream_t *
_mongoc_cluster_create_server_stream (
mongoc_topology_description_t const *td,
const mongoc_server_description_t *handshake_sd,
mongoc_stream_t *stream)
{
mongoc_server_description_t *const sd =
mongoc_server_description_new_copy (handshake_sd);
/* can't just use mongoc_topology_server_by_id(), since we must hold the
* lock while copying topology->shared_descr.ptr->logical_time below */
return mongoc_server_stream_new (td, sd, stream);
}
static mongoc_server_stream_t *
_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster,
const mongoc_topology_description_t *td,
uint32_t server_id,
bool reconnect_ok,
bson_error_t *error /* OUT */)
{
mongoc_cluster_node_t *cluster_node;
mongoc_server_description_t const *sd;
bool has_server_description = false;
cluster_node =
(mongoc_cluster_node_t *) mongoc_set_get (cluster->nodes, server_id);
sd = mongoc_topology_description_server_by_id_const (td, server_id, error);
if (sd) {
has_server_description = true;
}
if (cluster_node) {
uint32_t connection_pool_generation = 0;
BSON_ASSERT (cluster_node->stream);
connection_pool_generation =
_mongoc_topology_get_connection_pool_generation (
td, server_id, &cluster_node->handshake_sd->service_id);
if (!has_server_description ||
cluster_node->handshake_sd->generation < connection_pool_generation) {
/* Since the stream was created, connections to this server were
* invalidated.
* This may have happened if:
* - A background scan removed the server description.
* - A network error or a "not primary"/"node is recovering" error
* occurred on an app connection.
* - A network error occurred on the monitor connection.
*/
mongoc_cluster_disconnect_node (cluster, server_id);
} else {
return _mongoc_cluster_create_server_stream (
td, cluster_node->handshake_sd, cluster_node->stream);
}
}
/* no node, or out of date */
if (!reconnect_ok) {
node_not_found (td, server_id, error);
return NULL;
}
cluster_node = _cluster_add_node (cluster, td, server_id, error);
if (cluster_node) {
return _mongoc_cluster_create_server_stream (
td, cluster_node->handshake_sd, cluster_node->stream);
} else {
return NULL;
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_init --
*
* Initializes @cluster using the @uri and @client provided. The
* @uri is used to determine the "mode" of the cluster. Based on the
* uri we can determine if we are connected to a single host, a
* replicaSet, or a shardedCluster.
*
* Returns:
* None.
*
* Side effects:
* @cluster is initialized.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cluster_init (mongoc_cluster_t *cluster,
const mongoc_uri_t *uri,
void *client)
{
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (uri);
memset (cluster, 0, sizeof *cluster);
cluster->uri = mongoc_uri_copy (uri);
cluster->client = (mongoc_client_t *) client;
cluster->requires_auth =
(mongoc_uri_get_username (uri) || mongoc_uri_get_auth_mechanism (uri));
cluster->sockettimeoutms = mongoc_uri_get_option_as_int32 (
uri, MONGOC_URI_SOCKETTIMEOUTMS, MONGOC_DEFAULT_SOCKETTIMEOUTMS);
cluster->socketcheckintervalms =
mongoc_uri_get_option_as_int32 (uri,
MONGOC_URI_SOCKETCHECKINTERVALMS,
MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS);
/* TODO for single-threaded case we don't need this */
cluster->nodes = mongoc_set_new (8, _mongoc_cluster_node_dtor, NULL);
_mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t));
cluster->operation_id = rand ();
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_destroy --
*
* Clean up after @cluster and destroy all active connections.
* All resources for @cluster are released.
*
* Returns:
* None.
*
* Side effects:
* Everything.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cluster_destroy (mongoc_cluster_t *cluster) /* INOUT */
{
ENTRY;
BSON_ASSERT (cluster);
mongoc_uri_destroy (cluster->uri);
mongoc_set_destroy (cluster->nodes);
_mongoc_array_destroy (&cluster->iov);
#ifdef MONGOC_ENABLE_CRYPTO
if (cluster->scram_cache) {
_mongoc_scram_cache_destroy (cluster->scram_cache);
}
#endif
EXIT;
}
static uint32_t
_mongoc_cluster_select_server_id (mongoc_client_session_t *cs,
mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bool *must_use_primary,
bson_error_t *error)
{
uint32_t server_id;
if (_in_sharded_txn (cs)) {
server_id = cs->server_id;
if (!server_id) {
server_id = mongoc_topology_select_server_id (
topology, optype, read_prefs, must_use_primary, error);
if (server_id) {
_mongoc_client_session_pin (cs, server_id);
}
}
} else {
server_id = mongoc_topology_select_server_id (
topology, optype, read_prefs, must_use_primary, error);
/* Transactions Spec: Additionally, any non-transaction operation using a
* pinned ClientSession MUST unpin the session and the operation MUST
* perform normal server selection. */
if (cs && !_mongoc_client_session_in_txn_or_ending (cs)) {
_mongoc_client_session_unpin (cs);
}
}
return server_id;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_stream_for_optype --
*
* Internal server selection.
*
* Returns:
* A mongoc_server_stream_t on which you must call
* mongoc_server_stream_cleanup, or NULL on failure (sets @error)
*
* Side effects:
* May add or disconnect nodes in @cluster->nodes.
* Sets @error and initializes @reply on error.
*
*--------------------------------------------------------------------------
*/
static mongoc_server_stream_t *
_mongoc_cluster_stream_for_optype (mongoc_cluster_t *cluster,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error)
{
mongoc_server_stream_t *server_stream;
uint32_t server_id;
mongoc_topology_t *topology = cluster->client->topology;
bool must_use_primary = false;
ENTRY;
BSON_ASSERT (cluster);
server_id = _mongoc_cluster_select_server_id (
cs, topology, optype, read_prefs, &must_use_primary, error);
if (!server_id) {
_mongoc_bson_init_with_transient_txn_error (cs, reply);
RETURN (NULL);
}
if (!mongoc_cluster_check_interval (cluster, server_id)) {
/* Server Selection Spec: try once more */
server_id = _mongoc_cluster_select_server_id (
cs, topology, optype, read_prefs, &must_use_primary, error);
if (!server_id) {
_mongoc_bson_init_with_transient_txn_error (cs, reply);
RETURN (NULL);
}
}
/* connect or reconnect to server if necessary */
server_stream = _mongoc_cluster_stream_for_server (
cluster, server_id, true /* reconnect_ok */, cs, reply, error);
if (server_stream) {
server_stream->must_use_primary = must_use_primary;
}
RETURN (server_stream);
}
mongoc_server_stream_t *
mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster,
const mongoc_read_prefs_t *read_prefs,
mongoc_client_session_t *cs,
bson_t *reply,
bool has_write_stage,
bson_error_t *error)
{
const mongoc_read_prefs_t *prefs_override = read_prefs;
if (_mongoc_client_session_in_txn (cs)) {
prefs_override = cs->txn.opts.read_prefs;
}
return _mongoc_cluster_stream_for_optype (
cluster,
/* Narrow down the optype if this is an aggregate op with a write stage */
has_write_stage ? MONGOC_SS_AGGREGATE_WITH_WRITE : MONGOC_SS_READ,
prefs_override,
cs,
reply,
error);
}
mongoc_server_stream_t *
mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster,
mongoc_client_session_t *cs,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_cluster_stream_for_optype (
cluster, MONGOC_SS_WRITE, NULL, cs, reply, error);
}
static bool
_mongoc_cluster_min_of_max_obj_size_sds (const void *item, void *ctx)
{
const mongoc_server_description_t *sd = item;
int32_t *current_min = (int32_t *) ctx;
if (sd->max_bson_obj_size < *current_min) {
*current_min = sd->max_bson_obj_size;
}
return true;
}
static bool
_mongoc_cluster_min_of_max_obj_size_nodes (void *item, void *ctx)
{
mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) item;
int32_t *current_min = (int32_t *) ctx;
if (node->handshake_sd->max_bson_obj_size < *current_min) {
*current_min = node->handshake_sd->max_bson_obj_size;
}
return true;
}
static bool
_mongoc_cluster_min_of_max_msg_size_sds (const void *item, void *ctx)
{
const mongoc_server_description_t *sd = item;
int32_t *current_min = (int32_t *) ctx;
if (sd->max_msg_size < *current_min) {
*current_min = sd->max_msg_size;
}
return true;
}
static bool
_mongoc_cluster_min_of_max_msg_size_nodes (void *item, void *ctx)
{
mongoc_cluster_node_t *node = (mongoc_cluster_node_t *) item;
int32_t *current_min = (int32_t *) ctx;
if (node->handshake_sd->max_msg_size < *current_min) {
*current_min = node->handshake_sd->max_msg_size;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_get_max_bson_obj_size --
*
* Return the minimum max_bson_obj_size across all servers in cluster.
*
* Returns:
* The minimum max_bson_obj_size.
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
int32_t
mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster)
{
int32_t max_bson_obj_size = -1;
max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
if (!cluster->client->topology->single_threaded) {
mongoc_set_for_each (cluster->nodes,
_mongoc_cluster_min_of_max_obj_size_nodes,
&max_bson_obj_size);
} else {
mc_shared_tpld td =
mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (cluster)->client->topology);
mongoc_set_for_each_const (mc_tpld_servers_const (td.ptr),
_mongoc_cluster_min_of_max_obj_size_sds,
&max_bson_obj_size);
mc_tpld_drop_ref (&td);
}
return max_bson_obj_size;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_get_max_msg_size --
*
* Return the minimum max msg size across all servers in cluster.
*
* Returns:
* The minimum max_msg_size
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
int32_t
mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster)
{
int32_t max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE;
if (!cluster->client->topology->single_threaded) {
mongoc_set_for_each (cluster->nodes,
_mongoc_cluster_min_of_max_msg_size_nodes,
&max_msg_size);
} else {
mc_shared_tpld td =
mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (cluster)->client->topology);
mongoc_set_for_each_const (mc_tpld_servers_const (td.ptr),
_mongoc_cluster_min_of_max_msg_size_sds,
&max_msg_size);
mc_tpld_drop_ref (&td);
}
return max_msg_size;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_check_interval --
*
* Server Selection Spec:
*
* Only for single-threaded drivers.
*
* If a server is selected that has an existing connection that has been
* idle for socketCheckIntervalMS, the driver MUST check the connection
* with the "ping" command. If the ping succeeds, use the selected
* connection. If not, set the server's type to Unknown and update the
* Topology Description according to the Server Discovery and Monitoring
* Spec, and attempt once more to select a server.
*
* Returns:
* True if the check succeeded or no check was required, false if the
* check failed.
*
* Side effects:
* If a check fails, closes stream and may set server type Unknown.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id)
{
mongoc_cmd_parts_t parts;
mongoc_topology_t *topology;
mongoc_topology_scanner_node_t *scanner_node;
mongoc_stream_t *stream;
int64_t now;
bson_t command;
bson_error_t error;
bool r = true;
mongoc_server_stream_t *server_stream;
mongoc_server_description_t *handshake_sd;
topology = cluster->client->topology;
if (!topology->single_threaded) {
return true;
}
scanner_node =
mongoc_topology_scanner_get_node (topology->scanner, server_id);
if (!scanner_node) {
return false;
}
BSON_ASSERT (!scanner_node->retired);
stream = scanner_node->stream;
if (!stream) {
return false;
}
handshake_sd = scanner_node->handshake_sd;
BSON_ASSERT (handshake_sd);
now = bson_get_monotonic_time ();
if (scanner_node->last_used + (1000 * CHECK_CLOSED_DURATION_MSEC) < now) {
if (mongoc_stream_check_closed (stream)) {
mc_tpld_modification tdmod;
bson_set_error (&error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"connection closed");
mongoc_cluster_disconnect_node (cluster, server_id);
tdmod = mc_tpld_modify_begin (topology);
/* invalidate_server() is okay if 'server_id' was already removed. */
mongoc_topology_description_invalidate_server (
tdmod.new_td, server_id, &error);
mc_tpld_modify_commit (tdmod);
return false;
}
}
if (scanner_node->last_used + (1000 * cluster->socketcheckintervalms) <
now) {
mc_shared_tpld td;
bson_init (&command);
BSON_APPEND_INT32 (&command, "ping", 1);
mongoc_cmd_parts_init (
&parts, cluster->client, "admin", MONGOC_QUERY_SECONDARY_OK, &command);
parts.prohibit_lsid = true;
td = mc_tpld_take_ref (cluster->client->topology);
server_stream =
_mongoc_cluster_create_server_stream (td.ptr, handshake_sd, stream);
mc_tpld_drop_ref (&td);
if (!server_stream) {
bson_destroy (&command);
return false;
}
r = mongoc_cluster_run_command_parts (
cluster, server_stream, &parts, NULL, &error);
mongoc_server_stream_cleanup (server_stream);
bson_destroy (&command);
if (!r) {
mc_tpld_modification tdmod;
mongoc_cluster_disconnect_node (cluster, server_id);
tdmod = mc_tpld_modify_begin (cluster->client->topology);
/* invalidate_server() is okay if 'server_id' was already removed. */
mongoc_topology_description_invalidate_server (
tdmod.new_td, server_id, &error);
mc_tpld_modify_commit (tdmod);
}
}
return r;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_legacy_rpc_sendv_to_server --
*
* Sends the given RPCs to the given server. Used for OP_QUERY cursors,
* OP_KILLCURSORS, and legacy writes with OP_INSERT, OP_UPDATE, and
* OP_DELETE. This function is *not* in the OP_QUERY command path.
*
* Returns:
* True if successful.
*
* Side effects:
* @rpc may be mutated and should be considered invalid after calling
* this method.
*
* @error may be set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_legacy_rpc_sendv_to_server (
mongoc_cluster_t *cluster,
mongoc_rpc_t *rpc,
mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
uint32_t server_id;
int32_t max_msg_size;
bool ret = false;
int32_t compressor_id = 0;
char *output = NULL;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (rpc);
BSON_ASSERT (server_stream);
server_id = server_stream->sd->id;
if (cluster->client->in_exhaust) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"A cursor derived from this client is in exhaust.");
GOTO (done);
}
_mongoc_array_clear (&cluster->iov);
compressor_id = mongoc_server_description_compressor_id (server_stream->sd);
_mongoc_rpc_gather (rpc, &cluster->iov);
_mongoc_rpc_swab_to_le (rpc);
if (compressor_id != -1) {
output = _mongoc_rpc_compress (cluster, compressor_id, rpc, error);
if (output == NULL) {
GOTO (done);
}
}
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if (BSON_UINT32_FROM_LE (rpc->header.msg_len) > max_msg_size) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_TOO_BIG,
"Attempted to send an RPC larger than the "
"max allowed message size. Was %u, allowed %u.",
BSON_UINT32_FROM_LE (rpc->header.msg_len),
max_msg_size);
GOTO (done);
}
if (!_mongoc_stream_writev_full (server_stream->stream,
cluster->iov.data,
cluster->iov.len,
cluster->sockettimeoutms,
error)) {
GOTO (done);
}
_mongoc_topology_update_last_used (cluster->client->topology, server_id);
ret = true;
done:
if (compressor_id) {
bson_free (output);
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cluster_try_recv --
*
* Tries to receive the next event from the MongoDB server.
* The contents are loaded into @buffer and then
* scattered into the @rpc structure. @rpc is valid as long as
* @buffer contains the contents read into it.
*
* Callers that can optimize a reuse of @buffer should do so. It
* can save many memory allocations.
*
* Returns:
* True if successful.
*
* Side effects:
* @rpc is set on success, @error on failure.
* @buffer will be filled with the input data.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cluster_try_recv (mongoc_cluster_t *cluster,
mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
bson_error_t err_local;
int32_t msg_len;
int32_t max_msg_size;
off_t pos;
ENTRY;
BSON_ASSERT (cluster);
BSON_ASSERT (rpc);
BSON_ASSERT (buffer);
BSON_ASSERT (server_stream);
TRACE ("Waiting for reply from server_id \"%u\"", server_stream->sd->id);
if (!error) {
error = &err_local;
}
/*
* Buffer the message length to determine how much more to read.
*/
pos = buffer->len;
if (!_mongoc_buffer_append_from_stream (
buffer, server_stream->stream, 4, cluster->sockettimeoutms, error)) {
MONGOC_DEBUG (
"Could not read 4 bytes, stream probably closed or timed out");
mongoc_counter_protocol_ingress_error_inc ();
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
RETURN (false);
}
/*
* Read the msg length from the buffer.
*/
memcpy (&msg_len, &buffer->data[pos], 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if ((msg_len < 16) || (msg_len > max_msg_size)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Corrupt or malicious reply received.");
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
mongoc_counter_protocol_ingress_error_inc ();
RETURN (false);
}
/*
* Read the rest of the message from the stream.
*/
if (!_mongoc_buffer_append_from_stream (buffer,
server_stream->stream,
msg_len - 4,
cluster->sockettimeoutms,
error)) {
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
mongoc_counter_protocol_ingress_error_inc ();
RETURN (false);
}
/*
* Scatter the buffer into the rpc structure.
*/
if (!_mongoc_rpc_scatter (rpc, &buffer->data[pos], msg_len)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Failed to decode reply from server.");
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
mongoc_counter_protocol_ingress_error_inc ();
RETURN (false);
}
if (BSON_UINT32_FROM_LE (rpc->header.opcode) == MONGOC_OPCODE_COMPRESSED) {
uint8_t *buf = NULL;
size_t len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
buf = bson_malloc0 (len);
if (!_mongoc_rpc_decompress (rpc, buf, len)) {
bson_free (buf);
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress server reply");
RETURN (false);
}
_mongoc_buffer_destroy (buffer);
_mongoc_buffer_init (buffer, buf, len, NULL, NULL);
}
_mongoc_rpc_swab_from_le (rpc);
RETURN (true);
}
static void
network_error_reply (bson_t *reply, mongoc_cmd_t *cmd)
{
bson_t labels;
if (reply) {
bson_init (reply);
}
if (cmd->session) {
if (cmd->session->server_session) {
cmd->session->server_session->dirty = true;
}
/* Transactions Spec defines TransientTransactionError: "Any
* network error or server selection error encountered running any
* command besides commitTransaction in a transaction. In the case
* of command errors, the server adds the label; in the case of
* network errors or server selection errors where the client
* receives no server reply, the client adds the label." */
if (_mongoc_client_session_in_txn (cmd->session) && !cmd->is_txn_finish) {
/* Transaction Spec: "Drivers MUST unpin a ClientSession when a command
* within a transaction, including commitTransaction and
* abortTransaction,
* fails with a TransientTransactionError". If we're about to add
* a TransientTransactionError label due to a client side error then we
* unpin. If commitTransaction/abortTransation includes a label in the
* server reply, we unpin in _mongoc_client_session_handle_reply. */
cmd->session->server_id = 0;
if (!reply) {
return;
}
BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels);
BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR);
bson_append_array_end (reply, &labels);
}
}
}
static bool
mongoc_cluster_run_opmsg (mongoc_cluster_t *cluster,
mongoc_cmd_t *cmd,
bson_t *reply,
bson_error_t *error)
{
mongoc_rpc_section_t section[2];
mongoc_buffer_t buffer;
bson_t reply_local; /* only statically initialized */
char *output = NULL;
mongoc_rpc_t rpc;
int32_t msg_len;
bool ok;
mongoc_server_stream_t *server_stream;
server_stream = cmd->server_stream;
if (!cmd->command_name) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Empty command document");
_mongoc_bson_init_if_set (reply);
return false;
}
if (cluster->client->in_exhaust) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"A cursor derived from this client is in exhaust.");
_mongoc_bson_init_if_set (reply);
return false;
}
_mongoc_array_clear (&cluster->iov);
_mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL);
rpc.header.msg_len = 0;
rpc.header.request_id = ++cluster->request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_MSG;
if (cmd->is_acknowledged) {
rpc.msg.flags = 0;
} else {
rpc.msg.flags = MONGOC_MSG_MORE_TO_COME;
}
rpc.msg.n_sections = 1;
section[0].payload_type = 0;
section[0].payload.bson_document = bson_get_data (cmd->command);
rpc.msg.sections[0] = section[0];
if (cmd->payload) {
section[1].payload_type = 1;
section[1].payload.sequence.size = cmd->payload_size +
strlen (cmd->payload_identifier) + 1 +
sizeof (int32_t);
section[1].payload.sequence.identifier = cmd->payload_identifier;
section[1].payload.sequence.bson_documents = cmd->payload;
rpc.msg.sections[1] = section[1];
rpc.msg.n_sections++;
}
_mongoc_rpc_gather (&rpc, &cluster->iov);
_mongoc_rpc_swab_to_le (&rpc);
if (mongoc_cmd_is_compressible (cmd)) {
int32_t compressor_id =
mongoc_server_description_compressor_id (server_stream->sd);
TRACE (
"Function '%s' is compressible: %d", cmd->command_name, compressor_id);
if (compressor_id != -1) {
output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error);
if (output == NULL) {
_mongoc_bson_init_if_set (reply);
_mongoc_buffer_destroy (&buffer);
return false;
}
}
}
ok = _mongoc_stream_writev_full (server_stream->stream,
(mongoc_iovec_t *) cluster->iov.data,
cluster->iov.len,
cluster->sockettimeoutms,
error);
if (!ok) {
/* add info about the command to writev_full's error message */
RUN_CMD_ERR_DECORATE;
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
/* If acknowledged, wait for a server response. Otherwise, exit early */
if (cmd->is_acknowledged) {
ok = _mongoc_buffer_append_from_stream (
&buffer, server_stream->stream, 4, cluster->sockettimeoutms, error);
if (!ok) {
RUN_CMD_ERR_DECORATE;
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
BSON_ASSERT (buffer.len == 4);
memcpy (&msg_len, buffer.data, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if ((msg_len < 16) || (msg_len > server_stream->sd->max_msg_size)) {
RUN_CMD_ERR (
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Message size %d is not within expected range 16-%d bytes",
msg_len,
server_stream->sd->max_msg_size);
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
ok = _mongoc_buffer_append_from_stream (&buffer,
server_stream->stream,
(size_t) msg_len - 4,
cluster->sockettimeoutms,
error);
if (!ok) {
RUN_CMD_ERR_DECORATE;
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
ok = _mongoc_rpc_scatter (&rpc, buffer.data, buffer.len);
if (!ok) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Malformed message from server");
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) {
size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
output = bson_realloc (output, len);
if (!_mongoc_rpc_decompress (&rpc, (uint8_t *) output, len)) {
RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress message from server");
_handle_network_error (
cluster, server_stream, true /* handshake complete */, error);
server_stream->stream = NULL;
bson_free (output);
network_error_reply (reply, cmd);
_mongoc_buffer_destroy (&buffer);
return false;
}
}
_mongoc_rpc_swab_from_le (&rpc);
memcpy (&msg_len, rpc.msg.sections[0].payload.bson_document, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
bson_init_static (
&reply_local, rpc.msg.sections[0].payload.bson_document, msg_len);
_mongoc_topology_update_cluster_time (cluster->client->topology,
&reply_local);
ok = _mongoc_cmd_check_ok (
&reply_local, cluster->client->error_api_version, error);
if (cmd->session) {
_mongoc_client_session_handle_reply (cmd->session,
cmd->is_acknowledged,
cmd->command_name,
&reply_local);
}
if (reply) {
bson_copy_to (&reply_local, reply);
}
} else {
_mongoc_bson_init_if_set (reply);
}
_mongoc_buffer_destroy (&buffer);
bson_free (output);
return ok;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
index 3a71e8e1..5c000b34 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c
@@ -1,1197 +1,1201 @@
/*
* Copyright 2017 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-cmd-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-client-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-server-api-private.h"
#include "mongoc-write-concern-private.h"
/* For strcasecmp on Windows */
#include "mongoc-util-private.h"
void
mongoc_cmd_parts_init (mongoc_cmd_parts_t *parts,
mongoc_client_t *client,
const char *db_name,
mongoc_query_flags_t user_query_flags,
const bson_t *command_body)
{
parts->body = command_body;
parts->user_query_flags = user_query_flags;
parts->read_prefs = NULL;
parts->is_read_command = false;
parts->is_write_command = false;
parts->prohibit_lsid = false;
parts->allow_txn_number = MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN;
parts->is_retryable_read = false;
parts->is_retryable_write = false;
parts->has_temp_session = false;
parts->client = client;
bson_init (&parts->read_concern_document);
bson_init (&parts->write_concern_document);
bson_init (&parts->extra);
bson_init (&parts->assembled_body);
parts->assembled.db_name = db_name;
parts->assembled.command = NULL;
parts->assembled.query_flags = MONGOC_QUERY_NONE;
parts->assembled.payload_identifier = NULL;
parts->assembled.payload = NULL;
parts->assembled.session = NULL;
parts->assembled.is_acknowledged = true;
parts->assembled.is_txn_finish = false;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_set_session --
*
* Set the client session field.
*
* Side effects:
* Aborts if the command is assembled or if mongoc_cmd_parts_append_opts
* was called before.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cmd_parts_set_session (mongoc_cmd_parts_t *parts,
mongoc_client_session_t *cs)
{
BSON_ASSERT (parts);
BSON_ASSERT (!parts->assembled.command);
BSON_ASSERT (!parts->assembled.session);
parts->assembled.session = cs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_append_opts --
*
* Take an iterator over user-supplied options document and append the
* options to @parts->command_extra, taking the selected server's max
* wire version into account.
*
* Return:
* True if the options were successfully applied. If any options are
* invalid, returns false and fills out @error. In that case @parts is
* invalid and must not be used.
*
* Side effects:
* May partly apply options before returning an error.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts,
bson_iter_t *iter,
int max_wire_version,
bson_error_t *error)
{
mongoc_client_session_t *cs = NULL;
mongoc_write_concern_t *wc;
uint32_t len;
const uint8_t *data;
bson_t read_concern;
const char *to_append;
ENTRY;
/* not yet assembled */
BSON_ASSERT (!parts->assembled.command);
while (bson_iter_next (iter)) {
if (BSON_ITER_IS_KEY (iter, "collation")) {
if (max_wire_version < WIRE_VERSION_COLLATION) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
RETURN (false);
}
} else if (BSON_ITER_IS_KEY (iter, "writeConcern")) {
wc = _mongoc_write_concern_new_from_iter (iter, error);
if (!wc) {
RETURN (false);
}
if (!mongoc_cmd_parts_set_write_concern (
parts, wc, max_wire_version, error)) {
mongoc_write_concern_destroy (wc);
RETURN (false);
}
mongoc_write_concern_destroy (wc);
continue;
} else if (BSON_ITER_IS_KEY (iter, "readConcern")) {
if (max_wire_version < WIRE_VERSION_READ_CONCERN) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support readConcern");
RETURN (false);
}
if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Invalid readConcern");
RETURN (false);
}
/* add readConcern later, once we know about causal consistency */
bson_iter_document (iter, &len, &data);
BSON_ASSERT (bson_init_static (&read_concern, data, (size_t) len));
bson_destroy (&parts->read_concern_document);
bson_copy_to (&read_concern, &parts->read_concern_document);
continue;
} else if (BSON_ITER_IS_KEY (iter, "sessionId")) {
BSON_ASSERT (!parts->assembled.session);
if (!_mongoc_client_session_from_iter (
parts->client, iter, &cs, error)) {
RETURN (false);
}
parts->assembled.session = cs;
continue;
} else if (BSON_ITER_IS_KEY (iter, "serverId") ||
BSON_ITER_IS_KEY (iter, "maxAwaitTimeMS") ||
BSON_ITER_IS_KEY (iter, "exhaust")) {
continue;
}
to_append = bson_iter_key (iter);
if (!bson_append_iter (&parts->extra, to_append, -1, iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Failed to append \"%s\" to create command.",
to_append);
RETURN (false);
}
}
RETURN (true);
}
#define OPTS_ERR(_code, ...) \
do { \
bson_set_error ( \
error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_##_code, __VA_ARGS__); \
RETURN (false); \
} while (0)
/* set readConcern if allowed, otherwise error */
bool
mongoc_cmd_parts_set_read_concern (mongoc_cmd_parts_t *parts,
const mongoc_read_concern_t *rc,
int max_wire_version,
bson_error_t *error)
{
const char *command_name;
ENTRY;
/* In a txn, set read concern in mongoc_cmd_parts_assemble, not here. *
* Transactions Spec: "The readConcern MUST NOT be inherited from the
* collection, database, or client associated with the driver method that
* invokes the first command." */
if (_mongoc_client_session_in_txn (parts->assembled.session)) {
RETURN (true);
}
command_name = _mongoc_get_command_name (parts->body);
if (!command_name) {
OPTS_ERR (COMMAND_INVALID_ARG, "Empty command document");
}
if (mongoc_read_concern_is_default (rc)) {
RETURN (true);
}
if (max_wire_version < WIRE_VERSION_READ_CONCERN) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"\"%s\" command does not support readConcern with "
"wire version %d, wire version %d is required",
command_name,
max_wire_version,
WIRE_VERSION_READ_CONCERN);
RETURN (false);
}
bson_destroy (&parts->read_concern_document);
bson_copy_to (_mongoc_read_concern_get_bson ((mongoc_read_concern_t *) rc),
&parts->read_concern_document);
RETURN (true);
}
/* set writeConcern if allowed, otherwise ignore - unlike set_read_concern, it's
* the caller's responsibility to check if writeConcern is supported */
bool
mongoc_cmd_parts_set_write_concern (mongoc_cmd_parts_t *parts,
const mongoc_write_concern_t *wc,
int max_wire_version,
bson_error_t *error)
{
const char *command_name;
bool is_fam;
bool wc_allowed;
ENTRY;
if (!wc) {
RETURN (true);
}
command_name = _mongoc_get_command_name (parts->body);
if (!command_name) {
OPTS_ERR (COMMAND_INVALID_ARG, "Empty command document");
}
is_fam = !strcasecmp (command_name, "findandmodify");
wc_allowed =
parts->is_write_command ||
(is_fam && max_wire_version >= WIRE_VERSION_FAM_WRITE_CONCERN) ||
(!is_fam && max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN);
if (wc_allowed) {
parts->assembled.is_acknowledged =
mongoc_write_concern_is_acknowledged (wc);
bson_destroy (&parts->write_concern_document);
bson_copy_to (
_mongoc_write_concern_get_bson ((mongoc_write_concern_t *) wc),
&parts->write_concern_document);
}
RETURN (true);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_append_read_write --
*
* Append user-supplied options to @parts->command_extra, taking the
* selected server's max wire version into account.
*
* Return:
* True if the options were successfully applied. If any options are
* invalid, returns false and fills out @error. In that case @parts is
* invalid and must not be used.
*
* Side effects:
* May partly apply options before returning an error.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cmd_parts_append_read_write (mongoc_cmd_parts_t *parts,
mongoc_read_write_opts_t *rw_opts,
int max_wire_version,
bson_error_t *error)
{
ENTRY;
/* not yet assembled */
BSON_ASSERT (!parts->assembled.command);
if (!bson_empty (&rw_opts->collation)) {
if (max_wire_version < WIRE_VERSION_COLLATION) {
OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
}
if (!bson_append_document (
&parts->extra, "collation", 9, &rw_opts->collation)) {
OPTS_ERR (COMMAND_INVALID_ARG, "'opts' with 'collation' is too large");
}
}
if (!mongoc_cmd_parts_set_write_concern (
parts, rw_opts->writeConcern, max_wire_version, error)) {
RETURN (false);
}
/* process explicit read concern */
if (!bson_empty (&rw_opts->readConcern)) {
if (max_wire_version < WIRE_VERSION_READ_CONCERN) {
OPTS_ERR (PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support readConcern");
}
/* save readConcern for later, once we know about causal consistency */
bson_destroy (&parts->read_concern_document);
bson_copy_to (&rw_opts->readConcern, &parts->read_concern_document);
}
if (rw_opts->client_session) {
BSON_ASSERT (!parts->assembled.session);
parts->assembled.session = rw_opts->client_session;
}
if (!bson_concat (&parts->extra, &rw_opts->extra)) {
OPTS_ERR (COMMAND_INVALID_ARG, "'opts' with extra fields is too large");
}
RETURN (true);
}
#undef OPTS_ERR
static void
_mongoc_cmd_parts_ensure_copied (mongoc_cmd_parts_t *parts)
{
if (parts->assembled.command == parts->body) {
bson_concat (&parts->assembled_body, parts->body);
bson_concat (&parts->assembled_body, &parts->extra);
parts->assembled.command = &parts->assembled_body;
}
}
static void
_mongoc_cmd_parts_add_write_concern (mongoc_cmd_parts_t *parts)
{
if (!bson_empty (&parts->write_concern_document)) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"writeConcern",
12,
&parts->write_concern_document);
}
}
/* The server type must be mongos, or message must be OP_MSG. */
static void
_mongoc_cmd_parts_add_read_prefs (bson_t *query,
const mongoc_read_prefs_t *prefs)
{
bson_t child;
const char *mode_str;
const bson_t *tags;
int64_t stale;
const bson_t *hedge;
mode_str = _mongoc_read_mode_as_str (mongoc_read_prefs_get_mode (prefs));
tags = mongoc_read_prefs_get_tags (prefs);
stale = mongoc_read_prefs_get_max_staleness_seconds (prefs);
hedge = mongoc_read_prefs_get_hedge (prefs);
bson_append_document_begin (query, "$readPreference", 15, &child);
bson_append_utf8 (&child, "mode", 4, mode_str, -1);
if (!bson_empty0 (tags)) {
bson_append_array (&child, "tags", 4, tags);
}
if (stale != MONGOC_NO_MAX_STALENESS) {
bson_append_int64 (&child, "maxStalenessSeconds", 19, stale);
}
if (!bson_empty0 (hedge)) {
bson_append_document (&child, "hedge", 5, hedge);
}
bson_append_document_end (query, &child);
}
static void
_iter_concat (bson_t *dst, bson_iter_t *iter)
{
uint32_t len;
const uint8_t *data;
bson_t src;
bson_iter_document (iter, &len, &data);
BSON_ASSERT (bson_init_static (&src, data, len));
BSON_ASSERT (bson_concat (dst, &src));
}
/* Update result with the read prefs. Server must be mongos.
*/
static void
_mongoc_cmd_parts_assemble_mongos (mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
mongoc_read_mode_t mode;
const bson_t *tags = NULL;
int64_t max_staleness_seconds = MONGOC_NO_MAX_STALENESS;
const bson_t *hedge = NULL;
bool add_read_prefs = false;
bson_t query;
bson_iter_t dollar_query;
bool has_dollar_query = false;
bool requires_read_concern;
bool requires_write_concern;
ENTRY;
mode = mongoc_read_prefs_get_mode (parts->read_prefs);
if (parts->read_prefs) {
max_staleness_seconds =
mongoc_read_prefs_get_max_staleness_seconds (parts->read_prefs);
tags = mongoc_read_prefs_get_tags (parts->read_prefs);
hedge = mongoc_read_prefs_get_hedge (parts->read_prefs);
}
if (server_stream->must_use_primary) {
/* Server selection has overriden the read mode used to generate this
* server stream. This has effects on the body of the message that we send
* to the server */
mode = MONGOC_READ_PRIMARY;
}
/* Server Selection Spec says:
*
* For mode 'primary', drivers MUST NOT set the secondaryOk wire protocol
* flag and MUST NOT use $readPreference
*
* For mode 'secondary', drivers MUST set the secondaryOk wire protocol flag
* and MUST also use $readPreference
*
* For mode 'primaryPreferred', drivers MUST set the secondaryOk wire
* protocol flag and MUST also use $readPreference
*
* For mode 'secondaryPreferred', drivers MUST set the secondaryOk wire
* protocol flag. If the read preference contains a non-empty tag_sets
* parameter, maxStalenessSeconds is a positive integer, or the hedge
* parameter is non-empty, drivers MUST use $readPreference; otherwise,
* drivers MUST NOT use $readPreference
*
* For mode 'nearest', drivers MUST set the secondaryOk wire protocol flag
* and MUST also use $readPreference
*/
switch (mode) {
case MONGOC_READ_PRIMARY:
break;
case MONGOC_READ_SECONDARY_PREFERRED:
if (!bson_empty0 (tags) || max_staleness_seconds > 0 ||
!bson_empty0 (hedge)) {
add_read_prefs = true;
}
parts->assembled.query_flags |= MONGOC_QUERY_SECONDARY_OK;
break;
case MONGOC_READ_PRIMARY_PREFERRED:
case MONGOC_READ_SECONDARY:
case MONGOC_READ_NEAREST:
default:
parts->assembled.query_flags |= MONGOC_QUERY_SECONDARY_OK;
add_read_prefs = true;
}
requires_read_concern =
!bson_empty (&parts->read_concern_document) &&
strcmp (parts->assembled.command_name, "getMore") != 0;
requires_write_concern = !bson_empty (&parts->write_concern_document);
if (add_read_prefs) {
/* produce {$query: {user query, readConcern}, $readPreference: ... } */
bson_append_document_begin (&parts->assembled_body, "$query", 6, &query);
if (bson_iter_init_find (&dollar_query, parts->body, "$query")) {
/* user provided something like {$query: {key: "x"}} */
has_dollar_query = true;
_iter_concat (&query, &dollar_query);
} else {
bson_concat (&query, parts->body);
}
bson_concat (&query, &parts->extra);
if (requires_read_concern) {
bson_append_document (
&query, "readConcern", 11, &parts->read_concern_document);
}
if (requires_write_concern) {
bson_append_document (
&query, "writeConcern", 12, &parts->write_concern_document);
}
bson_append_document_end (&parts->assembled_body, &query);
_mongoc_cmd_parts_add_read_prefs (&parts->assembled_body,
parts->read_prefs);
if (has_dollar_query) {
/* copy anything that isn't in user's $query */
bson_copy_to_excluding_noinit (
parts->body, &parts->assembled_body, "$query", NULL);
}
parts->assembled.command = &parts->assembled_body;
} else if (bson_iter_init_find (&dollar_query, parts->body, "$query")) {
/* user provided $query, we have no read prefs */
bson_append_document_begin (&parts->assembled_body, "$query", 6, &query);
_iter_concat (&query, &dollar_query);
bson_concat (&query, &parts->extra);
if (requires_read_concern) {
bson_append_document (
&query, "readConcern", 11, &parts->read_concern_document);
}
if (requires_write_concern) {
bson_append_document (
&query, "writeConcern", 12, &parts->write_concern_document);
}
bson_append_document_end (&parts->assembled_body, &query);
/* copy anything that isn't in user's $query */
bson_copy_to_excluding_noinit (
parts->body, &parts->assembled_body, "$query", NULL);
parts->assembled.command = &parts->assembled_body;
} else {
if (requires_read_concern) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"readConcern",
11,
&parts->read_concern_document);
}
_mongoc_cmd_parts_add_write_concern (parts);
}
if (!bson_empty (&parts->extra)) {
/* if none of the above logic has merged "extra", do it now */
_mongoc_cmd_parts_ensure_copied (parts);
}
EXIT;
}
static void
_mongoc_cmd_parts_assemble_mongod (mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
ENTRY;
if (!parts->is_write_command) {
switch (server_stream->topology_type) {
case MONGOC_TOPOLOGY_SINGLE:
/* Server Selection Spec: for topology type single and server types
* besides mongos, "clients MUST always set the secondaryOk wire
* protocol flag on reads to ensure that any server type can handle
* the request."
*/
parts->assembled.query_flags |= MONGOC_QUERY_SECONDARY_OK;
break;
case MONGOC_TOPOLOGY_RS_NO_PRIMARY:
case MONGOC_TOPOLOGY_RS_WITH_PRIMARY:
/* Server Selection Spec: for RS topology types, "For all read
* preferences modes except primary, clients MUST set the secondaryOk
* wire protocol flag to ensure that any suitable server can handle the
* request. Clients MUST NOT set the secondaryOk wire protocol flag if
* the read preference mode is primary.
*/
if (parts->read_prefs &&
parts->read_prefs->mode != MONGOC_READ_PRIMARY) {
parts->assembled.query_flags |= MONGOC_QUERY_SECONDARY_OK;
}
break;
case MONGOC_TOPOLOGY_SHARDED:
case MONGOC_TOPOLOGY_UNKNOWN:
case MONGOC_TOPOLOGY_LOAD_BALANCED:
case MONGOC_TOPOLOGY_DESCRIPTION_TYPES:
default:
/* must not call this function w/ sharded, load balanced, or unknown
* topology type */
BSON_ASSERT (false);
}
} /* if (!parts->is_write_command) */
if (!bson_empty (&parts->extra)) {
_mongoc_cmd_parts_ensure_copied (parts);
}
if (!bson_empty (&parts->read_concern_document) &&
strcmp (parts->assembled.command_name, "getMore") != 0) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"readConcern",
11,
&parts->read_concern_document);
}
_mongoc_cmd_parts_add_write_concern (parts);
EXIT;
}
static const bson_t *
_largest_cluster_time (const bson_t *a, const bson_t *b)
{
if (!a) {
return b;
}
if (!b) {
return a;
}
if (_mongoc_cluster_time_greater (a, b)) {
return a;
}
return b;
}
/* Check if the command should allow a transaction number if that has not
* already been determined.
*
* This should only return true for write commands that are always retryable for
* the server stream's wire version.
*
* The basic write commands (i.e. insert, update, delete) are intentionally
* excluded here. While insert is always retryable, update and delete are only
* retryable if they include no multi-document writes. Since it would be costly
* to inspect the command document here, the bulk operation API explicitly sets
* allow_txn_number for us. This means that insert, update, and delete are not
* retryable if executed via mongoc_client_write_command_with_opts(); however,
* documentation already instructs users not to use that for basic writes.
*/
static bool
_allow_txn_number (const mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
/* There is no reason to call this function if allow_txn_number is set */
BSON_ASSERT (parts->allow_txn_number ==
MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN);
if (!parts->is_write_command) {
return false;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) {
return false;
}
if (!parts->assembled.is_acknowledged) {
return false;
}
if (!strcasecmp (parts->assembled.command_name, "findandmodify")) {
return true;
}
return false;
}
/* Check if the write command should support retryable behavior. */
static bool
_is_retryable_write (const mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
if (!parts->assembled.session) {
return false;
}
if (!parts->is_write_command) {
return false;
}
if (parts->allow_txn_number != MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES) {
return false;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_WRITES) {
return false;
}
if (server_stream->sd->type == MONGOC_SERVER_STANDALONE) {
return false;
}
if (_mongoc_client_session_in_txn (parts->assembled.session)) {
return false;
}
if (!mongoc_uri_get_option_as_bool (parts->client->uri,
MONGOC_URI_RETRYWRITES,
MONGOC_DEFAULT_RETRYWRITES)) {
return false;
}
return true;
}
/* Check if the read command should support retryable behavior. */
bool
_is_retryable_read (const mongoc_cmd_parts_t *parts,
const mongoc_server_stream_t *server_stream)
{
if (!parts->is_read_command) {
return false;
}
/* Commands that go through read_write_command helpers are also write
* commands. Prohibit from read retry. */
if (parts->is_write_command) {
return false;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_RETRY_READS) {
return false;
}
if (_mongoc_client_session_in_txn (parts->assembled.session)) {
return false;
}
if (!mongoc_uri_get_option_as_bool (parts->client->uri,
MONGOC_URI_RETRYREADS,
MONGOC_DEFAULT_RETRYREADS)) {
return false;
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_assemble --
*
* Assemble the command body, options, and read preference into one
* command.
*
* Return:
* True if the options were successfully applied. If any options are
* invalid, returns false and fills out @error. In that case @parts is
* invalid and must not be used.
*
* Side effects:
* May partly assemble before returning an error.
* mongoc_cmd_parts_cleanup should be called in all cases.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts,
mongoc_server_stream_t *server_stream,
bson_error_t *error)
{
mongoc_server_description_type_t server_type;
mongoc_client_session_t *cs;
const bson_t *cluster_time = NULL;
mongoc_read_prefs_t *prefs = NULL;
const char *cmd_name;
bool is_get_more;
const mongoc_read_prefs_t *prefs_ptr;
- mongoc_read_mode_t mode = mongoc_read_prefs_get_mode (parts->read_prefs);
+ mongoc_read_mode_t mode;
bool ret = false;
ENTRY;
BSON_ASSERT (parts);
BSON_ASSERT (server_stream);
server_type = server_stream->sd->type;
+
cs = parts->prohibit_lsid ? NULL : parts->assembled.session;
/* Assembling the command depends on the type of server. If the server has
* been invalidated, error. */
if (server_type == MONGOC_SERVER_UNKNOWN) {
if (error) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot assemble command for invalidated server: %s",
server_stream->sd->error.message);
}
RETURN (false);
}
/* must not be assembled already */
BSON_ASSERT (!parts->assembled.command);
BSON_ASSERT (bson_empty (&parts->assembled_body));
/* begin with raw flags/cmd as assembled flags/cmd, might change below */
parts->assembled.command = parts->body;
/* unused in OP_MSG: */
parts->assembled.query_flags = parts->user_query_flags;
parts->assembled.server_stream = server_stream;
cmd_name = parts->assembled.command_name =
_mongoc_get_command_name (parts->assembled.command);
if (!parts->assembled.command_name) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Empty command document");
GOTO (done);
}
TRACE ("Preparing '%s'", cmd_name);
is_get_more = !strcmp (cmd_name, "getMore");
parts->assembled.is_txn_finish = !strcmp (cmd_name, "commitTransaction") ||
!strcmp (cmd_name, "abortTransaction");
if (!parts->is_write_command && IS_PREF_PRIMARY (parts->read_prefs) &&
server_stream->topology_type == MONGOC_TOPOLOGY_SINGLE &&
server_type != MONGOC_SERVER_MONGOS) {
prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED);
prefs_ptr = prefs;
} else {
prefs_ptr = parts->read_prefs;
}
mode = mongoc_read_prefs_get_mode (prefs_ptr);
if (server_stream->must_use_primary) {
/* Server selection may have overriden the read mode used to generate this
* server stream. This has effects on the body of the message that we send
* to the server */
mode = MONGOC_READ_PRIMARY;
}
- if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
+ if (mongoc_client_uses_server_api (parts->client) ||
+ server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
if (!bson_has_field (parts->body, "$db")) {
BSON_APPEND_UTF8 (&parts->extra, "$db", parts->assembled.db_name);
}
if (cs && _mongoc_client_session_in_txn (cs)) {
if (!IS_PREF_PRIMARY (cs->txn.opts.read_prefs) &&
!parts->is_write_command) {
bson_set_error (error,
MONGOC_ERROR_TRANSACTION,
MONGOC_ERROR_TRANSACTION_INVALID_STATE,
"Read preference in a transaction must be primary");
GOTO (done);
}
} else if (mode != MONGOC_READ_PRIMARY &&
server_type != MONGOC_SERVER_STANDALONE) {
/* "Type Standalone: clients MUST NOT send the read preference to the
* server" */
_mongoc_cmd_parts_add_read_prefs (&parts->extra, prefs_ptr);
}
if (!bson_empty (&parts->extra)) {
_mongoc_cmd_parts_ensure_copied (parts);
}
/* If an explicit session was not provided and lsid is not prohibited,
* attempt to create an implicit session (ignoring any errors). */
if (!cs && !parts->prohibit_lsid && parts->assembled.is_acknowledged) {
cs = mongoc_client_start_session (parts->client, NULL, NULL);
if (cs) {
parts->assembled.session = cs;
parts->has_temp_session = true;
}
}
/* Driver Sessions Spec: "For unacknowledged writes with an explicit
* session, drivers SHOULD raise an error.... Without an explicit
* session, drivers SHOULD NOT use an implicit session." We intentionally
* do not restrict this logic to parts->is_write_command, since
* mongoc_client_command_with_opts() does not identify as a write
* command but may still include a write concern.
*/
if (cs) {
if (!parts->assembled.is_acknowledged) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot use client session with unacknowledged command");
GOTO (done);
}
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"lsid",
4,
mongoc_client_session_get_lsid (cs));
cs->server_session->last_used_usec = bson_get_monotonic_time ();
cluster_time = mongoc_client_session_get_cluster_time (cs);
}
/* Ensure we know if the write command allows a transaction number */
if (!_mongoc_client_session_txn_in_progress (cs) &&
parts->is_write_command &&
parts->allow_txn_number ==
MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_UNKNOWN) {
parts->allow_txn_number = _allow_txn_number (parts, server_stream)
? MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES
: MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO;
}
/* Determine if the command is retryable. If so, append txnNumber now
* for future use and mark the command as such. */
if (_is_retryable_write (parts, server_stream)) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_int64 (&parts->assembled_body, "txnNumber", 9, 0);
parts->is_retryable_write = true;
}
/* Conversely, check if the command is retryable if it is a read. */
if (_is_retryable_read (parts, server_stream) && !is_get_more) {
parts->is_retryable_read = true;
}
if (!bson_empty (&server_stream->cluster_time)) {
cluster_time =
_largest_cluster_time (&server_stream->cluster_time, cluster_time);
}
if (cluster_time && server_type != MONGOC_SERVER_STANDALONE) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (
&parts->assembled_body, "$clusterTime", 12, cluster_time);
}
/* Add versioned server api, if it is set. */
- if (parts->client->api) {
+ if (mongoc_client_uses_server_api (parts->client)) {
_mongoc_cmd_append_server_api (&parts->assembled_body,
parts->client->api);
}
if (!is_get_more) {
if (cs) {
/* Snapshot Sessions Spec: "Snapshot reads require MongoDB 5.0+."
* Throw an error if snapshot is enabled and wire version is less
* than 13 before potentially appending "snapshot" read concern. */
if (mongoc_session_opts_get_snapshot (&cs->opts) &&
server_stream->sd->max_wire_version <
WIRE_VERSION_SNAPSHOT_READS) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_SESSION_FAILURE,
"Snapshot reads require MongoDB 5.0 or later");
GOTO (done);
}
_mongoc_cmd_parts_ensure_copied (parts);
_mongoc_client_session_append_read_concern (
cs,
&parts->read_concern_document,
parts->is_read_command,
&parts->assembled_body);
} else if (!bson_empty (&parts->read_concern_document)) {
_mongoc_cmd_parts_ensure_copied (parts);
bson_append_document (&parts->assembled_body,
"readConcern",
11,
&parts->read_concern_document);
}
}
/* if transaction is in progress do not inherit write concern */
if (parts->assembled.is_txn_finish ||
!_mongoc_client_session_in_txn (cs)) {
_mongoc_cmd_parts_add_write_concern (parts);
}
_mongoc_cmd_parts_ensure_copied (parts);
if (!_mongoc_client_session_append_txn (
cs, &parts->assembled_body, error)) {
GOTO (done);
}
ret = true;
} else if (server_type == MONGOC_SERVER_MONGOS ||
server_stream->topology_type == MONGOC_TOPOLOGY_LOAD_BALANCED) {
/* TODO (CDRIVER-4117) remove the check of the topology description type.
*/
_mongoc_cmd_parts_assemble_mongos (parts, server_stream);
ret = true;
} else {
_mongoc_cmd_parts_assemble_mongod (parts, server_stream);
ret = true;
}
done:
mongoc_read_prefs_destroy (prefs);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cmd_parts_cleanup --
*
* Free memory associated with a stack-allocated mongoc_cmd_parts_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_cmd_parts_cleanup (mongoc_cmd_parts_t *parts)
{
bson_destroy (&parts->read_concern_document);
bson_destroy (&parts->write_concern_document);
bson_destroy (&parts->extra);
bson_destroy (&parts->assembled_body);
if (parts->has_temp_session) {
/* client session returns its server session to server session pool */
mongoc_client_session_destroy (parts->assembled.session);
}
}
bool
mongoc_cmd_is_compressible (mongoc_cmd_t *cmd)
{
BSON_ASSERT (cmd);
BSON_ASSERT (cmd->command_name);
return !!strcasecmp (cmd->command_name, "hello") &&
!!strcasecmp (cmd->command_name, HANDSHAKE_CMD_LEGACY_HELLO) &&
!!strcasecmp (cmd->command_name, "authenticate") &&
!!strcasecmp (cmd->command_name, "getnonce") &&
!!strcasecmp (cmd->command_name, "saslstart") &&
!!strcasecmp (cmd->command_name, "saslcontinue") &&
!!strcasecmp (cmd->command_name, "createuser") &&
!!strcasecmp (cmd->command_name, "updateuser");
}
/*--------------------------------------------------------------------------
*
* _mongoc_cmd_append_payload_as_array --
* Append a write command payload as an array in a BSON document.
* Used by APM and Client-Side Encryption
*
* Arguments:
* cmd The mongoc_cmd_t, which may contain a payload to be appended.
* out A bson_t, which will be appended to if @cmd->payload is set.
*
* Pre-conditions:
* - @out is initialized.
* - cmd has a payload (i.e. is a write command).
*
* Post-conditions:
* - If @cmd->payload is set, then @out is appended to with the payload
* field's name ("documents" if insert, "updates" if update,
* "deletes" if delete) an the payload as a BSON array.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_cmd_append_payload_as_array (const mongoc_cmd_t *cmd, bson_t *out)
{
int32_t doc_len;
bson_t doc;
const uint8_t *pos;
const char *field_name;
bson_t bson;
char str[16];
const char *key;
uint32_t i;
BSON_ASSERT (cmd->payload && cmd->payload_size);
/* make array from outgoing OP_MSG payload type 1 on an "insert",
* "update", or "delete" command. */
field_name = _mongoc_get_documents_field_name (cmd->command_name);
BSON_ASSERT (field_name);
BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (out, field_name, &bson));
pos = cmd->payload;
i = 0;
while (pos < cmd->payload + cmd->payload_size) {
memcpy (&doc_len, pos, sizeof (doc_len));
doc_len = BSON_UINT32_FROM_LE (doc_len);
BSON_ASSERT (bson_init_static (&doc, pos, (size_t) doc_len));
bson_uint32_to_string (i, &key, str, sizeof (str));
BSON_APPEND_DOCUMENT (&bson, key, &doc);
pos += doc_len;
i++;
}
bson_append_array_end (out, &bson);
}
/*--------------------------------------------------------------------------
*
* _mongoc_cmd_append_server_api --
* Append versioned API fields to a mongoc_cmd_t
*
* Arguments:
* cmd The mongoc_cmd_t, which will have versioned API fields added
* api A mongoc_server_api_t holding server API information
*
* Pre-conditions:
* - @api is initialized.
* - @command_body is initialised
*
*--------------------------------------------------------------------------
*/
void
_mongoc_cmd_append_server_api (bson_t *command_body,
const mongoc_server_api_t *api)
{
const char *string_version;
BSON_ASSERT (command_body);
BSON_ASSERT (api);
string_version = mongoc_server_api_version_to_string (api->version);
+ BSON_ASSERT (string_version);
+
bson_append_utf8 (command_body, "apiVersion", -1, string_version, -1);
if (api->strict.is_set) {
bson_append_bool (command_body, "apiStrict", -1, api->strict.value);
}
if (api->deprecation_errors.is_set) {
bson_append_bool (command_body,
"apiDeprecationErrors",
-1,
api->deprecation_errors.value);
}
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
similarity index 93%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
index 38a2377a..5b083cea 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c
@@ -1,3592 +1,3720 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "mongoc-aggregate-private.h"
#include "mongoc-bulk-operation.h"
#include "mongoc-bulk-operation-private.h"
#include "mongoc-change-stream-private.h"
#include "mongoc-client-private.h"
#include "mongoc-find-and-modify-private.h"
#include "mongoc-find-and-modify.h"
#include "mongoc-collection.h"
#include "mongoc-collection-private.h"
#include "mongoc-cursor-private.h"
#include "mongoc-error.h"
#include "mongoc-index.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-command-private.h"
#include "mongoc-opts-private.h"
#include "mongoc-write-command-private.h"
#include "mongoc-error-private.h"
+#include "mongoc-database-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "collection"
static void
_mongoc_collection_write_command_execute (
mongoc_write_command_t *command,
const mongoc_collection_t *collection,
const mongoc_write_concern_t *write_concern,
mongoc_client_session_t *cs,
mongoc_write_result_t *result)
{
mongoc_server_stream_t *server_stream;
ENTRY;
server_stream = mongoc_cluster_stream_for_writes (
&collection->client->cluster, cs, NULL, &result->error);
if (!server_stream) {
/* result->error has been filled out */
EXIT;
}
_mongoc_write_command_execute (command,
collection->client,
server_stream,
collection->db,
collection->collection,
write_concern,
0 /* offset */,
cs,
result);
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
static void
_mongoc_collection_write_command_execute_idl (
mongoc_write_command_t *command,
const mongoc_collection_t *collection,
mongoc_crud_opts_t *crud,
mongoc_write_result_t *result)
{
mongoc_server_stream_t *server_stream;
bson_t reply;
ENTRY;
server_stream =
mongoc_cluster_stream_for_writes (&collection->client->cluster,
crud->client_session,
&reply,
&result->error);
if (!server_stream) {
/* result->error and reply have been filled out */
_mongoc_bson_array_copy_labels_to (&reply, &result->errorLabels);
bson_destroy (&reply);
EXIT;
}
if (_mongoc_client_session_in_txn (crud->client_session) &&
crud->writeConcern) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
if (!crud->writeConcern &&
!_mongoc_client_session_in_txn (crud->client_session)) {
crud->writeConcern = collection->write_concern;
crud->write_concern_owned = false;
}
_mongoc_write_command_execute_idl (command,
collection->client,
server_stream,
collection->db,
collection->collection,
0 /* offset */,
crud,
result);
mongoc_server_stream_cleanup (server_stream);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_collection_new --
*
* INTERNAL API
*
* Create a new mongoc_collection_t structure for the given client.
*
* @client must remain valid during the lifetime of this structure.
* @db is the db name of the collection.
* @collection is the name of the collection.
* @read_prefs is the default read preferences to apply or NULL.
* @read_concern is the default read concern to apply or NULL.
* @write_concern is the default write concern to apply or NULL.
*
* Returns:
* A newly allocated mongoc_collection_t that should be freed with
* mongoc_collection_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_collection_t *
_mongoc_collection_new (mongoc_client_t *client,
const char *db,
const char *collection,
const mongoc_read_prefs_t *read_prefs,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern)
{
mongoc_collection_t *col;
ENTRY;
BSON_ASSERT_PARAM (client);
BSON_ASSERT_PARAM (db);
BSON_ASSERT_PARAM (collection);
col = (mongoc_collection_t *) bson_malloc0 (sizeof *col);
col->client = client;
col->write_concern = write_concern
? mongoc_write_concern_copy (write_concern)
: mongoc_write_concern_new ();
col->read_concern = read_concern ? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
col->read_prefs = read_prefs ? mongoc_read_prefs_copy (read_prefs)
: mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
col->ns = bson_strdup_printf ("%s.%s", db, collection);
col->db = bson_strdup (db);
col->collection = bson_strdup (collection);
col->collectionlen = (uint32_t) strlen (col->collection);
col->nslen = (uint32_t) strlen (col->ns);
col->gle = NULL;
RETURN (col);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_destroy --
*
* Release resources associated with @collection and frees the
* structure.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_destroy (mongoc_collection_t *collection) /* IN */
{
ENTRY;
if (!collection) {
EXIT;
}
bson_clear (&collection->gle);
if (collection->read_prefs) {
mongoc_read_prefs_destroy (collection->read_prefs);
collection->read_prefs = NULL;
}
if (collection->read_concern) {
mongoc_read_concern_destroy (collection->read_concern);
collection->read_concern = NULL;
}
if (collection->write_concern) {
mongoc_write_concern_destroy (collection->write_concern);
collection->write_concern = NULL;
}
bson_free (collection->collection);
bson_free (collection->db);
bson_free (collection->ns);
bson_free (collection);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_copy --
*
* Returns a copy of @collection that needs to be freed by calling
* mongoc_collection_destroy.
*
* Returns:
* A copy of this collection.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_collection_t *
mongoc_collection_copy (mongoc_collection_t *collection) /* IN */
{
ENTRY;
BSON_ASSERT_PARAM (collection);
RETURN (_mongoc_collection_new (collection->client,
collection->db,
collection->collection,
collection->read_prefs,
collection->read_concern,
collection->write_concern));
}
mongoc_cursor_t *
mongoc_collection_aggregate (mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
const bson_t *pipeline, /* IN */
const bson_t *opts, /* IN */
const mongoc_read_prefs_t *read_prefs) /* IN */
{
return _mongoc_aggregate (collection->client,
collection->ns,
flags,
pipeline,
opts,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find --
*
* DEPRECATED: use mongoc_collection_find_with_opts.
*
* Performs a query against the configured MongoDB server. If @read_prefs
* is provided, it will be used to locate a MongoDB node in the cluster
* to deliver the query to.
*
* @flags may be bitwise-or'd flags or MONGOC_QUERY_NONE.
*
* @skip may contain the number of documents to skip before returning the
* matching document.
*
* @limit may contain the maximum number of documents that may be
* returned.
*
* This function will always return a cursor, with the exception of
* invalid API use.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: A bitwise or of mongoc_query_flags_t.
* @skip: The number of documents to skip.
* @limit: The maximum number of items.
* @batch_size: The batch size
* @query: The query to locate matching documents.
* @fields: The fields to return, or NULL for all fields.
* @read_prefs: Read preferences to choose cluster node.
*
* Returns:
* A newly allocated mongoc_cursor_t that should be freed with
* mongoc_cursor_destroy().
*
* The client used by mongoc_collection_t must be valid for the
* lifetime of the resulting mongoc_cursor_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_cursor_t *
mongoc_collection_find (mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
uint32_t skip, /* IN */
uint32_t limit, /* IN */
uint32_t batch_size, /* IN */
const bson_t *query, /* IN */
const bson_t *fields, /* IN */
const mongoc_read_prefs_t *read_prefs) /* IN */
{
bool has_unwrapped;
bson_t unwrapped;
bson_error_t error = {0};
bson_t opts;
bool secondary_ok;
mongoc_cursor_t *cursor;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (query);
bson_clear (&collection->gle);
bson_init (&opts);
_mongoc_cursor_flags_to_opts (flags, &opts, &secondary_ok);
/* check if the query is wrapped in $query */
has_unwrapped = _mongoc_cursor_translate_dollar_query_opts (
query, &opts, &unwrapped, &error);
if (!bson_empty0 (fields)) {
bson_append_document (
&opts, MONGOC_CURSOR_PROJECTION, MONGOC_CURSOR_PROJECTION_LEN, fields);
}
cursor = _mongoc_cursor_find_new (collection->client,
collection->ns,
has_unwrapped ? &unwrapped : query,
&opts,
read_prefs,
collection->read_prefs,
collection->read_concern);
if (skip) {
_mongoc_cursor_set_opt_int64 (cursor, MONGOC_CURSOR_SKIP, skip);
}
if (limit) {
/* limit must be cast to int32_t. Although the argument is a uint32_t,
* callers can specify a negative limit by casting to a signed int32_t
* value to uint32_t. E.g. to set a limit of -4, the caller passes
* UINT32_MAX - 3 */
(void) mongoc_cursor_set_limit (cursor, (int32_t) limit);
}
if (batch_size) {
mongoc_cursor_set_batch_size (cursor, batch_size);
}
bson_destroy (&unwrapped);
bson_destroy (&opts);
if (error.domain) {
memcpy (&cursor->error, &error, sizeof (error));
}
return cursor;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find_with_opts --
*
* Create a cursor with a query filter. All other options are
* specified in a free-form BSON document.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @filter: The query to locate matching documents.
* @opts: Other options.
* @read_prefs: Optional read preferences to choose cluster node.
*
* Returns:
* A newly allocated mongoc_cursor_t that should be freed with
* mongoc_cursor_destroy().
*
* The client used by mongoc_collection_t must be valid for the
* lifetime of the resulting mongoc_cursor_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_cursor_t *
mongoc_collection_find_with_opts (mongoc_collection_t *collection,
const bson_t *filter,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (filter);
bson_clear (&collection->gle);
return _mongoc_cursor_find_new (collection->client,
collection->ns,
filter,
opts,
read_prefs,
collection->read_prefs,
collection->read_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_command --
*
* Executes a command on a cluster node matching @read_prefs. If
* @read_prefs is not provided, it will be run on the primary node.
*
* This function will always return a mongoc_cursor_t.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: Bitwise-or'd flags for command.
* @skip: Number of documents to skip, typically 0.
* @limit : Number of documents to return
* @batch_size : Batch size
* @query: The command to execute.
* @fields: The fields to return, or NULL.
* @read_prefs: Command read preferences or NULL.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_cursor_t *
mongoc_collection_command (mongoc_collection_t *collection,
mongoc_query_flags_t flags,
uint32_t skip,
uint32_t limit,
uint32_t batch_size,
const bson_t *query,
const bson_t *fields,
const mongoc_read_prefs_t *read_prefs)
{
char *ns;
mongoc_cursor_t *cursor;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (query);
if (!read_prefs) {
read_prefs = collection->read_prefs;
}
bson_clear (&collection->gle);
if (NULL == strstr (collection->collection, "$cmd")) {
ns = bson_strdup_printf ("%s.$cmd", collection->db);
} else {
ns = bson_strdup (collection->db);
}
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
/* flags, skip, limit, batch_size, fields are unused */
cursor = _mongoc_cursor_cmd_deprecated_new (
collection->client, ns, query, read_prefs);
bson_free (ns);
return cursor;
}
bool
mongoc_collection_read_command_with_opts (mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
BSON_ASSERT_PARAM (collection);
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_READ,
opts,
MONGOC_QUERY_NONE,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_write_command_with_opts (mongoc_collection_t *collection,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
BSON_ASSERT_PARAM (collection);
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_read_write_command_with_opts (
mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs /* IGNORED */,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
BSON_ASSERT_PARAM (collection);
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_RW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_command_with_opts (mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
BSON_ASSERT_PARAM (collection);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument." */
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_RAW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
NULL /* default prefs */,
collection->read_concern,
collection->write_concern,
reply,
error);
}
bool
mongoc_collection_command_simple (mongoc_collection_t *collection,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (command);
bson_clear (&collection->gle);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
return _mongoc_client_command_with_opts (collection->client,
collection->db,
command,
MONGOC_CMD_RAW,
NULL /* opts */,
MONGOC_QUERY_NONE,
read_prefs,
NULL /* default prefs */,
NULL /* read concern */,
NULL /* write concern */,
reply,
error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_count --
*
* Count the number of documents matching @query.
*
* Parameters:
* @flags: A mongoc_query_flags_t describing the query flags or 0.
* @query: The query to perform or NULL for {}.
* @skip: The $skip to perform within the query or 0.
* @limit: The $limit to perform within the query or 0.
* @read_prefs: desired read preferences or NULL.
* @error: A location for an error or NULL.
*
* Returns:
* -1 on failure; otherwise the number of matching documents.
*
* Side effects:
* @error is set upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
int64_t
mongoc_collection_count (mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
const bson_t *query, /* IN */
int64_t skip, /* IN */
int64_t limit, /* IN */
const mongoc_read_prefs_t *read_prefs, /* IN */
bson_error_t *error) /* OUT */
{
int64_t ret;
bson_t opts = BSON_INITIALIZER;
/* Complex types must be parts of `opts`, otherwise we can't
* follow various specs that require validation etc */
if (collection->read_concern->level != NULL) {
const bson_t *read_concern_bson;
read_concern_bson =
_mongoc_read_concern_get_bson (collection->read_concern);
BSON_APPEND_DOCUMENT (&opts, "readConcern", read_concern_bson);
}
/* Server Selection Spec: "may-use-secondary" commands SHOULD take a read
* preference argument and otherwise MUST use the default read preference
* from client, database or collection configuration. */
BEGIN_IGNORE_DEPRECATIONS
ret = mongoc_collection_count_with_opts (
collection, flags, query, skip, limit, &opts, read_prefs, error);
END_IGNORE_DEPRECATIONS
bson_destroy (&opts);
return ret;
}
int64_t
mongoc_collection_count_with_opts (
mongoc_collection_t *collection, /* IN */
mongoc_query_flags_t flags, /* IN */
const bson_t *query, /* IN */
int64_t skip, /* IN */
int64_t limit, /* IN */
const bson_t *opts, /* IN */
const mongoc_read_prefs_t *read_prefs, /* IN */
bson_error_t *error) /* OUT */
{
bson_iter_t iter;
int64_t ret = -1;
bool success;
bson_t reply;
bson_t cmd = BSON_INITIALIZER;
bson_t q;
ENTRY;
BSON_ASSERT_PARAM (collection);
bson_append_utf8 (
&cmd, "count", 5, collection->collection, collection->collectionlen);
if (query) {
bson_append_document (&cmd, "query", 5, query);
} else {
bson_init (&q);
bson_append_document (&cmd, "query", 5, &q);
bson_destroy (&q);
}
if (limit) {
bson_append_int64 (&cmd, "limit", 5, limit);
}
if (skip) {
bson_append_int64 (&cmd, "skip", 4, skip);
}
success = _mongoc_client_command_with_opts (collection->client,
collection->db,
&cmd,
MONGOC_CMD_READ,
opts,
flags,
read_prefs,
collection->read_prefs,
collection->read_concern,
collection->write_concern,
&reply,
error);
if (success) {
if (bson_iter_init_find (&iter, &reply, "n")) {
ret = bson_iter_as_int64 (&iter);
}
}
bson_destroy (&reply);
bson_destroy (&cmd);
RETURN (ret);
}
-/* --------------------------------------------------------------------------
- *
- * _make_aggregate_for_edc --
- *
- * Construct an aggregate pipeline with the following form:
- *
- *
- * { pipeline: [
- * { $collStats: { count: {} } },
- * { $group: { _id: 1, n: { $sum: $count } } },
- * ]
- * }
- *
- *--------------------------------------------------------------------------
- */
-static void
-_make_aggregate_for_edc (const mongoc_collection_t *coll, bson_t *out)
-{
- bson_t pipeline;
- bson_t coll_stats_stage;
- bson_t coll_stats_stage_doc;
- bson_t group_stage;
- bson_t group_stage_doc;
- bson_t sum;
- bson_t cursor_empty;
- bson_t empty;
-
- BSON_APPEND_UTF8 (out, "aggregate", coll->collection);
- BSON_APPEND_DOCUMENT_BEGIN (out, "cursor", &cursor_empty);
- bson_append_document_end (out, &cursor_empty);
- BSON_APPEND_ARRAY_BEGIN (out, "pipeline", &pipeline);
-
- BSON_APPEND_DOCUMENT_BEGIN (&pipeline, "0", &coll_stats_stage);
- BSON_APPEND_DOCUMENT_BEGIN (
- &coll_stats_stage, "$collStats", &coll_stats_stage_doc);
- BSON_APPEND_DOCUMENT_BEGIN (&coll_stats_stage_doc, "count", &empty);
- bson_append_document_end (&coll_stats_stage_doc, &empty);
- bson_append_document_end (&coll_stats_stage, &coll_stats_stage_doc);
- bson_append_document_end (&pipeline, &coll_stats_stage);
-
- BSON_APPEND_DOCUMENT_BEGIN (&pipeline, "1", &group_stage);
- BSON_APPEND_DOCUMENT_BEGIN (&group_stage, "$group", &group_stage_doc);
- BSON_APPEND_INT32 (&group_stage_doc, "_id", 1);
- BSON_APPEND_DOCUMENT_BEGIN (&group_stage_doc, "n", &sum);
- BSON_APPEND_UTF8 (&sum, "$sum", "$count");
- bson_append_document_end (&group_stage_doc, &sum);
- bson_append_document_end (&group_stage, &group_stage_doc);
- bson_append_document_end (&pipeline, &group_stage);
- bson_append_array_end (out, &pipeline);
-}
-
int64_t
mongoc_collection_estimated_document_count (
mongoc_collection_t *coll,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
bson_iter_t iter;
int64_t count = -1;
bool ret;
bson_t reply_local;
bson_t *reply_ptr;
bson_t cmd = BSON_INITIALIZER;
mongoc_server_stream_t *server_stream = NULL;
ENTRY;
BSON_ASSERT_PARAM (coll);
server_stream =
mongoc_cluster_stream_for_reads (&coll->client->cluster,
read_prefs,
NULL,
reply,
/* Not aggregate-with-write */ false,
error);
if (opts && bson_has_field (opts, "sessionId")) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Collection count must not specify explicit session");
GOTO (done);
}
reply_ptr = reply ? reply : &reply_local;
- if (server_stream->sd->max_wire_version < WIRE_VERSION_4_9) {
- /* On < 4.9, use actual count command for estimatedDocumentCount */
- BSON_APPEND_UTF8 (&cmd, "count", coll->collection);
- ret = _mongoc_client_command_with_opts (coll->client,
- coll->db,
- &cmd,
- MONGOC_CMD_READ,
- opts,
- MONGOC_QUERY_NONE,
- read_prefs,
- coll->read_prefs,
- coll->read_concern,
- coll->write_concern,
- reply_ptr,
- error);
- if (ret) {
- if (bson_iter_init_find (&iter, reply_ptr, "n")) {
- count = bson_iter_as_int64 (&iter);
- }
- }
- } else {
- /* On >= 4.9, use aggregate with collStats for estimatedDocumentCount */
- _make_aggregate_for_edc (coll, &cmd);
- ret = mongoc_collection_read_command_with_opts (
- coll, &cmd, read_prefs, opts, reply_ptr, error);
-
- if (!ret && error->code == MONGOC_ERROR_COLLECTION_DOES_NOT_EXIST) {
- /* Collection does not exist. From spec: return 0 but no err:
- * https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#estimateddocumentcount
- */
- if (reply) {
- bson_reinit (reply);
- }
- memset (error, 0, sizeof *error);
- count = 0;
- GOTO (done);
- }
- if (ret && bson_iter_init (&iter, reply_ptr)) {
- if (bson_iter_find_descendant (
- &iter, "cursor.firstBatch.0.n", &iter)) {
- count = bson_iter_as_int64 (&iter);
- }
+
+ BSON_APPEND_UTF8 (&cmd, "count", coll->collection);
+ ret = _mongoc_client_command_with_opts (coll->client,
+ coll->db,
+ &cmd,
+ MONGOC_CMD_READ,
+ opts,
+ MONGOC_QUERY_NONE,
+ read_prefs,
+ coll->read_prefs,
+ coll->read_concern,
+ coll->write_concern,
+ reply_ptr,
+ error);
+ if (ret) {
+ if (bson_iter_init_find (&iter, reply_ptr, "n")) {
+ count = bson_iter_as_int64 (&iter);
}
}
done:
if (!reply) {
bson_destroy (&reply_local);
}
bson_destroy (&cmd);
mongoc_server_stream_cleanup (server_stream);
RETURN (count);
}
/* --------------------------------------------------------------------------
*
* _make_aggregate_for_count --
*
* Construct an aggregate pipeline with the following form:
* { pipeline: [
* { $match: {...} },
* { $group: { _id: 1, n: { sum: 1 } } },
* { $skip: ... },
* { $limit: ... }
* ]
* }
*
*--------------------------------------------------------------------------
*/
static void
_make_aggregate_for_count (const mongoc_collection_t *coll,
const bson_t *filter,
const bson_t *opts,
bson_t *out)
{
bson_iter_t iter;
bson_t pipeline;
bson_t match_stage;
bson_t group_stage;
bson_t group_stage_doc;
bson_t sum;
bson_t empty;
const char *keys[] = {"0", "1", "2", "3"};
int key = 0;
bson_init (out);
bson_append_utf8 (
out, "aggregate", 9, coll->collection, coll->collectionlen);
bson_append_document_begin (out, "cursor", 6, &empty);
bson_append_document_end (out, &empty);
bson_append_array_begin (out, "pipeline", 8, &pipeline);
bson_append_document_begin (&pipeline, keys[key++], 1, &match_stage);
bson_append_document (&match_stage, "$match", 6, filter);
bson_append_document_end (&pipeline, &match_stage);
/* if @opts includes "skip", or "count", append $skip and $count stages to
* the aggregate pipeline. */
if (opts && bson_iter_init_find (&iter, opts, "skip")) {
bson_t skip_stage;
bson_append_document_begin (&pipeline, keys[key++], 1, &skip_stage);
bson_append_value (&skip_stage, "$skip", 5, bson_iter_value (&iter));
bson_append_document_end (&pipeline, &skip_stage);
}
if (opts && bson_iter_init_find (&iter, opts, "limit")) {
bson_t limit_stage;
bson_append_document_begin (&pipeline, keys[key++], 1, &limit_stage);
bson_append_value (&limit_stage, "$limit", 6, bson_iter_value (&iter));
bson_append_document_end (&pipeline, &limit_stage);
}
bson_append_document_begin (&pipeline, keys[key], 1, &group_stage);
bson_append_document_begin (&group_stage, "$group", 6, &group_stage_doc);
bson_append_int32 (&group_stage_doc, "_id", 3, 1);
bson_append_document_begin (&group_stage_doc, "n", 1, &sum);
bson_append_int32 (&sum, "$sum", 4, 1);
bson_append_document_end (&group_stage_doc, &sum);
bson_append_document_end (&group_stage, &group_stage_doc);
bson_append_document_end (&pipeline, &group_stage);
bson_append_array_end (out, &pipeline);
}
int64_t
mongoc_collection_count_documents (mongoc_collection_t *coll,
const bson_t *filter,
const bson_t *opts,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
bson_t aggregate_cmd;
bson_t aggregate_opts;
bool ret;
const bson_t *result;
mongoc_cursor_t *cursor = NULL;
int64_t count = -1;
bson_t cmd_reply;
bson_iter_t iter;
ENTRY;
BSON_ASSERT_PARAM (coll);
BSON_ASSERT_PARAM (filter);
_make_aggregate_for_count (coll, filter, opts, &aggregate_cmd);
bson_init (&aggregate_opts);
if (opts) {
bson_copy_to_excluding_noinit (
opts, &aggregate_opts, "skip", "limit", NULL);
}
ret = mongoc_collection_read_command_with_opts (
coll, &aggregate_cmd, read_prefs, &aggregate_opts, &cmd_reply, error);
bson_destroy (&aggregate_cmd);
bson_destroy (&aggregate_opts);
if (reply) {
bson_copy_to (&cmd_reply, reply);
}
if (!ret) {
bson_destroy (&cmd_reply);
GOTO (done);
}
/* steals reply */
cursor = mongoc_cursor_new_from_command_reply_with_opts (
coll->client, &cmd_reply, NULL);
BSON_ASSERT (mongoc_cursor_get_id (cursor) == 0);
ret = mongoc_cursor_next (cursor, &result);
if (!ret) {
if (mongoc_cursor_error (cursor, error)) {
GOTO (done);
} else {
count = 0;
GOTO (done);
}
}
if (bson_iter_init_find (&iter, result, "n") &&
BSON_ITER_HOLDS_INT (&iter)) {
count = bson_iter_as_int64 (&iter);
}
done:
if (cursor) {
mongoc_cursor_destroy (cursor);
}
RETURN (count);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_drop --
*
* Request the MongoDB server drop the collection.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is set upon failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_drop (mongoc_collection_t *collection, /* IN */
bson_error_t *error) /* OUT */
{
return mongoc_collection_drop_with_opts (collection, NULL, error);
}
-bool
-mongoc_collection_drop_with_opts (mongoc_collection_t *collection,
- const bson_t *opts,
- bson_error_t *error)
+static bool
+drop_with_opts (mongoc_collection_t *collection,
+ const bson_t *opts,
+ bson_error_t *error)
{
bool ret;
bson_t cmd;
BSON_ASSERT_PARAM (collection);
bson_init (&cmd);
bson_append_utf8 (
&cmd, "drop", 4, collection->collection, collection->collectionlen);
ret = _mongoc_client_command_with_opts (collection->client,
collection->db,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
collection->read_prefs,
collection->read_concern,
collection->write_concern,
NULL, /* reply */
error);
bson_destroy (&cmd);
return ret;
}
+static bool
+drop_with_opts_with_encryptedFields (mongoc_collection_t *collection,
+ const bson_t *opts,
+ const bson_t *encryptedFields,
+ bson_error_t *error)
+{
+ char *escName = NULL;
+ char *eccName = NULL;
+ char *ecocName = NULL;
+ mongoc_collection_t *escCollection = NULL;
+ mongoc_collection_t *eccCollection = NULL;
+ mongoc_collection_t *ecocCollection = NULL;
+ bool ok = false;
+ const char *name = mongoc_collection_get_name (collection);
+
+ /* Drop ESC collection. */
+ escName = _mongoc_get_encryptedField_state_collection (
+ encryptedFields, name, "esc", error);
+ if (!escName) {
+ goto fail;
+ }
+
+ escCollection = mongoc_client_get_collection (
+ collection->client, collection->db, escName);
+ if (!drop_with_opts (escCollection, NULL /* opts */, error)) {
+ if (error->code == MONGOC_SERVER_ERR_NS_NOT_FOUND) {
+ memset (error, 0, sizeof (bson_error_t));
+ } else {
+ goto fail;
+ }
+ }
+
+ /* Drop ECC collection. */
+ eccName = _mongoc_get_encryptedField_state_collection (
+ encryptedFields, name, "ecc", error);
+ if (!eccName) {
+ goto fail;
+ }
+
+ eccCollection = mongoc_client_get_collection (
+ collection->client, collection->db, eccName);
+ if (!drop_with_opts (eccCollection, NULL /* opts */, error)) {
+ if (error->code == MONGOC_SERVER_ERR_NS_NOT_FOUND) {
+ memset (error, 0, sizeof (bson_error_t));
+ } else {
+ goto fail;
+ }
+ }
+
+ /* Drop ECOC collection. */
+ ecocName = _mongoc_get_encryptedField_state_collection (
+ encryptedFields, name, "ecoc", error);
+ if (!ecocName) {
+ goto fail;
+ }
+
+ ecocCollection = mongoc_client_get_collection (
+ collection->client, collection->db, ecocName);
+ if (!drop_with_opts (ecocCollection, NULL /* opts */, error)) {
+ if (error->code == MONGOC_SERVER_ERR_NS_NOT_FOUND) {
+ memset (error, 0, sizeof (bson_error_t));
+ } else {
+ goto fail;
+ }
+ }
+
+ /* Drop data collection. */
+ if (!drop_with_opts (collection, opts, error)) {
+ if (error->code == MONGOC_SERVER_ERR_NS_NOT_FOUND) {
+ memset (error, 0, sizeof (bson_error_t));
+ } else {
+ goto fail;
+ }
+ }
+
+ ok = true;
+fail:
+ mongoc_collection_destroy (ecocCollection);
+ bson_free (ecocName);
+ mongoc_collection_destroy (eccCollection);
+ bson_free (eccName);
+ mongoc_collection_destroy (escCollection);
+ bson_free (escName);
+ return ok;
+}
+
+bool
+mongoc_collection_drop_with_opts (mongoc_collection_t *collection,
+ const bson_t *opts,
+ bson_error_t *error)
+{
+ bson_iter_t iter;
+ bson_t encryptedFields = BSON_INITIALIZER;
+
+ if (opts && bson_iter_init_find (&iter, opts, "encryptedFields")) {
+ if (!_mongoc_iter_document_as_bson (&iter, &encryptedFields, error)) {
+ return false;
+ }
+ }
+
+ if (bson_empty (&encryptedFields)) {
+ if (!_mongoc_get_encryptedFields_from_map (
+ collection->client,
+ collection->db,
+ mongoc_collection_get_name (collection),
+ &encryptedFields,
+ error)) {
+ return false;
+ }
+ }
+
+ if (bson_empty (&encryptedFields) &&
+ collection->client->topology->encrypted_fields_map != NULL) {
+ if (!_mongoc_get_encryptedFields_from_server (
+ collection->client,
+ collection->db,
+ mongoc_collection_get_name (collection),
+ &encryptedFields,
+ error)) {
+ return false;
+ }
+ }
+
+ if (!bson_empty (&encryptedFields)) {
+ bson_t opts_without_encryptedFields = BSON_INITIALIZER;
+
+ if (opts) {
+ bson_copy_to_excluding_noinit (
+ opts, &opts_without_encryptedFields, "encryptedFields", NULL);
+ }
+
+ bool ret = drop_with_opts_with_encryptedFields (
+ collection, &opts_without_encryptedFields, &encryptedFields, error);
+
+ bson_destroy (&opts_without_encryptedFields);
+ bson_destroy (&encryptedFields);
+ return ret;
+ }
+
+ return drop_with_opts (collection, opts, error);
+}
+
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_drop_index --
*
* Request the MongoDB server drop the named index.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is setup upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_drop_index (mongoc_collection_t *collection, /* IN */
const char *index_name, /* IN */
bson_error_t *error) /* OUT */
{
return mongoc_collection_drop_index_with_opts (
collection, index_name, NULL, error);
}
bool
mongoc_collection_drop_index_with_opts (mongoc_collection_t *collection,
const char *index_name,
const bson_t *opts,
bson_error_t *error)
{
bool ret;
bson_t cmd;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (index_name);
bson_init (&cmd);
bson_append_utf8 (&cmd,
"dropIndexes",
-1,
collection->collection,
collection->collectionlen);
bson_append_utf8 (&cmd, "index", -1, index_name, -1);
ret = _mongoc_client_command_with_opts (collection->client,
collection->db,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
collection->read_prefs,
collection->read_concern,
collection->write_concern,
NULL, /* reply */
error);
bson_destroy (&cmd);
return ret;
}
char *
mongoc_collection_keys_to_index_string (const bson_t *keys)
{
bson_string_t *s;
bson_iter_t iter;
bson_type_t type;
int i = 0;
BSON_ASSERT_PARAM (keys);
if (!bson_iter_init (&iter, keys)) {
return NULL;
}
s = bson_string_new (NULL);
while (bson_iter_next (&iter)) {
/* Index type can be specified as a string ("2d") or as an integer
* representing direction */
type = bson_iter_type (&iter);
if (type == BSON_TYPE_UTF8) {
bson_string_append_printf (s,
(i++ ? "_%s_%s" : "%s_%s"),
bson_iter_key (&iter),
bson_iter_utf8 (&iter, NULL));
} else if (type == BSON_TYPE_INT32) {
bson_string_append_printf (s,
(i++ ? "_%s_%d" : "%s_%d"),
bson_iter_key (&iter),
bson_iter_int32 (&iter));
} else if (type == BSON_TYPE_INT64) {
bson_string_append_printf (s,
(i++ ? "_%s_%" PRId64 : "%s_%" PRId64),
bson_iter_key (&iter),
bson_iter_int64 (&iter));
} else {
bson_string_free (s, true);
return NULL;
}
}
return bson_string_free (s, false);
}
bool
mongoc_collection_create_index (mongoc_collection_t *collection,
const bson_t *keys,
const mongoc_index_opt_t *opt,
bson_error_t *error)
{
bson_t reply;
bool ret;
BEGIN_IGNORE_DEPRECATIONS
ret = mongoc_collection_create_index_with_opts (
collection, keys, opt, NULL, &reply, error);
END_IGNORE_DEPRECATIONS
bson_destroy (&reply);
return ret;
}
static bool
_mongoc_collection_index_keys_equal (const bson_t *expected,
const bson_t *actual)
{
bson_iter_t iter_expected;
bson_iter_t iter_actual;
bson_iter_init (&iter_expected, expected);
bson_iter_init (&iter_actual, actual);
while (bson_iter_next (&iter_expected)) {
/* If the key document has fewer items than expected, indexes are unequal
*/
if (!bson_iter_next (&iter_actual)) {
return false;
}
/* If key order does not match, indexes are unequal */
if (strcmp (bson_iter_key (&iter_expected),
bson_iter_key (&iter_actual)) != 0) {
return false;
}
if (BSON_ITER_HOLDS_NUMBER (&iter_expected) &&
BSON_ITER_HOLDS_NUMBER (&iter_actual)) {
if (bson_iter_as_int64 (&iter_expected) !=
bson_iter_as_int64 (&iter_actual)) {
return false;
}
} else if (BSON_ITER_HOLDS_UTF8 (&iter_expected) &&
BSON_ITER_HOLDS_UTF8 (&iter_actual)) {
if (strcmp (bson_iter_utf8 (&iter_expected, NULL),
bson_iter_utf8 (&iter_actual, NULL)) != 0) {
return false;
}
} else {
return false;
}
}
/* If our expected document is exhausted, make sure there are no extra keys
* in the actual key document */
if (bson_iter_next (&iter_actual)) {
return false;
}
return true;
}
bool
_mongoc_collection_create_index_if_not_exists (mongoc_collection_t *collection,
const bson_t *keys,
const bson_t *opts,
bson_error_t *error)
{
mongoc_cursor_t *cursor;
bool index_exists;
bool r = false;
const bson_t *doc;
bson_iter_t iter;
bson_t inner_doc;
uint32_t data_len;
const uint8_t *data;
bson_t index;
bson_t command;
BSON_ASSERT (collection);
BSON_ASSERT (keys);
cursor = mongoc_collection_find_indexes_with_opts (collection, NULL);
index_exists = false;
while (mongoc_cursor_next (cursor, &doc) && !index_exists) {
r = bson_iter_init_find (&iter, doc, "key");
if (!r) {
continue;
}
bson_iter_document (&iter, &data_len, &data);
bson_init_static (&inner_doc, data, data_len);
if (_mongoc_collection_index_keys_equal (keys, &inner_doc)) {
index_exists = true;
}
bson_destroy (&inner_doc);
}
if (mongoc_cursor_error (cursor, error)) {
mongoc_cursor_destroy (cursor);
return false;
}
mongoc_cursor_destroy (cursor);
if (index_exists) {
return true;
}
if (opts) {
bson_copy_to (opts, &index);
} else {
bson_init (&index);
}
BSON_APPEND_DOCUMENT (&index, "key", keys);
if (!bson_has_field (&index, "name")) {
char *alloc_name = mongoc_collection_keys_to_index_string (keys);
if (!alloc_name) {
bson_set_error (
error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Cannot generate index name from invalid `keys` argument");
GOTO (done);
}
BSON_APPEND_UTF8 (&index, "name", alloc_name);
bson_free (alloc_name);
}
bson_init (&command);
BCON_APPEND (&command,
"createIndexes",
BCON_UTF8 (mongoc_collection_get_name (collection)),
"indexes",
"[",
BCON_DOCUMENT (&index),
"]");
r = mongoc_collection_write_command_with_opts (
collection, &command, NULL, NULL, error);
done:
bson_destroy (&index);
bson_destroy (&command);
return r;
}
bool
mongoc_collection_create_index_with_opts (mongoc_collection_t *collection,
const bson_t *keys,
const mongoc_index_opt_t *opt,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_create_index_opts_t parsed;
mongoc_cmd_parts_t parts;
const mongoc_index_opt_t *def_opt;
const mongoc_index_opt_geo_t *def_geo;
const char *name;
bson_t cmd = BSON_INITIALIZER;
bson_t ar;
bson_t doc;
bson_t storage_doc;
bson_t wt_doc;
const mongoc_index_opt_geo_t *geo_opt;
const mongoc_index_opt_storage_t *storage_opt;
const mongoc_index_opt_wt_t *wt_opt;
char *alloc_name = NULL;
bool ret = false;
bool reply_initialized = false;
bool has_collation = false;
mongoc_server_stream_t *server_stream = NULL;
mongoc_cluster_t *cluster;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (keys);
def_opt = mongoc_index_opt_get_default ();
opt = opt ? opt : def_opt;
mongoc_cmd_parts_init (
&parts, collection->client, collection->db, MONGOC_QUERY_NONE, &cmd);
parts.is_write_command = true;
if (!_mongoc_create_index_opts_parse (
collection->client, opts, &parsed, error)) {
GOTO (done);
}
if (!parsed.writeConcern) {
parsed.writeConcern = collection->write_concern;
parsed.write_concern_owned = false;
}
/*
* Generate the key name if it was not provided.
*/
name = (opt->name != def_opt->name) ? opt->name : NULL;
if (!name) {
alloc_name = mongoc_collection_keys_to_index_string (keys);
if (alloc_name) {
name = alloc_name;
} else {
bson_set_error (
error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Cannot generate index name from invalid `keys` argument");
GOTO (done);
}
}
/*
* Build our createIndexes command to send to the server.
*/
BSON_ASSERT (
BSON_APPEND_UTF8 (&cmd, "createIndexes", collection->collection));
bson_append_array_begin (&cmd, "indexes", 7, &ar);
bson_append_document_begin (&ar, "0", 1, &doc);
BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "key", keys));
BSON_ASSERT (BSON_APPEND_UTF8 (&doc, "name", name));
if (opt->background) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "background", true));
}
if (opt->unique) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "unique", true));
}
if (opt->drop_dups) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "dropDups", true));
}
if (opt->sparse) {
BSON_ASSERT (BSON_APPEND_BOOL (&doc, "sparse", true));
}
if (opt->expire_after_seconds != def_opt->expire_after_seconds) {
BSON_ASSERT (BSON_APPEND_INT32 (
&doc, "expireAfterSeconds", opt->expire_after_seconds));
}
if (opt->v != def_opt->v) {
BSON_ASSERT (BSON_APPEND_INT32 (&doc, "v", opt->v));
}
if (opt->weights && (opt->weights != def_opt->weights)) {
BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "weights", opt->weights));
}
if (opt->default_language != def_opt->default_language) {
BSON_ASSERT (
BSON_APPEND_UTF8 (&doc, "default_language", opt->default_language));
}
if (opt->language_override != def_opt->language_override) {
BSON_ASSERT (
BSON_APPEND_UTF8 (&doc, "language_override", opt->language_override));
}
if (opt->partial_filter_expression) {
BSON_ASSERT (BSON_APPEND_DOCUMENT (
&doc, "partialFilterExpression", opt->partial_filter_expression));
}
if (opt->collation) {
BSON_ASSERT (BSON_APPEND_DOCUMENT (&doc, "collation", opt->collation));
has_collation = true;
}
if (opt->geo_options) {
geo_opt = opt->geo_options;
def_geo = mongoc_index_opt_geo_get_default ();
if (geo_opt->twod_sphere_version != def_geo->twod_sphere_version) {
BSON_ASSERT (BSON_APPEND_INT32 (
&doc, "2dsphereIndexVersion", geo_opt->twod_sphere_version));
}
if (geo_opt->twod_bits_precision != def_geo->twod_bits_precision) {
BSON_ASSERT (
BSON_APPEND_INT32 (&doc, "bits", geo_opt->twod_bits_precision));
}
if (geo_opt->twod_location_min != def_geo->twod_location_min) {
BSON_ASSERT (
BSON_APPEND_DOUBLE (&doc, "min", geo_opt->twod_location_min));
}
if (geo_opt->twod_location_max != def_geo->twod_location_max) {
BSON_ASSERT (
BSON_APPEND_DOUBLE (&doc, "max", geo_opt->twod_location_max));
}
if (geo_opt->haystack_bucket_size != def_geo->haystack_bucket_size) {
BSON_ASSERT (BSON_APPEND_DOUBLE (
&doc, "bucketSize", geo_opt->haystack_bucket_size));
}
}
if (opt->storage_options) {
storage_opt = opt->storage_options;
switch (storage_opt->type) {
case MONGOC_INDEX_STORAGE_OPT_WIREDTIGER:
wt_opt = (mongoc_index_opt_wt_t *) storage_opt;
BSON_APPEND_DOCUMENT_BEGIN (&doc, "storageEngine", &storage_doc);
BSON_APPEND_DOCUMENT_BEGIN (&storage_doc, "wiredTiger", &wt_doc);
BSON_ASSERT (
BSON_APPEND_UTF8 (&wt_doc, "configString", wt_opt->config_str));
bson_append_document_end (&storage_doc, &wt_doc);
bson_append_document_end (&doc, &storage_doc);
break;
default:
break;
}
}
bson_append_document_end (&ar, &doc);
bson_append_array_end (&cmd, &ar);
server_stream = mongoc_cluster_stream_for_writes (
&collection->client->cluster, parsed.client_session, reply, error);
if (!server_stream) {
reply_initialized = true;
GOTO (done);
}
if (!mongoc_cmd_parts_set_write_concern (&parts,
parsed.writeConcern,
server_stream->sd->max_wire_version,
error)) {
GOTO (done);
}
if (has_collation &&
server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
GOTO (done);
}
parts.assembled.session = parsed.client_session;
if (!bson_concat (&parts.extra, &parsed.extra)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"'opts' is too large");
GOTO (done);
}
cluster = &collection->client->cluster;
if (mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
ret = mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, reply, error);
} else {
_mongoc_bson_init_if_set (reply);
}
reply_initialized = true;
if (ret) {
if (reply) {
ret = !_mongoc_parse_wc_err (reply, error);
}
}
done:
bson_destroy (&cmd);
bson_free (alloc_name);
_mongoc_create_index_opts_cleanup (&parsed);
mongoc_server_stream_cleanup (server_stream);
mongoc_cmd_parts_cleanup (&parts);
if (!reply_initialized && reply) {
bson_init (reply);
}
RETURN (ret);
}
bool
mongoc_collection_ensure_index (mongoc_collection_t *collection,
const bson_t *keys,
const mongoc_index_opt_t *opt,
bson_error_t *error)
{
BEGIN_IGNORE_DEPRECATIONS
return mongoc_collection_create_index (collection, keys, opt, error);
END_IGNORE_DEPRECATIONS
}
mongoc_cursor_t *
mongoc_collection_find_indexes (mongoc_collection_t *collection,
bson_error_t *error)
{
mongoc_cursor_t *cursor;
cursor = mongoc_collection_find_indexes_with_opts (collection, NULL);
(void) mongoc_cursor_error (cursor, error);
return cursor;
}
mongoc_cursor_t *
mongoc_collection_find_indexes_with_opts (mongoc_collection_t *collection,
const bson_t *opts)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
bson_t child;
bson_error_t error;
BSON_ASSERT_PARAM (collection);
bson_append_utf8 (&cmd,
"listIndexes",
-1,
collection->collection,
collection->collectionlen);
BSON_APPEND_DOCUMENT_BEGIN (&cmd, "cursor", &child);
bson_append_document_end (&cmd, &child);
/* No read preference. Index Enumeration Spec: "run listIndexes on the
* primary node in replicaSet mode". */
cursor = _mongoc_cursor_cmd_new (
collection->client, collection->ns, &cmd, opts, NULL, NULL, NULL);
if (!mongoc_cursor_error (cursor, &error)) {
_mongoc_cursor_prime (cursor);
}
if (mongoc_cursor_error (cursor, &error) &&
error.code == MONGOC_ERROR_COLLECTION_DOES_NOT_EXIST) {
/* collection does not exist. from spec: return no documents but no err:
* https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst#enumeration-getting-index-information
*/
_mongoc_cursor_set_empty (cursor);
}
bson_destroy (&cmd);
return cursor;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_insert_bulk --
*
* Bulk insert documents into a MongoDB collection.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: flags for the insert or 0.
* @documents: The documents to insert.
* @n_documents: The number of documents to insert.
* @write_concern: A write concern or NULL.
* @error: a location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* If the write concern does not dictate checking the result of the
* insert, then true may be returned even though the document was
* not actually inserted on the MongoDB server or cluster.
*
* Side effects:
* @collection->gle is setup, depending on write_concern->w value.
* @error may be set upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_insert_bulk (mongoc_collection_t *collection,
mongoc_insert_flags_t flags,
const bson_t **documents,
uint32_t n_documents,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
mongoc_write_command_t command;
mongoc_write_result_t result;
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
uint32_t i;
bool ret;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (documents);
if (!write_concern) {
write_concern = collection->write_concern;
}
if (!(flags & MONGOC_INSERT_NO_VALIDATE)) {
for (i = 0; i < n_documents; i++) {
if (!_mongoc_validate_new_document (
documents[i], _mongoc_default_insert_vflags, error)) {
RETURN (false);
}
}
}
bson_clear (&collection->gle);
_mongoc_write_result_init (&result);
write_flags.ordered = !(flags & MONGOC_INSERT_CONTINUE_ON_ERROR);
_mongoc_write_command_init_insert (
&command,
NULL,
NULL,
write_flags,
++collection->client->cluster.operation_id);
for (i = 0; i < n_documents; i++) {
_mongoc_write_command_insert_append (&command, documents[i]);
}
_mongoc_collection_write_command_execute (
&command, collection, write_concern, NULL, &result);
collection->gle = bson_new ();
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
write_concern,
/* no error domain override */
(mongoc_error_domain_t) 0,
collection->gle,
error);
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
return ret;
}
bool
mongoc_collection_insert (mongoc_collection_t *collection,
mongoc_insert_flags_t flags,
const bson_t *document,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
bson_t opts = BSON_INITIALIZER;
bson_t reply;
bool r;
bson_clear (&collection->gle);
if (flags & MONGOC_INSERT_NO_VALIDATE) {
bson_append_bool (&opts, "validate", 8, false);
}
if (write_concern) {
mongoc_write_concern_append ((mongoc_write_concern_t *) write_concern,
&opts);
}
r =
mongoc_collection_insert_one (collection, document, &opts, &reply, error);
collection->gle = bson_copy (&reply);
bson_destroy (&reply);
bson_destroy (&opts);
return r;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_insert_one --
*
* Insert a document into a MongoDB collection.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @document: The document to insert.
* @opts: Standard command options.
* @reply: Optional. Uninitialized doc to receive the update result.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* If the write concern does not dictate checking the result of the
* insert, then true may be returned even though the document was
* not actually inserted on the MongoDB server or cluster.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_insert_one (mongoc_collection_t *collection,
const bson_t *document,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_insert_one_opts_t insert_one_opts;
mongoc_write_command_t command;
mongoc_write_result_t result;
+ bson_t cmd_opts = BSON_INITIALIZER;
bool ret = false;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (document);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_insert_one_opts_parse (
collection->client, opts, &insert_one_opts, error)) {
GOTO (done);
}
+ if (!bson_empty (&insert_one_opts.extra)) {
+ bson_concat (&cmd_opts, &insert_one_opts.extra);
+ }
+
+ if (insert_one_opts.crud.comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (
+ &cmd_opts, "comment", 7, &insert_one_opts.crud.comment);
+ }
+
if (!_mongoc_validate_new_document (
document, insert_one_opts.crud.validate, error)) {
GOTO (done);
}
_mongoc_write_result_init (&result);
_mongoc_write_command_init_insert_idl (
&command,
document,
- &insert_one_opts.extra,
+ &cmd_opts,
++collection->client->cluster.operation_id);
command.flags.bypass_document_validation = insert_one_opts.bypass;
_mongoc_collection_write_command_execute_idl (
&command, collection, &insert_one_opts.crud, &result);
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
insert_one_opts.crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"insertedCount");
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
done:
_mongoc_insert_one_opts_cleanup (&insert_one_opts);
+ bson_destroy (&cmd_opts);
+
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_insert_many --
*
* Insert documents into a MongoDB collection. Replaces
* mongoc_collection_insert_bulk.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @documents: The documents to insert.
* @n_documents: Length of @documents array.
* @opts: Standard command options.
* @reply: Optional. Uninitialized doc to receive the update result.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* If the write concern does not dictate checking the result of the
* insert, then true may be returned even though the document was
* not actually inserted on the MongoDB server or cluster.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_insert_many (mongoc_collection_t *collection,
const bson_t **documents,
size_t n_documents,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_insert_many_opts_t insert_many_opts;
mongoc_write_command_t command;
mongoc_write_result_t result;
+ bson_t cmd_opts = BSON_INITIALIZER;
size_t i;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (documents);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_insert_many_opts_parse (
collection->client, opts, &insert_many_opts, error)) {
_mongoc_insert_many_opts_cleanup (&insert_many_opts);
return false;
}
+ if (insert_many_opts.crud.comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (
+ &cmd_opts, "comment", 7, &insert_many_opts.crud.comment);
+ }
+
+ if (!bson_empty (&insert_many_opts.extra)) {
+ bson_concat (&cmd_opts, &insert_many_opts.extra);
+ }
+
_mongoc_write_result_init (&result);
_mongoc_write_command_init_insert_idl (
- &command,
- NULL,
- &insert_many_opts.extra,
- ++collection->client->cluster.operation_id);
+ &command, NULL, &cmd_opts, ++collection->client->cluster.operation_id);
command.flags.ordered = insert_many_opts.ordered;
command.flags.bypass_document_validation = insert_many_opts.bypass;
for (i = 0; i < n_documents; i++) {
if (!_mongoc_validate_new_document (
documents[i], insert_many_opts.crud.validate, error)) {
ret = false;
GOTO (done);
}
_mongoc_write_command_insert_append (&command, documents[i]);
}
_mongoc_collection_write_command_execute_idl (
&command, collection, &insert_many_opts.crud, &result);
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
insert_many_opts.crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"insertedCount");
done:
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
_mongoc_insert_many_opts_cleanup (&insert_many_opts);
+ bson_destroy (&cmd_opts);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_update --
*
* Updates one or more documents matching @selector with @update.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: The flags for the update.
* @selector: A bson_t containing your selector.
* @update: A bson_t containing your update document.
* @write_concern: The write concern or NULL.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @collection->gle is setup, depending on write_concern->w value.
* @error is setup upon failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_update (mongoc_collection_t *collection,
mongoc_update_flags_t uflags,
const bson_t *selector,
const bson_t *update,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
mongoc_write_command_t command;
mongoc_write_result_t result;
bson_iter_t iter;
bool ret;
int flags = uflags;
bson_t opts;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (selector);
BSON_ASSERT_PARAM (update);
bson_clear (&collection->gle);
if (!write_concern) {
write_concern = collection->write_concern;
}
if (!((uint32_t) flags & MONGOC_UPDATE_NO_VALIDATE) &&
bson_iter_init (&iter, update) && bson_iter_next (&iter)) {
if (bson_iter_key (&iter)[0] == '$') {
/* update document, all keys must be $-operators */
if (!_mongoc_validate_update (
update, _mongoc_default_update_vflags, error)) {
return false;
}
} else {
if (!_mongoc_validate_replace (
update, _mongoc_default_replace_vflags, error)) {
return false;
}
}
}
bson_init (&opts);
BSON_APPEND_BOOL (&opts, "upsert", !!(flags & MONGOC_UPDATE_UPSERT));
BSON_APPEND_BOOL (&opts, "multi", !!(flags & MONGOC_UPDATE_MULTI_UPDATE));
_mongoc_write_result_init (&result);
_mongoc_write_command_init_update (
&command,
selector,
update,
+ NULL, /* cmd_opts */
&opts,
write_flags,
++collection->client->cluster.operation_id);
bson_destroy (&opts);
command.flags.has_multi_write = !!(flags & MONGOC_UPDATE_MULTI_UPDATE);
_mongoc_collection_write_command_execute (
&command, collection, write_concern, NULL, &result);
collection->gle = bson_new ();
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
write_concern,
/* no error domain override */
(mongoc_error_domain_t) 0,
collection->gle,
error);
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
RETURN (ret);
}
static bool
_mongoc_collection_update_or_replace (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *update,
mongoc_update_opts_t *update_opts,
bool multi,
bool bypass,
const bson_t *array_filters,
bson_t *extra,
bson_t *reply,
bson_error_t *error)
{
mongoc_write_command_t command;
mongoc_write_result_t result;
mongoc_server_stream_t *server_stream = NULL;
+ bson_t cmd_opts = BSON_INITIALIZER;
bool reply_initialized = false;
bool ret = false;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (selector);
BSON_ASSERT_PARAM (update);
+ if (!bson_empty (&update_opts->let)) {
+ bson_append_document (&cmd_opts, "let", 3, &update_opts->let);
+ }
+
+ if (update_opts->crud.comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (&cmd_opts, "comment", 7, &update_opts->crud.comment);
+ }
+
if (update_opts->upsert) {
bson_append_bool (extra, "upsert", 6, true);
}
if (!bson_empty (&update_opts->collation)) {
bson_append_document (extra, "collation", 9, &update_opts->collation);
}
if (update_opts->hint.value_type) {
bson_append_value (extra, "hint", 4, &update_opts->hint);
}
if (!bson_empty0 (array_filters)) {
bson_append_array (extra, "arrayFilters", 12, array_filters);
}
if (multi) {
bson_append_bool (extra, "multi", 5, true);
}
_mongoc_write_result_init (&result);
_mongoc_write_command_init_update_idl (
&command,
selector,
update,
+ &cmd_opts,
extra,
++collection->client->cluster.operation_id);
command.flags.has_multi_write = multi;
command.flags.bypass_document_validation = bypass;
if (!bson_empty (&update_opts->collation)) {
command.flags.has_collation = true;
}
if (update_opts->hint.value_type) {
command.flags.has_update_hint = true;
}
server_stream =
mongoc_cluster_stream_for_writes (&collection->client->cluster,
update_opts->crud.client_session,
reply,
error);
if (!server_stream) {
/* mongoc_cluster_stream_for_writes inits reply on error */
reply_initialized = true;
GOTO (done);
}
if (!bson_empty0 (array_filters)) {
if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support array filters");
GOTO (done);
}
if (!mongoc_write_concern_is_acknowledged (
update_opts->crud.writeConcern)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Cannot use array filters with unacknowledged writes");
GOTO (done);
}
}
if (_mongoc_client_session_in_txn (update_opts->crud.client_session) &&
update_opts->crud.writeConcern) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
GOTO (done);
}
if (!update_opts->crud.writeConcern &&
!_mongoc_client_session_in_txn (update_opts->crud.client_session)) {
update_opts->crud.writeConcern = collection->write_concern;
update_opts->crud.write_concern_owned = false;
}
_mongoc_write_command_execute_idl (&command,
collection->client,
server_stream,
collection->db,
collection->collection,
0 /* offset */,
&update_opts->crud,
&result);
_mongoc_bson_init_if_set (reply);
reply_initialized = true;
/* set fields described in CRUD spec for the UpdateResult */
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
update_opts->crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"modifiedCount",
"matchedCount",
"upsertedCount",
"upsertedId");
done:
_mongoc_write_result_destroy (&result);
mongoc_server_stream_cleanup (server_stream);
_mongoc_write_command_destroy (&command);
+ bson_destroy (&cmd_opts);
if (!reply_initialized) {
_mongoc_bson_init_if_set (reply);
}
RETURN (ret);
}
bool
mongoc_collection_update_one (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *update,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_update_one_opts_t update_one_opts;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (update);
if (!_mongoc_update_one_opts_parse (
collection->client, opts, &update_one_opts, error)) {
_mongoc_update_one_opts_cleanup (&update_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
if (!_mongoc_validate_update (
update, update_one_opts.update.crud.validate, error)) {
_mongoc_update_one_opts_cleanup (&update_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
ret = _mongoc_collection_update_or_replace (collection,
selector,
update,
&update_one_opts.update,
false /* multi */,
update_one_opts.update.bypass,
&update_one_opts.arrayFilters,
&update_one_opts.extra,
reply,
error);
_mongoc_update_one_opts_cleanup (&update_one_opts);
RETURN (ret);
}
bool
mongoc_collection_update_many (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *update,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_update_many_opts_t update_many_opts;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (update);
if (!_mongoc_update_many_opts_parse (
collection->client, opts, &update_many_opts, error)) {
_mongoc_update_many_opts_cleanup (&update_many_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
if (!_mongoc_validate_update (
update, update_many_opts.update.crud.validate, error)) {
_mongoc_update_many_opts_cleanup (&update_many_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
ret = _mongoc_collection_update_or_replace (collection,
selector,
update,
&update_many_opts.update,
true /* multi */,
update_many_opts.update.bypass,
&update_many_opts.arrayFilters,
&update_many_opts.extra,
reply,
error);
_mongoc_update_many_opts_cleanup (&update_many_opts);
RETURN (ret);
}
bool
mongoc_collection_replace_one (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *replacement,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_replace_one_opts_t replace_one_opts;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (replacement);
if (!_mongoc_replace_one_opts_parse (
collection->client, opts, &replace_one_opts, error)) {
_mongoc_replace_one_opts_cleanup (&replace_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
if (!_mongoc_validate_replace (
replacement, replace_one_opts.update.crud.validate, error)) {
_mongoc_replace_one_opts_cleanup (&replace_one_opts);
_mongoc_bson_init_if_set (reply);
return false;
}
ret = _mongoc_collection_update_or_replace (collection,
selector,
replacement,
&replace_one_opts.update,
false /* multi */,
replace_one_opts.update.bypass,
NULL,
&replace_one_opts.extra,
reply,
error);
_mongoc_replace_one_opts_cleanup (&replace_one_opts);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_save --
*
* Save @document to @collection.
*
* If the document has an _id field, it will be updated. Otherwise,
* the document will be inserted into the collection.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @error is set upon failure if non-NULL.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_save (mongoc_collection_t *collection,
const bson_t *document,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
bson_iter_t iter;
bool ret;
bson_t selector;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (document);
BEGIN_IGNORE_DEPRECATIONS
if (!bson_iter_init_find (&iter, document, "_id")) {
return mongoc_collection_insert (
collection, MONGOC_INSERT_NONE, document, write_concern, error);
}
bson_init (&selector);
if (!bson_append_iter (&selector, NULL, 0, &iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Failed to append bson to create update.");
bson_destroy (&selector);
return false;
}
/* this document will be inserted, validate same as for inserts */
if (!_mongoc_validate_new_document (
document, _mongoc_default_insert_vflags, error)) {
return false;
}
ret = mongoc_collection_update (collection,
MONGOC_UPDATE_UPSERT |
MONGOC_UPDATE_NO_VALIDATE,
&selector,
document,
write_concern,
error);
END_IGNORE_DEPRECATIONS
bson_destroy (&selector);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_remove --
*
* Delete one or more items from a collection. If you want to
* limit to a single delete, provided MONGOC_REMOVE_SINGLE_REMOVE
* for @flags.
*
* Superseded by mongoc_collection_delete_one/many.
*
* Parameters:
* @collection: A mongoc_collection_t.
* @flags: the delete flags or 0.
* @selector: A selector of documents to delete.
* @write_concern: A write concern or NULL. If NULL, the default
* write concern for the collection will be used.
* @error: A location for an error or NULL.
*
* Returns:
* true if successful; otherwise false and error is set.
*
* If the write concern does not dictate checking the result, this
* function may return true even if it failed.
*
* Side effects:
* @collection->gle is setup, depending on write_concern->w value.
* @error is setup upon failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_remove (mongoc_collection_t *collection,
mongoc_remove_flags_t flags,
const bson_t *selector,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
mongoc_write_command_t command;
mongoc_write_result_t result;
bson_t opts;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (selector);
bson_clear (&collection->gle);
if (!write_concern) {
write_concern = collection->write_concern;
}
bson_init (&opts);
BSON_APPEND_INT32 (
&opts, "limit", flags & MONGOC_REMOVE_SINGLE_REMOVE ? 1 : 0);
_mongoc_write_result_init (&result);
++collection->client->cluster.operation_id;
_mongoc_write_command_init_delete (&command,
selector,
NULL,
&opts,
write_flags,
collection->client->cluster.operation_id);
bson_destroy (&opts);
command.flags.has_multi_write = !(flags & MONGOC_REMOVE_SINGLE_REMOVE);
_mongoc_collection_write_command_execute (
&command, collection, write_concern, NULL, &result);
collection->gle = bson_new ();
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
write_concern,
0 /* no error domain override */,
collection->gle,
error);
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
RETURN (ret);
}
bool
mongoc_collection_delete (mongoc_collection_t *collection,
mongoc_delete_flags_t flags,
const bson_t *selector,
const mongoc_write_concern_t *write_concern,
bson_error_t *error)
{
return mongoc_collection_remove (collection,
(mongoc_remove_flags_t) flags,
selector,
write_concern,
error);
}
static bool
_mongoc_delete_one_or_many (mongoc_collection_t *collection,
bool multi,
const bson_t *selector,
mongoc_delete_opts_t *delete_opts,
- const bson_t *cmd_opts,
- bson_t *opts,
+ const bson_t *extra,
bson_t *reply,
bson_error_t *error)
{
mongoc_write_command_t command;
mongoc_write_result_t result;
+ bson_t cmd_opts = BSON_INITIALIZER;
+ bson_t opts = BSON_INITIALIZER;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (selector);
BSON_ASSERT (bson_empty0 (reply));
+ /* TODO: This function has historically used `extra` for top-level, command
+ * options. That is inconsistent with the update function, which uses `extra`
+ * for statement-level options. We will keep the original behavior for BC
+ * reasons, but this should ultimately be addressed by CDRIVER-4306. */
+ if (!bson_empty0 (extra)) {
+ bson_concat (&cmd_opts, extra);
+ }
+
+ if (!bson_empty (&delete_opts->let)) {
+ bson_append_document (&cmd_opts, "let", 3, &delete_opts->let);
+ }
+
+ if (delete_opts->crud.comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (&cmd_opts, "comment", 7, &delete_opts->crud.comment);
+ }
+
_mongoc_write_result_init (&result);
- bson_append_int32 (opts, "limit", 5, multi ? 0 : 1);
+ bson_append_int32 (&opts, "limit", 5, multi ? 0 : 1);
if (!bson_empty (&delete_opts->collation)) {
- bson_append_document (opts, "collation", 9, &delete_opts->collation);
+ bson_append_document (&opts, "collation", 9, &delete_opts->collation);
}
if (delete_opts->hint.value_type) {
- bson_append_value (opts, "hint", 4, &delete_opts->hint);
+ bson_append_value (&opts, "hint", 4, &delete_opts->hint);
}
_mongoc_write_command_init_delete_idl (
&command,
selector,
- cmd_opts,
- opts,
+ &cmd_opts,
+ &opts,
++collection->client->cluster.operation_id);
command.flags.has_multi_write = multi;
if (!bson_empty (&delete_opts->collation)) {
command.flags.has_collation = true;
}
if (delete_opts->hint.value_type) {
command.flags.has_delete_hint = true;
}
_mongoc_collection_write_command_execute_idl (
&command, collection, &delete_opts->crud, &result);
/* set field described in CRUD spec for the DeleteResult */
ret = MONGOC_WRITE_RESULT_COMPLETE (&result,
collection->client->error_api_version,
delete_opts->crud.writeConcern,
/* no error domain override */
(mongoc_error_domain_t) 0,
reply,
error,
"deletedCount");
_mongoc_write_result_destroy (&result);
_mongoc_write_command_destroy (&command);
+ bson_destroy (&cmd_opts);
+ bson_destroy (&opts);
RETURN (ret);
}
bool
mongoc_collection_delete_one (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_delete_one_opts_t delete_one_opts;
- bson_t limit = BSON_INITIALIZER;
bool ret = false;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (selector);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_delete_one_opts_parse (
collection->client, opts, &delete_one_opts, error)) {
GOTO (done);
}
ret = _mongoc_delete_one_or_many (collection,
false /* multi */,
selector,
&delete_one_opts.delete,
&delete_one_opts.extra,
- &limit,
reply,
error);
done:
_mongoc_delete_one_opts_cleanup (&delete_one_opts);
- bson_destroy (&limit);
RETURN (ret);
}
bool
mongoc_collection_delete_many (mongoc_collection_t *collection,
const bson_t *selector,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_delete_many_opts_t delete_many_opts;
- bson_t limit = BSON_INITIALIZER;
bool ret = false;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (selector);
_mongoc_bson_init_if_set (reply);
if (!_mongoc_delete_many_opts_parse (
collection->client, opts, &delete_many_opts, error)) {
GOTO (done);
}
ret = _mongoc_delete_one_or_many (collection,
true /* multi */,
selector,
&delete_many_opts.delete,
&delete_many_opts.extra,
- &limit,
reply,
error);
done:
_mongoc_delete_many_opts_cleanup (&delete_many_opts);
- bson_destroy (&limit);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_read_prefs --
*
* Fetch the default read preferences for the collection.
*
* Returns:
* A mongoc_read_prefs_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_prefs_t *
mongoc_collection_get_read_prefs (const mongoc_collection_t *collection)
{
BSON_ASSERT_PARAM (collection);
return collection->read_prefs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_set_read_prefs --
*
* Sets the default read preferences for the collection instance.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_set_read_prefs (mongoc_collection_t *collection,
const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT_PARAM (collection);
if (collection->read_prefs) {
mongoc_read_prefs_destroy (collection->read_prefs);
collection->read_prefs = NULL;
}
if (read_prefs) {
collection->read_prefs = mongoc_read_prefs_copy (read_prefs);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_read_concern --
*
* Fetches the default read concern for the collection instance.
*
* Returns:
* A mongoc_read_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_concern_t *
mongoc_collection_get_read_concern (const mongoc_collection_t *collection)
{
BSON_ASSERT_PARAM (collection);
return collection->read_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_set_read_concern --
*
* Sets the default read concern for the collection instance.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_set_read_concern (mongoc_collection_t *collection,
const mongoc_read_concern_t *read_concern)
{
BSON_ASSERT_PARAM (collection);
if (collection->read_concern) {
mongoc_read_concern_destroy (collection->read_concern);
collection->read_concern = NULL;
}
if (read_concern) {
collection->read_concern = mongoc_read_concern_copy (read_concern);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_write_concern --
*
* Fetches the default write concern for the collection instance.
*
* Returns:
* A mongoc_write_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_write_concern_t *
mongoc_collection_get_write_concern (const mongoc_collection_t *collection)
{
BSON_ASSERT_PARAM (collection);
return collection->write_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_set_write_concern --
*
* Sets the default write concern for the collection instance.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_collection_set_write_concern (
mongoc_collection_t *collection, const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT_PARAM (collection);
if (collection->write_concern) {
mongoc_write_concern_destroy (collection->write_concern);
collection->write_concern = NULL;
}
if (write_concern) {
collection->write_concern = mongoc_write_concern_copy (write_concern);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_name --
*
* Returns the name of the collection, excluding the database name.
*
* Returns:
* A string which should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const char *
mongoc_collection_get_name (mongoc_collection_t *collection)
{
BSON_ASSERT_PARAM (collection);
return collection->collection;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_get_last_error --
*
* Returns a bulk result.
*
* Returns:
* NULL or a bson_t that should not be modified or freed. This value
* is not guaranteed to be persistent between calls into the
* mongoc_collection_t instance, and therefore must be copied if
* you would like to keep it around.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const bson_t *
mongoc_collection_get_last_error (
const mongoc_collection_t *collection) /* IN */
{
BSON_ASSERT_PARAM (collection);
return collection->gle;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_validate --
*
* Helper to call the validate command on the MongoDB server to
* validate the collection.
*
* Options may be additional options, or NULL.
* Currently supported options are:
*
* "full": Boolean
*
* If full is true, then perform a more resource intensive
* validation.
*
* The result is stored in reply.
*
* Returns:
* true if successful; otherwise false and @error is set.
*
* Side effects:
* @reply is set if successful.
* @error may be set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_validate (mongoc_collection_t *collection, /* IN */
const bson_t *options, /* IN */
bson_t *reply, /* OUT */
bson_error_t *error) /* IN */
{
bson_iter_t iter;
bson_t cmd = BSON_INITIALIZER;
bool ret = false;
bool reply_initialized = false;
BSON_ASSERT_PARAM (collection);
if (options && bson_iter_init_find (&iter, options, "full") &&
!BSON_ITER_HOLDS_BOOL (&iter)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"'full' must be a boolean value.");
goto cleanup;
}
bson_append_utf8 (
&cmd, "validate", 8, collection->collection, collection->collectionlen);
if (options) {
bson_concat (&cmd, options);
}
ret =
mongoc_collection_command_simple (collection, &cmd, NULL, reply, error);
reply_initialized = true;
cleanup:
bson_destroy (&cmd);
if (reply && !reply_initialized) {
bson_init (reply);
}
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_rename --
*
* Rename the collection to @new_name.
*
* If @new_db is NULL, the same db will be used.
*
* If @drop_target_before_rename is true, then a collection named
* @new_name will be dropped before renaming @collection to
* @new_name.
*
* Returns:
* true on success; false on failure and @error is set.
*
* Side effects:
* @error is set on failure.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_rename (mongoc_collection_t *collection,
const char *new_db,
const char *new_name,
bool drop_target_before_rename,
bson_error_t *error)
{
return mongoc_collection_rename_with_opts (
collection, new_db, new_name, drop_target_before_rename, NULL, error);
}
bool
mongoc_collection_rename_with_opts (mongoc_collection_t *collection,
const char *new_db,
const char *new_name,
bool drop_target_before_rename,
const bson_t *opts,
bson_error_t *error)
{
bson_t cmd = BSON_INITIALIZER;
char *newns;
bool ret;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (new_name);
if (strchr (new_name, '$')) {
bson_set_error (error,
MONGOC_ERROR_NAMESPACE,
MONGOC_ERROR_NAMESPACE_INVALID,
"\"%s\" is an invalid collection name.",
new_name);
return false;
}
newns =
bson_strdup_printf ("%s.%s", new_db ? new_db : collection->db, new_name);
BSON_APPEND_UTF8 (&cmd, "renameCollection", collection->ns);
BSON_APPEND_UTF8 (&cmd, "to", newns);
if (drop_target_before_rename) {
BSON_APPEND_BOOL (&cmd, "dropTarget", true);
}
ret = _mongoc_client_command_with_opts (collection->client,
"admin",
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
collection->read_prefs,
collection->read_concern,
collection->write_concern,
NULL, /* reply */
error);
if (ret) {
if (new_db) {
bson_free (collection->db);
collection->db = bson_strdup (new_db);
}
bson_free (collection->collection);
collection->collection = bson_strdup (new_name);
collection->collectionlen = (int) strlen (collection->collection);
bson_free (collection->ns);
collection->ns = bson_strdup_printf ("%s.%s", collection->db, new_name);
collection->nslen = (int) strlen (collection->ns);
}
bson_free (newns);
bson_destroy (&cmd);
return ret;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_stats --
*
* Fetches statistics about the collection.
*
* The result is stored in @stats, which should NOT be an initialized
* bson_t or a leak will occur.
*
* @stats, @options, and @error are optional.
*
* Returns:
* true on success and @stats is set.
* false on failure and @error is set.
*
* Side effects:
* @stats and @error.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_stats (mongoc_collection_t *collection,
const bson_t *options,
bson_t *stats,
bson_error_t *error)
{
bson_iter_t iter;
bson_t cmd = BSON_INITIALIZER;
bool ret;
BSON_ASSERT_PARAM (collection);
if (options && bson_iter_init_find (&iter, options, "scale") &&
!BSON_ITER_HOLDS_INT32 (&iter)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"'scale' must be an int32 value.");
return false;
}
BSON_APPEND_UTF8 (&cmd, "collStats", collection->collection);
if (options) {
bson_concat (&cmd, options);
}
/* Server Selection Spec: "may-use-secondary" commands SHOULD take a read
* preference argument and otherwise MUST use the default read preference
* from client, database or collection configuration. */
ret = mongoc_collection_command_simple (
collection, &cmd, collection->read_prefs, stats, error);
bson_destroy (&cmd);
return ret;
}
mongoc_bulk_operation_t *
mongoc_collection_create_bulk_operation (
mongoc_collection_t *collection,
bool ordered,
const mongoc_write_concern_t *write_concern)
{
bson_t opts = BSON_INITIALIZER;
mongoc_bulk_operation_t *bulk;
bool wc_ok = true;
bson_append_bool (&opts, "ordered", 7, ordered);
if (write_concern) {
wc_ok = mongoc_write_concern_append (
(mongoc_write_concern_t *) write_concern, &opts);
}
bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
bson_destroy (&opts);
if (!wc_ok) {
bson_set_error (&bulk->result.error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid writeConcern");
}
return bulk;
}
mongoc_bulk_operation_t *
mongoc_collection_create_bulk_operation_with_opts (
mongoc_collection_t *collection, const bson_t *opts)
{
mongoc_bulk_opts_t bulk_opts;
mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT;
mongoc_write_concern_t *wc = NULL;
mongoc_bulk_operation_t *bulk;
bson_error_t err = {0};
BSON_ASSERT_PARAM (collection);
(void) _mongoc_bulk_opts_parse (collection->client, opts, &bulk_opts, &err);
if (!_mongoc_client_session_in_txn (bulk_opts.client_session)) {
wc = COALESCE (bulk_opts.writeConcern, collection->write_concern);
}
write_flags.ordered = bulk_opts.ordered;
bulk = _mongoc_bulk_operation_new (collection->client,
collection->db,
collection->collection,
write_flags,
wc);
+ if (!bson_empty (&bulk_opts.let)) {
+ mongoc_bulk_operation_set_let (bulk, &bulk_opts.let);
+ }
+
+ if (bulk_opts.comment.value_type != BSON_TYPE_EOD) {
+ mongoc_bulk_operation_set_comment (bulk, &bulk_opts.comment);
+ }
+
bulk->session = bulk_opts.client_session;
if (err.domain) {
/* _mongoc_bulk_opts_parse failed, above */
memcpy (&bulk->result.error, &err, sizeof (bson_error_t));
} else if (_mongoc_client_session_in_txn (bulk_opts.client_session) &&
!mongoc_write_concern_is_default (bulk_opts.writeConcern)) {
bson_set_error (&bulk->result.error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
}
_mongoc_bulk_opts_cleanup (&bulk_opts);
return bulk;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find_and_modify_with_opts --
*
* Find a document in @collection matching @query, applying @opts.
*
* If @reply is not NULL, then the result document will be placed
* in reply and should be released with bson_destroy().
*
* See http://docs.mongodb.org/manual/reference/command/findAndModify/
* for more information.
*
* Returns:
* true on success; false on failure.
*
* Side effects:
* reply is initialized.
* error is set if false is returned.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_find_and_modify_with_opts (
mongoc_collection_t *collection,
const bson_t *query,
const mongoc_find_and_modify_opts_t *opts,
bson_t *reply,
bson_error_t *error)
{
mongoc_cluster_t *cluster;
mongoc_cmd_parts_t parts;
bool is_retryable;
bson_iter_t iter;
bson_iter_t inner;
const char *name;
bson_t ss_reply;
bson_t reply_local;
bson_t *reply_ptr;
bool ret = false;
bson_t command = BSON_INITIALIZER;
mongoc_server_stream_t *server_stream = NULL;
mongoc_server_stream_t *retry_server_stream = NULL;
mongoc_find_and_modify_appended_opts_t appended_opts;
mongoc_write_concern_t *write_concern = NULL;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (query);
BSON_ASSERT_PARAM (opts);
reply_ptr = reply ? reply : &reply_local;
cluster = &collection->client->cluster;
mongoc_cmd_parts_init (
&parts, collection->client, collection->db, MONGOC_QUERY_NONE, &command);
parts.is_read_command = true;
parts.is_write_command = true;
bson_init (reply_ptr);
if (!_mongoc_find_and_modify_appended_opts_parse (
cluster->client, &opts->extra, &appended_opts, error)) {
GOTO (done);
}
server_stream = mongoc_cluster_stream_for_writes (
cluster, appended_opts.client_session, &ss_reply, error);
if (!server_stream) {
bson_concat (reply_ptr, &ss_reply);
bson_destroy (&ss_reply);
GOTO (done);
}
name = mongoc_collection_get_name (collection);
BSON_APPEND_UTF8 (&command, "findAndModify", name);
BSON_APPEND_DOCUMENT (&command, "query", query);
if (opts->sort) {
BSON_APPEND_DOCUMENT (&command, "sort", opts->sort);
}
if (opts->update) {
if (_mongoc_document_is_pipeline (opts->update)) {
BSON_APPEND_ARRAY (&command, "update", opts->update);
} else {
BSON_APPEND_DOCUMENT (&command, "update", opts->update);
}
}
if (opts->fields) {
BSON_APPEND_DOCUMENT (&command, "fields", opts->fields);
}
if (opts->flags & MONGOC_FIND_AND_MODIFY_REMOVE) {
BSON_APPEND_BOOL (&command, "remove", true);
}
if (opts->flags & MONGOC_FIND_AND_MODIFY_UPSERT) {
BSON_APPEND_BOOL (&command, "upsert", true);
}
if (opts->flags & MONGOC_FIND_AND_MODIFY_RETURN_NEW) {
BSON_APPEND_BOOL (&command, "new", true);
}
if (opts->bypass_document_validation) {
BSON_APPEND_BOOL (&command,
"bypassDocumentValidation",
opts->bypass_document_validation);
}
if (opts->max_time_ms > 0) {
BSON_APPEND_INT32 (&command, "maxTimeMS", opts->max_time_ms);
}
/* Some options set via mongoc_find_and_modify_opts_append were parsed. Set
* them on the command parts. */
if (appended_opts.client_session) {
mongoc_cmd_parts_set_session (&parts, appended_opts.client_session);
}
if (appended_opts.writeConcern) {
if (_mongoc_client_session_in_txn (parts.assembled.session)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set write concern after starting transaction");
GOTO (done);
}
write_concern = appended_opts.writeConcern;
}
/* inherit write concern from collection if not in transaction */
else if (server_stream->sd->max_wire_version >=
WIRE_VERSION_FAM_WRITE_CONCERN &&
!_mongoc_client_session_in_txn (parts.assembled.session)) {
if (!mongoc_write_concern_is_valid (collection->write_concern)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The write concern is invalid.");
GOTO (done);
}
write_concern = collection->write_concern;
}
if (appended_opts.hint.value_type) {
int max_wire_version =
mongoc_write_concern_is_acknowledged (write_concern)
? WIRE_VERSION_FIND_AND_MODIFY_HINT_SERVER_SIDE_ERROR
: WIRE_VERSION_FIND_AND_MODIFY_HINT;
if (server_stream->sd->max_wire_version < max_wire_version) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"selected server does not support hint on findAndModify");
GOTO (done);
}
bson_append_value (&parts.extra, "hint", 4, &appended_opts.hint);
}
+ if (!bson_empty (&appended_opts.let)) {
+ bson_append_document (&parts.extra, "let", 3, &appended_opts.let);
+ }
+
+ if (appended_opts.comment.value_type != BSON_TYPE_EOD) {
+ bson_append_value (&parts.extra, "comment", 7, &appended_opts.comment);
+ }
+
/* Append any remaining unparsed options set via
* mongoc_find_and_modify_opts_append to the command part. */
if (bson_iter_init (&iter, &appended_opts.extra)) {
bool ok = mongoc_cmd_parts_append_opts (
&parts, &iter, server_stream->sd->max_wire_version, error);
if (!ok) {
GOTO (done);
}
}
/* An empty write concern amounts to a no-op, so there's no need to guard
* against it. */
if (!mongoc_cmd_parts_set_write_concern (
&parts, write_concern, server_stream->sd->max_wire_version, error)) {
GOTO (done);
}
parts.assembled.operation_id = ++cluster->operation_id;
if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
GOTO (done);
}
is_retryable = parts.is_retryable_write;
/* increment the transaction number for the first attempt of each retryable
* write command */
if (is_retryable) {
bson_iter_t txn_number_iter;
BSON_ASSERT (bson_iter_init_find (
&txn_number_iter, parts.assembled.command, "txnNumber"));
bson_iter_overwrite_int64 (
&txn_number_iter,
++parts.assembled.session->server_session->txn_number);
}
retry:
bson_destroy (reply_ptr);
ret = mongoc_cluster_run_command_monitored (
cluster, &parts.assembled, reply_ptr, error);
if (parts.is_retryable_write) {
_mongoc_write_error_handle_labels (
ret, error, reply_ptr, server_stream->sd->max_wire_version);
}
if (is_retryable) {
_mongoc_write_error_update_if_unsupported_storage_engine (
ret, error, reply_ptr);
}
/* If a retryable error is encountered and the write is retryable, select
* a new writable stream and retry. If server selection fails or the selected
* server does not support retryable writes, fall through and allow the
* original error to be reported. */
if (is_retryable &&
_mongoc_write_error_get_type (reply_ptr) == MONGOC_WRITE_ERR_RETRY) {
bson_error_t ignored_error;
/* each write command may be retried at most once */
is_retryable = false;
retry_server_stream = mongoc_cluster_stream_for_writes (
cluster, parts.assembled.session, NULL /* reply */, &ignored_error);
if (retry_server_stream && retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_WRITES) {
parts.assembled.server_stream = retry_server_stream;
GOTO (retry);
}
}
if (bson_iter_init_find (&iter, reply_ptr, "writeConcernError") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
const char *errmsg = NULL;
int32_t code = 0;
BSON_ASSERT (bson_iter_recurse (&iter, &inner));
while (bson_iter_next (&inner)) {
if (BSON_ITER_IS_KEY (&inner, "code")) {
code = (uint32_t) bson_iter_as_int64 (&inner);
} else if (BSON_ITER_IS_KEY (&inner, "errmsg")) {
errmsg = bson_iter_utf8 (&inner, NULL);
}
}
bson_set_error (error,
MONGOC_ERROR_WRITE_CONCERN,
code,
"Write Concern error: %s",
errmsg);
ret = false;
}
done:
mongoc_server_stream_cleanup (server_stream);
mongoc_server_stream_cleanup (retry_server_stream);
if (ret && error) {
/* if a retry succeeded, clear the initial error */
memset (error, 0, sizeof (bson_error_t));
}
mongoc_cmd_parts_cleanup (&parts);
bson_destroy (&command);
if (&reply_local == reply_ptr) {
bson_destroy (&reply_local);
}
_mongoc_find_and_modify_appended_opts_cleanup (&appended_opts);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_collection_find_and_modify --
*
* Find a document in @collection matching @query and update it with
* the update document @update.
*
* If @reply is not NULL, then the result document will be placed
* in reply and should be released with bson_destroy().
*
* If @remove is true, then the matching documents will be removed.
*
* If @fields is not NULL, it will be used to select the desired
* resulting fields.
*
* If @_new is true, then the new version of the document is returned
* instead of the old document.
*
* See http://docs.mongodb.org/manual/reference/command/findAndModify/
* for more information.
*
* Returns:
* true on success; false on failure.
*
* Side effects:
* reply is initialized.
* error is set if false is returned.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_collection_find_and_modify (mongoc_collection_t *collection,
const bson_t *query,
const bson_t *sort,
const bson_t *update,
const bson_t *fields,
bool _remove,
bool upsert,
bool _new,
bson_t *reply,
bson_error_t *error)
{
mongoc_find_and_modify_opts_t *opts;
int flags = 0;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (collection);
BSON_ASSERT_PARAM (query);
BSON_ASSERT (update || _remove);
if (_remove) {
flags |= MONGOC_FIND_AND_MODIFY_REMOVE;
}
if (upsert) {
flags |= MONGOC_FIND_AND_MODIFY_UPSERT;
}
if (_new) {
flags |= MONGOC_FIND_AND_MODIFY_RETURN_NEW;
}
opts = mongoc_find_and_modify_opts_new ();
mongoc_find_and_modify_opts_set_sort (opts, sort);
mongoc_find_and_modify_opts_set_update (opts, update);
mongoc_find_and_modify_opts_set_fields (opts, fields);
mongoc_find_and_modify_opts_set_flags (opts, flags);
ret = mongoc_collection_find_and_modify_with_opts (
collection, query, opts, reply, error);
mongoc_find_and_modify_opts_destroy (opts);
return ret;
}
mongoc_change_stream_t *
mongoc_collection_watch (const mongoc_collection_t *coll,
const bson_t *pipeline,
const bson_t *opts)
{
return _mongoc_change_stream_new_from_collection (coll, pipeline, opts);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
similarity index 74%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
index 6d51eaac..ac3fb942 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h
@@ -1,116 +1,145 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_CRYPT_PRIVATE_H
#define MONGOC_CRYPT_PRIVATE_H
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#include "mongoc.h"
/* For interacting with libmongocrypt */
typedef struct __mongoc_crypt_t _mongoc_crypt_t;
/*
Creates a new handle into libmongocrypt.
- schema_map may be NULL.
- may return NULL and set error.
*/
_mongoc_crypt_t *
_mongoc_crypt_new (const bson_t *kms_providers,
const bson_t *schema_map,
+ const bson_t *encrypted_fields_map,
const bson_t *tls_opts,
+ const char *crypt_shared_lib_path,
+ bool crypt_shared_lib_required,
+ bool bypass_auto_encryption,
+ bool bypass_query_analysis,
bson_error_t *error);
void
_mongoc_crypt_destroy (_mongoc_crypt_t *crypt);
/*
Perform auto encryption.
- cmd_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_auto_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
mongoc_client_t *mongocryptd_client,
mongoc_client_t *collinfo_client,
const char *db_name,
const bson_t *cmd_in,
bson_t *cmd_out,
bson_error_t *error);
/*
Perform auto decryption.
- doc_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_auto_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
const bson_t *doc_in,
bson_t *doc_out,
bson_error_t *error);
/*
Perform explicit encryption.
- exactly one of keyid or keyaltname must be set, the other NULL, or an error is
returned.
- value_out is always initialized.
+- query_type may be NULL.
+- contention_factor may be NULL.
- may return false and set error.
*/
bool
_mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
const char *algorithm,
const bson_value_t *keyid,
char *keyaltname,
+ const char *query_type,
+ const int64_t *contention_factor,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error);
/*
Perform explicit decryption.
- value_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_explicit_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *key_vault_coll,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error);
/*
Create a data key document (does not insert into key vault).
- keyaltnames may be NULL.
- doc_out is always initialized.
- may return false and set error.
*/
bool
_mongoc_crypt_create_datakey (_mongoc_crypt_t *crypt,
const char *kms_provider,
const bson_t *masterkey,
char **keyaltnames,
uint32_t keyaltnames_count,
+ const uint8_t *keymaterial,
+ uint32_t keymaterial_len,
bson_t *doc_out,
bson_error_t *error);
+/*
+Rewrap datakeys in keyvault_coll matching the given filter with a new KMS
+provider (does not bulk-update into key vault).
+- filter may be NULL (equivalent to an empty document).
+- kms_provider may be NULL.
+- masterkey may be NULL if kms_provider is NULL.
+- doc_out is always initialized.
+- may return false and set error.
+*/
+bool
+_mongoc_crypt_rewrap_many_datakey (_mongoc_crypt_t *crypt,
+ mongoc_collection_t *keyvault_coll,
+ const bson_t *filter,
+ const char *provider,
+ const bson_t *master_key,
+ bson_t *doc_out,
+ bson_error_t *error);
+
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
#endif /* MONGOC_CRYPT_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
similarity index 84%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
index 610b1b0d..86ffde92 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c
@@ -1,1319 +1,1493 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define MONGOC_LOG_DOMAIN "client-side-encryption"
#include "mongoc-crypt-private.h"
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
#include <mongocrypt/mongocrypt.h>
#include "mongoc-client-private.h"
#include "mongoc-collection-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-ssl-private.h"
#include "mongoc-util-private.h"
struct __mongoc_crypt_t {
mongocrypt_t *handle;
mongoc_ssl_opt_t kmip_tls_opt;
mongoc_ssl_opt_t aws_tls_opt;
mongoc_ssl_opt_t azure_tls_opt;
mongoc_ssl_opt_t gcp_tls_opt;
};
static void
_log_callback (mongocrypt_log_level_t mongocrypt_log_level,
const char *message,
uint32_t message_len,
void *ctx)
{
mongoc_log_level_t log_level = MONGOC_LOG_LEVEL_ERROR;
switch (mongocrypt_log_level) {
case MONGOCRYPT_LOG_LEVEL_FATAL:
log_level = MONGOC_LOG_LEVEL_CRITICAL;
break;
case MONGOCRYPT_LOG_LEVEL_ERROR:
log_level = MONGOC_LOG_LEVEL_ERROR;
break;
case MONGOCRYPT_LOG_LEVEL_WARNING:
log_level = MONGOC_LOG_LEVEL_WARNING;
break;
case MONGOCRYPT_LOG_LEVEL_INFO:
log_level = MONGOC_LOG_LEVEL_INFO;
break;
case MONGOCRYPT_LOG_LEVEL_TRACE:
log_level = MONGOC_LOG_LEVEL_TRACE;
break;
default:
log_level = MONGOC_LOG_LEVEL_CRITICAL;
break;
}
mongoc_log (log_level, MONGOC_LOG_DOMAIN, "%s", message);
}
static void
_prefix_mongocryptd_error (bson_error_t *error)
{
char buf[sizeof (error->message)];
bson_snprintf (buf, sizeof (buf), "mongocryptd error: %s:", error->message);
memcpy (error->message, buf, sizeof (buf));
}
static void
_prefix_keyvault_error (bson_error_t *error)
{
char buf[sizeof (error->message)];
bson_snprintf (buf, sizeof (buf), "key vault error: %s:", error->message);
memcpy (error->message, buf, sizeof (buf));
}
static void
_status_to_error (mongocrypt_status_t *status, bson_error_t *error)
{
bson_set_error (error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
mongocrypt_status_code (status),
"%s",
mongocrypt_status_message (status, NULL));
}
/* Checks for an error on mongocrypt context.
* If error_expected, then we expect mongocrypt_ctx_status to report a failure
* status (due to a previous failed function call). If it did not, return a
* generic error.
* Returns true if ok, and does not modify @error.
* Returns false if error, and sets @error.
*/
bool
_ctx_check_error (mongocrypt_ctx_t *ctx,
bson_error_t *error,
bool error_expected)
{
mongocrypt_status_t *status;
status = mongocrypt_status_new ();
if (!mongocrypt_ctx_status (ctx, status)) {
_status_to_error (status, error);
mongocrypt_status_destroy (status);
return false;
} else if (error_expected) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"generic error from libmongocrypt operation");
mongocrypt_status_destroy (status);
return false;
}
mongocrypt_status_destroy (status);
return true;
}
bool
_kms_ctx_check_error (mongocrypt_kms_ctx_t *kms_ctx,
bson_error_t *error,
bool error_expected)
{
mongocrypt_status_t *status;
status = mongocrypt_status_new ();
if (!mongocrypt_kms_ctx_status (kms_ctx, status)) {
_status_to_error (status, error);
mongocrypt_status_destroy (status);
return false;
} else if (error_expected) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"generic error from libmongocrypt KMS operation");
mongocrypt_status_destroy (status);
return false;
}
mongocrypt_status_destroy (status);
return true;
}
bool
_crypt_check_error (mongocrypt_t *crypt,
bson_error_t *error,
bool error_expected)
{
mongocrypt_status_t *status;
status = mongocrypt_status_new ();
if (!mongocrypt_status (crypt, status)) {
_status_to_error (status, error);
mongocrypt_status_destroy (status);
return false;
} else if (error_expected) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"generic error from libmongocrypt handle");
mongocrypt_status_destroy (status);
return false;
}
mongocrypt_status_destroy (status);
return true;
}
/* Convert a mongocrypt_binary_t to a static bson_t */
static bool
_bin_to_static_bson (mongocrypt_binary_t *bin, bson_t *out, bson_error_t *error)
{
/* Copy bin into bson_t result. */
if (!bson_init_static (
out, mongocrypt_binary_data (bin), mongocrypt_binary_len (bin))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"invalid returned bson");
return false;
}
return true;
}
typedef struct {
mongocrypt_ctx_t *ctx;
mongoc_collection_t *keyvault_coll;
mongoc_client_t *mongocryptd_client;
mongoc_client_t *collinfo_client;
const char *db_name;
_mongoc_crypt_t *crypt;
} _state_machine_t;
_state_machine_t *
_state_machine_new (_mongoc_crypt_t *crypt)
{
_state_machine_t *sm = bson_malloc0 (sizeof (_state_machine_t));
sm->crypt = crypt;
return sm;
}
void
_state_machine_destroy (_state_machine_t *state_machine)
{
mongocrypt_ctx_destroy (state_machine->ctx);
bson_free (state_machine);
}
/* State handler MONGOCRYPT_CTX_NEED_MONGO_COLLINFO */
static bool
_state_need_mongo_collinfo (_state_machine_t *state_machine,
bson_error_t *error)
{
mongoc_database_t *db = NULL;
mongoc_cursor_t *cursor = NULL;
bson_t filter_bson;
const bson_t *collinfo_bson = NULL;
bson_t opts = BSON_INITIALIZER;
mongocrypt_binary_t *filter_bin = NULL;
mongocrypt_binary_t *collinfo_bin = NULL;
bool ret = false;
/* 1. Run listCollections on the encrypted MongoClient with the filter
* provided by mongocrypt_ctx_mongo_op */
filter_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_mongo_op (state_machine->ctx, filter_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (filter_bin, &filter_bson, error)) {
goto fail;
}
bson_append_document (&opts, "filter", -1, &filter_bson);
db = mongoc_client_get_database (state_machine->collinfo_client,
state_machine->db_name);
cursor = mongoc_database_find_collections_with_opts (db, &opts);
if (mongoc_cursor_error (cursor, error)) {
goto fail;
}
/* 2. Return the first result (if any) with mongocrypt_ctx_mongo_feed or
* proceed to the next step if nothing was returned. */
if (mongoc_cursor_next (cursor, &collinfo_bson)) {
collinfo_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (collinfo_bson), collinfo_bson->len);
if (!mongocrypt_ctx_mongo_feed (state_machine->ctx, collinfo_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
} else if (mongoc_cursor_error (cursor, error)) {
goto fail;
}
/* 3. Call mongocrypt_ctx_mongo_done */
if (!mongocrypt_ctx_mongo_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
bson_destroy (&opts);
mongocrypt_binary_destroy (filter_bin);
mongocrypt_binary_destroy (collinfo_bin);
mongoc_cursor_destroy (cursor);
mongoc_database_destroy (db);
return ret;
}
static bool
_state_need_mongo_markings (_state_machine_t *state_machine,
bson_error_t *error)
{
bool ret = false;
mongocrypt_binary_t *mongocryptd_cmd_bin = NULL;
mongocrypt_binary_t *mongocryptd_reply_bin = NULL;
bson_t mongocryptd_cmd_bson;
bson_t reply = BSON_INITIALIZER;
mongocryptd_cmd_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_mongo_op (state_machine->ctx, mongocryptd_cmd_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (
mongocryptd_cmd_bin, &mongocryptd_cmd_bson, error)) {
goto fail;
}
/* 1. Use db.runCommand to run the command provided by
* mongocrypt_ctx_mongo_op on the MongoClient connected to mongocryptd. */
bson_destroy (&reply);
if (!mongoc_client_command_simple (state_machine->mongocryptd_client,
- "admin",
+ state_machine->db_name,
&mongocryptd_cmd_bson,
NULL /* read_prefs */,
&reply,
error)) {
_prefix_mongocryptd_error (error);
goto fail;
}
/* 2. Feed the reply back with mongocrypt_ctx_mongo_feed. */
mongocryptd_reply_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (&reply), reply.len);
if (!mongocrypt_ctx_mongo_feed (state_machine->ctx, mongocryptd_reply_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
/* 3. Call mongocrypt_ctx_mongo_done. */
if (!mongocrypt_ctx_mongo_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
bson_destroy (&reply);
mongocrypt_binary_destroy (mongocryptd_cmd_bin);
mongocrypt_binary_destroy (mongocryptd_reply_bin);
return ret;
}
static bool
_state_need_mongo_keys (_state_machine_t *state_machine, bson_error_t *error)
{
bool ret = false;
mongocrypt_binary_t *filter_bin = NULL;
bson_t filter_bson;
bson_t opts = BSON_INITIALIZER;
mongocrypt_binary_t *key_bin = NULL;
const bson_t *key_bson;
mongoc_cursor_t *cursor = NULL;
- mongoc_read_concern_t *rc = NULL;
/* 1. Use MongoCollection.find on the MongoClient connected to the key vault
* client (which may be the same as the encrypted client). Use the filter
* provided by mongocrypt_ctx_mongo_op. */
filter_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_mongo_op (state_machine->ctx, filter_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (filter_bin, &filter_bson, error)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
- rc = mongoc_read_concern_new ();
- mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY);
- if (!mongoc_read_concern_append (rc, &opts)) {
- bson_set_error (error,
- MONGOC_ERROR_BSON,
- MONGOC_ERROR_BSON_INVALID,
- "%s",
- "could not set read concern");
- goto fail;
+ {
+ const mongoc_read_concern_t *const rc =
+ mongoc_collection_get_read_concern (state_machine->keyvault_coll);
+ const char *const level = rc ? mongoc_read_concern_get_level (rc) : NULL;
+ BSON_ASSERT (level &&
+ strcmp (level, MONGOC_READ_CONCERN_LEVEL_MAJORITY) == 0);
}
cursor = mongoc_collection_find_with_opts (
state_machine->keyvault_coll, &filter_bson, &opts, NULL /* read prefs */);
/* 2. Feed all resulting documents back (if any) with repeated calls to
* mongocrypt_ctx_mongo_feed. */
while (mongoc_cursor_next (cursor, &key_bson)) {
mongocrypt_binary_destroy (key_bin);
key_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (key_bson), key_bson->len);
if (!mongocrypt_ctx_mongo_feed (state_machine->ctx, key_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
if (mongoc_cursor_error (cursor, error)) {
_prefix_keyvault_error (error);
goto fail;
}
/* 3. Call mongocrypt_ctx_mongo_done. */
if (!mongocrypt_ctx_mongo_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
mongocrypt_binary_destroy (filter_bin);
mongoc_cursor_destroy (cursor);
- mongoc_read_concern_destroy (rc);
bson_destroy (&opts);
mongocrypt_binary_destroy (key_bin);
return ret;
}
static mongoc_stream_t *
_get_stream (const char *endpoint,
int32_t connecttimeoutms,
const mongoc_ssl_opt_t *ssl_opt,
bson_error_t *error)
{
mongoc_stream_t *base_stream = NULL;
mongoc_stream_t *tls_stream = NULL;
bool ret = false;
mongoc_ssl_opt_t ssl_opt_copy = {0};
mongoc_host_list_t host;
if (!_mongoc_host_list_from_string_with_err (&host, endpoint, error)) {
goto fail;
}
base_stream = mongoc_client_connect_tcp (connecttimeoutms, &host, error);
if (!base_stream) {
goto fail;
}
/* Wrap in a tls_stream. */
_mongoc_ssl_opts_copy_to (ssl_opt, &ssl_opt_copy, true /* copy_internal */);
tls_stream = mongoc_stream_tls_new_with_hostname (
base_stream, host.host, &ssl_opt_copy, 1 /* client */);
if (!mongoc_stream_tls_handshake_block (
tls_stream, host.host, connecttimeoutms, error)) {
goto fail;
}
ret = true;
fail:
_mongoc_ssl_opts_cleanup (&ssl_opt_copy, true /* free_internal */);
if (!ret) {
if (tls_stream) {
/* destroys base_stream too */
mongoc_stream_destroy (tls_stream);
} else if (base_stream) {
mongoc_stream_destroy (base_stream);
}
return NULL;
}
return tls_stream;
}
static bool
_state_need_kms (_state_machine_t *state_machine, bson_error_t *error)
{
mongocrypt_kms_ctx_t *kms_ctx = NULL;
mongoc_stream_t *tls_stream = NULL;
bool ret = false;
mongocrypt_binary_t *http_req = NULL;
mongocrypt_binary_t *http_reply = NULL;
const char *endpoint;
uint32_t sockettimeout;
sockettimeout = MONGOC_DEFAULT_SOCKETTIMEOUTMS;
kms_ctx = mongocrypt_ctx_next_kms_ctx (state_machine->ctx);
while (kms_ctx) {
mongoc_iovec_t iov;
const mongoc_ssl_opt_t *ssl_opt;
const char *provider;
provider = mongocrypt_kms_ctx_get_kms_provider (kms_ctx, NULL);
if (0 == strcmp ("kmip", provider)) {
ssl_opt = &state_machine->crypt->kmip_tls_opt;
} else if (0 == strcmp ("aws", provider)) {
ssl_opt = &state_machine->crypt->aws_tls_opt;
} else if (0 == strcmp ("azure", provider)) {
ssl_opt = &state_machine->crypt->azure_tls_opt;
} else if (0 == strcmp ("gcp", provider)) {
ssl_opt = &state_machine->crypt->gcp_tls_opt;
} else {
ssl_opt = mongoc_ssl_opt_get_default ();
}
mongocrypt_binary_destroy (http_req);
http_req = mongocrypt_binary_new ();
if (!mongocrypt_kms_ctx_message (kms_ctx, http_req)) {
_kms_ctx_check_error (kms_ctx, error, true);
goto fail;
}
if (!mongocrypt_kms_ctx_endpoint (kms_ctx, &endpoint)) {
_kms_ctx_check_error (kms_ctx, error, true);
goto fail;
}
mongoc_stream_destroy (tls_stream);
tls_stream = _get_stream (endpoint, sockettimeout, ssl_opt, error);
#ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL
/* Retry once with schannel as a workaround for CDRIVER-3566. */
if (!tls_stream) {
tls_stream = _get_stream (endpoint, sockettimeout, ssl_opt, error);
}
#endif
if (!tls_stream) {
goto fail;
}
iov.iov_base = (char *) mongocrypt_binary_data (http_req);
iov.iov_len = mongocrypt_binary_len (http_req);
if (!_mongoc_stream_writev_full (
tls_stream, &iov, 1, sockettimeout, error)) {
goto fail;
}
/* Read and feed reply. */
while (mongocrypt_kms_ctx_bytes_needed (kms_ctx) > 0) {
#define BUFFER_SIZE 1024
uint8_t buf[BUFFER_SIZE];
uint32_t bytes_needed = mongocrypt_kms_ctx_bytes_needed (kms_ctx);
ssize_t read_ret;
/* Cap the bytes requested at the buffer size. */
if (bytes_needed > BUFFER_SIZE) {
bytes_needed = BUFFER_SIZE;
}
read_ret = mongoc_stream_read (
tls_stream, buf, bytes_needed, 1 /* min_bytes. */, sockettimeout);
if (read_ret == -1) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"failed to read from KMS stream: %d",
errno);
goto fail;
}
if (read_ret == 0) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"unexpected EOF from KMS stream");
goto fail;
}
mongocrypt_binary_destroy (http_reply);
http_reply = mongocrypt_binary_new_from_data (buf, read_ret);
if (!mongocrypt_kms_ctx_feed (kms_ctx, http_reply)) {
_kms_ctx_check_error (kms_ctx, error, true);
goto fail;
}
}
kms_ctx = mongocrypt_ctx_next_kms_ctx (state_machine->ctx);
}
/* When NULL is returned by mongocrypt_ctx_next_kms_ctx, this can either be
* an error or end-of-list. */
if (!_ctx_check_error (state_machine->ctx, error, false)) {
goto fail;
}
if (!mongocrypt_ctx_kms_done (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
ret = true;
fail:
mongoc_stream_destroy (tls_stream);
mongocrypt_binary_destroy (http_req);
mongocrypt_binary_destroy (http_reply);
return ret;
#undef BUFFER_SIZE
}
static bool
_state_ready (_state_machine_t *state_machine,
bson_t *result,
bson_error_t *error)
{
mongocrypt_binary_t *result_bin = NULL;
bson_t tmp;
bool ret = false;
bson_init (result);
result_bin = mongocrypt_binary_new ();
if (!mongocrypt_ctx_finalize (state_machine->ctx, result_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (!_bin_to_static_bson (result_bin, &tmp, error)) {
goto fail;
}
bson_destroy (result);
bson_copy_to (&tmp, result);
ret = true;
fail:
mongocrypt_binary_destroy (result_bin);
return ret;
}
/*--------------------------------------------------------------------------
*
* _mongoc_cse_run_state_machine --
* Run the mongocrypt_ctx state machine.
*
* Post-conditions:
* *result may be set to a new bson_t, or NULL otherwise. Caller should
* not assume return value of true means *result is set. If false returned,
* @error is set.
*
* --------------------------------------------------------------------------
*/
bool
_state_machine_run (_state_machine_t *state_machine,
bson_t *result,
bson_error_t *error)
{
bool ret = false;
mongocrypt_binary_t *bin = NULL;
bson_init (result);
while (true) {
switch (mongocrypt_ctx_state (state_machine->ctx)) {
default:
case MONGOCRYPT_CTX_ERROR:
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
if (!_state_need_mongo_collinfo (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
if (!_state_need_mongo_markings (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
if (!_state_need_mongo_keys (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_NEED_KMS:
if (!_state_need_kms (state_machine, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_READY:
bson_destroy (result);
if (!_state_ready (state_machine, result, error)) {
goto fail;
}
break;
case MONGOCRYPT_CTX_DONE:
goto success;
break;
}
}
success:
ret = true;
fail:
mongocrypt_binary_destroy (bin);
return ret;
}
/* _parse_one_tls_opts parses one TLS document.
* Pre-conditions:
* - @iter is an iterator at the start of a KMS provider key/value pair.
* - @out_opt must not be initialized.
* Post-conditions:
* - @out_opt is always initialized.
* Returns false and sets @error on error. */
static bool
_parse_one_tls_opts (bson_iter_t *iter,
mongoc_ssl_opt_t *out_opt,
bson_error_t *error)
{
bool ok = false;
const char *kms_provider;
bson_t tls_opts_doc;
const uint8_t *data;
uint32_t len;
bson_string_t *errmsg;
bson_iter_t permitted_iter;
errmsg = bson_string_new (NULL);
kms_provider = bson_iter_key (iter);
memset (out_opt, 0, sizeof (mongoc_ssl_opt_t));
if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Expected TLS options for %s to be a document, got: %s",
kms_provider,
_mongoc_bson_type_to_str (bson_iter_type (iter)));
goto fail;
}
bson_iter_document (iter, &len, &data);
if (!bson_init_static (&tls_opts_doc, data, len) ||
!bson_iter_init (&permitted_iter, &tls_opts_doc)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Error iterating into TLS options document for %s",
kms_provider);
goto fail;
}
while (bson_iter_next (&permitted_iter)) {
const char *key = bson_iter_key (&permitted_iter);
if (0 ==
bson_strcasecmp (key, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
continue;
}
if (0 == bson_strcasecmp (key, MONGOC_URI_TLSCERTIFICATEKEYFILE)) {
continue;
}
if (0 == bson_strcasecmp (key, MONGOC_URI_TLSCAFILE)) {
continue;
}
bson_set_error (
error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Error setting TLS option %s for %s. Insecure TLS options prohibited.",
key,
kms_provider);
goto fail;
}
if (!_mongoc_ssl_opts_from_bson (out_opt, &tls_opts_doc, errmsg)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Error parsing TLS options for %s: %s",
kms_provider,
errmsg->str);
goto fail;
}
ok = true;
fail:
bson_string_free (errmsg, true /* free_segment */);
return ok;
}
/* _parse_all_tls_opts initializes TLS options for all KMS providers.
* @tls_opts is the BSON document passed through
* mongoc_client_encryption_opts_set_tls_opts or
* mongoc_auto_encryption_opts_set_tls_opts.
* Defaults to using mongoc_ssl_opt_get_default() if options are not passed for
* a provider. Returns false and sets @error on error. */
static bool
_parse_all_tls_opts (_mongoc_crypt_t *crypt,
const bson_t *tls_opts,
bson_error_t *error)
{
bson_iter_t iter;
bool ok = false;
bool has_aws = false;
bool has_azure = false;
bool has_gcp = false;
bool has_kmip = false;
if (!tls_opts) {
return true;
}
if (!bson_iter_init (&iter, tls_opts)) {
bson_set_error (error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Error starting iteration of TLS options");
goto fail;
}
while (bson_iter_next (&iter)) {
const char *key;
key = bson_iter_key (&iter);
if (0 == strcmp (key, "aws")) {
if (has_aws) {
bson_set_error (error,
- MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
- MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
- "Error parsing duplicate TLS options for %s", key);
+ MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
+ "Error parsing duplicate TLS options for %s",
+ key);
goto fail;
}
has_aws = true;
if (!_parse_one_tls_opts (&iter, &crypt->aws_tls_opt, error)) {
goto fail;
}
continue;
}
if (0 == strcmp (key, "azure")) {
if (has_azure) {
bson_set_error (error,
- MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
- MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
- "Error parsing duplicate TLS options for %s", key);
+ MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
+ "Error parsing duplicate TLS options for %s",
+ key);
goto fail;
}
has_azure = true;
if (!_parse_one_tls_opts (&iter, &crypt->azure_tls_opt, error)) {
goto fail;
}
continue;
}
if (0 == strcmp (key, "gcp")) {
if (has_gcp) {
bson_set_error (error,
- MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
- MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
- "Error parsing duplicate TLS options for %s", key);
+ MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
+ "Error parsing duplicate TLS options for %s",
+ key);
goto fail;
}
has_gcp = true;
if (!_parse_one_tls_opts (&iter, &crypt->gcp_tls_opt, error)) {
goto fail;
}
continue;
}
if (0 == strcmp (key, "kmip")) {
if (has_kmip) {
bson_set_error (error,
- MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
- MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
- "Error parsing duplicate TLS options for %s", key);
+ MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
+ "Error parsing duplicate TLS options for %s",
+ key);
goto fail;
}
has_kmip = true;
if (!_parse_one_tls_opts (&iter, &crypt->kmip_tls_opt, error)) {
goto fail;
}
continue;
}
bson_set_error (error,
MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"Cannot configure TLS options for KMS provider: %s",
key);
goto fail;
}
/* Configure with default TLS options. The mongoc_ssl_opt_t returned by
* mongoc_ssl_opt_get_default may contain non-NULL fields if
* MONGOC_SSL_DEFAULT_TRUST_FILE or MONGOC_SSL_DEFAULT_TRUST_DIR are defined.
*/
if (!has_aws) {
_mongoc_ssl_opts_copy_to (mongoc_ssl_opt_get_default (),
&crypt->aws_tls_opt,
false /* copy internal */);
}
if (!has_azure) {
_mongoc_ssl_opts_copy_to (mongoc_ssl_opt_get_default (),
&crypt->azure_tls_opt,
false /* copy internal */);
}
if (!has_gcp) {
_mongoc_ssl_opts_copy_to (mongoc_ssl_opt_get_default (),
&crypt->gcp_tls_opt,
false /* copy internal */);
}
if (!has_kmip) {
_mongoc_ssl_opts_copy_to (mongoc_ssl_opt_get_default (),
&crypt->kmip_tls_opt,
false /* copy internal */);
}
ok = true;
fail:
return ok;
}
/* Note, _mongoc_crypt_t only has one member, to the top-level handle of
libmongocrypt, mongocrypt_t.
The purpose of defining _mongoc_crypt_t is to limit all interaction with
libmongocrypt to this one
file.
*/
_mongoc_crypt_t *
_mongoc_crypt_new (const bson_t *kms_providers,
const bson_t *schema_map,
+ const bson_t *encrypted_fields_map,
const bson_t *tls_opts,
+ const char *crypt_shared_lib_path,
+ bool crypt_shared_lib_required,
+ bool bypass_auto_encryption,
+ bool bypass_query_analysis,
bson_error_t *error)
{
_mongoc_crypt_t *crypt;
mongocrypt_binary_t *local_masterkey_bin = NULL;
mongocrypt_binary_t *schema_map_bin = NULL;
+ mongocrypt_binary_t *encrypted_fields_map_bin = NULL;
mongocrypt_binary_t *kms_providers_bin = NULL;
bool success = false;
/* Create the handle to libmongocrypt. */
crypt = bson_malloc0 (sizeof (*crypt));
crypt->handle = mongocrypt_new ();
if (!_parse_all_tls_opts (crypt, tls_opts, error)) {
goto fail;
}
mongocrypt_setopt_log_handler (
crypt->handle, _log_callback, NULL /* context */);
kms_providers_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (kms_providers), kms_providers->len);
if (!mongocrypt_setopt_kms_providers (crypt->handle, kms_providers_bin)) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
if (schema_map) {
schema_map_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (schema_map), schema_map->len);
if (!mongocrypt_setopt_schema_map (crypt->handle, schema_map_bin)) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
}
+ if (encrypted_fields_map) {
+ encrypted_fields_map_bin = mongocrypt_binary_new_from_data (
+ (uint8_t *) bson_get_data (encrypted_fields_map),
+ encrypted_fields_map->len);
+ if (!mongocrypt_setopt_encrypted_field_config_map (
+ crypt->handle, encrypted_fields_map_bin)) {
+ _crypt_check_error (crypt->handle, error, true);
+ goto fail;
+ }
+ }
+
+ if (!bypass_auto_encryption) {
+ mongocrypt_setopt_append_crypt_shared_lib_search_path (crypt->handle,
+ "$SYSTEM");
+ if (!_crypt_check_error (crypt->handle, error, false)) {
+ goto fail;
+ }
+
+ if (crypt_shared_lib_path != NULL) {
+ mongocrypt_setopt_set_crypt_shared_lib_path_override (
+ crypt->handle, crypt_shared_lib_path);
+ if (!_crypt_check_error (crypt->handle, error, false)) {
+ goto fail;
+ }
+ }
+ }
+
+ if (bypass_query_analysis) {
+ mongocrypt_setopt_bypass_query_analysis (crypt->handle);
+ if (!_crypt_check_error (crypt->handle, error, false)) {
+ goto fail;
+ }
+ }
+
if (!mongocrypt_init (crypt->handle)) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
+ if (crypt_shared_lib_required) {
+ uint32_t len = 0;
+ const char *s =
+ mongocrypt_crypt_shared_lib_version_string (crypt->handle, &len);
+ if (!s || len == 0) {
+ // empty/null version string indicates that crypt_shared was not loaded
+ // by libmongocrypt
+ bson_set_error (
+ error,
+ MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION,
+ MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
+ "Option 'cryptSharedLibRequired' is 'true', but failed to "
+ "load the crypt_shared runtime libary");
+ goto fail;
+ }
+ mongoc_log (MONGOC_LOG_LEVEL_DEBUG,
+ MONGOC_LOG_DOMAIN,
+ "crypt_shared library version '%s' was found and loaded",
+ s);
+ }
+
success = true;
fail:
mongocrypt_binary_destroy (local_masterkey_bin);
+ mongocrypt_binary_destroy (encrypted_fields_map_bin);
mongocrypt_binary_destroy (schema_map_bin);
mongocrypt_binary_destroy (kms_providers_bin);
if (!success) {
_mongoc_crypt_destroy (crypt);
return NULL;
}
return crypt;
}
void
_mongoc_crypt_destroy (_mongoc_crypt_t *crypt)
{
if (!crypt) {
return;
}
mongocrypt_destroy (crypt->handle);
_mongoc_ssl_opts_cleanup (&crypt->kmip_tls_opt, true /* free_internal */);
_mongoc_ssl_opts_cleanup (&crypt->aws_tls_opt, true /* free_internal */);
_mongoc_ssl_opts_cleanup (&crypt->azure_tls_opt, true /* free_internal */);
_mongoc_ssl_opts_cleanup (&crypt->gcp_tls_opt, true /* free_internal */);
bson_free (crypt);
}
bool
_mongoc_crypt_auto_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
mongoc_client_t *mongocryptd_client,
mongoc_client_t *collinfo_client,
const char *db_name,
const bson_t *cmd_in,
bson_t *cmd_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
mongocrypt_binary_t *cmd_bin = NULL;
bool ret = false;
bson_init (cmd_out);
state_machine = _state_machine_new (crypt);
state_machine->keyvault_coll = keyvault_coll;
state_machine->mongocryptd_client = mongocryptd_client;
state_machine->collinfo_client = collinfo_client;
state_machine->db_name = db_name;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
cmd_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (cmd_in), cmd_in->len);
if (!mongocrypt_ctx_encrypt_init (
state_machine->ctx, db_name, -1, cmd_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (cmd_out);
if (!_state_machine_run (state_machine, cmd_out, error)) {
goto fail;
}
ret = true;
fail:
mongocrypt_binary_destroy (cmd_bin);
_state_machine_destroy (state_machine);
return ret;
}
bool
_mongoc_crypt_auto_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
const bson_t *doc_in,
bson_t *doc_out,
bson_error_t *error)
{
bool ret = false;
_state_machine_t *state_machine = NULL;
mongocrypt_binary_t *doc_bin = NULL;
bson_init (doc_out);
state_machine = _state_machine_new (crypt);
state_machine->keyvault_coll = keyvault_coll;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
doc_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (doc_in), doc_in->len);
if (!mongocrypt_ctx_decrypt_init (state_machine->ctx, doc_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (doc_out);
if (!_state_machine_run (state_machine, doc_out, error)) {
goto fail;
}
ret = true;
fail:
mongocrypt_binary_destroy (doc_bin);
_state_machine_destroy (state_machine);
return ret;
}
bool
_mongoc_crypt_explicit_encrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
const char *algorithm,
const bson_value_t *keyid,
char *keyaltname,
+ const char *query_type,
+ const int64_t *contention_factor,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
bson_t *to_encrypt_doc = NULL;
mongocrypt_binary_t *to_encrypt_bin = NULL;
bson_iter_t iter;
bool ret = false;
bson_t result = BSON_INITIALIZER;
value_out->value_type = BSON_TYPE_EOD;
/* Create the context for the operation. */
state_machine = _state_machine_new (crypt);
state_machine->keyvault_coll = keyvault_coll;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
if (!mongocrypt_ctx_setopt_algorithm (state_machine->ctx, algorithm, -1)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
+ if (query_type != NULL) {
+ if (!mongocrypt_ctx_setopt_query_type (
+ state_machine->ctx, query_type, -1)) {
+ goto fail;
+ }
+ }
+
+ if (contention_factor != NULL) {
+ if (!mongocrypt_ctx_setopt_contention_factor (state_machine->ctx,
+ *contention_factor)) {
+ _ctx_check_error (state_machine->ctx, error, true);
+ goto fail;
+ }
+ }
+
if (keyaltname) {
bool keyaltname_ret;
mongocrypt_binary_t *keyaltname_bin;
bson_t *keyaltname_doc;
keyaltname_doc = BCON_NEW ("keyAltName", keyaltname);
keyaltname_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (keyaltname_doc), keyaltname_doc->len);
keyaltname_ret = mongocrypt_ctx_setopt_key_alt_name (state_machine->ctx,
keyaltname_bin);
mongocrypt_binary_destroy (keyaltname_bin);
bson_destroy (keyaltname_doc);
if (!keyaltname_ret) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
if (keyid && keyid->value_type == BSON_TYPE_BINARY) {
mongocrypt_binary_t *keyid_bin;
bool keyid_ret;
if (keyid->value.v_binary.subtype != BSON_SUBTYPE_UUID) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG,
"keyid must be a UUID");
goto fail;
}
keyid_bin = mongocrypt_binary_new_from_data (
keyid->value.v_binary.data, keyid->value.v_binary.data_len);
keyid_ret = mongocrypt_ctx_setopt_key_id (state_machine->ctx, keyid_bin);
mongocrypt_binary_destroy (keyid_bin);
if (!keyid_ret) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
to_encrypt_doc = bson_new ();
BSON_APPEND_VALUE (to_encrypt_doc, "v", value_in);
to_encrypt_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (to_encrypt_doc), to_encrypt_doc->len);
if (!mongocrypt_ctx_explicit_encrypt_init (state_machine->ctx,
to_encrypt_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (&result);
if (!_state_machine_run (state_machine, &result, error)) {
goto fail;
}
/* extract value */
if (!bson_iter_init_find (&iter, &result, "v")) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"encrypted result unexpected");
goto fail;
} else {
const bson_value_t *tmp;
tmp = bson_iter_value (&iter);
bson_value_copy (tmp, value_out);
}
ret = true;
fail:
_state_machine_destroy (state_machine);
mongocrypt_binary_destroy (to_encrypt_bin);
bson_destroy (to_encrypt_doc);
bson_destroy (&result);
return ret;
}
bool
_mongoc_crypt_explicit_decrypt (_mongoc_crypt_t *crypt,
mongoc_collection_t *keyvault_coll,
const bson_value_t *value_in,
bson_value_t *value_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
bson_t *to_decrypt_doc = NULL;
mongocrypt_binary_t *to_decrypt_bin = NULL;
bson_iter_t iter;
bool ret = false;
bson_t result = BSON_INITIALIZER;
state_machine = _state_machine_new (crypt);
state_machine->keyvault_coll = keyvault_coll;
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
to_decrypt_doc = bson_new ();
BSON_APPEND_VALUE (to_decrypt_doc, "v", value_in);
to_decrypt_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (to_decrypt_doc), to_decrypt_doc->len);
if (!mongocrypt_ctx_explicit_decrypt_init (state_machine->ctx,
to_decrypt_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (&result);
if (!_state_machine_run (state_machine, &result, error)) {
goto fail;
}
/* extract value */
if (!bson_iter_init_find (&iter, &result, "v")) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_STATE,
"decrypted result unexpected");
goto fail;
} else {
const bson_value_t *tmp;
tmp = bson_iter_value (&iter);
bson_value_copy (tmp, value_out);
}
ret = true;
fail:
_state_machine_destroy (state_machine);
mongocrypt_binary_destroy (to_decrypt_bin);
bson_destroy (to_decrypt_doc);
bson_destroy (&result);
return ret;
}
bool
_mongoc_crypt_create_datakey (_mongoc_crypt_t *crypt,
const char *kms_provider,
const bson_t *masterkey,
char **keyaltnames,
uint32_t keyaltnames_count,
+ const uint8_t *keymaterial,
+ uint32_t keymaterial_len,
bson_t *doc_out,
bson_error_t *error)
{
_state_machine_t *state_machine = NULL;
bool ret = false;
bson_t masterkey_w_provider = BSON_INITIALIZER;
mongocrypt_binary_t *masterkey_w_provider_bin = NULL;
bson_init (doc_out);
state_machine = _state_machine_new (crypt);
state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
if (!state_machine->ctx) {
_crypt_check_error (crypt->handle, error, true);
goto fail;
}
BSON_APPEND_UTF8 (&masterkey_w_provider, "provider", kms_provider);
if (masterkey) {
bson_concat (&masterkey_w_provider, masterkey);
}
masterkey_w_provider_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (&masterkey_w_provider),
masterkey_w_provider.len);
if (!mongocrypt_ctx_setopt_key_encryption_key (state_machine->ctx,
masterkey_w_provider_bin)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
if (keyaltnames) {
int i;
for (i = 0; i < keyaltnames_count; i++) {
bool keyaltname_ret;
mongocrypt_binary_t *keyaltname_bin;
bson_t *keyaltname_doc;
keyaltname_doc = BCON_NEW ("keyAltName", keyaltnames[i]);
keyaltname_bin = mongocrypt_binary_new_from_data (
(uint8_t *) bson_get_data (keyaltname_doc), keyaltname_doc->len);
keyaltname_ret = mongocrypt_ctx_setopt_key_alt_name (
state_machine->ctx, keyaltname_bin);
mongocrypt_binary_destroy (keyaltname_bin);
bson_destroy (keyaltname_doc);
if (!keyaltname_ret) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
}
}
+ if (keymaterial) {
+ bson_t *const bson = BCON_NEW (
+ "keyMaterial",
+ BCON_BIN (BSON_SUBTYPE_BINARY, keymaterial, keymaterial_len));
+ mongocrypt_binary_t *const bin = mongocrypt_binary_new_from_data (
+ (uint8_t *) bson_get_data (bson), bson->len);
+
+ mongocrypt_ctx_setopt_key_material (state_machine->ctx, bin);
+
+ bson_destroy (bson);
+ mongocrypt_binary_destroy (bin);
+ }
+
if (!mongocrypt_ctx_datakey_init (state_machine->ctx)) {
_ctx_check_error (state_machine->ctx, error, true);
goto fail;
}
bson_destroy (doc_out);
if (!_state_machine_run (state_machine, doc_out, error)) {
goto fail;
}
ret = true;
fail:
bson_destroy (&masterkey_w_provider);
mongocrypt_binary_destroy (masterkey_w_provider_bin);
_state_machine_destroy (state_machine);
return ret;
}
+bool
+_mongoc_crypt_rewrap_many_datakey (_mongoc_crypt_t *crypt,
+ mongoc_collection_t *keyvault_coll,
+ const bson_t *filter,
+ const char *provider,
+ const bson_t *master_key,
+ bson_t *doc_out,
+ bson_error_t *error)
+{
+ _state_machine_t *state_machine = NULL;
+ const bson_t empty_bson = BSON_INITIALIZER;
+ mongocrypt_binary_t *filter_bin = NULL;
+ bool ret = false;
+
+ bson_init (doc_out);
+ state_machine = _state_machine_new (crypt);
+ state_machine->keyvault_coll = keyvault_coll;
+ state_machine->ctx = mongocrypt_ctx_new (crypt->handle);
+ if (!state_machine->ctx) {
+ _crypt_check_error (crypt->handle, error, true);
+ goto fail;
+ }
+
+ {
+ bson_t new_provider = BSON_INITIALIZER;
+ mongocrypt_binary_t *new_provider_bin = NULL;
+ bool success = true;
+
+ if (provider) {
+ BSON_APPEND_UTF8 (&new_provider, "provider", provider);
+
+ if (master_key) {
+ bson_concat (&new_provider, master_key);
+ }
+
+ new_provider_bin = mongocrypt_binary_new_from_data (
+ (uint8_t *) bson_get_data (&new_provider), new_provider.len);
+
+ if (!mongocrypt_ctx_setopt_key_encryption_key (state_machine->ctx,
+ new_provider_bin)) {
+ _ctx_check_error (state_machine->ctx, error, true);
+ success = false;
+ }
+
+ mongocrypt_binary_destroy (new_provider_bin);
+ }
+
+ bson_destroy (&new_provider);
+
+ if (!success) {
+ goto fail;
+ }
+ }
+
+ if (!filter) {
+ filter = &empty_bson;
+ }
+
+ filter_bin = mongocrypt_binary_new_from_data (
+ (uint8_t *) bson_get_data (filter), filter->len);
+
+ if (!mongocrypt_ctx_rewrap_many_datakey_init (state_machine->ctx,
+ filter_bin)) {
+ _ctx_check_error (state_machine->ctx, error, true);
+ goto fail;
+ }
+
+ bson_destroy (doc_out);
+ if (!_state_machine_run (state_machine, doc_out, error)) {
+ goto fail;
+ }
+
+ ret = true;
+
+fail:
+ mongocrypt_binary_destroy (filter_bin);
+ _state_machine_destroy (state_machine);
+
+ return ret;
+}
+
#else
/* ensure the translation unit is not empty */
extern int no_mongoc_client_side_encryption;
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
index 07742817..5f346d90 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c
@@ -1,626 +1,627 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* cursor functions for pre-3.2 MongoDB, including:
* - OP_QUERY find (superseded by the find command)
* - OP_GETMORE (superseded by the getMore command)
* - receiving OP_REPLY documents in a stream (instead of batch)
*/
#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-client-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-rpc-private.h"
static bool
_mongoc_cursor_monitor_legacy_get_more (mongoc_cursor_t *cursor,
mongoc_server_stream_t *server_stream)
{
bson_t doc;
char *db;
mongoc_client_t *client;
mongoc_apm_command_started_t event;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.started) {
/* successful */
RETURN (true);
}
_mongoc_cursor_prepare_getmore_command (cursor, &doc);
db = bson_strndup (cursor->ns, cursor->dblen);
mongoc_apm_command_started_init (&event,
&doc,
db,
"getMore",
client->cluster.request_id,
cursor->operation_id,
&server_stream->sd->host,
server_stream->sd->id,
&server_stream->sd->service_id,
+ server_stream->sd->server_connection_id,
NULL,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
bson_destroy (&doc);
bson_free (db);
RETURN (true);
}
static bool
_mongoc_cursor_monitor_legacy_query (mongoc_cursor_t *cursor,
const bson_t *filter,
mongoc_server_stream_t *server_stream)
{
bson_t doc;
mongoc_client_t *client;
char *db;
bool r;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.started) {
/* successful */
RETURN (true);
}
bson_init (&doc);
db = bson_strndup (cursor->ns, cursor->dblen);
/* simulate a MongoDB 3.2+ "find" command */
_mongoc_cursor_prepare_find_command (cursor, filter, &doc);
bson_copy_to_excluding_noinit (
&cursor->opts, &doc, "serverId", "maxAwaitTimeMS", "sessionId", NULL);
r = _mongoc_cursor_monitor_command (cursor, server_stream, &doc, "find");
bson_destroy (&doc);
bson_free (db);
RETURN (r);
}
void
_mongoc_cursor_op_getmore (mongoc_cursor_t *cursor,
mongoc_cursor_response_legacy_t *response)
{
int64_t started;
mongoc_rpc_t rpc;
uint32_t request_id;
mongoc_cluster_t *cluster;
mongoc_query_flags_t flags;
mongoc_server_stream_t *server_stream;
ENTRY;
started = bson_get_monotonic_time ();
cluster = &cursor->client->cluster;
server_stream = _mongoc_cursor_fetch_stream (cursor);
if (!server_stream) {
return;
}
if (!_mongoc_cursor_opts_to_flags (cursor, server_stream, &flags)) {
GOTO (fail);
}
if (cursor->in_exhaust) {
request_id = (uint32_t) response->rpc.header.request_id;
} else {
request_id = ++cluster->request_id;
rpc.get_more.cursor_id = cursor->cursor_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_GET_MORE;
rpc.get_more.zero = 0;
rpc.get_more.collection = cursor->ns;
if (flags & MONGOC_QUERY_TAILABLE_CURSOR) {
rpc.get_more.n_return = 0;
} else {
rpc.get_more.n_return = _mongoc_n_return (cursor);
}
if (!_mongoc_cursor_monitor_legacy_get_more (cursor, server_stream)) {
GOTO (fail);
}
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
cluster, &rpc, server_stream, &cursor->error)) {
GOTO (fail);
}
}
_mongoc_buffer_clear (&response->buffer, false);
/* reset the last known cursor id. */
cursor->cursor_id = 0;
if (!_mongoc_client_recv (cursor->client,
&response->rpc,
&response->buffer,
server_stream,
&cursor->error)) {
GOTO (fail);
}
if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid opcode. Expected %d, got %d.",
MONGOC_OPCODE_REPLY,
response->rpc.header.opcode);
GOTO (fail);
}
if (response->rpc.header.response_to != request_id) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid response_to for getmore. Expected %d, got %d.",
request_id,
response->rpc.header.response_to);
GOTO (fail);
}
if (!_mongoc_rpc_check_ok (&response->rpc,
cursor->client->error_api_version,
&cursor->error,
&cursor->error_doc)) {
GOTO (fail);
}
if (response->reader) {
bson_reader_destroy (response->reader);
}
cursor->cursor_id = response->rpc.reply.cursor_id;
response->reader =
bson_reader_new_from_data (response->rpc.reply.documents,
(size_t) response->rpc.reply.documents_len);
_mongoc_cursor_monitor_succeeded (cursor,
response,
bson_get_monotonic_time () - started,
false, /* not first batch */
server_stream,
"getMore");
GOTO (done);
fail:
_mongoc_cursor_monitor_failed (
cursor, bson_get_monotonic_time () - started, server_stream, "getMore");
done:
mongoc_server_stream_cleanup (server_stream);
}
#define OPT_CHECK(_type) \
do { \
if (!BSON_ITER_HOLDS_##_type (&iter)) { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"invalid option %s, should be type %s", \
key, \
#_type); \
return NULL; \
} \
} while (false)
#define OPT_CHECK_INT() \
do { \
if (!BSON_ITER_HOLDS_INT (&iter)) { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"invalid option %s, should be integer", \
key); \
return NULL; \
} \
} while (false)
#define OPT_ERR(_msg) \
do { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
_msg); \
return NULL; \
} while (false)
#define OPT_BSON_ERR(_msg) \
do { \
bson_set_error ( \
&cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, _msg); \
return NULL; \
} while (false)
#define OPT_FLAG(_flag) \
do { \
OPT_CHECK (BOOL); \
if (bson_iter_as_bool (&iter)) { \
*flags |= _flag; \
} \
} while (false)
#define PUSH_DOLLAR_QUERY() \
do { \
if (!pushed_dollar_query) { \
pushed_dollar_query = true; \
bson_append_document (query, "$query", 6, filter); \
} \
} while (false)
#define OPT_SUBDOCUMENT(_opt_name, _legacy_name) \
do { \
OPT_CHECK (DOCUMENT); \
bson_iter_document (&iter, &len, &data); \
if (!bson_init_static (&subdocument, data, (size_t) len)) { \
OPT_BSON_ERR ("Invalid '" #_opt_name "' subdocument in 'opts'."); \
} \
BSON_APPEND_DOCUMENT (query, "$" #_legacy_name, &subdocument); \
} while (false)
static bson_t *
_mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor,
mongoc_server_stream_t *stream,
bson_t *filter,
bson_t *query /* OUT */,
bson_t *fields /* OUT */,
mongoc_query_flags_t *flags /* OUT */,
int32_t *skip /* OUT */)
{
bool pushed_dollar_query;
bson_iter_t iter;
uint32_t len;
const uint8_t *data;
bson_t subdocument;
const char *key;
char *dollar_modifier;
*flags = MONGOC_QUERY_NONE;
*skip = 0;
/* assume we'll send filter straight to server, like "{a: 1}". if we find an
* opt we must add, like "sort", we push the query like "$query: {a: 1}",
* then add a query modifier for the option, in this example "$orderby".
*/
pushed_dollar_query = false;
if (!bson_iter_init (&iter, &cursor->opts)) {
OPT_BSON_ERR ("Invalid 'opts' parameter.");
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
/* most common options first */
if (!strcmp (key, MONGOC_CURSOR_PROJECTION)) {
OPT_CHECK (DOCUMENT);
bson_iter_document (&iter, &len, &data);
if (!bson_init_static (&subdocument, data, (size_t) len)) {
OPT_BSON_ERR ("Invalid 'projection' subdocument in 'opts'.");
}
bson_destroy (fields);
bson_copy_to (&subdocument, fields);
} else if (!strcmp (key, MONGOC_CURSOR_SORT)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (sort, orderby);
} else if (!strcmp (key, MONGOC_CURSOR_SKIP)) {
OPT_CHECK_INT ();
*skip = (int32_t) bson_iter_as_int64 (&iter);
}
/* the rest of the options, alphabetically */
else if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) {
OPT_FLAG (MONGOC_QUERY_PARTIAL);
} else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) {
OPT_FLAG (MONGOC_QUERY_AWAIT_DATA);
} else if (!strcmp (key, MONGOC_CURSOR_COMMENT)) {
OPT_CHECK (UTF8);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_UTF8 (query, "$comment", bson_iter_utf8 (&iter, NULL));
} else if (!strcmp (key, MONGOC_CURSOR_HINT)) {
if (BSON_ITER_HOLDS_UTF8 (&iter)) {
PUSH_DOLLAR_QUERY ();
BSON_APPEND_UTF8 (query, "$hint", bson_iter_utf8 (&iter, NULL));
} else if (BSON_ITER_HOLDS_DOCUMENT (&iter)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (hint, hint);
} else {
OPT_ERR ("Wrong type for 'hint' field in 'opts'.");
}
} else if (!strcmp (key, MONGOC_CURSOR_MAX)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (max, max);
} else if (!strcmp (key, MONGOC_CURSOR_MAX_SCAN)) {
OPT_CHECK_INT ();
PUSH_DOLLAR_QUERY ();
BSON_APPEND_INT64 (query, "$maxScan", bson_iter_as_int64 (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_MAX_TIME_MS)) {
OPT_CHECK_INT ();
PUSH_DOLLAR_QUERY ();
BSON_APPEND_INT64 (query, "$maxTimeMS", bson_iter_as_int64 (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_MIN)) {
PUSH_DOLLAR_QUERY ();
OPT_SUBDOCUMENT (min, min);
} else if (!strcmp (key, MONGOC_CURSOR_READ_CONCERN)) {
OPT_ERR ("Set readConcern on client, database, or collection,"
" not in a query.");
} else if (!strcmp (key, MONGOC_CURSOR_RETURN_KEY)) {
OPT_CHECK (BOOL);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_BOOL (query, "$returnKey", bson_iter_as_bool (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_SHOW_RECORD_ID)) {
OPT_CHECK (BOOL);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_BOOL (query, "$showDiskLoc", bson_iter_as_bool (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_SNAPSHOT)) {
OPT_CHECK (BOOL);
PUSH_DOLLAR_QUERY ();
BSON_APPEND_BOOL (query, "$snapshot", bson_iter_as_bool (&iter));
} else if (!strcmp (key, MONGOC_CURSOR_COLLATION)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
return NULL;
}
/* singleBatch limit and batchSize are handled in _mongoc_n_return,
* exhaust noCursorTimeout oplogReplay tailable in _mongoc_cursor_flags
* maxAwaitTimeMS is handled in _mongoc_cursor_prepare_getmore_command
* sessionId is used to retrieve the mongoc_client_session_t
*/
else if (strcmp (key, MONGOC_CURSOR_SINGLE_BATCH) &&
strcmp (key, MONGOC_CURSOR_LIMIT) &&
strcmp (key, MONGOC_CURSOR_BATCH_SIZE) &&
strcmp (key, MONGOC_CURSOR_EXHAUST) &&
strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT) &&
strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY) &&
strcmp (key, MONGOC_CURSOR_TAILABLE) &&
strcmp (key, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) {
/* pass unrecognized options to server, prefixed with $ */
PUSH_DOLLAR_QUERY ();
dollar_modifier = bson_strdup_printf ("$%s", key);
if (!bson_append_iter (query, dollar_modifier, -1, &iter)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Error adding \"%s\" to query",
dollar_modifier);
bson_free (dollar_modifier);
return NULL;
}
bson_free (dollar_modifier);
}
}
if (!_mongoc_cursor_opts_to_flags (cursor, stream, flags)) {
/* cursor->error is set */
return NULL;
}
return pushed_dollar_query ? query : filter;
}
#undef OPT_CHECK
#undef OPT_ERR
#undef OPT_BSON_ERR
#undef OPT_FLAG
#undef OPT_SUBDOCUMENT
bool
_mongoc_cursor_op_query_find (mongoc_cursor_t *cursor,
bson_t *filter,
mongoc_cursor_response_legacy_t *response)
{
int64_t started;
uint32_t request_id;
mongoc_rpc_t rpc;
const bson_t *query_ptr;
bson_t query = BSON_INITIALIZER;
bson_t fields = BSON_INITIALIZER;
mongoc_query_flags_t flags;
mongoc_assemble_query_result_t result = ASSEMBLE_QUERY_RESULT_INIT;
bool succeeded = false;
mongoc_server_stream_t *server_stream;
ENTRY;
server_stream = _mongoc_cursor_fetch_stream (cursor);
if (!server_stream) {
return false;
}
started = bson_get_monotonic_time ();
/* When the user explicitly provides a readConcern -- but the server
* doesn't support readConcern, we must error:
* https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.rst#errors-1
*/
if (cursor->read_concern->level != NULL &&
server_stream->sd->max_wire_version < WIRE_VERSION_READ_CONCERN) {
bson_set_error (&cursor->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support readConcern");
GOTO (done);
}
cursor->operation_id = ++cursor->client->cluster.operation_id;
request_id = ++cursor->client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_QUERY;
rpc.query.flags = MONGOC_QUERY_NONE;
rpc.query.collection = cursor->ns;
rpc.query.skip = 0;
rpc.query.n_return = 0;
rpc.query.fields = NULL;
query_ptr = _mongoc_cursor_parse_opts_for_op_query (
cursor, server_stream, filter, &query, &fields, &flags, &rpc.query.skip);
if (!query_ptr) {
/* invalid opts. cursor->error is set */
GOTO (done);
}
assemble_query (
cursor->read_prefs, server_stream, query_ptr, flags, &result);
rpc.query.query = bson_get_data (result.assembled_query);
rpc.query.flags = result.flags;
rpc.query.n_return = _mongoc_n_return (cursor);
if (!bson_empty (&fields)) {
rpc.query.fields = bson_get_data (&fields);
}
/* cursor from mongoc_collection_find[_with_opts] is about to send its
* initial OP_QUERY to pre-3.2 MongoDB */
if (!_mongoc_cursor_monitor_legacy_query (cursor, filter, server_stream)) {
GOTO (done);
}
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&cursor->client->cluster, &rpc, server_stream, &cursor->error)) {
GOTO (done);
}
_mongoc_buffer_clear (&response->buffer, false);
if (!_mongoc_client_recv (cursor->client,
&response->rpc,
&response->buffer,
server_stream,
&cursor->error)) {
GOTO (done);
}
if (response->rpc.header.opcode != MONGOC_OPCODE_REPLY) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid opcode. Expected %d, got %d.",
MONGOC_OPCODE_REPLY,
response->rpc.header.opcode);
GOTO (done);
}
if (response->rpc.header.response_to != request_id) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid response_to for query. Expected %d, got %d.",
request_id,
response->rpc.header.response_to);
GOTO (done);
}
if (!_mongoc_rpc_check_ok (&response->rpc,
cursor->client->error_api_version,
&cursor->error,
&cursor->error_doc)) {
GOTO (done);
}
if (response->reader) {
bson_reader_destroy (response->reader);
}
cursor->cursor_id = response->rpc.reply.cursor_id;
response->reader =
bson_reader_new_from_data (response->rpc.reply.documents,
(size_t) response->rpc.reply.documents_len);
if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) {
cursor->in_exhaust = true;
cursor->client->in_exhaust = true;
}
_mongoc_cursor_monitor_succeeded (cursor,
response,
bson_get_monotonic_time () - started,
true, /* first_batch */
server_stream,
"find");
succeeded = true;
done:
if (!succeeded) {
_mongoc_cursor_monitor_failed (
cursor, bson_get_monotonic_time () - started, server_stream, "find");
}
mongoc_server_stream_cleanup (server_stream);
assemble_query_result_cleanup (&result);
bson_destroy (&query);
bson_destroy (&fields);
return succeeded;
}
void
_mongoc_cursor_response_legacy_init (mongoc_cursor_response_legacy_t *response)
{
_mongoc_buffer_init (&response->buffer, NULL, 0, NULL, NULL);
}
void
_mongoc_cursor_response_legacy_destroy (
mongoc_cursor_response_legacy_t *response)
{
if (response->reader) {
bson_reader_destroy (response->reader);
response->reader = NULL;
}
_mongoc_buffer_destroy (&response->buffer);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
index 2aa8164c..58f87896 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c
@@ -1,1791 +1,1818 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-client-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-error.h"
#include "mongoc-error-private.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-aggregate-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "cursor"
#define CURSOR_FAILED(cursor_) ((cursor_)->error.domain != 0)
static bool
_translate_query_opt (const char *query_field,
const char **cmd_field,
int *len);
bool
_mongoc_cursor_set_opt_int64 (mongoc_cursor_t *cursor,
const char *option,
int64_t value)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
if (!BSON_ITER_HOLDS_INT64 (&iter)) {
return false;
}
bson_iter_overwrite_int64 (&iter, value);
return true;
}
return BSON_APPEND_INT64 (&cursor->opts, option, value);
}
static int64_t
_mongoc_cursor_get_opt_int64 (const mongoc_cursor_t *cursor,
const char *option,
int64_t default_value)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
return bson_iter_as_int64 (&iter);
}
return default_value;
}
static bool
_mongoc_cursor_set_opt_bool (mongoc_cursor_t *cursor,
const char *option,
bool value)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
if (!BSON_ITER_HOLDS_BOOL (&iter)) {
return false;
}
bson_iter_overwrite_bool (&iter, value);
return true;
}
return BSON_APPEND_BOOL (&cursor->opts, option, value);
}
bool
_mongoc_cursor_get_opt_bool (const mongoc_cursor_t *cursor, const char *option)
{
bson_iter_t iter;
if (bson_iter_init_find (&iter, &cursor->opts, option)) {
return bson_iter_as_bool (&iter);
}
return false;
}
int32_t
_mongoc_n_return (mongoc_cursor_t *cursor)
{
int64_t limit;
int64_t batch_size;
int64_t n_return;
/* calculate numberToReturn according to:
* https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#combining-limit-and-batch-size-for-the-wire-protocol
*/
limit = mongoc_cursor_get_limit (cursor);
batch_size = mongoc_cursor_get_batch_size (cursor);
if (limit < 0) {
n_return = limit;
} else if (limit == 0) {
n_return = batch_size;
} else if (batch_size == 0) {
n_return = limit;
} else if (limit < batch_size) {
n_return = limit;
} else {
n_return = batch_size;
}
/* if a specified limit exists, account for documents already returned. */
if (limit > 0 && cursor->count) {
int64_t remaining = limit - cursor->count;
/* remaining can be 0 if we have retrieved "limit" documents, but still
* have a cursor id: SERVER-21086. use nonzero batchSize to fetch final
* empty batch and trigger server to close cursor. */
if (remaining <= 0) {
return 1;
}
n_return = BSON_MIN (n_return, remaining);
}
/* check boundary conditions */
if (n_return < INT32_MIN) {
return INT32_MIN;
} else if (n_return > INT32_MAX) {
return INT32_MAX;
} else {
return (int32_t) n_return;
}
}
void
_mongoc_set_cursor_ns (mongoc_cursor_t *cursor, const char *ns, uint32_t nslen)
{
const char *dot;
bson_free (cursor->ns);
cursor->ns = bson_strndup (ns, nslen);
cursor->nslen = nslen;
dot = strstr (cursor->ns, ".");
if (dot) {
cursor->dblen = (uint32_t) (dot - cursor->ns);
} else {
/* a database name with no collection name */
cursor->dblen = cursor->nslen;
}
}
/* return first key beginning with $, or NULL. precondition: bson is valid. */
static const char *
_first_dollar_field (const bson_t *bson)
{
bson_iter_t iter;
const char *key;
BSON_ASSERT (bson_iter_init (&iter, bson));
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (key[0] == '$') {
return key;
}
}
return NULL;
}
/* if src is non-NULL, it is validated and copied to dst. returns false and
* sets the cursor error if validation fails. */
bool
_mongoc_cursor_check_and_copy_to (mongoc_cursor_t *cursor,
const char *err_prefix,
const bson_t *src,
bson_t *dst)
{
bson_error_t validate_err;
bson_init (dst);
if (src) {
if (!bson_validate_with_error (
src, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Invalid %s: %s",
err_prefix,
validate_err.message);
return false;
}
bson_destroy (dst);
bson_copy_to (src, dst);
}
return true;
}
mongoc_cursor_t *
_mongoc_cursor_new_with_opts (mongoc_client_t *client,
const char *db_and_collection,
const bson_t *opts,
const mongoc_read_prefs_t *user_prefs,
const mongoc_read_prefs_t *default_prefs,
const mongoc_read_concern_t *read_concern)
{
mongoc_cursor_t *cursor;
mongoc_topology_description_type_t td_type;
uint32_t server_id;
mongoc_read_concern_t *read_concern_local = NULL;
bson_error_t validate_err;
const char *dollar_field;
bson_iter_t iter;
ENTRY;
BSON_ASSERT (client);
cursor = (mongoc_cursor_t *) bson_malloc0 (sizeof *cursor);
cursor->client = client;
cursor->state = UNPRIMED;
cursor->client_generation = client->generation;
cursor->is_aggr_with_write_stage = false;
bson_init (&cursor->opts);
bson_init (&cursor->error_doc);
if (opts) {
if (!bson_validate_with_error (
opts, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Invalid opts: %s",
validate_err.message);
GOTO (finish);
}
dollar_field = _first_dollar_field (opts);
if (dollar_field) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot use $-modifiers in opts: \"%s\"",
dollar_field);
GOTO (finish);
}
if (bson_iter_init_find (&iter, opts, "sessionId")) {
if (!_mongoc_client_session_from_iter (
client, &iter, &cursor->client_session, &cursor->error)) {
GOTO (finish);
}
cursor->explicit_session = true;
}
if (bson_iter_init_find (&iter, opts, "readConcern")) {
read_concern_local =
_mongoc_read_concern_new_from_iter (&iter, &cursor->error);
if (!read_concern_local) {
/* invalid read concern */
GOTO (finish);
}
read_concern = read_concern_local;
}
/* true if there's a valid serverId or no serverId, false on err */
if (!_mongoc_get_server_id_from_opts (opts,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
&server_id,
&cursor->error)) {
GOTO (finish);
}
if (server_id) {
(void) mongoc_cursor_set_hint (cursor, server_id);
}
bson_copy_to_excluding_noinit (opts,
&cursor->opts,
"serverId",
"sessionId",
"bypassDocumentValidation",
NULL);
/* only include bypassDocumentValidation if it's true */
if (bson_iter_init_find (&iter, opts, "bypassDocumentValidation") &&
bson_iter_as_bool (&iter)) {
BSON_APPEND_BOOL (&cursor->opts, "bypassDocumentValidation", true);
}
}
if (_mongoc_client_session_in_txn (cursor->client_session)) {
if (!IS_PREF_PRIMARY (user_prefs)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Read preference in a transaction must be primary");
GOTO (finish);
}
cursor->read_prefs =
mongoc_read_prefs_copy (cursor->client_session->txn.opts.read_prefs);
if (bson_has_field (opts, "readConcern")) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot set read concern after starting transaction");
GOTO (finish);
}
} else if (user_prefs) {
cursor->read_prefs = mongoc_read_prefs_copy (user_prefs);
} else if (default_prefs) {
cursor->read_prefs = mongoc_read_prefs_copy (default_prefs);
} else {
cursor->read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
}
cursor->read_concern = read_concern ? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
if (db_and_collection) {
_mongoc_set_cursor_ns (
cursor, db_and_collection, (uint32_t) strlen (db_and_collection));
}
if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) {
if (_mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot specify both 'exhaust' and 'limit'.");
GOTO (finish);
}
td_type = _mongoc_topology_get_type (client->topology);
if (td_type == MONGOC_TOPOLOGY_SHARDED) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot use exhaust cursor with sharded cluster.");
GOTO (finish);
}
}
(void) _mongoc_read_prefs_validate (cursor->read_prefs, &cursor->error);
finish:
mongoc_read_concern_destroy (read_concern_local);
mongoc_counter_cursors_active_inc ();
RETURN (cursor);
}
static bool
_translate_query_opt (const char *query_field, const char **cmd_field, int *len)
{
if (query_field[0] != '$') {
*cmd_field = query_field;
*len = -1;
return true;
}
/* strip the leading '$' */
query_field++;
if (!strcmp (MONGOC_CURSOR_ORDERBY, query_field)) {
*cmd_field = MONGOC_CURSOR_SORT;
*len = MONGOC_CURSOR_SORT_LEN;
} else if (!strcmp (MONGOC_CURSOR_SHOW_DISK_LOC,
query_field)) { /* <= MongoDb 3.0 */
*cmd_field = MONGOC_CURSOR_SHOW_RECORD_ID;
*len = MONGOC_CURSOR_SHOW_RECORD_ID_LEN;
} else if (!strcmp (MONGOC_CURSOR_HINT, query_field)) {
*cmd_field = MONGOC_CURSOR_HINT;
*len = MONGOC_CURSOR_HINT_LEN;
} else if (!strcmp (MONGOC_CURSOR_COMMENT, query_field)) {
*cmd_field = MONGOC_CURSOR_COMMENT;
*len = MONGOC_CURSOR_COMMENT_LEN;
} else if (!strcmp (MONGOC_CURSOR_MAX_SCAN, query_field)) {
*cmd_field = MONGOC_CURSOR_MAX_SCAN;
*len = MONGOC_CURSOR_MAX_SCAN_LEN;
} else if (!strcmp (MONGOC_CURSOR_MAX_TIME_MS, query_field)) {
*cmd_field = MONGOC_CURSOR_MAX_TIME_MS;
*len = MONGOC_CURSOR_MAX_TIME_MS_LEN;
} else if (!strcmp (MONGOC_CURSOR_MAX, query_field)) {
*cmd_field = MONGOC_CURSOR_MAX;
*len = MONGOC_CURSOR_MAX_LEN;
} else if (!strcmp (MONGOC_CURSOR_MIN, query_field)) {
*cmd_field = MONGOC_CURSOR_MIN;
*len = MONGOC_CURSOR_MIN_LEN;
} else if (!strcmp (MONGOC_CURSOR_RETURN_KEY, query_field)) {
*cmd_field = MONGOC_CURSOR_RETURN_KEY;
*len = MONGOC_CURSOR_RETURN_KEY_LEN;
} else if (!strcmp (MONGOC_CURSOR_SNAPSHOT, query_field)) {
*cmd_field = MONGOC_CURSOR_SNAPSHOT;
*len = MONGOC_CURSOR_SNAPSHOT_LEN;
} else {
/* not a special command field, must be a query operator like $or */
return false;
}
return true;
}
/* set up a new opt bson from older ways of specifying options.
* secondary_ok may be NULL.
* error may be NULL.
*/
void
_mongoc_cursor_flags_to_opts (mongoc_query_flags_t qflags,
bson_t *opts, /* IN/OUT */
bool *secondary_ok /* OUT */)
{
ENTRY;
BSON_ASSERT (opts);
if (secondary_ok) {
*secondary_ok = !!(qflags & MONGOC_QUERY_SECONDARY_OK);
}
if (qflags & MONGOC_QUERY_TAILABLE_CURSOR) {
bson_append_bool (
opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true);
}
if (qflags & MONGOC_QUERY_OPLOG_REPLAY) {
bson_append_bool (opts,
MONGOC_CURSOR_OPLOG_REPLAY,
MONGOC_CURSOR_OPLOG_REPLAY_LEN,
true);
}
if (qflags & MONGOC_QUERY_NO_CURSOR_TIMEOUT) {
bson_append_bool (opts,
MONGOC_CURSOR_NO_CURSOR_TIMEOUT,
MONGOC_CURSOR_NO_CURSOR_TIMEOUT_LEN,
true);
}
if (qflags & MONGOC_QUERY_AWAIT_DATA) {
bson_append_bool (
opts, MONGOC_CURSOR_AWAIT_DATA, MONGOC_CURSOR_AWAIT_DATA_LEN, true);
}
if (qflags & MONGOC_QUERY_EXHAUST) {
bson_append_bool (
opts, MONGOC_CURSOR_EXHAUST, MONGOC_CURSOR_EXHAUST_LEN, true);
}
if (qflags & MONGOC_QUERY_PARTIAL) {
bson_append_bool (opts,
MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS,
MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS_LEN,
true);
}
}
/* Checks if the passed query was wrapped in a $query, and if so, parses the
* query modifiers:
* https://docs.mongodb.com/manual/reference/operator/query-modifier/
* and translates them to find command options:
* https://docs.mongodb.com/manual/reference/command/find/
* opts must be initialized, and may already have options set.
* unwrapped must be uninitialized, and will be initialized at return.
* Returns true if query was unwrapped. */
bool
_mongoc_cursor_translate_dollar_query_opts (const bson_t *query,
bson_t *opts,
bson_t *unwrapped,
bson_error_t *error)
{
bool has_filter = false;
const char *key;
bson_iter_t iter;
const char *opt_key;
int len;
uint32_t data_len;
const uint8_t *data;
bson_error_t error_local = {0};
ENTRY;
BSON_ASSERT (query);
BSON_ASSERT (opts);
/* If the query is explicitly specified wrapped in $query, unwrap it and
* translate the options to new options. */
if (bson_has_field (query, "$query")) {
/* like "{$query: {a: 1}, $orderby: {b: 1}, $otherModifier: true}" */
if (!bson_iter_init (&iter, query)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid BSON in query document");
GOTO (done);
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (key[0] != '$') {
bson_set_error (&error_local,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot mix $query with non-dollar field '%s'",
key);
GOTO (done);
}
if (!strcmp (key, "$query")) {
/* set "filter" to the incoming document's "$query" */
bson_iter_document (&iter, &data_len, &data);
if (!bson_init_static (unwrapped, data, (size_t) data_len)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid BSON in $query subdocument");
GOTO (done);
}
has_filter = true;
} else if (_translate_query_opt (key, &opt_key, &len)) {
/* "$orderby" becomes "sort", etc., "$unknown" -> "unknown" */
if (!bson_append_iter (opts, opt_key, len, &iter)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Error adding \"%s\" to query",
opt_key);
}
} else {
/* strip leading "$" */
if (!bson_append_iter (opts, key + 1, -1, &iter)) {
bson_set_error (&error_local,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Error adding \"%s\" to query",
key);
}
}
}
}
done:
if (error) {
memcpy (error, &error_local, sizeof (bson_error_t));
}
if (!has_filter) {
bson_init (unwrapped);
}
RETURN (has_filter);
}
void
mongoc_cursor_destroy (mongoc_cursor_t *cursor)
{
char *db;
ENTRY;
if (!cursor) {
EXIT;
}
if (cursor->impl.destroy) {
cursor->impl.destroy (&cursor->impl);
}
/* Always close the socket for an exhaust cursor, even if the client was
* reset with mongoc_client_reset. That prevents further use of that socket.
*/
if (cursor->in_exhaust) {
cursor->client->in_exhaust = false;
if (cursor->state != DONE) {
/* The only way to stop an exhaust cursor is to kill the connection
*/
mongoc_cluster_disconnect_node (&cursor->client->cluster,
cursor->server_id);
}
} else if (cursor->client_generation == cursor->client->generation) {
if (cursor->cursor_id) {
db = bson_strndup (cursor->ns, cursor->dblen);
_mongoc_client_kill_cursor (cursor->client,
cursor->server_id,
cursor->cursor_id,
cursor->operation_id,
db,
cursor->ns + cursor->dblen + 1,
cursor->client_session);
bson_free (db);
}
}
if (cursor->client_session && !cursor->explicit_session) {
mongoc_client_session_destroy (cursor->client_session);
}
mongoc_read_prefs_destroy (cursor->read_prefs);
mongoc_read_concern_destroy (cursor->read_concern);
mongoc_write_concern_destroy (cursor->write_concern);
bson_destroy (&cursor->opts);
bson_destroy (&cursor->error_doc);
bson_free (cursor->ns);
bson_free (cursor);
mongoc_counter_cursors_active_dec ();
mongoc_counter_cursors_disposed_inc ();
EXIT;
}
mongoc_server_stream_t *
_mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor)
{
mongoc_server_stream_t *server_stream;
bson_t reply;
ENTRY;
if (cursor->server_id) {
/* We already did server selection once before. Reuse the prior
* selection to create a new stream on the same server. */
server_stream =
mongoc_cluster_stream_for_server (&cursor->client->cluster,
cursor->server_id,
true /* reconnect_ok */,
cursor->client_session,
&reply,
&cursor->error);
if (server_stream) {
/* Also restore whether primary read preference was forced by server
* selection */
server_stream->must_use_primary = cursor->must_use_primary;
}
} else {
server_stream =
mongoc_cluster_stream_for_reads (&cursor->client->cluster,
cursor->read_prefs,
cursor->client_session,
&reply,
cursor->is_aggr_with_write_stage,
&cursor->error);
if (server_stream) {
/* Remember the selected server_id and whether primary read mode was
* forced so that we can re-create an equivalent server_stream at a
* later time */
cursor->server_id = server_stream->sd->id;
cursor->must_use_primary = server_stream->must_use_primary;
}
}
if (!server_stream) {
bson_destroy (&cursor->error_doc);
bson_copy_to (&reply, &cursor->error_doc);
bson_destroy (&reply);
}
RETURN (server_stream);
}
bool
_mongoc_cursor_monitor_command (mongoc_cursor_t *cursor,
mongoc_server_stream_t *server_stream,
const bson_t *cmd,
const char *cmd_name)
{
mongoc_client_t *client;
mongoc_apm_command_started_t event;
char *db;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.started) {
/* successful */
RETURN (true);
}
db = bson_strndup (cursor->ns, cursor->dblen);
mongoc_apm_command_started_init (&event,
cmd,
db,
cmd_name,
client->cluster.request_id,
cursor->operation_id,
&server_stream->sd->host,
server_stream->sd->id,
&server_stream->sd->service_id,
+ server_stream->sd->server_connection_id,
NULL,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
bson_free (db);
RETURN (true);
}
/* append array of docs from current cursor batch */
static void
_mongoc_cursor_append_docs_array (mongoc_cursor_t *cursor,
bson_t *docs,
mongoc_cursor_response_legacy_t *response)
{
bool eof = false;
char str[16];
const char *key;
uint32_t i = 0;
size_t keylen;
const bson_t *doc;
while ((doc = bson_reader_read (response->reader, &eof))) {
keylen = bson_uint32_to_string (i, &key, str, sizeof str);
bson_append_document (docs, key, (int) keylen, doc);
}
bson_reader_reset (response->reader);
}
void
_mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor,
mongoc_cursor_response_legacy_t *response,
int64_t duration,
bool first_batch,
mongoc_server_stream_t *stream,
const char *cmd_name)
{
bson_t docs_array;
mongoc_apm_command_succeeded_t event;
mongoc_client_t *client;
bson_t reply;
bson_t reply_cursor;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.succeeded) {
EXIT;
}
/* we sent OP_QUERY/OP_GETMORE, fake a reply to find/getMore command:
* {ok: 1, cursor: {id: 17, ns: "...", first/nextBatch: [ ... docs ... ]}}
*/
bson_init (&docs_array);
_mongoc_cursor_append_docs_array (cursor, &docs_array, response);
bson_init (&reply);
bson_append_int32 (&reply, "ok", 2, 1);
bson_append_document_begin (&reply, "cursor", 6, &reply_cursor);
bson_append_int64 (&reply_cursor, "id", 2, mongoc_cursor_get_id (cursor));
bson_append_utf8 (&reply_cursor, "ns", 2, cursor->ns, cursor->nslen);
bson_append_array (&reply_cursor,
first_batch ? "firstBatch" : "nextBatch",
first_batch ? 10 : 9,
&docs_array);
bson_append_document_end (&reply, &reply_cursor);
bson_destroy (&docs_array);
mongoc_apm_command_succeeded_init (&event,
duration,
&reply,
cmd_name,
client->cluster.request_id,
cursor->operation_id,
&stream->sd->host,
stream->sd->id,
&stream->sd->service_id,
+ stream->sd->server_connection_id,
false,
client->apm_context);
client->apm_callbacks.succeeded (&event);
mongoc_apm_command_succeeded_cleanup (&event);
bson_destroy (&reply);
EXIT;
}
void
_mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor,
int64_t duration,
mongoc_server_stream_t *stream,
const char *cmd_name)
{
mongoc_apm_command_failed_t event;
mongoc_client_t *client;
bson_t reply;
ENTRY;
client = cursor->client;
if (!client->apm_callbacks.failed) {
EXIT;
}
/* we sent OP_QUERY/OP_GETMORE, fake a reply to find/getMore command:
* {ok: 0}
*/
bson_init (&reply);
bson_append_int32 (&reply, "ok", 2, 0);
mongoc_apm_command_failed_init (&event,
duration,
cmd_name,
&cursor->error,
&reply,
client->cluster.request_id,
cursor->operation_id,
&stream->sd->host,
stream->sd->id,
&stream->sd->service_id,
+ stream->sd->server_connection_id,
false,
client->apm_context);
client->apm_callbacks.failed (&event);
mongoc_apm_command_failed_cleanup (&event);
bson_destroy (&reply);
EXIT;
}
#define ADD_FLAG(_flags, _value) \
do { \
if (!BSON_ITER_HOLDS_BOOL (&iter)) { \
bson_set_error (&cursor->error, \
MONGOC_ERROR_COMMAND, \
MONGOC_ERROR_COMMAND_INVALID_ARG, \
"invalid option %s, should be type bool", \
key); \
return false; \
} \
if (bson_iter_as_bool (&iter)) { \
*_flags |= _value; \
} \
} while (false);
bool
_mongoc_cursor_opts_to_flags (mongoc_cursor_t *cursor,
mongoc_server_stream_t *stream,
mongoc_query_flags_t *flags /* OUT */)
{
bson_iter_t iter;
const char *key;
*flags = MONGOC_QUERY_NONE;
if (!bson_iter_init (&iter, &cursor->opts)) {
bson_set_error (&cursor->error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) {
ADD_FLAG (flags, MONGOC_QUERY_PARTIAL);
} else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) {
ADD_FLAG (flags, MONGOC_QUERY_AWAIT_DATA);
} else if (!strcmp (key, MONGOC_CURSOR_EXHAUST)) {
ADD_FLAG (flags, MONGOC_QUERY_EXHAUST);
} else if (!strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT)) {
ADD_FLAG (flags, MONGOC_QUERY_NO_CURSOR_TIMEOUT);
} else if (!strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY)) {
ADD_FLAG (flags, MONGOC_QUERY_OPLOG_REPLAY);
} else if (!strcmp (key, MONGOC_CURSOR_TAILABLE)) {
ADD_FLAG (flags, MONGOC_QUERY_TAILABLE_CURSOR);
}
}
if (cursor->secondary_ok) {
*flags |= MONGOC_QUERY_SECONDARY_OK;
} else if (cursor->server_id &&
(stream->topology_type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY ||
stream->topology_type == MONGOC_TOPOLOGY_RS_NO_PRIMARY) &&
stream->sd->type != MONGOC_SERVER_RS_PRIMARY) {
*flags |= MONGOC_QUERY_SECONDARY_OK;
}
return true;
}
bool
_mongoc_cursor_run_command (mongoc_cursor_t *cursor,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bool retry_prohibited)
{
mongoc_server_stream_t *server_stream;
bson_iter_t iter;
mongoc_cmd_parts_t parts;
const char *cmd_name;
bool is_primary;
mongoc_read_prefs_t *prefs = NULL;
char *db = NULL;
mongoc_session_opt_t *session_opts;
bool ret = false;
bool is_retryable = true;
ENTRY;
mongoc_cmd_parts_init (
&parts, cursor->client, db, MONGOC_QUERY_NONE, command);
parts.is_read_command = true;
parts.read_prefs = cursor->read_prefs;
parts.assembled.operation_id = cursor->operation_id;
server_stream = _mongoc_cursor_fetch_stream (cursor);
if (!server_stream) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
if (opts) {
if (!bson_iter_init (&iter, opts)) {
_mongoc_bson_init_if_set (reply);
bson_set_error (&cursor->error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid BSON in opts document");
GOTO (done);
}
if (!mongoc_cmd_parts_append_opts (&parts,
&iter,
server_stream->sd->max_wire_version,
&cursor->error)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) {
MONGOC_WARNING (
"exhaust cursors not supported with OP_MSG, using normal "
"cursor instead");
}
}
if (parts.assembled.session) {
/* initial query/aggregate/etc, and opts contains "sessionId" */
BSON_ASSERT (!cursor->client_session);
BSON_ASSERT (!cursor->explicit_session);
cursor->client_session = parts.assembled.session;
cursor->explicit_session = true;
} else if (cursor->client_session) {
/* a getMore with implicit or explicit session already acquired */
mongoc_cmd_parts_set_session (&parts, cursor->client_session);
} else {
/* try to create an implicit session. not causally consistent. we keep
* the session but leave cursor->explicit_session as 0, so we use the
* same lsid for getMores but destroy the session when the cursor dies.
*/
session_opts = mongoc_session_opts_new ();
mongoc_session_opts_set_causal_consistency (session_opts, false);
/* returns NULL if sessions aren't supported. ignore errors. */
cursor->client_session =
mongoc_client_start_session (cursor->client, session_opts, NULL);
mongoc_cmd_parts_set_session (&parts, cursor->client_session);
mongoc_session_opts_destroy (session_opts);
}
if (!mongoc_cmd_parts_set_read_concern (&parts,
cursor->read_concern,
server_stream->sd->max_wire_version,
&cursor->error)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
db = bson_strndup (cursor->ns, cursor->dblen);
parts.assembled.db_name = db;
if (!_mongoc_cursor_opts_to_flags (
cursor, server_stream, &parts.user_query_flags)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
/* Exhaust cursors with OP_MSG not yet supported; fallback to normal cursor.
* user_query_flags is unused in OP_MSG, so this technically has no effect,
* but is done anyways to ensure the query flags match handling of options.
*/
if (parts.user_query_flags & MONGOC_QUERY_EXHAUST) {
parts.user_query_flags ^= MONGOC_QUERY_EXHAUST;
}
/* we might use mongoc_cursor_set_hint to target a secondary but have no
* read preference, so the secondary rejects the read. same if we have a
* direct connection to a secondary (topology type "single"). with
* OP_QUERY we handle this by setting secondaryOk. here we use
* $readPreference.
*/
cmd_name = _mongoc_get_command_name (command);
is_primary =
!cursor->read_prefs || cursor->read_prefs->mode == MONGOC_READ_PRIMARY;
if (strcmp (cmd_name, "getMore") != 0 &&
server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG &&
is_primary && parts.user_query_flags & MONGOC_QUERY_SECONDARY_OK) {
parts.read_prefs = prefs =
mongoc_read_prefs_new (MONGOC_READ_PRIMARY_PREFERRED);
} else {
parts.read_prefs = cursor->read_prefs;
}
is_retryable = _is_retryable_read (&parts, server_stream);
if (!strcmp (cmd_name, "getMore")) {
is_retryable = false;
}
if (!strcmp (cmd_name, "aggregate")) {
bson_iter_t pipeline_iter;
if (bson_iter_init_find (&pipeline_iter, command, "pipeline") &&
BSON_ITER_HOLDS_ARRAY (&pipeline_iter) &&
bson_iter_recurse (&pipeline_iter, &pipeline_iter)) {
if (_has_write_key (&pipeline_iter)) {
is_retryable = false;
}
}
}
if (is_retryable && retry_prohibited) {
is_retryable = false;
}
if (cursor->write_concern &&
!mongoc_write_concern_is_default (cursor->write_concern) &&
server_stream->sd->max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN) {
parts.assembled.is_acknowledged =
mongoc_write_concern_is_acknowledged (cursor->write_concern);
mongoc_write_concern_append (cursor->write_concern, &parts.extra);
}
if (!mongoc_cmd_parts_assemble (&parts, server_stream, &cursor->error)) {
_mongoc_bson_init_if_set (reply);
GOTO (done);
}
retry:
ret = mongoc_cluster_run_command_monitored (
&cursor->client->cluster, &parts.assembled, reply, &cursor->error);
if (ret) {
memset (&cursor->error, 0, sizeof (bson_error_t));
}
if (is_retryable &&
_mongoc_read_error_get_type (ret, &cursor->error, reply) ==
MONGOC_READ_ERR_RETRY) {
is_retryable = false;
mongoc_server_stream_cleanup (server_stream);
BSON_ASSERT (!cursor->is_aggr_with_write_stage &&
"Cannot attempt a retry on an aggregate operation that "
"contains write stages");
server_stream =
mongoc_cluster_stream_for_reads (&cursor->client->cluster,
cursor->read_prefs,
cursor->client_session,
reply,
/* Not aggregate-with-write */ false,
&cursor->error);
if (server_stream &&
server_stream->sd->max_wire_version >= WIRE_VERSION_RETRY_READS) {
cursor->server_id = server_stream->sd->id;
parts.assembled.server_stream = server_stream;
bson_destroy (reply);
GOTO (retry);
}
}
if (cursor->error.domain) {
bson_destroy (&cursor->error_doc);
bson_copy_to (reply, &cursor->error_doc);
}
/* Read and Write Concern Spec: "Drivers SHOULD parse server replies for a
* "writeConcernError" field and report the error only in command-specific
* helper methods that take a separate write concern parameter or an options
* parameter that may contain a write concern option.
*
* Only command helpers with names like "_with_write_concern" can create
* cursors with a non-NULL write_concern field.
*/
if (ret && cursor->write_concern) {
ret = !_mongoc_parse_wc_err (reply, &cursor->error);
}
done:
mongoc_server_stream_cleanup (server_stream);
mongoc_cmd_parts_cleanup (&parts);
mongoc_read_prefs_destroy (prefs);
bson_free (db);
return ret;
}
void
_mongoc_cursor_collection (const mongoc_cursor_t *cursor,
const char **collection,
int *collection_len)
{
/* ns is like "db.collection". Collection name is located past the ".". */
*collection = cursor->ns + (cursor->dblen + 1);
/* Collection name's length is ns length, minus length of db name and ".". */
*collection_len = cursor->nslen - cursor->dblen - 1;
BSON_ASSERT (*collection_len > 0);
}
void
_mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor,
const bson_t *filter,
bson_t *command)
{
const char *collection;
int collection_len;
_mongoc_cursor_collection (cursor, &collection, &collection_len);
bson_append_utf8 (command,
MONGOC_CURSOR_FIND,
MONGOC_CURSOR_FIND_LEN,
collection,
collection_len);
bson_append_document (
command, MONGOC_CURSOR_FILTER, MONGOC_CURSOR_FILTER_LEN, filter);
}
bool
mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error)
{
ENTRY;
RETURN (mongoc_cursor_error_document (cursor, error, NULL));
}
bool
mongoc_cursor_error_document (mongoc_cursor_t *cursor,
bson_error_t *error,
const bson_t **doc)
{
ENTRY;
BSON_ASSERT (cursor);
if (BSON_UNLIKELY (CURSOR_FAILED (cursor))) {
bson_set_error (error,
cursor->error.domain,
cursor->error.code,
"%s",
cursor->error.message);
if (doc) {
*doc = &cursor->error_doc;
}
RETURN (true);
}
if (doc) {
*doc = NULL;
}
RETURN (false);
}
static mongoc_cursor_state_t
_call_transition (mongoc_cursor_t *cursor)
{
mongoc_cursor_state_t state = cursor->state;
_mongoc_cursor_impl_transition_t fn = NULL;
switch (state) {
case UNPRIMED:
fn = cursor->impl.prime;
break;
case IN_BATCH:
fn = cursor->impl.pop_from_batch;
break;
case END_OF_BATCH:
fn = cursor->impl.get_next_batch;
break;
case DONE:
default:
fn = NULL;
break;
}
if (!fn) {
return DONE;
}
state = fn (cursor);
if (cursor->error.domain) {
state = DONE;
}
return state;
}
bool
mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson)
{
bool ret = false;
bool attempted_refresh = false;
ENTRY;
BSON_ASSERT (cursor);
BSON_ASSERT (bson);
TRACE ("cursor_id(%" PRId64 ")", cursor->cursor_id);
if (cursor->client_generation != cursor->client->generation) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot advance cursor after client reset");
RETURN (false);
}
if (bson) {
*bson = NULL;
}
if (CURSOR_FAILED (cursor)) {
RETURN (false);
}
if (cursor->state == DONE) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"Cannot advance a completed or failed cursor.");
RETURN (false);
}
/*
* We cannot proceed if another cursor is receiving results in exhaust mode.
*/
if (cursor->client->in_exhaust && !cursor->in_exhaust) {
bson_set_error (&cursor->error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_IN_EXHAUST,
"Another cursor derived from this client is in exhaust.");
RETURN (false);
}
cursor->current = NULL;
/* if an error was set on this cursor before calling next, transition to DONE
* immediately. */
if (cursor->error.domain) {
cursor->state = DONE;
GOTO (done);
}
while (cursor->state != DONE) {
/* even when there is no data to return, some cursors remain open and
* continue sending empty batches (e.g. a tailable or change stream
* cursor). in that case, do not attempt to get another batch. */
if (cursor->state == END_OF_BATCH) {
if (attempted_refresh) {
RETURN (false);
}
attempted_refresh = true;
}
cursor->state = _call_transition (cursor);
/* check if we received a document. */
if (cursor->current) {
*bson = cursor->current;
ret = true;
GOTO (done);
}
if (cursor->state == DONE) {
GOTO (done);
}
}
done:
cursor->count++;
RETURN (ret);
}
bool
mongoc_cursor_more (mongoc_cursor_t *cursor)
{
ENTRY;
BSON_ASSERT (cursor);
if (CURSOR_FAILED (cursor)) {
RETURN (false);
}
RETURN (cursor->state != DONE);
}
void
mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host)
{
mongoc_server_description_t const *description;
mc_shared_tpld td;
BSON_ASSERT (cursor);
BSON_ASSERT (host);
memset (host, 0, sizeof *host);
if (!cursor->server_id) {
MONGOC_WARNING ("%s(): Must send query before fetching peer.", BSON_FUNC);
return;
}
td = mc_tpld_take_ref (cursor->client->topology);
description = mongoc_topology_description_server_by_id_const (
td.ptr, cursor->server_id, &cursor->error);
mc_tpld_drop_ref (&td);
if (!description) {
return;
}
*host = description->host;
EXIT;
}
mongoc_cursor_t *
mongoc_cursor_clone (const mongoc_cursor_t *cursor)
{
mongoc_cursor_t *_clone;
BSON_ASSERT (cursor);
_clone = (mongoc_cursor_t *) bson_malloc0 (sizeof *_clone);
_clone->client = cursor->client;
_clone->nslen = cursor->nslen;
_clone->dblen = cursor->dblen;
_clone->explicit_session = cursor->explicit_session;
if (cursor->read_prefs) {
_clone->read_prefs = mongoc_read_prefs_copy (cursor->read_prefs);
}
if (cursor->read_concern) {
_clone->read_concern = mongoc_read_concern_copy (cursor->read_concern);
}
if (cursor->write_concern) {
_clone->write_concern = mongoc_write_concern_copy (cursor->write_concern);
}
if (cursor->explicit_session) {
_clone->client_session = cursor->client_session;
}
bson_copy_to (&cursor->opts, &_clone->opts);
bson_init (&_clone->error_doc);
_clone->ns = bson_strdup (cursor->ns);
/* copy the context functions by default. */
memcpy (&_clone->impl, &cursor->impl, sizeof (cursor->impl));
if (cursor->impl.clone) {
cursor->impl.clone (&_clone->impl, &cursor->impl);
}
mongoc_counter_cursors_active_inc ();
RETURN (_clone);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_cursor_is_alive --
*
* Deprecated for mongoc_cursor_more.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_cursor_is_alive (const mongoc_cursor_t *cursor) /* IN */
{
return mongoc_cursor_more ((mongoc_cursor_t *) cursor);
}
const bson_t *
mongoc_cursor_current (const mongoc_cursor_t *cursor) /* IN */
{
BSON_ASSERT (cursor);
return cursor->current;
}
void
mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size)
{
BSON_ASSERT (cursor);
_mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_BATCH_SIZE, (int64_t) batch_size);
}
uint32_t
mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor)
{
BSON_ASSERT (cursor);
return (uint32_t) _mongoc_cursor_get_opt_int64 (
cursor, MONGOC_CURSOR_BATCH_SIZE, 0);
}
bool
mongoc_cursor_set_limit (mongoc_cursor_t *cursor, int64_t limit)
{
BSON_ASSERT (cursor);
if (cursor->state == UNPRIMED) {
if (limit < 0) {
return _mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_LIMIT, -limit) &&
_mongoc_cursor_set_opt_bool (
cursor, MONGOC_CURSOR_SINGLE_BATCH, true);
} else {
return _mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_LIMIT, limit);
}
} else {
return false;
}
}
int64_t
mongoc_cursor_get_limit (const mongoc_cursor_t *cursor)
{
int64_t limit;
bool single_batch;
BSON_ASSERT (cursor);
limit = _mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0);
single_batch =
_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_SINGLE_BATCH);
if (limit > 0 && single_batch) {
limit = -limit;
}
return limit;
}
bool
mongoc_cursor_set_hint (mongoc_cursor_t *cursor, uint32_t server_id)
{
BSON_ASSERT (cursor);
if (cursor->server_id) {
MONGOC_ERROR ("mongoc_cursor_set_hint: server_id already set");
return false;
}
if (!server_id) {
MONGOC_ERROR ("mongoc_cursor_set_hint: cannot set server_id to 0");
return false;
}
cursor->server_id = server_id;
return true;
}
uint32_t
mongoc_cursor_get_hint (const mongoc_cursor_t *cursor)
{
BSON_ASSERT (cursor);
return cursor->server_id;
}
int64_t
mongoc_cursor_get_id (const mongoc_cursor_t *cursor)
{
BSON_ASSERT (cursor);
return cursor->cursor_id;
}
void
mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor,
uint32_t max_await_time_ms)
{
BSON_ASSERT (cursor);
if (cursor->state == UNPRIMED) {
_mongoc_cursor_set_opt_int64 (
cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, (int64_t) max_await_time_ms);
}
}
uint32_t
mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor)
{
bson_iter_t iter;
BSON_ASSERT (cursor);
if (bson_iter_init_find (
&iter, &cursor->opts, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) {
return (uint32_t) bson_iter_as_int64 (&iter);
}
return 0;
}
/* deprecated for mongoc_cursor_new_from_command_reply_with_opts */
mongoc_cursor_t *
mongoc_cursor_new_from_command_reply (mongoc_client_t *client,
bson_t *reply,
uint32_t server_id)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
bson_t opts = BSON_INITIALIZER;
BSON_ASSERT (client);
BSON_ASSERT (reply);
/* options are passed through by adding them to reply. */
bson_copy_to_excluding_noinit (reply,
&opts,
"cursor",
"ok",
"operationTime",
"$clusterTime",
"$gleStats",
NULL);
if (server_id) {
bson_append_int64 (&opts, "serverId", 8, server_id);
}
cursor = _mongoc_cursor_cmd_new_from_reply (client, &cmd, &opts, reply);
bson_destroy (&cmd);
bson_destroy (&opts);
return cursor;
}
mongoc_cursor_t *
mongoc_cursor_new_from_command_reply_with_opts (mongoc_client_t *client,
bson_t *reply,
const bson_t *opts)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
BSON_ASSERT (client);
BSON_ASSERT (reply);
cursor = _mongoc_cursor_cmd_new_from_reply (client, &cmd, opts, reply);
bson_destroy (&cmd);
return cursor;
}
bool
_mongoc_cursor_start_reading_response (mongoc_cursor_t *cursor,
mongoc_cursor_response_t *response)
{
bson_iter_t iter;
bson_iter_t child;
const char *ns;
uint32_t nslen;
bool in_batch = false;
if (bson_iter_init_find (&iter, &response->reply, "cursor") &&
BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child)) {
while (bson_iter_next (&child)) {
if (BSON_ITER_IS_KEY (&child, "id")) {
cursor->cursor_id = bson_iter_as_int64 (&child);
} else if (BSON_ITER_IS_KEY (&child, "ns")) {
ns = bson_iter_utf8 (&child, &nslen);
_mongoc_set_cursor_ns (cursor, ns, nslen);
} else if (BSON_ITER_IS_KEY (&child, "firstBatch") ||
BSON_ITER_IS_KEY (&child, "nextBatch")) {
if (BSON_ITER_HOLDS_ARRAY (&child) &&
bson_iter_recurse (&child, &response->batch_iter)) {
in_batch = true;
}
}
}
}
/* Driver Sessions Spec: "When an implicit session is associated with a
* cursor for use with getMore operations, the session MUST be returned to
* the pool immediately following a getMore operation that indicates that the
* cursor has been exhausted." */
if (cursor->cursor_id == 0 && cursor->client_session &&
!cursor->explicit_session) {
mongoc_client_session_destroy (cursor->client_session);
cursor->client_session = NULL;
}
return in_batch;
}
void
_mongoc_cursor_response_read (mongoc_cursor_t *cursor,
mongoc_cursor_response_t *response,
const bson_t **bson)
{
const uint8_t *data = NULL;
uint32_t data_len = 0;
ENTRY;
if (bson_iter_next (&response->batch_iter) &&
BSON_ITER_HOLDS_DOCUMENT (&response->batch_iter)) {
bson_iter_document (&response->batch_iter, &data_len, &data);
/* bson_iter_next guarantees valid BSON, so this must succeed */
BSON_ASSERT (bson_init_static (&response->current_doc, data, data_len));
*bson = &response->current_doc;
}
}
/* sets cursor error if could not get the next batch. */
void
_mongoc_cursor_response_refresh (mongoc_cursor_t *cursor,
const bson_t *command,
const bson_t *opts,
mongoc_cursor_response_t *response)
{
ENTRY;
bson_destroy (&response->reply);
/* server replies to find / aggregate with {cursor: {id: N, firstBatch: []}},
* to getMore command with {cursor: {id: N, nextBatch: []}}. */
if (_mongoc_cursor_run_command (
cursor, command, opts, &response->reply, false) &&
_mongoc_cursor_start_reading_response (cursor, response)) {
return;
}
if (!cursor->error.domain) {
bson_set_error (&cursor->error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply to %s command.",
_mongoc_get_command_name (command));
}
}
void
_mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor,
bson_t *command)
{
const char *collection;
int collection_len;
int64_t batch_size;
+ bson_iter_t iter;
bool await_data;
int64_t max_await_time_ms;
ENTRY;
_mongoc_cursor_collection (cursor, &collection, &collection_len);
bson_init (command);
bson_append_int64 (command, "getMore", 7, mongoc_cursor_get_id (cursor));
bson_append_utf8 (command, "collection", 10, collection, collection_len);
batch_size = mongoc_cursor_get_batch_size (cursor);
/* See find, getMore, and killCursors Spec for batchSize rules */
if (batch_size) {
bson_append_int64 (command,
MONGOC_CURSOR_BATCH_SIZE,
MONGOC_CURSOR_BATCH_SIZE_LEN,
abs (_mongoc_n_return (cursor)));
}
+ if (bson_iter_init_find (&iter, &cursor->opts, MONGOC_CURSOR_COMMENT) &&
+ bson_iter_value (&iter)->value_type != BSON_TYPE_EOD) {
+ const bson_value_t *comment = bson_iter_value (&iter);
+ mongoc_server_stream_t *server_stream;
+
+ /* CRUD spec: If a comment is provided, drivers MUST attach this comment
+ * to all subsequent getMore commands run on the same cursor for server
+ * versions 4.4 and above. For server versions below 4.4 drivers MUST NOT
+ * attach a comment to getMore commands.
+ *
+ * Since this function has no error reporting, we also no-op if we cannot
+ * fetch a stream. */
+ server_stream = _mongoc_cursor_fetch_stream (cursor);
+
+ if (server_stream != NULL &&
+ server_stream->sd->max_wire_version >= WIRE_VERSION_4_4) {
+ bson_append_value (
+ command, MONGOC_CURSOR_COMMENT, MONGOC_CURSOR_COMMENT_LEN, comment);
+ }
+
+ mongoc_server_stream_cleanup (server_stream);
+ }
+
/* Find, getMore And killCursors Commands Spec: "In the case of a tailable
cursor with awaitData == true the driver MUST provide a Cursor level
option named maxAwaitTimeMS (See CRUD specification for details). The
maxTimeMS option on the getMore command MUST be set to the value of the
option maxAwaitTimeMS. If no maxAwaitTimeMS is specified, the driver
SHOULD not set maxTimeMS on the getMore command."
*/
await_data = _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_TAILABLE) &&
_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_AWAIT_DATA);
if (await_data) {
max_await_time_ms = _mongoc_cursor_get_opt_int64 (
cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, 0);
if (max_await_time_ms) {
bson_append_int64 (command,
MONGOC_CURSOR_MAX_TIME_MS,
MONGOC_CURSOR_MAX_TIME_MS_LEN,
max_await_time_ms);
}
}
}
/* sets the cursor to be empty so it returns NULL on the first call to
* cursor_next but does not return an error. */
void
_mongoc_cursor_set_empty (mongoc_cursor_t *cursor)
{
memset (&cursor->error, 0, sizeof (bson_error_t));
bson_reinit (&cursor->error_doc);
cursor->state = IN_BATCH;
}
void
_mongoc_cursor_prime (mongoc_cursor_t *cursor)
{
cursor->state = cursor->impl.prime (cursor);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
similarity index 96%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
index dba953d0..63c62b14 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c
@@ -1,468 +1,466 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SASL_CYRUS
#include <string.h>
#include "mongoc-error.h"
#include "mongoc-cyrus-private.h"
#include "mongoc-util-private.h"
#include "mongoc-trace-private.h"
#include "common-b64-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "CYRUS-SASL"
bool
_mongoc_cyrus_set_mechanism (mongoc_cyrus_t *sasl,
const char *mechanism,
bson_error_t *error)
{
bson_string_t *str = bson_string_new ("");
const char **mechs = sasl_global_listmech ();
int i = 0;
bool ok = false;
BSON_ASSERT (sasl);
for (i = 0; mechs[i]; i++) {
if (!strcmp (mechs[i], mechanism)) {
ok = true;
break;
}
bson_string_append (str, mechs[i]);
if (mechs[i + 1]) {
bson_string_append (str, ",");
}
}
if (ok) {
bson_free (sasl->credentials.mechanism);
sasl->credentials.mechanism = mechanism ? bson_strdup (mechanism) : NULL;
} else {
bson_set_error (error,
MONGOC_ERROR_SASL,
SASL_NOMECH,
"SASL Failure: Unsupported mechanism by client: %s. "
"Available mechanisms: %s",
mechanism,
str->str);
}
bson_string_free (str, true);
return ok;
}
static int
_mongoc_cyrus_get_pass (mongoc_cyrus_t *sasl,
int param_id,
const char **result,
unsigned *result_len)
{
BSON_ASSERT (sasl);
BSON_ASSERT (param_id == SASL_CB_PASS);
if (result) {
*result = sasl->credentials.pass;
}
if (result_len) {
*result_len = sasl->credentials.pass
? (unsigned) strlen (sasl->credentials.pass)
: 0;
}
return (sasl->credentials.pass != NULL) ? SASL_OK : SASL_FAIL;
}
static int
_mongoc_cyrus_canon_user (sasl_conn_t *conn,
mongoc_cyrus_t *sasl,
const char *in,
unsigned inlen,
unsigned flags,
const char *user_realm,
char *out,
unsigned out_max,
unsigned *out_len)
{
TRACE ("Canonicalizing %s (%" PRIu32 ")\n", in, inlen);
strcpy (out, in);
*out_len = inlen;
return SASL_OK;
}
static int
_mongoc_cyrus_get_user (mongoc_cyrus_t *sasl,
int param_id,
const char **result,
unsigned *result_len)
{
BSON_ASSERT (sasl);
BSON_ASSERT ((param_id == SASL_CB_USER) || (param_id == SASL_CB_AUTHNAME));
if (result) {
*result = sasl->credentials.user;
}
if (result_len) {
*result_len = sasl->credentials.user
? (unsigned) strlen (sasl->credentials.user)
: 0;
}
return (sasl->credentials.user != NULL) ? SASL_OK : SASL_FAIL;
}
void
_mongoc_cyrus_init (mongoc_cyrus_t *sasl)
{
sasl_callback_t callbacks[] = {
{SASL_CB_AUTHNAME, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl},
{SASL_CB_USER, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl},
{SASL_CB_PASS, SASL_CALLBACK_FN (_mongoc_cyrus_get_pass), sasl},
{SASL_CB_CANON_USER, SASL_CALLBACK_FN (_mongoc_cyrus_canon_user), sasl},
{SASL_CB_LIST_END}};
BSON_ASSERT (sasl);
memset (sasl, 0, sizeof *sasl);
memcpy (&sasl->callbacks, callbacks, sizeof callbacks);
sasl->done = false;
sasl->step = 0;
sasl->conn = NULL;
sasl->interact = NULL;
sasl->credentials.mechanism = NULL;
sasl->credentials.user = NULL;
sasl->credentials.pass = NULL;
sasl->credentials.service_name = NULL;
sasl->credentials.service_host = NULL;
}
bool
_mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl,
mongoc_cluster_t *cluster,
mongoc_stream_t *stream,
const char *hostname,
bson_error_t *error)
{
const char *mechanism;
char real_name[BSON_HOST_NAME_MAX + 1];
_mongoc_cyrus_init (sasl);
mechanism = mongoc_uri_get_auth_mechanism (cluster->uri);
if (!mechanism) {
mechanism = "GSSAPI";
}
if (!_mongoc_cyrus_set_mechanism (sasl, mechanism, error)) {
_mongoc_cyrus_destroy (sasl);
return false;
}
_mongoc_sasl_set_pass ((mongoc_sasl_t *) sasl,
mongoc_uri_get_password (cluster->uri));
_mongoc_sasl_set_user ((mongoc_sasl_t *) sasl,
mongoc_uri_get_username (cluster->uri));
_mongoc_sasl_set_properties ((mongoc_sasl_t *) sasl, cluster->uri);
/*
* If the URI requested canonicalizeHostname, we need to resolve the real
* hostname for the IP Address and pass that to the SASL layer. Some
* underlying GSSAPI layers will do this for us, but can be disabled in
* their config (krb.conf).
*
* This allows the consumer to specify canonicalizeHostname=true in the URI
* and have us do that for them.
*
* See CDRIVER-323 for more information.
*/
if (sasl->credentials.canonicalize_host_name &&
_mongoc_sasl_get_canonicalized_name (
stream, real_name, sizeof real_name)) {
_mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, real_name);
} else {
_mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, hostname);
}
return true;
}
void
_mongoc_cyrus_destroy (mongoc_cyrus_t *sasl)
{
BSON_ASSERT (sasl);
if (sasl->conn) {
sasl_dispose (&sasl->conn);
}
bson_free (sasl->credentials.user);
bson_free (sasl->credentials.pass);
bson_free (sasl->credentials.mechanism);
bson_free (sasl->credentials.service_name);
bson_free (sasl->credentials.service_host);
}
static bool
_mongoc_cyrus_is_failure (int status, bson_error_t *error)
{
bool ret = (status < 0);
TRACE ("Got status: %d ok is %d, continue=%d interact=%d\n",
status,
SASL_OK,
SASL_CONTINUE,
SASL_INTERACT);
if (ret) {
switch (status) {
case SASL_NOMEM:
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"SASL Failure: insufficient memory.");
break;
case SASL_NOMECH: {
bson_string_t *str = bson_string_new ("available mechanisms: ");
const char **mechs = sasl_global_listmech ();
int i = 0;
for (i = 0; mechs[i]; i++) {
bson_string_append (str, mechs[i]);
if (mechs[i + 1]) {
bson_string_append (str, ",");
}
}
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"SASL Failure: failure to negotiate mechanism (%s)",
str->str);
bson_string_free (str, 0);
} break;
case SASL_BADPARAM:
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"Bad parameter supplied. Please file a bug "
"with mongo-c-driver.");
break;
default:
bson_set_error (error,
MONGOC_ERROR_SASL,
status,
"SASL Failure: (%d): %s",
status,
sasl_errstring (status, NULL, NULL));
break;
}
}
return ret;
}
static bool
_mongoc_cyrus_start (mongoc_cyrus_t *sasl,
uint8_t **outbuf,
uint32_t *outbuflen,
bson_error_t *error)
{
const char *service_name = "mongodb";
const char *service_host = "";
const char *mechanism = NULL;
const char *raw = NULL;
unsigned raw_len = 0;
int status;
int b64_ret;
int outbuf_capacity;
BSON_ASSERT (sasl);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbuflen);
if (sasl->credentials.service_name) {
service_name = sasl->credentials.service_name;
}
if (sasl->credentials.service_host) {
service_host = sasl->credentials.service_host;
}
status = sasl_client_new (
service_name, service_host, NULL, NULL, sasl->callbacks, 0, &sasl->conn);
TRACE ("Created new sasl client %s",
status == SASL_OK ? "successfully" : "UNSUCCESSFULLY");
if (_mongoc_cyrus_is_failure (status, error)) {
return false;
}
status = sasl_client_start (sasl->conn,
sasl->credentials.mechanism,
&sasl->interact,
&raw,
&raw_len,
&mechanism);
TRACE ("Started the sasl client %s",
status == SASL_CONTINUE ? "successfully" : "UNSUCCESSFULLY");
if (_mongoc_cyrus_is_failure (status, error)) {
return false;
}
if ((0 != strcasecmp (mechanism, "GSSAPI")) &&
(0 != strcasecmp (mechanism, "PLAIN"))) {
bson_set_error (error,
MONGOC_ERROR_SASL,
SASL_NOMECH,
"SASL Failure: invalid mechanism \"%s\"",
mechanism);
return false;
}
*outbuflen = 0;
- outbuf_capacity =
- COMMON_PREFIX (bson_b64_ntop_calculate_target_size (raw_len));
+ outbuf_capacity = mcommon_b64_ntop_calculate_target_size (raw_len);
*outbuf = bson_malloc (outbuf_capacity);
- b64_ret = COMMON_PREFIX (bson_b64_ntop) (
+ b64_ret = mcommon_b64_ntop (
(uint8_t *) raw, raw_len, (char *) *outbuf, outbuf_capacity);
if (b64_ret == -1) {
bson_set_error (error,
MONGOC_ERROR_SASL,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Unable to base64 encode client SASL message");
return false;
} else {
*outbuflen = b64_ret;
}
return true;
}
bool
_mongoc_cyrus_step (mongoc_cyrus_t *sasl,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t **outbuf,
uint32_t *outbuflen,
bson_error_t *error)
{
const char *raw = NULL;
unsigned rawlen = 0;
int status;
char *decoded; /* post base64 decoded data */
uint32_t decoded_len;
uint32_t decoded_capacity;
uint32_t outbuf_capacity;
int b64_ret;
BSON_ASSERT (sasl);
if (sasl->step > 1) {
BSON_ASSERT (inbuf);
}
BSON_ASSERT (outbuf);
BSON_ASSERT (outbuflen);
TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen);
sasl->step++;
if (sasl->step == 1) {
return _mongoc_cyrus_start (sasl, outbuf, outbuflen, error);
} else if (sasl->step >= 10) {
bson_set_error (error,
MONGOC_ERROR_SASL,
SASL_NOTDONE,
"SASL Failure: maximum steps detected");
return false;
}
TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen);
if (!inbuflen) {
bson_set_error (error,
MONGOC_ERROR_SASL,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"SASL Failure: no payload provided from server: %s",
sasl_errdetail (sasl->conn));
return false;
}
decoded_len = 0;
- decoded_capacity =
- COMMON_PREFIX (bson_b64_pton_calculate_target_size) (inbuflen);
+ decoded_capacity = mcommon_b64_pton_calculate_target_size (inbuflen);
decoded = bson_malloc (decoded_capacity);
- b64_ret = COMMON_PREFIX (bson_b64_pton) (
- (char *) inbuf, (uint8_t *) decoded, decoded_capacity);
+ b64_ret =
+ mcommon_b64_pton ((char *) inbuf, (uint8_t *) decoded, decoded_capacity);
if (b64_ret == -1) {
bson_set_error (error,
MONGOC_ERROR_SASL,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Unable to base64 decode client SASL message");
bson_free (decoded);
bson_free (*outbuf);
*outbuf = NULL;
return false;
} else {
/* Set the output length to the number of bytes actually decoded to
* excluding the NULL. */
decoded_len = b64_ret;
}
TRACE ("%s", "Running client_step");
status = sasl_client_step (
sasl->conn, decoded, decoded_len, &sasl->interact, &raw, &rawlen);
TRACE ("%s sent a client step",
status == SASL_OK ? "Successfully" : "UNSUCCESSFULLY");
if (_mongoc_cyrus_is_failure (status, error)) {
bson_free (decoded);
return false;
}
*outbuflen = 0;
- outbuf_capacity = COMMON_PREFIX (bson_b64_ntop_calculate_target_size (rawlen));
+ outbuf_capacity = mcommon_b64_ntop_calculate_target_size (rawlen);
*outbuf = bson_malloc0 (outbuf_capacity);
- b64_ret = COMMON_PREFIX (bson_b64_ntop) (
+ b64_ret = mcommon_b64_ntop (
(const uint8_t *) raw, rawlen, (char *) *outbuf, outbuf_capacity);
if (b64_ret == -1) {
bson_set_error (error,
MONGOC_ERROR_SASL,
MONGOC_ERROR_CLIENT_AUTHENTICATE,
"Unable to base64 encode client SASL message");
bson_free (decoded);
bson_free (*outbuf);
*outbuf = NULL;
return false;
} else {
/* Set the output length to the number of characters written excluding the
* NULL. */
*outbuflen = b64_ret;
}
bson_free (decoded);
return true;
}
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
similarity index 52%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
index c19cf8cf..4405b5f7 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h
@@ -1,51 +1,82 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_DATABASE_PRIVATE_H
#define MONGOC_DATABASE_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-read-prefs.h"
#include "mongoc-read-concern.h"
#include "mongoc-write-concern.h"
BSON_BEGIN_DECLS
struct _mongoc_database_t {
mongoc_client_t *client;
char *name;
mongoc_read_prefs_t *read_prefs;
mongoc_read_concern_t *read_concern;
mongoc_write_concern_t *write_concern;
};
mongoc_database_t *
_mongoc_database_new (mongoc_client_t *client,
const char *name,
const mongoc_read_prefs_t *read_prefs,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern);
+/* _mongoc_get_encryptedFields_from_map checks the collection has an
+ * encryptedFields set on the client encryptedFieldsMap.
+ * encryptedFields is always initialized on return.
+ */
+bool
+_mongoc_get_encryptedFields_from_map (mongoc_client_t *client,
+ const char *dbName,
+ const char *collName,
+ bson_t *encryptedFields,
+ bson_error_t *error);
+
+/* _mongoc_get_encryptedFields_from_map checks the collection has an
+ * encryptedFields by running listCollections.
+ * encryptedFields is always initialized on return.
+ */
+bool
+_mongoc_get_encryptedFields_from_server (mongoc_client_t *client,
+ const char *dbName,
+ const char *collName,
+ bson_t *encryptedFields,
+ bson_error_t *error);
+
+/* _mongoc_get_encryptedField_state_collection returns the state collection
+ * name. Returns NULL on error. */
+char *
+_mongoc_get_encryptedField_state_collection (
+ const bson_t *encryptedFields,
+ const char *data_collection,
+ const char *state_collection_suffix,
+ bson_error_t *error);
+
BSON_END_DECLS
#endif /* MONGOC_DATABASE_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
similarity index 77%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
index 17829b1a..90f25aae 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c
@@ -1,1031 +1,1324 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-aggregate-private.h"
#include "mongoc-client-private.h"
#include "mongoc-collection.h"
#include "mongoc-collection-private.h"
#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-database.h"
#include "mongoc-database-private.h"
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-change-stream-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "database"
/*
*--------------------------------------------------------------------------
*
* _mongoc_database_new --
*
* Create a new instance of mongoc_database_t for @client.
*
* @client must stay valid for the life of the resulting
* database structure.
*
* Returns:
* A newly allocated mongoc_database_t that should be freed with
* mongoc_database_destroy().
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
_mongoc_database_new (mongoc_client_t *client,
const char *name,
const mongoc_read_prefs_t *read_prefs,
const mongoc_read_concern_t *read_concern,
const mongoc_write_concern_t *write_concern)
{
mongoc_database_t *db;
ENTRY;
BSON_ASSERT_PARAM (client);
BSON_ASSERT_PARAM (name);
db = (mongoc_database_t *) bson_malloc0 (sizeof *db);
db->client = client;
db->write_concern = write_concern ? mongoc_write_concern_copy (write_concern)
: mongoc_write_concern_new ();
db->read_concern = read_concern ? mongoc_read_concern_copy (read_concern)
: mongoc_read_concern_new ();
db->read_prefs = read_prefs ? mongoc_read_prefs_copy (read_prefs)
: mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
db->name = bson_strdup (name);
RETURN (db);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_destroy --
*
* Releases resources associated with @database.
*
* Returns:
* None.
*
* Side effects:
* Everything.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_destroy (mongoc_database_t *database)
{
ENTRY;
if (!database) {
EXIT;
}
if (database->read_prefs) {
mongoc_read_prefs_destroy (database->read_prefs);
database->read_prefs = NULL;
}
if (database->read_concern) {
mongoc_read_concern_destroy (database->read_concern);
database->read_concern = NULL;
}
if (database->write_concern) {
mongoc_write_concern_destroy (database->write_concern);
database->write_concern = NULL;
}
bson_free (database->name);
bson_free (database);
EXIT;
}
mongoc_cursor_t *
mongoc_database_aggregate (mongoc_database_t *db, /* IN */
const bson_t *pipeline, /* IN */
const bson_t *opts, /* IN */
const mongoc_read_prefs_t *read_prefs) /* IN */
{
return _mongoc_aggregate (db->client,
db->name,
MONGOC_QUERY_NONE,
pipeline,
opts,
read_prefs,
db->read_prefs,
db->read_concern,
db->write_concern);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_copy --
*
* Returns a copy of @database that needs to be freed by calling
* mongoc_database_destroy.
*
* Returns:
* A copy of this database.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_database_t *
mongoc_database_copy (mongoc_database_t *database)
{
ENTRY;
BSON_ASSERT_PARAM (database);
RETURN (_mongoc_database_new (database->client,
database->name,
database->read_prefs,
database->read_concern,
database->write_concern));
}
mongoc_cursor_t *
mongoc_database_command (mongoc_database_t *database,
mongoc_query_flags_t flags,
uint32_t skip,
uint32_t limit,
uint32_t batch_size,
const bson_t *command,
const bson_t *fields,
const mongoc_read_prefs_t *read_prefs)
{
char *ns;
mongoc_cursor_t *cursor;
BSON_ASSERT_PARAM (database);
BSON_ASSERT_PARAM (command);
ns = bson_strdup_printf ("%s.$cmd", database->name);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
/* flags, skip, limit, batch_size, fields are unused */
cursor = _mongoc_cursor_cmd_deprecated_new (
database->client, ns, command, read_prefs);
bson_free (ns);
return cursor;
}
bool
mongoc_database_command_simple (mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
bson_t *reply,
bson_error_t *error)
{
BSON_ASSERT_PARAM (database);
BSON_ASSERT_PARAM (command);
/* Server Selection Spec: "The generic command method has a default read
* preference of mode 'primary'. The generic command method MUST ignore any
* default read preference from client, database or collection
* configuration. The generic command method SHOULD allow an optional read
* preference argument."
*/
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_RAW,
NULL /* opts */,
MONGOC_QUERY_NONE,
read_prefs,
NULL, /* user prefs */
NULL /* read concern */,
NULL /* write concern */,
reply,
error);
}
bool
mongoc_database_read_command_with_opts (mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_READ,
opts,
MONGOC_QUERY_NONE,
read_prefs,
database->read_prefs,
database->read_concern,
database->write_concern,
reply,
error);
}
bool
mongoc_database_write_command_with_opts (mongoc_database_t *database,
const bson_t *command,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
database->read_prefs,
database->read_concern,
database->write_concern,
reply,
error);
}
bool
mongoc_database_read_write_command_with_opts (
mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs /* IGNORED */,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_RW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
database->read_prefs,
database->read_concern,
database->write_concern,
reply,
error);
}
bool
mongoc_database_command_with_opts (mongoc_database_t *database,
const bson_t *command,
const mongoc_read_prefs_t *read_prefs,
const bson_t *opts,
bson_t *reply,
bson_error_t *error)
{
return _mongoc_client_command_with_opts (database->client,
database->name,
command,
MONGOC_CMD_RAW,
opts,
MONGOC_QUERY_NONE,
read_prefs,
NULL, /* default prefs */
database->read_concern,
database->write_concern,
reply,
error);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_drop --
*
* Requests that the MongoDB server drops @database, including all
* collections and indexes associated with @database.
*
* Make sure this is really what you want!
*
* Returns:
* true if @database was dropped.
*
* Side effects:
* @error may be set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_database_drop (mongoc_database_t *database, bson_error_t *error)
{
return mongoc_database_drop_with_opts (database, NULL, error);
}
bool
mongoc_database_drop_with_opts (mongoc_database_t *database,
const bson_t *opts,
bson_error_t *error)
{
bool ret;
bson_t cmd;
BSON_ASSERT_PARAM (database);
bson_init (&cmd);
bson_append_int32 (&cmd, "dropDatabase", 12, 1);
ret = _mongoc_client_command_with_opts (database->client,
database->name,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
database->read_prefs,
database->read_concern,
database->write_concern,
NULL, /* reply */
error);
bson_destroy (&cmd);
return ret;
}
bool
mongoc_database_remove_user (mongoc_database_t *database,
const char *username,
bson_error_t *error)
{
bson_t cmd;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (database);
BSON_ASSERT_PARAM (username);
bson_init (&cmd);
BSON_APPEND_UTF8 (&cmd, "dropUser", username);
ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error);
bson_destroy (&cmd);
RETURN (ret);
}
bool
mongoc_database_remove_all_users (mongoc_database_t *database,
bson_error_t *error)
{
bson_t cmd;
bool ret;
ENTRY;
BSON_ASSERT_PARAM (database);
bson_init (&cmd);
BSON_APPEND_INT32 (&cmd, "dropAllUsersFromDatabase", 1);
ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error);
bson_destroy (&cmd);
RETURN (ret);
}
/**
* mongoc_database_add_user:
* @database: A #mongoc_database_t.
* @username: A string containing the username.
* @password: (allow-none): A string containing password, or NULL.
* @roles: (allow-none): An optional bson_t of roles.
* @custom_data: (allow-none): An optional bson_t of data to store.
* @error: (out) (allow-none): A location for a bson_error_t or %NULL.
*
* Creates a new user with access to @database.
*
* Returns: None.
* Side effects: None.
*/
bool
mongoc_database_add_user (mongoc_database_t *database,
const char *username,
const char *password,
const bson_t *roles,
const bson_t *custom_data,
bson_error_t *error)
{
bson_t cmd;
bson_t ar;
bool ret = false;
ENTRY;
BSON_ASSERT_PARAM (database);
BSON_ASSERT_PARAM (username);
bson_init (&cmd);
BSON_APPEND_UTF8 (&cmd, "createUser", username);
BSON_APPEND_UTF8 (&cmd, "pwd", password);
if (custom_data) {
BSON_APPEND_DOCUMENT (&cmd, "customData", custom_data);
}
if (roles) {
BSON_APPEND_ARRAY (&cmd, "roles", roles);
} else {
bson_append_array_begin (&cmd, "roles", 5, &ar);
bson_append_array_end (&cmd, &ar);
}
ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error);
bson_destroy (&cmd);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_get_read_prefs --
*
* Fetch the read preferences for @database.
*
* Returns:
* A mongoc_read_prefs_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_prefs_t *
mongoc_database_get_read_prefs (const mongoc_database_t *database) /* IN */
{
BSON_ASSERT_PARAM (database);
return database->read_prefs;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_set_read_prefs --
*
* Sets the default read preferences for @database.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_set_read_prefs (mongoc_database_t *database,
const mongoc_read_prefs_t *read_prefs)
{
BSON_ASSERT_PARAM (database);
if (database->read_prefs) {
mongoc_read_prefs_destroy (database->read_prefs);
database->read_prefs = NULL;
}
if (read_prefs) {
database->read_prefs = mongoc_read_prefs_copy (read_prefs);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_get_read_concern --
*
* Fetches the read concern for @database.
*
* Returns:
* A mongoc_read_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_read_concern_t *
mongoc_database_get_read_concern (const mongoc_database_t *database)
{
BSON_ASSERT_PARAM (database);
return database->read_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_set_read_concern --
*
* Set the default read concern for @database.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_set_read_concern (mongoc_database_t *database,
const mongoc_read_concern_t *read_concern)
{
BSON_ASSERT_PARAM (database);
if (database->read_concern) {
mongoc_read_concern_destroy (database->read_concern);
database->read_concern = NULL;
}
if (read_concern) {
database->read_concern = mongoc_read_concern_copy (read_concern);
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_get_write_concern --
*
* Fetches the write concern for @database.
*
* Returns:
* A mongoc_write_concern_t that should not be modified or freed.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
const mongoc_write_concern_t *
mongoc_database_get_write_concern (const mongoc_database_t *database)
{
BSON_ASSERT_PARAM (database);
return database->write_concern;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_database_set_write_concern --
*
* Set the default write concern for @database.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_database_set_write_concern (mongoc_database_t *database,
const mongoc_write_concern_t *write_concern)
{
BSON_ASSERT_PARAM (database);
if (database->write_concern) {
mongoc_write_concern_destroy (database->write_concern);
database->write_concern = NULL;
}
if (write_concern) {
database->write_concern = mongoc_write_concern_copy (write_concern);
}
}
/**
* mongoc_database_has_collection:
* @database: (in): A #mongoc_database_t.
* @name: (in): The name of the collection to check for.
* @error: (out) (allow-none): A location for a #bson_error_t, or %NULL.
*
* Checks to see if a collection exists within the database on the MongoDB
* server.
*
* This will return %false if their was an error communicating with the
* server, or if the collection does not exist.
*
* If @error is provided, it will first be zeroed. Upon error, error.domain
* will be set.
*
* Returns: %true if @name exists, otherwise %false. @error may be set.
*/
bool
mongoc_database_has_collection (mongoc_database_t *database,
const char *name,
bson_error_t *error)
{
bson_iter_t col_iter;
bool ret = false;
const char *cur_name;
bson_t opts = BSON_INITIALIZER;
bson_t filter;
mongoc_cursor_t *cursor;
const bson_t *doc;
ENTRY;
BSON_ASSERT_PARAM (database);
BSON_ASSERT_PARAM (name);
if (error) {
memset (error, 0, sizeof *error);
}
BSON_APPEND_DOCUMENT_BEGIN (&opts, "filter", &filter);
BSON_APPEND_UTF8 (&filter, "name", name);
bson_append_document_end (&opts, &filter);
cursor = mongoc_database_find_collections_with_opts (database, &opts);
while (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init (&col_iter, doc) &&
bson_iter_find (&col_iter, "name") &&
BSON_ITER_HOLDS_UTF8 (&col_iter) &&
(cur_name = bson_iter_utf8 (&col_iter, NULL))) {
if (!strcmp (cur_name, name)) {
ret = true;
GOTO (cleanup);
}
}
}
(void) mongoc_cursor_error (cursor, error);
cleanup:
mongoc_cursor_destroy (cursor);
bson_destroy (&opts);
RETURN (ret);
}
mongoc_cursor_t *
mongoc_database_find_collections (mongoc_database_t *database,
const bson_t *filter,
bson_error_t *error)
{
bson_t opts = BSON_INITIALIZER;
mongoc_cursor_t *cursor;
BSON_ASSERT_PARAM (database);
if (filter) {
if (!BSON_APPEND_DOCUMENT (&opts, "filter", filter)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'filter' parameter.");
bson_destroy (&opts);
return NULL;
}
}
cursor = mongoc_database_find_collections_with_opts (database, &opts);
bson_destroy (&opts);
/* this deprecated API returns NULL on error */
if (mongoc_cursor_error (cursor, error)) {
mongoc_cursor_destroy (cursor);
return NULL;
}
return cursor;
}
mongoc_cursor_t *
mongoc_database_find_collections_with_opts (mongoc_database_t *database,
const bson_t *opts)
{
mongoc_cursor_t *cursor;
bson_t cmd = BSON_INITIALIZER;
BSON_ASSERT_PARAM (database);
BSON_APPEND_INT32 (&cmd, "listCollections", 1);
/* Enumerate Collections Spec: "run listCollections on the primary node in
* replicaset mode" */
cursor = _mongoc_cursor_cmd_new (
database->client, database->name, &cmd, opts, NULL, NULL, NULL);
if (cursor->error.domain == 0) {
_mongoc_cursor_prime (cursor);
}
bson_destroy (&cmd);
return cursor;
}
char **
mongoc_database_get_collection_names (mongoc_database_t *database,
bson_error_t *error)
{
return mongoc_database_get_collection_names_with_opts (
database, NULL, error);
}
char **
mongoc_database_get_collection_names_with_opts (mongoc_database_t *database,
const bson_t *opts,
bson_error_t *error)
{
bson_t opts_copy;
bson_iter_t col;
const char *name;
char *namecopy;
mongoc_array_t strv_buf;
mongoc_cursor_t *cursor;
const bson_t *doc;
char **ret;
BSON_ASSERT_PARAM (database);
if (opts) {
bson_copy_to (opts, &opts_copy);
} else {
bson_init (&opts_copy);
}
/* nameOnly option is faster in MongoDB 4+, ignored by older versions,
* see Enumerating Collections Spec */
if (!bson_has_field (&opts_copy, "nameOnly")) {
bson_append_bool (&opts_copy, "nameOnly", 8, true);
}
cursor = mongoc_database_find_collections_with_opts (database, &opts_copy);
_mongoc_array_init (&strv_buf, sizeof (char *));
while (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init (&col, doc) && bson_iter_find (&col, "name") &&
BSON_ITER_HOLDS_UTF8 (&col) && (name = bson_iter_utf8 (&col, NULL))) {
namecopy = bson_strdup (name);
_mongoc_array_append_val (&strv_buf, namecopy);
}
}
/* append a null pointer for the last value. also handles the case
* of no values. */
namecopy = NULL;
_mongoc_array_append_val (&strv_buf, namecopy);
if (mongoc_cursor_error (cursor, error)) {
_mongoc_array_destroy (&strv_buf);
ret = NULL;
} else {
ret = (char **) strv_buf.data;
}
mongoc_cursor_destroy (cursor);
bson_destroy (&opts_copy);
return ret;
}
-
-mongoc_collection_t *
-mongoc_database_create_collection (mongoc_database_t *database,
- const char *name,
- const bson_t *opts,
- bson_error_t *error)
+static mongoc_collection_t *
+create_collection (mongoc_database_t *database,
+ const char *name,
+ const bson_t *opts,
+ bson_error_t *error)
{
mongoc_collection_t *collection = NULL;
bson_iter_t iter;
bson_t cmd;
bool capped = false;
BSON_ASSERT_PARAM (database);
BSON_ASSERT_PARAM (name);
if (strchr (name, '$')) {
bson_set_error (error,
MONGOC_ERROR_NAMESPACE,
MONGOC_ERROR_NAMESPACE_INVALID,
"The namespace \"%s\" is invalid.",
name);
return NULL;
}
if (opts) {
if (bson_iter_init_find (&iter, opts, "capped")) {
if (!BSON_ITER_HOLDS_BOOL (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The argument \"capped\" must be a boolean.");
return NULL;
}
capped = bson_iter_bool (&iter);
}
if (bson_iter_init_find (&iter, opts, "size")) {
if (!BSON_ITER_HOLDS_INT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The argument \"size\" must be an integer.");
return NULL;
}
if (!capped) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"size\" parameter requires {\"capped\": true}");
return NULL;
}
}
if (bson_iter_init_find (&iter, opts, "max")) {
if (!BSON_ITER_HOLDS_INT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The argument \"max\" must be an integer.");
return NULL;
}
if (!capped) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"max\" parameter requires {\"capped\": true}");
return NULL;
}
}
if (bson_iter_init_find (&iter, opts, "storageEngine")) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"storageEngine\" parameter must be a document");
return NULL;
}
if (bson_iter_find (&iter, "wiredTiger")) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"wiredTiger\" option must take a document "
"argument with a \"configString\" field");
return NULL;
}
if (bson_iter_find (&iter, "configString")) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
bson_set_error (
error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"configString\" parameter must be a string");
return NULL;
}
} else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The \"wiredTiger\" option must take a document "
"argument with a \"configString\" field");
return NULL;
}
}
}
}
bson_init (&cmd);
BSON_APPEND_UTF8 (&cmd, "create", name);
if (_mongoc_client_command_with_opts (database->client,
database->name,
&cmd,
MONGOC_CMD_WRITE,
opts,
MONGOC_QUERY_NONE,
NULL, /* user prefs */
database->read_prefs,
database->read_concern,
database->write_concern,
NULL, /* reply */
error)) {
collection = _mongoc_collection_new (database->client,
database->name,
name,
database->read_prefs,
database->read_concern,
database->write_concern);
}
bson_destroy (&cmd);
return collection;
}
+char *
+_mongoc_get_encryptedField_state_collection (
+ const bson_t *encryptedFields,
+ const char *data_collection,
+ const char *state_collection_suffix,
+ bson_error_t *error)
+{
+ bson_iter_t iter;
+ const char *fieldName = NULL;
+
+ if (0 == strcmp (state_collection_suffix, "esc")) {
+ fieldName = "escCollection";
+ } else if (0 == strcmp (state_collection_suffix, "ecc")) {
+ fieldName = "eccCollection";
+ } else if (0 == strcmp (state_collection_suffix, "ecoc")) {
+ fieldName = "ecocCollection";
+ } else {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "expected state_collection_suffix to be 'esc', 'ecc', or "
+ "'ecoc', got: %s",
+ state_collection_suffix);
+ return NULL;
+ }
+
+ if (bson_iter_init_find (&iter, encryptedFields, fieldName)) {
+ if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "expected encryptedFields.%s to be UTF-8",
+ fieldName);
+ return NULL;
+ }
+ return bson_strdup (bson_iter_utf8 (&iter, NULL));
+ }
+ return bson_strdup_printf (
+ "enxcol_.%s.%s", data_collection, state_collection_suffix);
+}
+
+static bool
+create_encField_state_collection (mongoc_database_t *database,
+ const bson_t *encryptedFields,
+ const char *data_collection,
+ const char *state_collection_suffix,
+ bson_error_t *error)
+{
+ char *state_collection = NULL;
+ mongoc_collection_t *collection = NULL;
+ bool ok = false;
+ bson_t opts = BSON_INITIALIZER;
+
+ state_collection = _mongoc_get_encryptedField_state_collection (
+ encryptedFields, data_collection, state_collection_suffix, error);
+ if (!state_collection) {
+ goto fail;
+ }
+
+ BCON_APPEND (&opts,
+ "clusteredIndex",
+ "{",
+ "key",
+ "{",
+ "_id",
+ BCON_INT32 (1),
+ "}",
+ "unique",
+ BCON_BOOL (true),
+ "}");
+
+ collection = create_collection (database, state_collection, &opts, error);
+ if (collection == NULL) {
+ goto fail;
+ }
+
+ ok = true;
+fail:
+ bson_free (state_collection);
+ mongoc_collection_destroy (collection);
+ bson_destroy (&opts);
+ return ok;
+}
+
+static mongoc_collection_t *
+create_collection_with_encryptedFields (mongoc_database_t *database,
+ const char *name,
+ const bson_t *opts,
+ const bson_t *encryptedFields,
+ bson_error_t *error)
+{
+ mongoc_collection_t *dataCollection = NULL;
+ bool ok = false;
+ bson_t *cc_opts = NULL;
+ bool state_collections_ok =
+ create_encField_state_collection (
+ database, encryptedFields, name, "esc", error) &&
+ create_encField_state_collection (
+ database, encryptedFields, name, "ecc", error) &&
+ create_encField_state_collection (
+ database, encryptedFields, name, "ecoc", error);
+ if (!state_collections_ok) {
+ // Failed to create one or more state collections
+ goto fail;
+ }
+
+ /* Create data collection. */
+ cc_opts = bson_copy (opts);
+ if (!BSON_APPEND_DOCUMENT (cc_opts, "encryptedFields", encryptedFields)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "unable to append encryptedFields");
+ goto fail;
+ }
+ dataCollection = create_collection (database, name, cc_opts, error);
+ if (!dataCollection) {
+ goto fail;
+ }
+
+ /* Create index on __safeContent__. */
+ {
+ bson_t *keys = BCON_NEW ("__safeContent__", BCON_INT32 (1));
+ char *index_name;
+ bson_t *create_indexes;
+
+ index_name = mongoc_collection_keys_to_index_string (keys);
+ create_indexes = BCON_NEW ("createIndexes",
+ BCON_UTF8 (name),
+ "indexes",
+ "[",
+ "{",
+ "key",
+ BCON_DOCUMENT (keys),
+ "name",
+ BCON_UTF8 (index_name),
+ "}",
+ "]");
+
+ ok = mongoc_database_write_command_with_opts (
+ database, create_indexes, NULL /* opts */, NULL /* reply */, error);
+ bson_destroy (create_indexes);
+ bson_free (index_name);
+ bson_destroy (keys);
+ if (!ok) {
+ goto fail;
+ }
+ }
+
+ ok = true;
+fail:
+ bson_destroy (cc_opts);
+ if (ok) {
+ return dataCollection;
+ } else {
+ mongoc_collection_destroy (dataCollection);
+ return NULL;
+ }
+}
+
+bool
+_mongoc_get_encryptedFields_from_map (mongoc_client_t *client,
+ const char *dbName,
+ const char *collName,
+ bson_t *encryptedFields,
+ bson_error_t *error)
+{
+ const bson_t *efMap = client->topology->encrypted_fields_map;
+
+ bson_init (encryptedFields);
+
+ if (bson_empty0 (efMap)) {
+ /* Unset or empty efMap will have no encrypted fields */
+ return true;
+ }
+
+ char *ns = bson_strdup_printf ("%s.%s", dbName, collName);
+ bson_iter_t iter;
+ if (!bson_iter_init_find (&iter, efMap, ns)) {
+ /* No efMap entry for this database+collection. */
+ bson_free (ns);
+ return true;
+ }
+ bson_free (ns);
+
+ if (!_mongoc_iter_document_as_bson (&iter, encryptedFields, error)) {
+ /* The efMap entry should always be a document. */
+ return false;
+ }
+
+ return true;
+}
+
+bool
+_mongoc_get_encryptedFields_from_server (mongoc_client_t *client,
+ const char *dbName,
+ const char *collName,
+ bson_t *encryptedFields,
+ bson_error_t *error)
+{
+ mongoc_database_t *db = mongoc_client_get_database (client, dbName);
+ bson_t *opts = BCON_NEW ("filter", "{", "name", BCON_UTF8 (collName), "}");
+ mongoc_cursor_t *cursor;
+ bool ret = false;
+ const bson_t *collInfo;
+
+ bson_init (encryptedFields);
+
+ cursor = mongoc_database_find_collections_with_opts (db, opts);
+ if (mongoc_cursor_error (cursor, error)) {
+ goto fail;
+ }
+
+ if (mongoc_cursor_next (cursor, &collInfo)) {
+ /* Check if the collInfo has options.encryptedFields. */
+ bson_iter_t iter;
+ if (!bson_iter_init (&iter, collInfo)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "unable to iterate listCollections result");
+ goto fail;
+ }
+
+ if (bson_iter_find_descendant (&iter, "options.encryptedFields", &iter)) {
+ bson_t tmp;
+ if (!_mongoc_iter_document_as_bson (&iter, &tmp, error)) {
+ goto fail;
+ }
+ bson_copy_to (&tmp, encryptedFields);
+ }
+ }
+
+ if (mongoc_cursor_error (cursor, error)) {
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ mongoc_cursor_destroy (cursor);
+ bson_destroy (opts);
+ mongoc_database_destroy (db);
+ return ret;
+}
+
+mongoc_collection_t *
+mongoc_database_create_collection (mongoc_database_t *database,
+ const char *name,
+ const bson_t *opts,
+ bson_error_t *error)
+{
+ bson_iter_t iter;
+ bson_t encryptedFields = BSON_INITIALIZER;
+
+ if (opts && bson_iter_init_find (&iter, opts, "encryptedFields")) {
+ if (!_mongoc_iter_document_as_bson (&iter, &encryptedFields, error)) {
+ return NULL;
+ }
+ }
+
+ if (bson_empty (&encryptedFields)) {
+ if (!_mongoc_get_encryptedFields_from_map (
+ database->client,
+ mongoc_database_get_name (database),
+ name,
+ &encryptedFields,
+ error)) {
+ return NULL;
+ }
+ }
+
+ if (!bson_empty (&encryptedFields)) {
+ bson_t opts_without_encryptedFields = BSON_INITIALIZER;
+
+ if (opts) {
+ bson_copy_to_excluding_noinit (
+ opts, &opts_without_encryptedFields, "encryptedFields", NULL);
+ }
+
+ mongoc_collection_t *ret =
+ create_collection_with_encryptedFields (database,
+ name,
+ &opts_without_encryptedFields,
+ &encryptedFields,
+ error);
+
+ bson_destroy (&opts_without_encryptedFields);
+ bson_destroy (&encryptedFields);
+ return ret;
+ }
+
+ return create_collection (database, name, opts, error);
+}
+
mongoc_collection_t *
mongoc_database_get_collection (mongoc_database_t *database,
const char *collection)
{
BSON_ASSERT_PARAM (database);
BSON_ASSERT_PARAM (collection);
return _mongoc_collection_new (database->client,
database->name,
collection,
database->read_prefs,
database->read_concern,
database->write_concern);
}
const char *
mongoc_database_get_name (mongoc_database_t *database)
{
BSON_ASSERT_PARAM (database);
return database->name;
}
mongoc_change_stream_t *
mongoc_database_watch (const mongoc_database_t *db,
const bson_t *pipeline,
const bson_t *opts)
{
return _mongoc_change_stream_new_from_database (db, pipeline, opts);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
similarity index 96%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
index f87b77db..3e4211cc 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h
@@ -1,87 +1,88 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#include <bson/bson.h>
#include <stddef.h>
BSON_BEGIN_DECLS
typedef enum {
MONGOC_READ_ERR_NONE,
MONGOC_READ_ERR_OTHER,
MONGOC_READ_ERR_RETRY
} mongoc_read_err_type_t;
/* Server error codes libmongoc cares about. Compare with:
* https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.yml
*/
typedef enum {
MONGOC_SERVER_ERR_HOSTUNREACHABLE = 6,
MONGOC_SERVER_ERR_HOSTNOTFOUND = 7,
MONGOC_SERVER_ERR_CURSOR_NOT_FOUND = 43,
MONGOC_SERVER_ERR_STALESHARDVERSION = 63,
MONGOC_SERVER_ERR_NETWORKTIMEOUT = 89,
MONGOC_SERVER_ERR_SHUTDOWNINPROGRESS = 91,
MONGOC_SERVER_ERR_FAILEDTOSATISFYREADPREFERENCE = 133,
MONGOC_SERVER_ERR_STALEEPOCH = 150,
MONGOC_SERVER_ERR_PRIMARYSTEPPEDDOWN = 189,
MONGOC_SERVER_ERR_ELECTIONINPROGRESS = 216,
MONGOC_SERVER_ERR_RETRYCHANGESTREAM = 234,
MONGOC_SERVER_ERR_EXCEEDEDTIMELIMIT = 262,
MONGOC_SERVER_ERR_SOCKETEXCEPTION = 9001,
MONGOC_SERVER_ERR_NOTPRIMARY = 10107,
MONGOC_SERVER_ERR_INTERRUPTEDATSHUTDOWN = 11600,
MONGOC_SERVER_ERR_INTERRUPTEDDUETOREPLSTATECHANGE = 11602,
MONGOC_SERVER_ERR_STALECONFIG = 13388,
MONGOC_SERVER_ERR_NOTPRIMARYNOSECONDARYOK = 13435,
MONGOC_SERVER_ERR_NOTPRIMARYORSECONDARY = 13436,
- MONGOC_SERVER_ERR_LEGACYNOTPRIMARY = 10058
+ MONGOC_SERVER_ERR_LEGACYNOTPRIMARY = 10058,
+ MONGOC_SERVER_ERR_NS_NOT_FOUND = 26
} mongoc_server_err_t;
mongoc_read_err_type_t
_mongoc_read_error_get_type (bool cmd_ret,
const bson_error_t *cmd_err,
const bson_t *reply);
void
_mongoc_error_copy_labels_and_upsert (const bson_t *src,
bson_t *dst,
char *label);
void
_mongoc_write_error_handle_labels (bool cmd_ret,
const bson_error_t *cmd_err,
bson_t *reply,
int32_t server_max_wire_version);
bool
_mongoc_error_is_shutdown (bson_error_t *error);
bool
_mongoc_error_is_recovering (bson_error_t *error);
bool
_mongoc_error_is_not_primary (bson_error_t *error);
bool
_mongoc_error_is_state_change (bson_error_t *error);
bool
_mongoc_error_is_network (const bson_error_t *error);
BSON_END_DECLS
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
index d3ad3dff..8da55ebc 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h
@@ -1,136 +1,139 @@
/*
* Copyright 2016 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_HANDSHAKE_PRIVATE_H
#define MONGOC_HANDSHAKE_PRIVATE_H
#include "mongoc.h"
BSON_BEGIN_DECLS
#define HANDSHAKE_FIELD "client"
#define HANDSHAKE_PLATFORM_FIELD "platform"
#define HANDSHAKE_MAX_SIZE 512
#define HANDSHAKE_OS_TYPE_MAX 32
#define HANDSHAKE_OS_NAME_MAX 32
#define HANDSHAKE_OS_VERSION_MAX 32
#define HANDSHAKE_OS_ARCHITECTURE_MAX 32
#define HANDSHAKE_DRIVER_NAME_MAX 64
#define HANDSHAKE_DRIVER_VERSION_MAX 32
+#define HANDSHAKE_CMD_HELLO "hello"
+#define HANDSHAKE_RESPONSE_HELLO "helloOk"
+
#define HANDSHAKE_CMD_LEGACY_HELLO "isMaster"
#define HANDSHAKE_RESPONSE_LEGACY_HELLO "ismaster"
/* platform has no fixed max size. It can just occupy the remaining
* available space in the document. */
/* When adding a new field to mongoc-config.h.in, update this! */
typedef enum {
/* The bit position (from the RHS) of each config flag. Do not reorder. */
MONGOC_MD_FLAG_ENABLE_CRYPTO = 0,
MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG,
MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO,
MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO,
MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE,
MONGOC_MD_FLAG_ENABLE_SASL,
MONGOC_MD_FLAG_ENABLE_SSL,
MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL,
MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL,
MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT,
MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES,
MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE,
MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS,
MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS,
MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL,
MONGOC_MD_FLAG_ENABLE_SASL_CYRUS,
MONGOC_MD_FLAG_ENABLE_SASL_SSPI,
MONGOC_MD_FLAG_HAVE_SOCKLEN,
MONGOC_MD_FLAG_ENABLE_COMPRESSION,
MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY,
MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB,
MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI_UNUSED, /* CDRIVER-2654 removed this . */
MONGOC_MD_FLAG_ENABLE_RES_NSEARCH,
MONGOC_MD_FLAG_ENABLE_RES_NDESTROY,
MONGOC_MD_FLAG_ENABLE_RES_NCLOSE,
MONGOC_MD_FLAG_ENABLE_RES_SEARCH,
MONGOC_MD_FLAG_ENABLE_DNSAPI,
MONGOC_MD_FLAG_ENABLE_RDTSCP,
MONGOC_MD_FLAG_HAVE_SCHED_GETCPU,
MONGOC_MD_FLAG_ENABLE_SHM_COUNTERS,
MONGOC_MD_FLAG_TRACE,
MONGOC_MD_FLAG_ENABLE_ICU,
MONGOC_MD_FLAG_ENABLE_CLIENT_SIDE_ENCRYPTION,
MONGOC_MD_FLAG_ENABLE_MONGODB_AWS_AUTH,
/* Add additional config flags here, above LAST_MONGOC_MD_FLAG. */
LAST_MONGOC_MD_FLAG
} mongoc_handshake_config_flag_bit_t;
typedef struct _mongoc_handshake_t {
char *os_type;
char *os_name;
char *os_version;
char *os_architecture;
char *driver_name;
char *driver_version;
char *platform;
char *compiler_info;
char *flags;
bool frozen;
} mongoc_handshake_t;
void
_mongoc_handshake_init (void);
void
_mongoc_handshake_cleanup (void);
bool
_mongoc_handshake_build_doc_with_application (bson_t *doc,
const char *application);
void
_mongoc_handshake_freeze (void);
mongoc_handshake_t *
_mongoc_handshake_get (void);
bool
_mongoc_handshake_appname_is_valid (const char *appname);
typedef struct {
bool scram_sha_256;
bool scram_sha_1;
} mongoc_handshake_sasl_supported_mechs_t;
void
_mongoc_handshake_append_sasl_supported_mechs (const mongoc_uri_t *uri,
bson_t *hello);
void
_mongoc_handshake_parse_sasl_supported_mechs (
const bson_t *hello,
mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs);
BSON_END_DECLS
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c
index 577bcc2c..3f4785b1 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c
@@ -1,321 +1,320 @@
/*
* Copyright 2020-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc/mongoc-errno-private.h"
#include "mongoc/mongoc-interrupt-private.h"
#include "mongoc/mongoc-log.h"
#include "mongoc/mongoc-socket-private.h"
#include "mongoc/mongoc-stream-socket.h"
#include "mongoc/mongoc-trace-private.h"
#include "common-thread-private.h"
/* The interrupt stream is implemented in two ways.
* On POSIX, this uses the self-pipe trick.
* On Windows, this uses a pair of TCP sockets.
*/
struct _mongoc_interrupt_t {
bson_mutex_t mutex;
union {
/* For POSIX. pipe_fds[0] is the read end and pipe_fds[1] is the write
* end. */
int pipe_fds[2];
/* For Windows */
struct {
mongoc_socket_t *read;
mongoc_socket_t *write;
} socket_pair;
} impl;
mongoc_stream_t *stream;
};
mongoc_stream_t *
_mongoc_interrupt_get_stream (mongoc_interrupt_t *interrupt)
{
return interrupt->stream;
}
static void
_log_errno (char *prefix, int _errno)
{
char buf[128] = {0};
bson_strerror_r (_errno, buf, sizeof (buf));
MONGOC_ERROR ("%s: (%d) %s", prefix, _errno, buf);
}
#ifdef _WIN32
/* TCP socket pair implementation. */
mongoc_interrupt_t *
_mongoc_interrupt_new (uint32_t timeout_ms)
{
mongoc_interrupt_t *interrupt;
mongoc_socket_t *listen_socket = NULL;
mongoc_socket_t *interrupt_socket = NULL;
struct sockaddr_storage server_addr;
mongoc_socklen_t sock_len;
int ret;
bool success = false;
struct sockaddr_in server_addr_in = {0};
ENTRY;
interrupt = (mongoc_interrupt_t *) bson_malloc0 (sizeof *interrupt);
bson_mutex_init (&interrupt->mutex);
/* Inspired by cpython's implementation of socketpair. */
listen_socket = mongoc_socket_new (AF_INET, SOCK_STREAM, 0);
if (!listen_socket) {
MONGOC_ERROR ("socket creation failed");
GOTO (fail);
}
memset (&server_addr_in, 0, sizeof (server_addr_in));
server_addr_in.sin_family = AF_INET;
server_addr_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
ret = mongoc_socket_bind (listen_socket,
(struct sockaddr *) &server_addr_in,
sizeof (server_addr_in));
if (ret == -1) {
_log_errno ("bind failed", mongoc_socket_errno (listen_socket));
GOTO (fail);
}
ret = mongoc_socket_listen (listen_socket, 1);
if (ret == -1) {
_log_errno ("listen failed", mongoc_socket_errno (listen_socket));
GOTO (fail);
}
sock_len = sizeof (server_addr);
ret = mongoc_socket_getsockname (
listen_socket, (struct sockaddr *) &server_addr, &sock_len);
if (-1 == ret) {
_log_errno ("getsockname failed", mongoc_socket_errno (listen_socket));
GOTO (fail);
}
interrupt->impl.socket_pair.read =
mongoc_socket_new (server_addr.ss_family, SOCK_STREAM, 0);
if (!interrupt->impl.socket_pair.read) {
MONGOC_ERROR ("socket creation failed");
GOTO (fail);
}
/* Begin non-blocking connect. */
ret = mongoc_socket_connect (interrupt->impl.socket_pair.read,
(struct sockaddr *) &server_addr,
sock_len,
0);
- if (ret == -1 &&
- !MONGOC_ERRNO_IS_AGAIN (
- mongoc_socket_errno (interrupt->impl.socket_pair.read))) {
+ if (ret == -1 && !MONGOC_ERRNO_IS_AGAIN (mongoc_socket_errno (
+ interrupt->impl.socket_pair.read))) {
_log_errno ("connect failed",
mongoc_socket_errno (interrupt->impl.socket_pair.read));
GOTO (fail);
}
interrupt->impl.socket_pair.write = mongoc_socket_accept (
listen_socket, bson_get_monotonic_time () + timeout_ms * 1000);
if (!interrupt->impl.socket_pair.write) {
_log_errno ("accept failed", mongoc_socket_errno (listen_socket));
GOTO (fail);
}
/* Create an unowned socket. interrupt_socket has 0 for the pid, so it will
* be considered unowned. */
interrupt_socket = bson_malloc0 (sizeof (mongoc_socket_t));
interrupt_socket->sd = interrupt->impl.socket_pair.read->sd;
/* Creating the stream takes ownership of the mongoc_socket_t. */
interrupt->stream = mongoc_stream_socket_new (interrupt_socket);
success = true;
fail:
mongoc_socket_destroy (listen_socket);
if (!success) {
_mongoc_interrupt_destroy (interrupt);
interrupt = NULL;
}
RETURN (interrupt);
}
void
_mongoc_interrupt_destroy (mongoc_interrupt_t *interrupt)
{
if (!interrupt) {
return;
}
bson_mutex_destroy (&interrupt->mutex);
mongoc_socket_destroy (interrupt->impl.socket_pair.read);
mongoc_socket_destroy (interrupt->impl.socket_pair.write);
mongoc_stream_destroy (interrupt->stream);
bson_free (interrupt);
}
bool
_mongoc_interrupt_flush (mongoc_interrupt_t *interrupt)
{
uint8_t buf[1];
while (true) {
if (-1 == mongoc_socket_recv (
interrupt->impl.socket_pair.read, buf, sizeof (buf), 0, 0)) {
if (MONGOC_ERRNO_IS_AGAIN (errno)) {
/* Nothing left to read. */
return true;
} else {
/* Unexpected error. */
_log_errno ("interrupt recv failed",
mongoc_socket_errno (interrupt->impl.socket_pair.read));
return false;
}
}
}
/* Should never be reached. */
BSON_ASSERT (false);
}
bool
_mongoc_interrupt_interrupt (mongoc_interrupt_t *interrupt)
{
bson_mutex_lock (&interrupt->mutex);
if (mongoc_socket_send (interrupt->impl.socket_pair.write, "!", 1, 0) ==
-1 &&
!MONGOC_ERRNO_IS_AGAIN (errno)) {
_log_errno ("interrupt send failed",
mongoc_socket_errno (interrupt->impl.socket_pair.write));
bson_mutex_unlock (&interrupt->mutex);
return false;
}
bson_mutex_unlock (&interrupt->mutex);
return true;
}
#else
/* Pipe implementation. */
/* Set non-blocking and close on exec. */
static bool
_set_pipe_flags (int pipe_fd)
{
int flags;
flags = fcntl (pipe_fd, F_GETFL);
if (-1 == fcntl (pipe_fd, F_SETFL, (flags | O_NONBLOCK))) {
return false;
}
#ifdef FD_CLOEXEC
flags = fcntl (pipe_fd, F_GETFD);
if (-1 == fcntl (pipe_fd, F_SETFD, (flags | FD_CLOEXEC))) {
return false;
}
#endif
return true;
}
mongoc_interrupt_t *
_mongoc_interrupt_new (uint32_t timeout_ms)
{
mongoc_interrupt_t *interrupt;
mongoc_socket_t *interrupt_socket = NULL;
bool success = false;
ENTRY;
interrupt = (mongoc_interrupt_t *) bson_malloc0 (sizeof *interrupt);
bson_mutex_init (&interrupt->mutex);
if (0 != pipe (interrupt->impl.pipe_fds)) {
_log_errno ("pipe creation failed", errno);
GOTO (fail);
}
/* Make the pipe non-blocking and close-on-exec. */
if (!_set_pipe_flags (interrupt->impl.pipe_fds[0]) ||
!_set_pipe_flags (interrupt->impl.pipe_fds[1])) {
_log_errno ("unable to configure pipes", errno);
}
/* Create an unowned socket. interrupt_socket has 0 for the pid, so it will
* be considered unowned. */
interrupt_socket = bson_malloc0 (sizeof (mongoc_socket_t));
interrupt_socket->sd = interrupt->impl.pipe_fds[0];
/* Creating the stream takes ownership of the mongoc_socket_t. */
interrupt->stream = mongoc_stream_socket_new (interrupt_socket);
success = true;
fail:
if (!success) {
_mongoc_interrupt_destroy (interrupt);
interrupt = NULL;
}
RETURN (interrupt);
}
bool
_mongoc_interrupt_flush (mongoc_interrupt_t *interrupt)
{
char c;
while (true) {
if (read (interrupt->impl.pipe_fds[0], &c, 1) == -1) {
if (MONGOC_ERRNO_IS_AGAIN (errno)) {
/* Nothing left to read. */
return true;
} else {
/* Unexpected error. */
MONGOC_ERROR ("failed to read from pipe: %d", errno);
return false;
}
}
}
- /* Should never be reached. */
- BSON_ASSERT (false);
+
+ BSON_UNREACHABLE("reached unreachable code");
}
bool
_mongoc_interrupt_interrupt (mongoc_interrupt_t *interrupt)
{
bson_mutex_lock (&interrupt->mutex);
if (write (interrupt->impl.pipe_fds[1], "!", 1) == -1 &&
!MONGOC_ERRNO_IS_AGAIN (errno)) {
MONGOC_ERROR ("failed to write to pipe: %d", errno);
bson_mutex_unlock (&interrupt->mutex);
return false;
}
bson_mutex_unlock (&interrupt->mutex);
return true;
}
void
_mongoc_interrupt_destroy (mongoc_interrupt_t *interrupt)
{
if (!interrupt) {
return;
}
bson_mutex_destroy (&interrupt->mutex);
if (interrupt->impl.pipe_fds[0]) {
close (interrupt->impl.pipe_fds[0]);
}
if (interrupt->impl.pipe_fds[1]) {
close (interrupt->impl.pipe_fds[1]);
}
mongoc_stream_destroy (interrupt->stream);
bson_free (interrupt);
}
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
index d6c1fef9..dbd23fd3 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c
@@ -1,1187 +1,1189 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_OPENSSL
#include <bson/bson.h>
#include <limits.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/ocsp.h>
#include <openssl/x509v3.h>
#include <openssl/crypto.h>
#include <string.h>
#include "mongoc-http-private.h"
#include "mongoc-init.h"
#include "mongoc-openssl-private.h"
#include "mongoc-socket.h"
#include "mongoc-ssl.h"
#include "mongoc-stream-tls-openssl-private.h"
#include "mongoc-thread-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#ifdef MONGOC_ENABLE_OCSP_OPENSSL
#include "mongoc-ocsp-cache-private.h"
#endif
#ifdef _WIN32
#include <wincrypt.h>
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static bson_mutex_t *gMongocOpenSslThreadLocks;
static void
_mongoc_openssl_thread_startup (void);
static void
_mongoc_openssl_thread_cleanup (void);
#endif
#ifndef MONGOC_HAVE_ASN1_STRING_GET0_DATA
#define ASN1_STRING_get0_data ASN1_STRING_data
#endif
static int tlsfeature_nid;
/**
* _mongoc_openssl_init:
*
* initialization function for SSL
*
* This needs to get called early on and is not threadsafe. Called by
* mongoc_init.
*/
void
_mongoc_openssl_init (void)
{
SSL_CTX *ctx;
SSL_library_init ();
SSL_load_error_strings ();
ERR_load_BIO_strings ();
OpenSSL_add_all_algorithms ();
#if OPENSSL_VERSION_NUMBER < 0x10100000L
_mongoc_openssl_thread_startup ();
#endif
ctx = SSL_CTX_new (SSLv23_method ());
if (!ctx) {
MONGOC_ERROR ("Failed to initialize OpenSSL.");
}
#ifdef NID_tlsfeature
tlsfeature_nid = NID_tlsfeature;
#else
/* TLS versions before 1.1.0 did not define the TLS Feature extension. */
tlsfeature_nid =
OBJ_create ("1.3.6.1.5.5.7.1.24", "tlsfeature", "TLS Feature");
#endif
SSL_CTX_free (ctx);
}
void
_mongoc_openssl_cleanup (void)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
_mongoc_openssl_thread_cleanup ();
#endif
}
static int
_mongoc_openssl_password_cb (char *buf, int num, int rwflag, void *user_data)
{
char *pass = (char *) user_data;
int pass_len = (int) strlen (pass);
if (num < pass_len + 1) {
return 0;
}
bson_strncpy (buf, pass, num);
return pass_len;
}
#ifdef _WIN32
bool
_mongoc_openssl_import_cert_store (LPWSTR store_name,
DWORD dwFlags,
X509_STORE *openssl_store)
{
PCCERT_CONTEXT cert = NULL;
HCERTSTORE cert_store;
cert_store = CertOpenStore (
CERT_STORE_PROV_SYSTEM, /* provider */
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */
0, /* unused */
dwFlags, /* dwFlags */
store_name); /* system store name. "My" or "Root" */
if (cert_store == NULL) {
LPTSTR msg = NULL;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError (),
LANG_NEUTRAL,
(LPTSTR) &msg,
0,
NULL);
MONGOC_ERROR ("Can't open CA store: 0x%.8X: '%s'", GetLastError (), msg);
LocalFree (msg);
return false;
}
while ((cert = CertEnumCertificatesInStore (cert_store, cert)) != NULL) {
X509 *x509Obj = d2i_X509 (NULL,
(const unsigned char **) &cert->pbCertEncoded,
cert->cbCertEncoded);
if (x509Obj == NULL) {
MONGOC_WARNING (
"Error parsing X509 object from Windows certificate store");
continue;
}
X509_STORE_add_cert (openssl_store, x509Obj);
X509_free (x509Obj);
}
CertCloseStore (cert_store, 0);
return true;
}
bool
_mongoc_openssl_import_cert_stores (SSL_CTX *context)
{
bool retval;
X509_STORE *store = SSL_CTX_get_cert_store (context);
if (!store) {
MONGOC_WARNING ("no X509 store found for SSL context while loading "
"system certificates");
return false;
}
retval = _mongoc_openssl_import_cert_store (L"root",
CERT_SYSTEM_STORE_CURRENT_USER |
CERT_STORE_READONLY_FLAG,
store);
retval &= _mongoc_openssl_import_cert_store (
L"CA", CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, store);
return retval;
}
#endif
#if OPENSSL_VERSION_NUMBER > 0x10002000L
bool
_mongoc_openssl_check_peer_hostname (SSL *ssl,
const char *host,
bool allow_invalid_hostname)
{
X509 *peer = NULL;
if (allow_invalid_hostname) {
return true;
}
peer = SSL_get_peer_certificate (ssl);
if (peer && (X509_check_host (peer, host, 0, 0, NULL) == 1 ||
X509_check_ip_asc (peer, host, 0) == 1)) {
X509_free (peer);
return true;
}
if (peer) {
X509_free (peer);
}
return false;
}
#else
/** mongoc_openssl_hostcheck
*
* rfc 6125 match a given hostname against a given pattern
*
* Patterns come from DNS common names or subjectAltNames.
*
* This code is meant to implement RFC 6125 6.4.[1-3]
*
*/
static bool
_mongoc_openssl_hostcheck (const char *pattern, const char *hostname)
{
const char *pattern_label_end;
const char *pattern_wildcard;
const char *hostname_label_end;
size_t prefixlen;
size_t suffixlen;
TRACE ("Comparing '%s' == '%s'", pattern, hostname);
pattern_wildcard = strchr (pattern, '*');
if (pattern_wildcard == NULL) {
return strcasecmp (pattern, hostname) == 0;
}
pattern_label_end = strchr (pattern, '.');
/* Bail out on wildcarding in a couple of situations:
* o we don't have 2 dots - we're not going to wildcard root tlds
* o the wildcard isn't in the left most group (separated by dots)
* o the pattern is embedded in an A-label or U-label
*/
if (pattern_label_end == NULL ||
strchr (pattern_label_end + 1, '.') == NULL ||
pattern_wildcard > pattern_label_end ||
strncasecmp (pattern, "xn--", 4) == 0) {
return strcasecmp (pattern, hostname) == 0;
}
hostname_label_end = strchr (hostname, '.');
/* we know we have a dot in the pattern, we need one in the hostname */
if (hostname_label_end == NULL ||
strcasecmp (pattern_label_end, hostname_label_end)) {
return 0;
}
/* The wildcard must match at least one character, so the left part of the
* hostname is at least as large as the left part of the pattern. */
if ((hostname_label_end - hostname) < (pattern_label_end - pattern)) {
return 0;
}
/* If the left prefix group before the star matches and right of the star
* matches... we have a wildcard match */
prefixlen = pattern_wildcard - pattern;
suffixlen = pattern_label_end - (pattern_wildcard + 1);
return strncasecmp (pattern, hostname, prefixlen) == 0 &&
strncasecmp (pattern_wildcard + 1,
hostname_label_end - suffixlen,
suffixlen) == 0;
}
/** check if a provided cert matches a passed hostname
*/
bool
_mongoc_openssl_check_peer_hostname (SSL *ssl,
const char *host,
bool allow_invalid_hostname)
{
X509 *peer;
X509_NAME *subject_name;
X509_NAME_ENTRY *entry;
ASN1_STRING *entry_data;
int length;
int idx;
int r = 0;
long verify_status;
size_t addrlen = 0;
unsigned char addr4[sizeof (struct in_addr)];
unsigned char addr6[sizeof (struct in6_addr)];
int i;
int n_sans = -1;
int target = GEN_DNS;
STACK_OF (GENERAL_NAME) *sans = NULL;
ENTRY;
BSON_ASSERT (ssl);
BSON_ASSERT (host);
if (allow_invalid_hostname) {
RETURN (true);
}
/** if the host looks like an IP address, match that, otherwise we assume we
* have a DNS name */
if (inet_pton (AF_INET, host, &addr4)) {
target = GEN_IPADD;
addrlen = sizeof addr4;
} else if (inet_pton (AF_INET6, host, &addr6)) {
target = GEN_IPADD;
addrlen = sizeof addr6;
}
peer = SSL_get_peer_certificate (ssl);
if (!peer) {
MONGOC_WARNING ("SSL Certification verification failed: %s",
ERR_error_string (ERR_get_error (), NULL));
RETURN (false);
}
verify_status = SSL_get_verify_result (ssl);
if (verify_status == X509_V_OK) {
/* gets a stack of alt names that we can iterate through */
sans = (STACK_OF (GENERAL_NAME) *) X509_get_ext_d2i (
(X509 *) peer, NID_subject_alt_name, NULL, NULL);
if (sans) {
n_sans = sk_GENERAL_NAME_num (sans);
/* loop through the stack, or until we find a match */
for (i = 0; i < n_sans && !r; i++) {
const GENERAL_NAME *name = sk_GENERAL_NAME_value (sans, i);
/* skip entries that can't apply, I.e. IP entries if we've got a
* DNS host */
if (name->type == target) {
const char *check;
check = (const char *) ASN1_STRING_get0_data (name->d.ia5);
length = ASN1_STRING_length (name->d.ia5);
switch (target) {
case GEN_DNS:
/* check that we don't have an embedded null byte */
if ((length == bson_strnlen (check, length)) &&
_mongoc_openssl_hostcheck (check, host)) {
r = 1;
}
break;
case GEN_IPADD:
if (length == addrlen) {
if (length == sizeof addr6 &&
!memcmp (check, &addr6, length)) {
r = 1;
} else if (length == sizeof addr4 &&
!memcmp (check, &addr4, length)) {
r = 1;
}
}
break;
default:
BSON_ASSERT (0);
break;
}
}
}
GENERAL_NAMES_free (sans);
} else {
subject_name = X509_get_subject_name (peer);
if (subject_name) {
i = -1;
/* skip to the last common name */
while ((idx = X509_NAME_get_index_by_NID (
subject_name, NID_commonName, i)) >= 0) {
i = idx;
}
if (i >= 0) {
entry = X509_NAME_get_entry (subject_name, i);
entry_data = X509_NAME_ENTRY_get_data (entry);
if (entry_data) {
char *check;
/* TODO: I've heard tell that old versions of SSL crap out
* when calling ASN1_STRING_to_UTF8 on already utf8 data.
* Check up on that */
length = ASN1_STRING_to_UTF8 ((unsigned char **) &check,
entry_data);
if (length >= 0) {
/* check for embedded nulls */
if ((length == bson_strnlen (check, length)) &&
_mongoc_openssl_hostcheck (check, host)) {
r = 1;
}
OPENSSL_free (check);
}
}
}
}
}
}
X509_free (peer);
RETURN (r);
}
#endif /* OPENSSL_VERSION_NUMBER */
static bool
_mongoc_openssl_setup_ca (SSL_CTX *ctx, const char *cert, const char *cert_dir)
{
BSON_ASSERT (ctx);
BSON_ASSERT (cert || cert_dir);
if (!SSL_CTX_load_verify_locations (ctx, cert, cert_dir)) {
MONGOC_ERROR ("Cannot load Certificate Authorities from '%s' and '%s'",
cert,
cert_dir);
return 0;
}
return 1;
}
static bool
_mongoc_openssl_setup_crl (SSL_CTX *ctx, const char *crlfile)
{
X509_STORE *store;
X509_LOOKUP *lookup;
int status;
store = SSL_CTX_get_cert_store (ctx);
X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK);
lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ());
status = X509_load_crl_file (lookup, crlfile, X509_FILETYPE_PEM);
return status != 0;
}
static bool
_mongoc_openssl_setup_pem_file (SSL_CTX *ctx,
const char *pem_file,
const char *password)
{
if (!SSL_CTX_use_certificate_chain_file (ctx, pem_file)) {
MONGOC_ERROR ("Cannot find certificate in '%s'", pem_file);
return 0;
}
if (password) {
SSL_CTX_set_default_passwd_cb_userdata (ctx, (void *) password);
SSL_CTX_set_default_passwd_cb (ctx, _mongoc_openssl_password_cb);
}
if (!(SSL_CTX_use_PrivateKey_file (ctx, pem_file, SSL_FILETYPE_PEM))) {
MONGOC_ERROR ("Cannot find private key in: '%s'", pem_file);
return 0;
}
if (!(SSL_CTX_check_private_key (ctx))) {
MONGOC_ERROR ("Cannot load private key: '%s'", pem_file);
return 0;
}
return 1;
}
#ifdef MONGOC_ENABLE_OCSP_OPENSSL
static X509 *
_get_issuer (X509 *cert, STACK_OF (X509) * chain)
{
X509 *issuer = NULL, *candidate = NULL;
X509_NAME *issuer_name = NULL, *candidate_name = NULL;
int i;
issuer_name = X509_get_issuer_name (cert);
for (i = 0; i < sk_X509_num (chain) && issuer == NULL; i++) {
candidate = sk_X509_value (chain, i);
candidate_name = X509_get_subject_name (candidate);
if (0 == X509_NAME_cmp (candidate_name, issuer_name)) {
issuer = candidate;
}
}
RETURN (issuer);
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
/* OpenSSL 1.1.0+ has conveniences that we polyfill in older OpenSSL versions.
*/
STACK_OF (X509) * _get_verified_chain (SSL *ssl)
{
return SSL_get0_verified_chain (ssl);
}
void _free_verified_chain (STACK_OF (X509) * verified_chain)
{
/* _get_verified_chain does not return a copy. Do nothing. */
return;
}
const STACK_OF (X509_EXTENSION) * _get_extensions (const X509 *cert)
{
return X509_get0_extensions (cert);
}
#else
/* Polyfill functionality for pre 1.1.0 OpenSSL */
STACK_OF (X509) * _get_verified_chain (SSL *ssl)
{
X509_STORE *store = NULL;
X509 *peer = NULL;
STACK_OF (X509) *peer_chain = NULL;
X509_STORE_CTX *store_ctx = NULL;
STACK_OF (X509) *verified_chain = NULL;
/* Get the certificate the server presented. */
peer = SSL_get_peer_certificate (ssl);
/* Get the chain of certificates the server presented. This is not a verified
* chain. */
peer_chain = SSL_get_peer_cert_chain (ssl);
store = SSL_CTX_get_cert_store (SSL_get_SSL_CTX (ssl));
store_ctx = X509_STORE_CTX_new ();
if (!X509_STORE_CTX_init (store_ctx, store, peer, peer_chain)) {
MONGOC_ERROR ("failed to initialize X509 store");
goto fail;
}
if (X509_verify_cert (store_ctx) <= 0) {
MONGOC_ERROR ("failed to obtain verified chain");
goto fail;
}
verified_chain = X509_STORE_CTX_get1_chain (store_ctx);
fail:
X509_free (peer);
X509_STORE_CTX_free (store_ctx);
return verified_chain;
}
/* On OpenSSL < 1.1.0, this chain isn't attached to the SSL session, so we need
* it to dispose of itself. */
void _free_verified_chain (STACK_OF (X509) * verified_chain)
{
if (!verified_chain) {
return;
}
sk_X509_pop_free (verified_chain, X509_free);
}
const STACK_OF (X509_EXTENSION) * _get_extensions (const X509 *cert)
{
return cert->cert_info->extensions;
}
#endif /* OPENSSL_VERSION_NUMBER */
#define TLSFEATURE_STATUS_REQUEST 5
/* Check a tlsfeature extension contents for a status_request.
*
* Parse just enough of a DER encoded data to check if a SEQUENCE of INTEGER
* contains the status_request extension (5). There are only five tlsfeature
* extension types, so this only handles the case that the sequence's length is
* representable in one byte, and that each integer is representable in one
* byte. */
bool
_mongoc_tlsfeature_has_status_request (const uint8_t *data, int length)
{
int i;
/* Expect a sequence type, with a sequence length representable in one byte.
*/
if (length < 3 || data[0] != 0x30 || data[1] >= 127) {
MONGOC_ERROR ("malformed tlsfeature extension sequence");
return false;
}
for (i = 2; i < length; i += 3) {
/* Expect an integer, representable in one byte. */
if (length < i + 3 || data[i] != 0x02 || data[i + 1] != 1) {
MONGOC_ERROR ("malformed tlsfeature extension integer");
return false;
}
if (data[i + 2] == TLSFEATURE_STATUS_REQUEST) {
TRACE ("%s", "found status request in tlsfeature extension");
return true;
}
}
return false;
}
/* Check that the certificate has a tlsfeature extension with status_request. */
bool
_get_must_staple (X509 *cert)
{
const STACK_OF (X509_EXTENSION) *exts = NULL;
X509_EXTENSION *ext;
ASN1_STRING *ext_data;
int idx;
exts = _get_extensions (cert);
if (!exts) {
TRACE ("%s", "certificate extensions not found");
return false;
}
idx = X509v3_get_ext_by_NID (exts, tlsfeature_nid, -1);
if (-1 == idx) {
TRACE ("%s", "tlsfeature extension not found");
return false;
}
ext = sk_X509_EXTENSION_value (exts, idx);
ext_data = X509_EXTENSION_get_data (ext);
/* Data is a DER encoded sequence of integers. */
return _mongoc_tlsfeature_has_status_request (
ASN1_STRING_get0_data (ext_data), ASN1_STRING_length (ext_data));
}
#define ERR_STR (ERR_error_string (ERR_get_error (), NULL))
#define MONGOC_OCSP_REQUEST_TIMEOUT_MS 5000
static OCSP_RESPONSE *
_contact_ocsp_responder (OCSP_CERTID *id,
X509 *peer,
mongoc_ssl_opt_t *ssl_opts,
int *ocsp_uri_count)
{
STACK_OF (OPENSSL_STRING) *url_stack = NULL;
OPENSSL_STRING url = NULL, host = NULL, path = NULL, port = NULL;
OCSP_REQUEST *req = NULL;
const unsigned char *resp_data;
OCSP_RESPONSE *resp = NULL;
int i, ssl;
url_stack = X509_get1_ocsp (peer);
*ocsp_uri_count = sk_OPENSSL_STRING_num (url_stack);
for (i = 0; i < *ocsp_uri_count && !resp; i++) {
unsigned char *request_der = NULL;
int request_der_len;
mongoc_http_request_t http_req;
mongoc_http_response_t http_res;
bson_error_t error;
_mongoc_http_request_init (&http_req);
_mongoc_http_response_init (&http_res);
url = sk_OPENSSL_STRING_value (url_stack, i);
TRACE ("Contacting OCSP responder '%s'", url);
/* splits the given url into its host, port and path components */
if (!OCSP_parse_url (url, &host, &port, &path, &ssl)) {
MONGOC_DEBUG ("Could not parse URL");
GOTO (retry);
}
if (!(req = OCSP_REQUEST_new ())) {
MONGOC_DEBUG ("Could not create new OCSP request");
GOTO (retry);
}
/* add the cert ID to the OCSP request object */
if (!id || !OCSP_request_add0_id (req, OCSP_CERTID_dup (id))) {
MONGOC_DEBUG ("Could not add cert ID to the OCSP request object");
GOTO (retry);
}
/* add nonce to OCSP request object */
if (!OCSP_request_add1_nonce (req, 0 /* use random nonce */, -1)) {
MONGOC_DEBUG ("Could not add nonce to OCSP request object");
GOTO (retry);
}
request_der_len = i2d_OCSP_REQUEST (req, &request_der);
if (request_der_len < 0) {
MONGOC_DEBUG ("Could not encode OCSP request");
GOTO (retry);
}
http_req.method = "POST";
http_req.extra_headers = "Content-Type: application/ocsp-request\r\n";
http_req.host = host;
http_req.path = path;
http_req.port = (int) bson_ascii_strtoll (port, NULL, 10);
http_req.body = (const char *) request_der;
http_req.body_len = request_der_len;
if (!_mongoc_http_send (&http_req,
MONGOC_OCSP_REQUEST_TIMEOUT_MS,
ssl != 0,
ssl_opts,
&http_res,
&error)) {
MONGOC_DEBUG ("Could not send HTTP request: %s", error.message);
GOTO (retry);
}
resp_data = (const unsigned char *) http_res.body;
if (http_res.body_len == 0 ||
!d2i_OCSP_RESPONSE (&resp, &resp_data, http_res.body_len)) {
MONGOC_DEBUG ("Could not parse OCSP response from HTTP response");
MONGOC_DEBUG ("Response headers: %s", http_res.headers);
GOTO (retry);
}
retry:
if (host)
OPENSSL_free (host);
if (port)
OPENSSL_free (port);
if (path)
OPENSSL_free (path);
if (req)
OCSP_REQUEST_free (req);
if (request_der)
OPENSSL_free (request_der);
_mongoc_http_response_cleanup (&http_res);
}
if (url_stack)
X509_email_free (url_stack);
RETURN (resp);
}
#define SOFT_FAIL(...) \
((stapled_response) ? MONGOC_ERROR (__VA_ARGS__) \
: MONGOC_DEBUG (__VA_ARGS__))
#define X509_CHECK_SUCCESS 1
#define OCSP_VERIFY_SUCCESS 1
int
_mongoc_ocsp_tlsext_status (SSL *ssl, mongoc_openssl_ocsp_opt_t *opts)
{
enum { OCSP_CB_ERROR = -1, OCSP_CB_REVOKED, OCSP_CB_SUCCESS } ret;
bool stapled_response = true;
bool must_staple;
OCSP_RESPONSE *resp = NULL;
OCSP_BASICRESP *basic = NULL;
X509_STORE *store = NULL;
X509 *peer = NULL, *issuer = NULL;
STACK_OF (X509) *cert_chain = NULL;
const unsigned char *resp_data = NULL;
+ unsigned char *mutable_resp_data = NULL;
int cert_status, reason, len, status;
OCSP_CERTID *id = NULL;
ASN1_GENERALIZEDTIME *produced_at = NULL, *this_update = NULL,
*next_update = NULL;
int ocsp_uri_count = 0;
if (opts->weak_cert_validation) {
return OCSP_CB_SUCCESS;
}
if (!(peer = SSL_get_peer_certificate (ssl))) {
MONGOC_ERROR ("No certificate was presented by the peer");
ret = OCSP_CB_ERROR;
GOTO (done);
}
/* Get a STACK_OF(X509) certs forming the cert chain of the peer, including
* the peer's cert */
if (!(cert_chain = _get_verified_chain (ssl))) {
MONGOC_ERROR ("Unable to obtain verified chain");
ret = OCSP_CB_REVOKED;
GOTO (done);
}
if (!(issuer = _get_issuer (peer, cert_chain))) {
MONGOC_ERROR ("Could not get issuer from peer cert");
ret = OCSP_CB_ERROR;
GOTO (done);
}
if (!(id = OCSP_cert_to_id (NULL /* SHA1 */, peer, issuer))) {
MONGOC_ERROR ("Could not obtain a valid OCSP_CERTID for peer");
ret = OCSP_CB_ERROR;
GOTO (done);
}
if (_mongoc_ocsp_cache_get_status (
id, &cert_status, &reason, &this_update, &next_update)) {
GOTO (validate);
}
/* Get the stapled OCSP response returned by the server */
- len = SSL_get_tlsext_status_ocsp_resp (ssl, &resp_data);
+ len = SSL_get_tlsext_status_ocsp_resp (ssl, &mutable_resp_data);
+ resp_data = mutable_resp_data;
stapled_response = !!resp_data;
if (stapled_response) {
/* obtain an OCSP_RESPONSE object from the OCSP response */
if (!d2i_OCSP_RESPONSE (&resp, &resp_data, len)) {
MONGOC_ERROR ("Failed to parse OCSP response");
ret = OCSP_CB_ERROR;
GOTO (done);
}
} else {
TRACE ("%s", "Server does not contain a stapled response");
must_staple = _get_must_staple (peer);
if (must_staple) {
MONGOC_ERROR ("Server must contain a stapled response");
ret = OCSP_CB_REVOKED;
GOTO (done);
}
if (opts->disable_endpoint_check ||
!(resp = _contact_ocsp_responder (
id, peer, &opts->ssl_opts, &ocsp_uri_count))) {
if (ocsp_uri_count > 0) {
/* Only log a soft failure if there were OCSP responders listed in
* the certificate. */
MONGOC_DEBUG ("Soft-fail: No OCSP responder could be reached");
}
ret = OCSP_CB_SUCCESS;
GOTO (done);
}
}
TRACE ("%s", "Validating OCSP response");
/* Validate the OCSP response status of the OCSP_RESPONSE object */
status = OCSP_response_status (resp);
if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
SOFT_FAIL ("OCSP response error %d %s",
status,
OCSP_response_status_str (status));
ret = OCSP_CB_ERROR;
GOTO (done);
}
TRACE ("%s", "OCSP response status successful");
/* Get the OCSP_BASICRESP structure contained in OCSP_RESPONSE object for the
* peer cert */
basic = OCSP_response_get1_basic (resp);
if (!basic) {
SOFT_FAIL ("Could not find BasicOCSPResponse: %s", ERR_STR);
ret = OCSP_CB_ERROR;
GOTO (done);
}
store = SSL_CTX_get_cert_store (SSL_get_SSL_CTX (ssl));
/*
* checks that the basic response message is correctly signed and that the
* signer certificate can be validated.
* 1. The function first verifies the signer cert of the response is in the
* given cert chain.
* 2. Next, the function verifies the signature of the basic response.
* 3. Finally, the function validates the signer cert, constructing the
* validation path via the untrusted cert chain.
*
* cert_chain has already been verified. Use OCSP_TRUSTOTHER so the signer
* certificate can be considered verified if it is in cert_chain.
*/
if (OCSP_basic_verify (basic, cert_chain, store, OCSP_TRUSTOTHER) !=
OCSP_VERIFY_SUCCESS) {
SOFT_FAIL ("OCSP response failed verification: %s", ERR_STR);
ret = OCSP_CB_ERROR;
GOTO (done);
}
/* searches the basic response for an OCSP response for the given cert ID */
if (!OCSP_resp_find_status (basic,
id,
&cert_status,
&reason,
&produced_at,
&this_update,
&next_update)) {
SOFT_FAIL ("No OCSP response found for the peer certificate");
ret = OCSP_CB_ERROR;
GOTO (done);
}
/* checks the validity of this_update and next_update values */
if (!OCSP_check_validity (this_update, next_update, 0L, -1L)) {
SOFT_FAIL ("OCSP response has expired: %s", ERR_STR);
ret = OCSP_CB_ERROR;
GOTO (done);
}
validate:
switch (cert_status) {
case V_OCSP_CERTSTATUS_GOOD:
TRACE ("%s", "OCSP Certificate Status: Good");
_mongoc_ocsp_cache_set_resp (
id, cert_status, reason, this_update, next_update);
break;
case V_OCSP_CERTSTATUS_REVOKED:
MONGOC_ERROR ("OCSP Certificate Status: Revoked. Reason: %s",
OCSP_crl_reason_str (reason));
ret = OCSP_CB_REVOKED;
_mongoc_ocsp_cache_set_resp (
id, cert_status, reason, this_update, next_update);
GOTO (done);
default:
MONGOC_DEBUG ("OCSP Certificate Status: Unknown");
break;
}
/* Validate hostname matches cert */
if (!_mongoc_openssl_check_peer_hostname (
ssl, opts->host, opts->allow_invalid_hostname)) {
ret = OCSP_CB_REVOKED;
GOTO (done);
}
ret = OCSP_CB_SUCCESS;
done:
if (ret == OCSP_CB_ERROR && !stapled_response) {
ret = OCSP_CB_SUCCESS;
}
if (basic)
OCSP_BASICRESP_free (basic);
if (resp)
OCSP_RESPONSE_free (resp);
if (id)
OCSP_CERTID_free (id);
if (peer)
X509_free (peer);
if (cert_chain)
_free_verified_chain (cert_chain);
RETURN (ret);
}
#endif /* MONGOC_ENABLE_OCSP_OPENSSL */
/**
* _mongoc_openssl_ctx_new:
*
* Create a new ssl context declaratively
*
* The opt.pem_pwd parameter, if passed, must exist for the life of this
* context object (for storing and loading the associated pem file)
*/
SSL_CTX *
_mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt)
{
SSL_CTX *ctx = NULL;
int ssl_ctx_options = 0;
/*
* Ensure we are initialized. This is safe to call multiple times.
*/
mongoc_init ();
ctx = SSL_CTX_new (SSLv23_method ());
BSON_ASSERT (ctx);
/* SSL_OP_ALL - Activate all bug workaround options, to support buggy client
* SSL's. */
ssl_ctx_options |= SSL_OP_ALL;
/* SSL_OP_NO_SSLv2 - Disable SSL v2 support */
ssl_ctx_options |= SSL_OP_NO_SSLv2;
/* Disable compression, if we can.
* OpenSSL 0.9.x added compression support which was always enabled when built
* against zlib
* OpenSSL 1.0.0 added the ability to disable it, while keeping it enabled by
* default
* OpenSSL 1.1.0 disabled it by default.
*/
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
#endif
/* man SSL_get_options says: "SSL_OP_NO_RENEGOTIATION options were added in
* OpenSSL 1.1.1". */
#ifdef SSL_OP_NO_RENEGOTIATION
ssl_ctx_options |= SSL_OP_NO_RENEGOTIATION;
#endif
SSL_CTX_set_options (ctx, ssl_ctx_options);
/* only defined in special build, using:
* --enable-system-crypto-profile (autotools)
* -DENABLE_CRYPTO_SYSTEM_PROFILE:BOOL=ON (cmake) */
#ifndef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE
/* HIGH - Enable strong ciphers
* !EXPORT - Disable export ciphers (40/56 bit)
* !aNULL - Disable anonymous auth ciphers
* @STRENGTH - Sort ciphers based on strength */
SSL_CTX_set_cipher_list (ctx, "HIGH:!EXPORT:!aNULL@STRENGTH");
#endif
/* If renegotiation is needed, don't return from recv() or send() until it's
* successful.
* Note: this is for blocking sockets only. */
SSL_CTX_set_mode (ctx, SSL_MODE_AUTO_RETRY);
/* Load my private keys to present to the server */
if (opt->pem_file &&
!_mongoc_openssl_setup_pem_file (ctx, opt->pem_file, opt->pem_pwd)) {
SSL_CTX_free (ctx);
return NULL;
}
/* Load in my Certificate Authority, to verify the server against
* If none provided, fallback to the distro defaults */
if (opt->ca_file || opt->ca_dir) {
if (!_mongoc_openssl_setup_ca (ctx, opt->ca_file, opt->ca_dir)) {
SSL_CTX_free (ctx);
return NULL;
}
} else {
/* If the server certificate is issued by known CA we trust it by default */
#ifdef _WIN32
_mongoc_openssl_import_cert_stores (ctx);
#else
SSL_CTX_set_default_verify_paths (ctx);
#endif
}
/* Load my revocation list, to verify the server against */
if (opt->crl_file && !_mongoc_openssl_setup_crl (ctx, opt->crl_file)) {
SSL_CTX_free (ctx);
return NULL;
}
return ctx;
}
char *
_mongoc_openssl_extract_subject (const char *filename, const char *passphrase)
{
X509_NAME *subject = NULL;
X509 *cert = NULL;
BIO *certbio = NULL;
BIO *strbio = NULL;
char *str = NULL;
int ret;
if (!filename) {
return NULL;
}
certbio = BIO_new (BIO_s_file ());
strbio = BIO_new (BIO_s_mem ());
;
BSON_ASSERT (certbio);
BSON_ASSERT (strbio);
if (BIO_read_filename (certbio, filename) &&
(cert = PEM_read_bio_X509 (certbio, NULL, 0, NULL))) {
if ((subject = X509_get_subject_name (cert))) {
ret = X509_NAME_print_ex (strbio, subject, 0, XN_FLAG_RFC2253);
if ((ret > 0) && (ret < INT_MAX)) {
str = (char *) bson_malloc (ret + 2);
BIO_gets (strbio, str, ret + 1);
str[ret] = '\0';
}
}
}
if (cert) {
X509_free (cert);
}
if (certbio) {
BIO_free (certbio);
}
if (strbio) {
BIO_free (strbio);
}
return str;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef _WIN32
static unsigned long
_mongoc_openssl_thread_id_callback (void)
{
unsigned long ret;
ret = (unsigned long) GetCurrentThreadId ();
return ret;
}
#else
static unsigned long
_mongoc_openssl_thread_id_callback (void)
{
unsigned long ret;
ret = (unsigned long) pthread_self ();
return ret;
}
#endif
static void
_mongoc_openssl_thread_locking_callback (int mode,
int type,
const char *file,
int line)
{
if (mode & CRYPTO_LOCK) {
bson_mutex_lock (&gMongocOpenSslThreadLocks[type]);
} else {
bson_mutex_unlock (&gMongocOpenSslThreadLocks[type]);
}
}
static void
_mongoc_openssl_thread_startup (void)
{
int i;
gMongocOpenSslThreadLocks = (bson_mutex_t *) OPENSSL_malloc (
CRYPTO_num_locks () * sizeof (bson_mutex_t));
for (i = 0; i < CRYPTO_num_locks (); i++) {
bson_mutex_init (&gMongocOpenSslThreadLocks[i]);
}
if (!CRYPTO_get_locking_callback ()) {
CRYPTO_set_locking_callback (_mongoc_openssl_thread_locking_callback);
CRYPTO_set_id_callback (_mongoc_openssl_thread_id_callback);
}
}
static void
_mongoc_openssl_thread_cleanup (void)
{
int i;
if (CRYPTO_get_locking_callback () ==
_mongoc_openssl_thread_locking_callback) {
CRYPTO_set_locking_callback (NULL);
}
if (CRYPTO_get_id_callback () == _mongoc_openssl_thread_id_callback) {
CRYPTO_set_id_callback (NULL);
}
for (i = 0; i < CRYPTO_num_locks (); i++) {
bson_mutex_destroy (&gMongocOpenSslThreadLocks[i]);
}
OPENSSL_free (gMongocOpenSslThreadLocks);
}
#endif
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
index 9d5e9e18..0f9e38dc 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h
@@ -1,410 +1,420 @@
#include "mongoc-prelude.h"
#ifndef MONGOC_OPTS_H
#define MONGOC_OPTS_H
#include <bson/bson.h>
#include "mongoc-client-session.h"
#include "mongoc-bulk-operation-private.h"
#include "mongoc-opts-helpers-private.h"
/**************************************************
*
* Generated by build/generate-opts.py.
*
* DO NOT EDIT THIS FILE.
*
*************************************************/
/* clang-format off */
typedef struct _mongoc_crud_opts_t {
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bson_validate_flags_t validate;
+ bson_value_t comment;
} mongoc_crud_opts_t;
typedef struct _mongoc_update_opts_t {
mongoc_crud_opts_t crud;
bool bypass;
bson_t collation;
bson_value_t hint;
bool upsert;
+ bson_t let;
} mongoc_update_opts_t;
typedef struct _mongoc_insert_one_opts_t {
mongoc_crud_opts_t crud;
bool bypass;
bson_t extra;
} mongoc_insert_one_opts_t;
typedef struct _mongoc_insert_many_opts_t {
mongoc_crud_opts_t crud;
bool ordered;
bool bypass;
bson_t extra;
} mongoc_insert_many_opts_t;
typedef struct _mongoc_delete_opts_t {
mongoc_crud_opts_t crud;
bson_t collation;
bson_value_t hint;
+ bson_t let;
} mongoc_delete_opts_t;
typedef struct _mongoc_delete_one_opts_t {
mongoc_delete_opts_t delete;
bson_t extra;
} mongoc_delete_one_opts_t;
typedef struct _mongoc_delete_many_opts_t {
mongoc_delete_opts_t delete;
bson_t extra;
} mongoc_delete_many_opts_t;
typedef struct _mongoc_update_one_opts_t {
mongoc_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_update_one_opts_t;
typedef struct _mongoc_update_many_opts_t {
mongoc_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_update_many_opts_t;
typedef struct _mongoc_replace_one_opts_t {
mongoc_update_opts_t update;
bson_t extra;
} mongoc_replace_one_opts_t;
typedef struct _mongoc_bulk_opts_t {
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
bool ordered;
mongoc_client_session_t *client_session;
+ bson_t let;
+ bson_value_t comment;
bson_t extra;
} mongoc_bulk_opts_t;
typedef struct _mongoc_bulk_insert_opts_t {
bson_validate_flags_t validate;
bson_t extra;
} mongoc_bulk_insert_opts_t;
typedef struct _mongoc_bulk_update_opts_t {
bson_validate_flags_t validate;
bson_t collation;
bson_value_t hint;
bool upsert;
bool multi;
} mongoc_bulk_update_opts_t;
typedef struct _mongoc_bulk_update_one_opts_t {
mongoc_bulk_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_bulk_update_one_opts_t;
typedef struct _mongoc_bulk_update_many_opts_t {
mongoc_bulk_update_opts_t update;
bson_t arrayFilters;
bson_t extra;
} mongoc_bulk_update_many_opts_t;
typedef struct _mongoc_bulk_replace_one_opts_t {
mongoc_bulk_update_opts_t update;
bson_t extra;
} mongoc_bulk_replace_one_opts_t;
typedef struct _mongoc_bulk_remove_opts_t {
bson_t collation;
bson_value_t hint;
int32_t limit;
} mongoc_bulk_remove_opts_t;
typedef struct _mongoc_bulk_remove_one_opts_t {
mongoc_bulk_remove_opts_t remove;
bson_t extra;
} mongoc_bulk_remove_one_opts_t;
typedef struct _mongoc_bulk_remove_many_opts_t {
mongoc_bulk_remove_opts_t remove;
bson_t extra;
} mongoc_bulk_remove_many_opts_t;
typedef struct _mongoc_change_stream_opts_t {
int32_t batchSize;
bson_t resumeAfter;
bson_t startAfter;
mongoc_timestamp_t startAtOperationTime;
int64_t maxAwaitTimeMS;
const char *fullDocument;
+ const char *fullDocumentBeforeChange;
+ bson_value_t comment;
bson_t extra;
} mongoc_change_stream_opts_t;
typedef struct _mongoc_create_index_opts_t {
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bson_t extra;
} mongoc_create_index_opts_t;
typedef struct _mongoc_read_write_opts_t {
bson_t readConcern;
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bson_t collation;
uint32_t serverId;
bson_t extra;
} mongoc_read_write_opts_t;
typedef struct _mongoc_gridfs_bucket_opts_t {
const char *bucketName;
int32_t chunkSizeBytes;
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_read_concern_t *readConcern;
bson_t extra;
} mongoc_gridfs_bucket_opts_t;
typedef struct _mongoc_gridfs_bucket_upload_opts_t {
int32_t chunkSizeBytes;
bson_t metadata;
bson_t extra;
} mongoc_gridfs_bucket_upload_opts_t;
typedef struct _mongoc_aggregate_opts_t {
mongoc_read_concern_t *readConcern;
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bool bypass;
bson_t collation;
uint32_t serverId;
int32_t batchSize;
bool batchSize_is_set;
bson_t let;
+ bson_value_t comment;
bson_t extra;
} mongoc_aggregate_opts_t;
typedef struct _mongoc_find_and_modify_appended_opts_t {
mongoc_write_concern_t *writeConcern;
bool write_concern_owned;
mongoc_client_session_t *client_session;
bson_value_t hint;
+ bson_t let;
+ bson_value_t comment;
bson_t extra;
} mongoc_find_and_modify_appended_opts_t;
bool
_mongoc_insert_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_one_opts_t *mongoc_insert_one_opts,
bson_error_t *error);
void
_mongoc_insert_one_opts_cleanup (mongoc_insert_one_opts_t *mongoc_insert_one_opts);
bool
_mongoc_insert_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_many_opts_t *mongoc_insert_many_opts,
bson_error_t *error);
void
_mongoc_insert_many_opts_cleanup (mongoc_insert_many_opts_t *mongoc_insert_many_opts);
bool
_mongoc_delete_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_one_opts_t *mongoc_delete_one_opts,
bson_error_t *error);
void
_mongoc_delete_one_opts_cleanup (mongoc_delete_one_opts_t *mongoc_delete_one_opts);
bool
_mongoc_delete_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_many_opts_t *mongoc_delete_many_opts,
bson_error_t *error);
void
_mongoc_delete_many_opts_cleanup (mongoc_delete_many_opts_t *mongoc_delete_many_opts);
bool
_mongoc_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_one_opts_t *mongoc_update_one_opts,
bson_error_t *error);
void
_mongoc_update_one_opts_cleanup (mongoc_update_one_opts_t *mongoc_update_one_opts);
bool
_mongoc_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_many_opts_t *mongoc_update_many_opts,
bson_error_t *error);
void
_mongoc_update_many_opts_cleanup (mongoc_update_many_opts_t *mongoc_update_many_opts);
bool
_mongoc_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_replace_one_opts_t *mongoc_replace_one_opts,
bson_error_t *error);
void
_mongoc_replace_one_opts_cleanup (mongoc_replace_one_opts_t *mongoc_replace_one_opts);
bool
_mongoc_bulk_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_opts_t *mongoc_bulk_opts,
bson_error_t *error);
void
_mongoc_bulk_opts_cleanup (mongoc_bulk_opts_t *mongoc_bulk_opts);
bool
_mongoc_bulk_insert_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts,
bson_error_t *error);
void
_mongoc_bulk_insert_opts_cleanup (mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts);
bool
_mongoc_bulk_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts,
bson_error_t *error);
void
_mongoc_bulk_update_one_opts_cleanup (mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts);
bool
_mongoc_bulk_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts,
bson_error_t *error);
void
_mongoc_bulk_update_many_opts_cleanup (mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts);
bool
_mongoc_bulk_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts,
bson_error_t *error);
void
_mongoc_bulk_replace_one_opts_cleanup (mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts);
bool
_mongoc_bulk_remove_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts,
bson_error_t *error);
void
_mongoc_bulk_remove_one_opts_cleanup (mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts);
bool
_mongoc_bulk_remove_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts,
bson_error_t *error);
void
_mongoc_bulk_remove_many_opts_cleanup (mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts);
bool
_mongoc_change_stream_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_change_stream_opts_t *mongoc_change_stream_opts,
bson_error_t *error);
void
_mongoc_change_stream_opts_cleanup (mongoc_change_stream_opts_t *mongoc_change_stream_opts);
bool
_mongoc_create_index_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_create_index_opts_t *mongoc_create_index_opts,
bson_error_t *error);
void
_mongoc_create_index_opts_cleanup (mongoc_create_index_opts_t *mongoc_create_index_opts);
bool
_mongoc_read_write_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_read_write_opts_t *mongoc_read_write_opts,
bson_error_t *error);
void
_mongoc_read_write_opts_cleanup (mongoc_read_write_opts_t *mongoc_read_write_opts);
bool
_mongoc_gridfs_bucket_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts,
bson_error_t *error);
void
_mongoc_gridfs_bucket_opts_cleanup (mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts);
bool
_mongoc_gridfs_bucket_upload_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts,
bson_error_t *error);
void
_mongoc_gridfs_bucket_upload_opts_cleanup (mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts);
bool
_mongoc_aggregate_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_aggregate_opts_t *mongoc_aggregate_opts,
bson_error_t *error);
void
_mongoc_aggregate_opts_cleanup (mongoc_aggregate_opts_t *mongoc_aggregate_opts);
bool
_mongoc_find_and_modify_appended_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts,
bson_error_t *error);
void
_mongoc_find_and_modify_appended_opts_cleanup (mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts);
#endif /* MONGOC_OPTS_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
similarity index 89%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
index b0f50129..d24d78ae 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c
@@ -1,2093 +1,2301 @@
#include "mongoc-opts-helpers-private.h"
#include "mongoc-opts-private.h"
#include "mongoc-error.h"
#include "mongoc-util-private.h"
#include "mongoc-client-private.h"
/**************************************************
*
* Generated by build/generate-opts.py.
*
* DO NOT EDIT THIS FILE.
*
*************************************************/
/* clang-format off */
bool
_mongoc_insert_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_one_opts_t *mongoc_insert_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_insert_one_opts->crud.writeConcern = NULL;
mongoc_insert_one_opts->crud.write_concern_owned = false;
mongoc_insert_one_opts->crud.client_session = NULL;
mongoc_insert_one_opts->crud.validate = _mongoc_default_insert_vflags;
+ memset (&mongoc_insert_one_opts->crud.comment, 0, sizeof (bson_value_t));
mongoc_insert_one_opts->bypass = false;
bson_init (&mongoc_insert_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_insert_one_opts->crud.writeConcern,
error)) {
return false;
}
mongoc_insert_one_opts->crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_insert_one_opts->crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_insert_one_opts->crud.validate,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_insert_one_opts->crud.comment,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_insert_one_opts->bypass,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_insert_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_insert_one_opts_cleanup (mongoc_insert_one_opts_t *mongoc_insert_one_opts)
{
if (mongoc_insert_one_opts->crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_insert_one_opts->crud.writeConcern);
}
+ bson_value_destroy (&mongoc_insert_one_opts->crud.comment);
bson_destroy (&mongoc_insert_one_opts->extra);
}
bool
_mongoc_insert_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_insert_many_opts_t *mongoc_insert_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_insert_many_opts->crud.writeConcern = NULL;
mongoc_insert_many_opts->crud.write_concern_owned = false;
mongoc_insert_many_opts->crud.client_session = NULL;
mongoc_insert_many_opts->crud.validate = _mongoc_default_insert_vflags;
+ memset (&mongoc_insert_many_opts->crud.comment, 0, sizeof (bson_value_t));
mongoc_insert_many_opts->ordered = true;
mongoc_insert_many_opts->bypass = false;
bson_init (&mongoc_insert_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_insert_many_opts->crud.writeConcern,
error)) {
return false;
}
mongoc_insert_many_opts->crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_insert_many_opts->crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_insert_many_opts->crud.validate,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_insert_many_opts->crud.comment,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "ordered")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_insert_many_opts->ordered,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_insert_many_opts->bypass,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_insert_many_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_insert_many_opts_cleanup (mongoc_insert_many_opts_t *mongoc_insert_many_opts)
{
if (mongoc_insert_many_opts->crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_insert_many_opts->crud.writeConcern);
}
+ bson_value_destroy (&mongoc_insert_many_opts->crud.comment);
bson_destroy (&mongoc_insert_many_opts->extra);
}
bool
_mongoc_delete_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_one_opts_t *mongoc_delete_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_delete_one_opts->delete.crud.writeConcern = NULL;
mongoc_delete_one_opts->delete.crud.write_concern_owned = false;
mongoc_delete_one_opts->delete.crud.client_session = NULL;
mongoc_delete_one_opts->delete.crud.validate = BSON_VALIDATE_NONE;
+ memset (&mongoc_delete_one_opts->delete.crud.comment, 0, sizeof (bson_value_t));
bson_init (&mongoc_delete_one_opts->delete.collation);
memset (&mongoc_delete_one_opts->delete.hint, 0, sizeof (bson_value_t));
+ bson_init (&mongoc_delete_one_opts->delete.let);
bson_init (&mongoc_delete_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_delete_one_opts->delete.crud.writeConcern,
error)) {
return false;
}
mongoc_delete_one_opts->delete.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_delete_one_opts->delete.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_delete_one_opts->delete.crud.validate,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_delete_one_opts->delete.crud.comment,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_delete_one_opts->delete.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_delete_one_opts->delete.hint,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "let")) {
+ if (!_mongoc_convert_document (
+ client,
+ &iter,
+ &mongoc_delete_one_opts->delete.let,
+ error)) {
+ return false;
+ }
+ }
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_delete_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_delete_one_opts_cleanup (mongoc_delete_one_opts_t *mongoc_delete_one_opts)
{
if (mongoc_delete_one_opts->delete.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_delete_one_opts->delete.crud.writeConcern);
}
+ bson_value_destroy (&mongoc_delete_one_opts->delete.crud.comment);
bson_destroy (&mongoc_delete_one_opts->delete.collation);
bson_value_destroy (&mongoc_delete_one_opts->delete.hint);
+ bson_destroy (&mongoc_delete_one_opts->delete.let);
bson_destroy (&mongoc_delete_one_opts->extra);
}
bool
_mongoc_delete_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_delete_many_opts_t *mongoc_delete_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_delete_many_opts->delete.crud.writeConcern = NULL;
mongoc_delete_many_opts->delete.crud.write_concern_owned = false;
mongoc_delete_many_opts->delete.crud.client_session = NULL;
mongoc_delete_many_opts->delete.crud.validate = BSON_VALIDATE_NONE;
+ memset (&mongoc_delete_many_opts->delete.crud.comment, 0, sizeof (bson_value_t));
bson_init (&mongoc_delete_many_opts->delete.collation);
memset (&mongoc_delete_many_opts->delete.hint, 0, sizeof (bson_value_t));
+ bson_init (&mongoc_delete_many_opts->delete.let);
bson_init (&mongoc_delete_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_delete_many_opts->delete.crud.writeConcern,
error)) {
return false;
}
mongoc_delete_many_opts->delete.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_delete_many_opts->delete.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_delete_many_opts->delete.crud.validate,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_delete_many_opts->delete.crud.comment,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_delete_many_opts->delete.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_delete_many_opts->delete.hint,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "let")) {
+ if (!_mongoc_convert_document (
+ client,
+ &iter,
+ &mongoc_delete_many_opts->delete.let,
+ error)) {
+ return false;
+ }
+ }
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_delete_many_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_delete_many_opts_cleanup (mongoc_delete_many_opts_t *mongoc_delete_many_opts)
{
if (mongoc_delete_many_opts->delete.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_delete_many_opts->delete.crud.writeConcern);
}
+ bson_value_destroy (&mongoc_delete_many_opts->delete.crud.comment);
bson_destroy (&mongoc_delete_many_opts->delete.collation);
bson_value_destroy (&mongoc_delete_many_opts->delete.hint);
+ bson_destroy (&mongoc_delete_many_opts->delete.let);
bson_destroy (&mongoc_delete_many_opts->extra);
}
bool
_mongoc_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_one_opts_t *mongoc_update_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_update_one_opts->update.crud.writeConcern = NULL;
mongoc_update_one_opts->update.crud.write_concern_owned = false;
mongoc_update_one_opts->update.crud.client_session = NULL;
mongoc_update_one_opts->update.crud.validate = _mongoc_default_update_vflags;
+ memset (&mongoc_update_one_opts->update.crud.comment, 0, sizeof (bson_value_t));
mongoc_update_one_opts->update.bypass = false;
bson_init (&mongoc_update_one_opts->update.collation);
memset (&mongoc_update_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_update_one_opts->update.upsert = false;
+ bson_init (&mongoc_update_one_opts->update.let);
bson_init (&mongoc_update_one_opts->arrayFilters);
bson_init (&mongoc_update_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_update_one_opts->update.crud.writeConcern,
error)) {
return false;
}
mongoc_update_one_opts->update.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_update_one_opts->update.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_update_one_opts->update.crud.validate,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_update_one_opts->update.crud.comment,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_one_opts->update.bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_update_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_update_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_one_opts->update.upsert,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "let")) {
+ if (!_mongoc_convert_document (
+ client,
+ &iter,
+ &mongoc_update_one_opts->update.let,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_update_one_opts->arrayFilters,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_update_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_update_one_opts_cleanup (mongoc_update_one_opts_t *mongoc_update_one_opts)
{
if (mongoc_update_one_opts->update.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_update_one_opts->update.crud.writeConcern);
}
+ bson_value_destroy (&mongoc_update_one_opts->update.crud.comment);
bson_destroy (&mongoc_update_one_opts->update.collation);
bson_value_destroy (&mongoc_update_one_opts->update.hint);
+ bson_destroy (&mongoc_update_one_opts->update.let);
bson_destroy (&mongoc_update_one_opts->arrayFilters);
bson_destroy (&mongoc_update_one_opts->extra);
}
bool
_mongoc_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_update_many_opts_t *mongoc_update_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_update_many_opts->update.crud.writeConcern = NULL;
mongoc_update_many_opts->update.crud.write_concern_owned = false;
mongoc_update_many_opts->update.crud.client_session = NULL;
mongoc_update_many_opts->update.crud.validate = _mongoc_default_update_vflags;
+ memset (&mongoc_update_many_opts->update.crud.comment, 0, sizeof (bson_value_t));
mongoc_update_many_opts->update.bypass = false;
bson_init (&mongoc_update_many_opts->update.collation);
memset (&mongoc_update_many_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_update_many_opts->update.upsert = false;
+ bson_init (&mongoc_update_many_opts->update.let);
bson_init (&mongoc_update_many_opts->arrayFilters);
bson_init (&mongoc_update_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_update_many_opts->update.crud.writeConcern,
error)) {
return false;
}
mongoc_update_many_opts->update.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_update_many_opts->update.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_update_many_opts->update.crud.validate,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_update_many_opts->update.crud.comment,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_many_opts->update.bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_update_many_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_update_many_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_update_many_opts->update.upsert,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "let")) {
+ if (!_mongoc_convert_document (
+ client,
+ &iter,
+ &mongoc_update_many_opts->update.let,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_update_many_opts->arrayFilters,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_update_many_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_update_many_opts_cleanup (mongoc_update_many_opts_t *mongoc_update_many_opts)
{
if (mongoc_update_many_opts->update.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_update_many_opts->update.crud.writeConcern);
}
+ bson_value_destroy (&mongoc_update_many_opts->update.crud.comment);
bson_destroy (&mongoc_update_many_opts->update.collation);
bson_value_destroy (&mongoc_update_many_opts->update.hint);
+ bson_destroy (&mongoc_update_many_opts->update.let);
bson_destroy (&mongoc_update_many_opts->arrayFilters);
bson_destroy (&mongoc_update_many_opts->extra);
}
bool
_mongoc_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_replace_one_opts_t *mongoc_replace_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_replace_one_opts->update.crud.writeConcern = NULL;
mongoc_replace_one_opts->update.crud.write_concern_owned = false;
mongoc_replace_one_opts->update.crud.client_session = NULL;
mongoc_replace_one_opts->update.crud.validate = _mongoc_default_replace_vflags;
+ memset (&mongoc_replace_one_opts->update.crud.comment, 0, sizeof (bson_value_t));
mongoc_replace_one_opts->update.bypass = false;
bson_init (&mongoc_replace_one_opts->update.collation);
memset (&mongoc_replace_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_replace_one_opts->update.upsert = false;
+ bson_init (&mongoc_replace_one_opts->update.let);
bson_init (&mongoc_replace_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_replace_one_opts->update.crud.writeConcern,
error)) {
return false;
}
mongoc_replace_one_opts->update.crud.write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_replace_one_opts->update.crud.client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_replace_one_opts->update.crud.validate,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_replace_one_opts->update.crud.comment,
+ error)) {
+ return false;
+ }
+ }
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_replace_one_opts->update.bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_replace_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_replace_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_replace_one_opts->update.upsert,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "let")) {
+ if (!_mongoc_convert_document (
+ client,
+ &iter,
+ &mongoc_replace_one_opts->update.let,
+ error)) {
+ return false;
+ }
+ }
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_replace_one_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_replace_one_opts_cleanup (mongoc_replace_one_opts_t *mongoc_replace_one_opts)
{
if (mongoc_replace_one_opts->update.crud.write_concern_owned) {
mongoc_write_concern_destroy (mongoc_replace_one_opts->update.crud.writeConcern);
}
+ bson_value_destroy (&mongoc_replace_one_opts->update.crud.comment);
bson_destroy (&mongoc_replace_one_opts->update.collation);
bson_value_destroy (&mongoc_replace_one_opts->update.hint);
+ bson_destroy (&mongoc_replace_one_opts->update.let);
bson_destroy (&mongoc_replace_one_opts->extra);
}
bool
_mongoc_bulk_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_opts_t *mongoc_bulk_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_opts->writeConcern = NULL;
mongoc_bulk_opts->write_concern_owned = false;
mongoc_bulk_opts->ordered = true;
mongoc_bulk_opts->client_session = NULL;
+ bson_init (&mongoc_bulk_opts->let);
+ memset (&mongoc_bulk_opts->comment, 0, sizeof (bson_value_t));
bson_init (&mongoc_bulk_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_bulk_opts->writeConcern,
error)) {
return false;
}
mongoc_bulk_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "ordered")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_opts->ordered,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_bulk_opts->client_session,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "let")) {
+ if (!_mongoc_convert_document (
+ client,
+ &iter,
+ &mongoc_bulk_opts->let,
+ error)) {
+ return false;
+ }
+ }
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_bulk_opts->comment,
+ error)) {
+ return false;
+ }
+ }
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_opts_cleanup (mongoc_bulk_opts_t *mongoc_bulk_opts)
{
if (mongoc_bulk_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_bulk_opts->writeConcern);
}
+ bson_destroy (&mongoc_bulk_opts->let);
+ bson_value_destroy (&mongoc_bulk_opts->comment);
bson_destroy (&mongoc_bulk_opts->extra);
}
bool
_mongoc_bulk_insert_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_insert_opts->validate = _mongoc_default_insert_vflags;
bson_init (&mongoc_bulk_insert_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_insert_opts->validate,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_insert_opts_cleanup (mongoc_bulk_insert_opts_t *mongoc_bulk_insert_opts)
{
bson_destroy (&mongoc_bulk_insert_opts->extra);
}
bool
_mongoc_bulk_update_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_update_one_opts->update.validate = _mongoc_default_update_vflags;
bson_init (&mongoc_bulk_update_one_opts->update.collation);
memset (&mongoc_bulk_update_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_bulk_update_one_opts->update.upsert = false;
mongoc_bulk_update_one_opts->update.multi = false;
bson_init (&mongoc_bulk_update_one_opts->arrayFilters);
bson_init (&mongoc_bulk_update_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_update_one_opts->update.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_update_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_update_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_one_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "multi")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_one_opts->update.multi,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_bulk_update_one_opts->arrayFilters,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_update_one_opts_cleanup (mongoc_bulk_update_one_opts_t *mongoc_bulk_update_one_opts)
{
bson_destroy (&mongoc_bulk_update_one_opts->update.collation);
bson_value_destroy (&mongoc_bulk_update_one_opts->update.hint);
bson_destroy (&mongoc_bulk_update_one_opts->arrayFilters);
bson_destroy (&mongoc_bulk_update_one_opts->extra);
}
bool
_mongoc_bulk_update_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_update_many_opts->update.validate = _mongoc_default_update_vflags;
bson_init (&mongoc_bulk_update_many_opts->update.collation);
memset (&mongoc_bulk_update_many_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_bulk_update_many_opts->update.upsert = false;
mongoc_bulk_update_many_opts->update.multi = true;
bson_init (&mongoc_bulk_update_many_opts->arrayFilters);
bson_init (&mongoc_bulk_update_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_update_many_opts->update.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_update_many_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_update_many_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_many_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "multi")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_update_many_opts->update.multi,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "arrayFilters")) {
if (!_mongoc_convert_array (
client,
&iter,
&mongoc_bulk_update_many_opts->arrayFilters,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_update_many_opts_cleanup (mongoc_bulk_update_many_opts_t *mongoc_bulk_update_many_opts)
{
bson_destroy (&mongoc_bulk_update_many_opts->update.collation);
bson_value_destroy (&mongoc_bulk_update_many_opts->update.hint);
bson_destroy (&mongoc_bulk_update_many_opts->arrayFilters);
bson_destroy (&mongoc_bulk_update_many_opts->extra);
}
bool
_mongoc_bulk_replace_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_bulk_replace_one_opts->update.validate = _mongoc_default_replace_vflags;
bson_init (&mongoc_bulk_replace_one_opts->update.collation);
memset (&mongoc_bulk_replace_one_opts->update.hint, 0, sizeof (bson_value_t));
mongoc_bulk_replace_one_opts->update.upsert = false;
mongoc_bulk_replace_one_opts->update.multi = false;
bson_init (&mongoc_bulk_replace_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.validate,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "upsert")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.upsert,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "multi")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_bulk_replace_one_opts->update.multi,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_replace_one_opts_cleanup (mongoc_bulk_replace_one_opts_t *mongoc_bulk_replace_one_opts)
{
bson_destroy (&mongoc_bulk_replace_one_opts->update.collation);
bson_value_destroy (&mongoc_bulk_replace_one_opts->update.hint);
bson_destroy (&mongoc_bulk_replace_one_opts->extra);
}
bool
_mongoc_bulk_remove_one_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts,
bson_error_t *error)
{
bson_iter_t iter;
bson_init (&mongoc_bulk_remove_one_opts->remove.collation);
memset (&mongoc_bulk_remove_one_opts->remove.hint, 0, sizeof (bson_value_t));
mongoc_bulk_remove_one_opts->remove.limit = 1;
bson_init (&mongoc_bulk_remove_one_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_remove_one_opts->remove.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_remove_one_opts->remove.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "limit")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_bulk_remove_one_opts->remove.limit,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_remove_one_opts_cleanup (mongoc_bulk_remove_one_opts_t *mongoc_bulk_remove_one_opts)
{
bson_destroy (&mongoc_bulk_remove_one_opts->remove.collation);
bson_value_destroy (&mongoc_bulk_remove_one_opts->remove.hint);
bson_destroy (&mongoc_bulk_remove_one_opts->extra);
}
bool
_mongoc_bulk_remove_many_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts,
bson_error_t *error)
{
bson_iter_t iter;
bson_init (&mongoc_bulk_remove_many_opts->remove.collation);
memset (&mongoc_bulk_remove_many_opts->remove.hint, 0, sizeof (bson_value_t));
mongoc_bulk_remove_many_opts->remove.limit = 0;
bson_init (&mongoc_bulk_remove_many_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_bulk_remove_many_opts->remove.collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_bulk_remove_many_opts->remove.hint,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "limit")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_bulk_remove_many_opts->remove.limit,
error)) {
return false;
}
}
else {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid option '%s'",
bson_iter_key (&iter));
return false;
}
}
return true;
}
void
_mongoc_bulk_remove_many_opts_cleanup (mongoc_bulk_remove_many_opts_t *mongoc_bulk_remove_many_opts)
{
bson_destroy (&mongoc_bulk_remove_many_opts->remove.collation);
bson_value_destroy (&mongoc_bulk_remove_many_opts->remove.hint);
bson_destroy (&mongoc_bulk_remove_many_opts->extra);
}
bool
_mongoc_change_stream_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_change_stream_opts_t *mongoc_change_stream_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_change_stream_opts->batchSize = 0;
bson_init (&mongoc_change_stream_opts->resumeAfter);
bson_init (&mongoc_change_stream_opts->startAfter);
memset (&mongoc_change_stream_opts->startAtOperationTime, 0, sizeof (mongoc_timestamp_t));
mongoc_change_stream_opts->maxAwaitTimeMS = 0;
- mongoc_change_stream_opts->fullDocument = "default";
+ mongoc_change_stream_opts->fullDocument = NULL;
+ mongoc_change_stream_opts->fullDocumentBeforeChange = NULL;
+ memset (&mongoc_change_stream_opts->comment, 0, sizeof (bson_value_t));
bson_init (&mongoc_change_stream_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "batchSize")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_change_stream_opts->batchSize,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "resumeAfter")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_change_stream_opts->resumeAfter,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "startAfter")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_change_stream_opts->startAfter,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "startAtOperationTime")) {
if (!_mongoc_convert_timestamp (
client,
&iter,
&mongoc_change_stream_opts->startAtOperationTime,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "maxAwaitTimeMS")) {
if (!_mongoc_convert_int64_positive (
client,
&iter,
&mongoc_change_stream_opts->maxAwaitTimeMS,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "fullDocument")) {
if (!_mongoc_convert_utf8 (
client,
&iter,
&mongoc_change_stream_opts->fullDocument,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "fullDocumentBeforeChange")) {
+ if (!_mongoc_convert_utf8 (
+ client,
+ &iter,
+ &mongoc_change_stream_opts->fullDocumentBeforeChange,
+ error)) {
+ return false;
+ }
+ }
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_change_stream_opts->comment,
+ error)) {
+ return false;
+ }
+ }
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_change_stream_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_change_stream_opts_cleanup (mongoc_change_stream_opts_t *mongoc_change_stream_opts)
{
bson_destroy (&mongoc_change_stream_opts->resumeAfter);
bson_destroy (&mongoc_change_stream_opts->startAfter);
+ bson_value_destroy (&mongoc_change_stream_opts->comment);
bson_destroy (&mongoc_change_stream_opts->extra);
}
bool
_mongoc_create_index_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_create_index_opts_t *mongoc_create_index_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_create_index_opts->writeConcern = NULL;
mongoc_create_index_opts->write_concern_owned = false;
mongoc_create_index_opts->client_session = NULL;
bson_init (&mongoc_create_index_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_create_index_opts->writeConcern,
error)) {
return false;
}
mongoc_create_index_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_create_index_opts->client_session,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_create_index_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_create_index_opts_cleanup (mongoc_create_index_opts_t *mongoc_create_index_opts)
{
if (mongoc_create_index_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_create_index_opts->writeConcern);
}
bson_destroy (&mongoc_create_index_opts->extra);
}
bool
_mongoc_read_write_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_read_write_opts_t *mongoc_read_write_opts,
bson_error_t *error)
{
bson_iter_t iter;
bson_init (&mongoc_read_write_opts->readConcern);
mongoc_read_write_opts->writeConcern = NULL;
mongoc_read_write_opts->write_concern_owned = false;
mongoc_read_write_opts->client_session = NULL;
bson_init (&mongoc_read_write_opts->collation);
mongoc_read_write_opts->serverId = 0;
bson_init (&mongoc_read_write_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "readConcern")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_read_write_opts->readConcern,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_read_write_opts->writeConcern,
error)) {
return false;
}
mongoc_read_write_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_read_write_opts->client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_read_write_opts->collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "serverId")) {
if (!_mongoc_convert_server_id (
client,
&iter,
&mongoc_read_write_opts->serverId,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_read_write_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_read_write_opts_cleanup (mongoc_read_write_opts_t *mongoc_read_write_opts)
{
bson_destroy (&mongoc_read_write_opts->readConcern);
if (mongoc_read_write_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_read_write_opts->writeConcern);
}
bson_destroy (&mongoc_read_write_opts->collation);
bson_destroy (&mongoc_read_write_opts->extra);
}
bool
_mongoc_gridfs_bucket_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_gridfs_bucket_opts->bucketName = "fs";
mongoc_gridfs_bucket_opts->chunkSizeBytes = 261120;
mongoc_gridfs_bucket_opts->writeConcern = NULL;
mongoc_gridfs_bucket_opts->write_concern_owned = false;
mongoc_gridfs_bucket_opts->readConcern = NULL;
bson_init (&mongoc_gridfs_bucket_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "bucketName")) {
if (!_mongoc_convert_utf8 (
client,
&iter,
&mongoc_gridfs_bucket_opts->bucketName,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "chunkSizeBytes")) {
if (!_mongoc_convert_int32_positive (
client,
&iter,
&mongoc_gridfs_bucket_opts->chunkSizeBytes,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_gridfs_bucket_opts->writeConcern,
error)) {
return false;
}
mongoc_gridfs_bucket_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "readConcern")) {
if (!_mongoc_convert_read_concern (
client,
&iter,
&mongoc_gridfs_bucket_opts->readConcern,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_gridfs_bucket_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_gridfs_bucket_opts_cleanup (mongoc_gridfs_bucket_opts_t *mongoc_gridfs_bucket_opts)
{
if (mongoc_gridfs_bucket_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_gridfs_bucket_opts->writeConcern);
}
mongoc_read_concern_destroy (mongoc_gridfs_bucket_opts->readConcern);
bson_destroy (&mongoc_gridfs_bucket_opts->extra);
}
bool
_mongoc_gridfs_bucket_upload_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_gridfs_bucket_upload_opts->chunkSizeBytes = 0;
bson_init (&mongoc_gridfs_bucket_upload_opts->metadata);
bson_init (&mongoc_gridfs_bucket_upload_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "chunkSizeBytes")) {
if (!_mongoc_convert_int32_positive (
client,
&iter,
&mongoc_gridfs_bucket_upload_opts->chunkSizeBytes,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "metadata")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_gridfs_bucket_upload_opts->metadata,
error)) {
return false;
}
}
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_gridfs_bucket_upload_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_gridfs_bucket_upload_opts_cleanup (mongoc_gridfs_bucket_upload_opts_t *mongoc_gridfs_bucket_upload_opts)
{
bson_destroy (&mongoc_gridfs_bucket_upload_opts->metadata);
bson_destroy (&mongoc_gridfs_bucket_upload_opts->extra);
}
bool
_mongoc_aggregate_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_aggregate_opts_t *mongoc_aggregate_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_aggregate_opts->readConcern = NULL;
mongoc_aggregate_opts->writeConcern = NULL;
mongoc_aggregate_opts->write_concern_owned = false;
mongoc_aggregate_opts->client_session = NULL;
mongoc_aggregate_opts->bypass = false;
bson_init (&mongoc_aggregate_opts->collation);
mongoc_aggregate_opts->serverId = 0;
mongoc_aggregate_opts->batchSize = 0;
mongoc_aggregate_opts->batchSize_is_set = false;
bson_init (&mongoc_aggregate_opts->let);
+ memset (&mongoc_aggregate_opts->comment, 0, sizeof (bson_value_t));
bson_init (&mongoc_aggregate_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "readConcern")) {
if (!_mongoc_convert_read_concern (
client,
&iter,
&mongoc_aggregate_opts->readConcern,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_aggregate_opts->writeConcern,
error)) {
return false;
}
mongoc_aggregate_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_aggregate_opts->client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
client,
&iter,
&mongoc_aggregate_opts->bypass,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_aggregate_opts->collation,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "serverId")) {
if (!_mongoc_convert_server_id (
client,
&iter,
&mongoc_aggregate_opts->serverId,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "batchSize")) {
if (!_mongoc_convert_int32_t (
client,
&iter,
&mongoc_aggregate_opts->batchSize,
error)) {
return false;
}
mongoc_aggregate_opts->batchSize_is_set = true;
}
else if (!strcmp (bson_iter_key (&iter), "let")) {
if (!_mongoc_convert_document (
client,
&iter,
&mongoc_aggregate_opts->let,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_aggregate_opts->comment,
+ error)) {
+ return false;
+ }
+ }
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_aggregate_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_aggregate_opts_cleanup (mongoc_aggregate_opts_t *mongoc_aggregate_opts)
{
mongoc_read_concern_destroy (mongoc_aggregate_opts->readConcern);
if (mongoc_aggregate_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_aggregate_opts->writeConcern);
}
bson_destroy (&mongoc_aggregate_opts->collation);
bson_destroy (&mongoc_aggregate_opts->let);
+ bson_value_destroy (&mongoc_aggregate_opts->comment);
bson_destroy (&mongoc_aggregate_opts->extra);
}
bool
_mongoc_find_and_modify_appended_opts_parse (
mongoc_client_t *client,
const bson_t *opts,
mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts,
bson_error_t *error)
{
bson_iter_t iter;
mongoc_find_and_modify_appended_opts->writeConcern = NULL;
mongoc_find_and_modify_appended_opts->write_concern_owned = false;
mongoc_find_and_modify_appended_opts->client_session = NULL;
memset (&mongoc_find_and_modify_appended_opts->hint, 0, sizeof (bson_value_t));
+ bson_init (&mongoc_find_and_modify_appended_opts->let);
+ memset (&mongoc_find_and_modify_appended_opts->comment, 0, sizeof (bson_value_t));
bson_init (&mongoc_find_and_modify_appended_opts->extra);
if (!opts) {
return true;
}
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
client,
&iter,
&mongoc_find_and_modify_appended_opts->writeConcern,
error)) {
return false;
}
mongoc_find_and_modify_appended_opts->write_concern_owned = true;
}
else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
client,
&iter,
&mongoc_find_and_modify_appended_opts->client_session,
error)) {
return false;
}
}
else if (!strcmp (bson_iter_key (&iter), "hint")) {
if (!_mongoc_convert_hint (
client,
&iter,
&mongoc_find_and_modify_appended_opts->hint,
error)) {
return false;
}
}
+ else if (!strcmp (bson_iter_key (&iter), "let")) {
+ if (!_mongoc_convert_document (
+ client,
+ &iter,
+ &mongoc_find_and_modify_appended_opts->let,
+ error)) {
+ return false;
+ }
+ }
+ else if (!strcmp (bson_iter_key (&iter), "comment")) {
+ if (!_mongoc_convert_bson_value_t (
+ client,
+ &iter,
+ &mongoc_find_and_modify_appended_opts->comment,
+ error)) {
+ return false;
+ }
+ }
else {
/* unrecognized values are copied to "extra" */
if (!BSON_APPEND_VALUE (
&mongoc_find_and_modify_appended_opts->extra,
bson_iter_key (&iter),
bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
void
_mongoc_find_and_modify_appended_opts_cleanup (mongoc_find_and_modify_appended_opts_t *mongoc_find_and_modify_appended_opts)
{
if (mongoc_find_and_modify_appended_opts->write_concern_owned) {
mongoc_write_concern_destroy (mongoc_find_and_modify_appended_opts->writeConcern);
}
bson_value_destroy (&mongoc_find_and_modify_appended_opts->hint);
+ bson_destroy (&mongoc_find_and_modify_appended_opts->let);
+ bson_value_destroy (&mongoc_find_and_modify_appended_opts->comment);
bson_destroy (&mongoc_find_and_modify_appended_opts->extra);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
index 795ed8e6..794ad87b 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h
@@ -1,187 +1,191 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_RPC_PRIVATE_H
#define MONGOC_RPC_PRIVATE_H
#include <bson/bson.h>
#include <stddef.h>
#include "mongoc-array-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-iovec.h"
#include "mongoc-write-concern.h"
#include "mongoc-flags.h"
/* forward declaration */
struct _mongoc_cluster_t;
BSON_BEGIN_DECLS
typedef struct _mongoc_rpc_section_t {
uint8_t payload_type;
union {
/* payload_type == 0 */
const uint8_t *bson_document;
/* payload_type == 1 */
struct {
int32_t size;
uint32_t size_le;
const char *identifier;
const uint8_t *bson_documents;
} sequence;
} payload;
} mongoc_rpc_section_t;
#define RPC(_name, _code) \
typedef struct { \
_code \
} mongoc_rpc_##_name##_t;
#define ENUM_FIELD(_name) uint32_t _name;
#define INT32_FIELD(_name) int32_t _name;
#define UINT8_FIELD(_name) uint8_t _name;
#define INT64_FIELD(_name) int64_t _name;
#define INT64_ARRAY_FIELD(_len, _name) \
int32_t _len; \
int64_t *_name;
#define CSTRING_FIELD(_name) const char *_name;
#define BSON_FIELD(_name) const uint8_t *_name;
#define BSON_ARRAY_FIELD(_name) \
const uint8_t *_name; \
int32_t _name##_len;
#define IOVEC_ARRAY_FIELD(_name) \
const mongoc_iovec_t *_name; \
int32_t n_##_name; \
mongoc_iovec_t _name##_recv;
#define SECTION_ARRAY_FIELD(_name) \
mongoc_rpc_section_t _name[2]; \
int32_t n_##_name;
#define RAW_BUFFER_FIELD(_name) \
const uint8_t *_name; \
int32_t _name##_len;
#define BSON_OPTIONAL(_check, _code) _code
#pragma pack(1)
#include "op-delete.def"
#include "op-get-more.def"
#include "op-header.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-reply-header.def"
#include "op-update.def"
#include "op-compressed.def"
/* restore default packing */
#pragma pack()
#include "op-msg.def"
typedef union {
mongoc_rpc_delete_t delete_;
mongoc_rpc_get_more_t get_more;
mongoc_rpc_header_t header;
mongoc_rpc_insert_t insert;
mongoc_rpc_kill_cursors_t kill_cursors;
mongoc_rpc_msg_t msg;
mongoc_rpc_query_t query;
mongoc_rpc_reply_t reply;
mongoc_rpc_reply_header_t reply_header;
mongoc_rpc_update_t update;
mongoc_rpc_compressed_t compressed;
} mongoc_rpc_t;
BSON_STATIC_ASSERT2 (sizeof_rpc_header, sizeof (mongoc_rpc_header_t) == 16);
BSON_STATIC_ASSERT2 (offsetof_rpc_header,
offsetof (mongoc_rpc_header_t, opcode) ==
offsetof (mongoc_rpc_reply_t, opcode));
BSON_STATIC_ASSERT2 (sizeof_reply_header,
sizeof (mongoc_rpc_reply_header_t) == 36);
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
void
_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array);
void
_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc);
void
_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc);
void
_mongoc_rpc_printf (mongoc_rpc_t *rpc);
bool
_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen);
bool
_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc,
const uint8_t *buf,
size_t buflen);
+
bool
_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply);
bool
_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson);
+bool
+_mongoc_rpc_reply_get_first_msg (mongoc_rpc_msg_t *reply, bson_t *bson);
+
void
_mongoc_rpc_prep_command (mongoc_rpc_t *rpc,
const char *cmd_ns,
mongoc_cmd_t *cmd);
bool
_mongoc_rpc_check_ok (mongoc_rpc_t *rpc,
int32_t error_api_version,
bson_error_t *error /* OUT */,
bson_t *error_doc /* OUT */);
bool
_mongoc_cmd_check_ok (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error);
bool
_mongoc_cmd_check_ok_no_wce (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error);
bool
_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen);
char *
_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster,
int32_t compressor_id,
mongoc_rpc_t *rpc_le,
bson_error_t *error);
bool
_mongoc_rpc_decompress_if_necessary (mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer,
bson_error_t *error);
BSON_END_DECLS
#endif /* MONGOC_RPC_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
index 0fa2e229..49db8437 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c
@@ -1,1371 +1,1399 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongoc.h"
#include "mongoc-rpc-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#include "mongoc-compression-private.h"
#include "mongoc-cluster-private.h"
#define RPC(_name, _code) \
static void _mongoc_rpc_gather_##_name (mongoc_rpc_##_name##_t *rpc, \
mongoc_rpc_header_t *header, \
mongoc_array_t *array) \
{ \
mongoc_iovec_t iov; \
BSON_ASSERT (rpc); \
BSON_ASSERT (array); \
header->msg_len = 0; \
_code \
}
#define UINT8_FIELD(_name) \
iov.iov_base = (void *) &rpc->_name; \
iov.iov_len = 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define INT32_FIELD(_name) \
iov.iov_base = (void *) &rpc->_name; \
iov.iov_len = 4; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define ENUM_FIELD INT32_FIELD
#define INT64_FIELD(_name) \
iov.iov_base = (void *) &rpc->_name; \
iov.iov_len = 8; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define CSTRING_FIELD(_name) \
BSON_ASSERT (rpc->_name); \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = strlen (rpc->_name) + 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define BSON_FIELD(_name) \
do { \
int32_t __l; \
memcpy (&__l, rpc->_name, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = __l; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
} while (0);
#define BSON_OPTIONAL(_check, _code) \
if (rpc->_check) { \
_code \
}
#define BSON_ARRAY_FIELD(_name) \
if (rpc->_name##_len) { \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = rpc->_name##_len; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
}
#define IOVEC_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
BSON_ASSERT (rpc->n_##_name); \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
BSON_ASSERT (rpc->_name[_i].iov_len); \
header->msg_len += (int32_t) rpc->_name[_i].iov_len; \
_mongoc_array_append_val (array, rpc->_name[_i]); \
} \
} while (0);
#define SECTION_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
BSON_ASSERT (rpc->n_##_name); \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
int32_t __l; \
iov.iov_base = (void *) &rpc->_name[_i].payload_type; \
iov.iov_len = 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
switch (rpc->_name[_i].payload_type) { \
case 0: \
memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
iov.iov_base = (void *) rpc->_name[_i].payload.bson_document; \
iov.iov_len = __l; \
break; \
case 1: \
rpc->_name[_i].payload.sequence.size_le = \
BSON_UINT32_TO_LE (rpc->_name[_i].payload.sequence.size); \
iov.iov_base = (void *) &rpc->_name[_i].payload.sequence.size_le; \
iov.iov_len = 4; \
header->msg_len += 4; \
_mongoc_array_append_val (array, iov); \
iov.iov_base = \
(void *) rpc->_name[_i].payload.sequence.identifier; \
iov.iov_len = \
strlen (rpc->_name[_i].payload.sequence.identifier) + 1; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
iov.iov_base = \
(void *) rpc->_name[_i].payload.sequence.bson_documents; \
iov.iov_len = \
rpc->_name[_i].payload.sequence.size - iov.iov_len - 4; \
break; \
default: \
MONGOC_ERROR ("Unknown Payload Type: %d", \
rpc->_name[_i].payload_type); \
BSON_ASSERT (0); \
} \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
} \
} while (0);
#define RAW_BUFFER_FIELD(_name) \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = rpc->_name##_len; \
BSON_ASSERT (iov.iov_len); \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#define INT64_ARRAY_FIELD(_len, _name) \
iov.iov_base = (void *) &rpc->_len; \
iov.iov_len = 4; \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov); \
iov.iov_base = (void *) rpc->_name; \
iov.iov_len = rpc->_len * 8; \
BSON_ASSERT (iov.iov_len); \
header->msg_len += (int32_t) iov.iov_len; \
_mongoc_array_append_val (array, iov);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef RAW_BUFFER_FIELD
#undef BSON_OPTIONAL
#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
#define RPC(_name, _code) \
static void _mongoc_rpc_swab_to_le_##_name (mongoc_rpc_##_name##_t *rpc) \
{ \
BSON_ASSERT (rpc); \
_code \
}
#define UINT8_FIELD(_name)
#define INT32_FIELD(_name) rpc->_name = BSON_UINT32_FROM_LE (rpc->_name);
#define ENUM_FIELD INT32_FIELD
#define INT64_FIELD(_name) rpc->_name = BSON_UINT64_FROM_LE (rpc->_name);
#define CSTRING_FIELD(_name)
#define BSON_FIELD(_name)
#define BSON_ARRAY_FIELD(_name)
#define IOVEC_ARRAY_FIELD(_name)
#define SECTION_ARRAY_FIELD(_name)
#define BSON_OPTIONAL(_check, _code) \
if (rpc->_check) { \
_code \
}
#define RAW_BUFFER_FIELD(_name)
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
ssize_t i; \
for (i = 0; i < rpc->_len; i++) { \
rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \
} \
rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \
} while (0);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef INT64_ARRAY_FIELD
#define RPC(_name, _code) \
static void _mongoc_rpc_swab_from_le_##_name (mongoc_rpc_##_name##_t *rpc) \
{ \
BSON_ASSERT (rpc); \
_code \
}
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
ssize_t i; \
rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \
for (i = 0; i < rpc->_len; i++) { \
rpc->_name[i] = BSON_UINT64_FROM_LE (rpc->_name[i]); \
} \
} while (0);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
#endif /* BSON_BYTE_ORDER == BSON_BIG_ENDIAN */
#define RPC(_name, _code) \
static void _mongoc_rpc_printf_##_name (mongoc_rpc_##_name##_t *rpc) \
{ \
BSON_ASSERT (rpc); \
_code \
}
#define UINT8_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name);
#define INT32_FIELD(_name) printf (" " #_name " : %d\n", rpc->_name);
#define ENUM_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name);
#define INT64_FIELD(_name) \
printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name);
#define CSTRING_FIELD(_name) printf (" " #_name " : %s\n", rpc->_name);
#define BSON_FIELD(_name) \
do { \
bson_t b; \
char *s; \
int32_t __l; \
memcpy (&__l, rpc->_name, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
BSON_ASSERT (bson_init_static (&b, rpc->_name, __l)); \
s = bson_as_relaxed_extended_json (&b, NULL); \
printf (" " #_name " : %s\n", s); \
bson_free (s); \
bson_destroy (&b); \
} while (0);
#define BSON_ARRAY_FIELD(_name) \
do { \
bson_reader_t *__r; \
bool __eof; \
const bson_t *__b; \
__r = bson_reader_new_from_data (rpc->_name, rpc->_name##_len); \
while ((__b = bson_reader_read (__r, &__eof))) { \
char *s = bson_as_relaxed_extended_json (__b, NULL); \
printf (" " #_name " : %s\n", s); \
bson_free (s); \
} \
bson_reader_destroy (__r); \
} while (0);
#define IOVEC_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
size_t _j; \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
printf (" " #_name " : "); \
for (_j = 0; _j < rpc->_name[_i].iov_len; _j++) { \
uint8_t u; \
u = ((char *) rpc->_name[_i].iov_base)[_j]; \
printf (" %02x", u); \
} \
printf ("\n"); \
} \
} while (0);
#define SECTION_ARRAY_FIELD(_name) \
do { \
ssize_t _i; \
printf (" " #_name " : %d\n", rpc->n_##_name); \
for (_i = 0; _i < rpc->n_##_name; _i++) { \
if (rpc->_name[_i].payload_type == 0) { \
do { \
bson_t b; \
char *s; \
int32_t __l; \
memcpy (&__l, rpc->_name[_i].payload.bson_document, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
BSON_ASSERT (bson_init_static ( \
&b, rpc->_name[_i].payload.bson_document, __l)); \
s = bson_as_relaxed_extended_json (&b, NULL); \
printf (" Type %d: %s\n", rpc->_name[_i].payload_type, s); \
bson_free (s); \
bson_destroy (&b); \
} while (0); \
} else if (rpc->_name[_i].payload_type == 1) { \
bson_reader_t *__r; \
int max = rpc->_name[_i].payload.sequence.size - \
strlen (rpc->_name[_i].payload.sequence.identifier) - \
1 - sizeof (int32_t); \
bool __eof; \
const bson_t *__b; \
printf (" Identifier: %s\n", \
rpc->_name[_i].payload.sequence.identifier); \
printf (" Size: %d\n", max); \
__r = bson_reader_new_from_data ( \
rpc->_name[_i].payload.sequence.bson_documents, max); \
while ((__b = bson_reader_read (__r, &__eof))) { \
char *s = bson_as_relaxed_extended_json (__b, NULL); \
bson_free (s); \
} \
bson_reader_destroy (__r); \
} \
} \
} while (0);
#define BSON_OPTIONAL(_check, _code) \
if (rpc->_check) { \
_code \
}
#define RAW_BUFFER_FIELD(_name) \
{ \
ssize_t __i; \
printf (" " #_name " :"); \
for (__i = 0; __i < rpc->_name##_len; __i++) { \
uint8_t u; \
u = ((char *) rpc->_name)[__i]; \
printf (" %02x", u); \
} \
printf ("\n"); \
}
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
ssize_t i; \
for (i = 0; i < rpc->_len; i++) { \
printf (" " #_name " : %" PRIi64 "\n", (int64_t) rpc->_name[i]); \
} \
rpc->_len = BSON_UINT32_FROM_LE (rpc->_len); \
} while (0);
#include "op-delete.def"
#include "op-get-more.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
#define RPC(_name, _code) \
static bool _mongoc_rpc_scatter_##_name ( \
mongoc_rpc_##_name##_t *rpc, const uint8_t *buf, size_t buflen) \
{ \
BSON_ASSERT (rpc); \
BSON_ASSERT (buf); \
BSON_ASSERT (buflen); \
_code return true; \
}
#define UINT8_FIELD(_name) \
if (buflen < 1) { \
return false; \
} \
memcpy (&rpc->_name, buf, 1); \
buflen -= 1; \
buf += 1;
#define INT32_FIELD(_name) \
if (buflen < 4) { \
return false; \
} \
memcpy (&rpc->_name, buf, 4); \
buflen -= 4; \
buf += 4;
#define ENUM_FIELD INT32_FIELD
#define INT64_FIELD(_name) \
if (buflen < 8) { \
return false; \
} \
memcpy (&rpc->_name, buf, 8); \
buflen -= 8; \
buf += 8;
#define INT64_ARRAY_FIELD(_len, _name) \
do { \
size_t needed; \
if (buflen < 4) { \
return false; \
} \
memcpy (&rpc->_len, buf, 4); \
buflen -= 4; \
buf += 4; \
needed = BSON_UINT32_FROM_LE (rpc->_len) * 8; \
if (needed > buflen) { \
return false; \
} \
rpc->_name = (int64_t *) buf; \
buf += needed; \
buflen -= needed; \
} while (0);
#define CSTRING_FIELD(_name) \
do { \
size_t __i; \
bool found = false; \
for (__i = 0; __i < buflen; __i++) { \
if (!buf[__i]) { \
rpc->_name = (const char *) buf; \
buflen -= __i + 1; \
buf += __i + 1; \
found = true; \
break; \
} \
} \
if (!found) { \
return false; \
} \
} while (0);
#define BSON_FIELD(_name) \
do { \
uint32_t __l; \
if (buflen < 4) { \
return false; \
} \
memcpy (&__l, buf, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
if (__l < 5 || __l > buflen) { \
return false; \
} \
rpc->_name = (uint8_t *) buf; \
buf += __l; \
buflen -= __l; \
} while (0);
#define BSON_ARRAY_FIELD(_name) \
rpc->_name = (uint8_t *) buf; \
rpc->_name##_len = (int32_t) buflen; \
buf = NULL; \
buflen = 0;
#define BSON_OPTIONAL(_check, _code) \
if (buflen) { \
_code \
}
#define IOVEC_ARRAY_FIELD(_name) \
rpc->_name##_recv.iov_base = (void *) buf; \
rpc->_name##_recv.iov_len = buflen; \
rpc->_name = &rpc->_name##_recv; \
rpc->n_##_name = 1; \
buf = NULL; \
buflen = 0;
#define SECTION_ARRAY_FIELD(_name) \
do { \
uint32_t __l; \
mongoc_rpc_section_t *section = &rpc->_name[rpc->n_##_name]; \
section->payload_type = buf[0]; \
buf++; \
buflen -= 1; \
memcpy (&__l, buf, 4); \
__l = BSON_UINT32_FROM_LE (__l); \
if (section->payload_type == 0) { \
section->payload.bson_document = buf; \
} else { \
const uint8_t *section_buf = buf + 4; \
section->payload.sequence.size = __l; \
section->payload.sequence.identifier = (const char *) section_buf; \
section_buf += strlen ((const char *) section_buf) + 1; \
section->payload.sequence.bson_documents = section_buf; \
} \
buf += __l; \
buflen -= __l; \
rpc->n_##_name++; \
} while (buflen);
#define RAW_BUFFER_FIELD(_name) \
rpc->_name = (void *) buf; \
rpc->_name##_len = (int32_t) buflen; \
buf = NULL; \
buflen = 0;
#include "op-delete.def"
#include "op-get-more.def"
#include "op-header.def"
#include "op-insert.def"
#include "op-kill-cursors.def"
#include "op-msg.def"
#include "op-query.def"
#include "op-reply.def"
#include "op-reply-header.def"
#include "op-compressed.def"
#include "op-update.def"
#undef RPC
#undef ENUM_FIELD
#undef UINT8_FIELD
#undef INT32_FIELD
#undef INT64_FIELD
#undef INT64_ARRAY_FIELD
#undef CSTRING_FIELD
#undef BSON_FIELD
#undef BSON_ARRAY_FIELD
#undef IOVEC_ARRAY_FIELD
#undef SECTION_ARRAY_FIELD
#undef BSON_OPTIONAL
#undef RAW_BUFFER_FIELD
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_gather --
*
* Takes a (native endian) rpc struct and gathers the buffer.
* Caller should swab to little endian after calling gather.
*
* Gather, swab, compress write.
* Read, scatter, uncompress, swab
*
*--------------------------------------------------------------------------
*/
void
_mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array)
{
mongoc_counter_op_egress_total_inc ();
switch ((mongoc_opcode_t) rpc->header.opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_gather_reply (&rpc->reply, &rpc->header, array);
return;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_gather_msg (&rpc->msg, &rpc->header, array);
mongoc_counter_op_egress_msg_inc ();
return;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_gather_update (&rpc->update, &rpc->header, array);
mongoc_counter_op_egress_update_inc ();
return;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_gather_insert (&rpc->insert, &rpc->header, array);
mongoc_counter_op_egress_insert_inc ();
return;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_gather_query (&rpc->query, &rpc->header, array);
mongoc_counter_op_egress_query_inc ();
return;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_gather_get_more (&rpc->get_more, &rpc->header, array);
mongoc_counter_op_egress_getmore_inc ();
return;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_gather_delete (&rpc->delete_, &rpc->header, array);
mongoc_counter_op_egress_delete_inc ();
return;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_gather_kill_cursors (&rpc->kill_cursors, &rpc->header, array);
mongoc_counter_op_egress_killcursors_inc ();
return;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_gather_compressed (&rpc->compressed, &rpc->header, array);
mongoc_counter_op_egress_compressed_inc ();
return;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode);
BSON_ASSERT (false);
break;
}
}
void
_mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc)
{
#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
mongoc_opcode_t opcode;
opcode = rpc->header.opcode;
switch (opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_swab_to_le_reply (&rpc->reply);
break;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_swab_to_le_msg (&rpc->msg);
break;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_swab_to_le_update (&rpc->update);
break;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_swab_to_le_insert (&rpc->insert);
break;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_swab_to_le_query (&rpc->query);
break;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_swab_to_le_get_more (&rpc->get_more);
break;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_swab_to_le_delete (&rpc->delete_);
break;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_swab_to_le_kill_cursors (&rpc->kill_cursors);
break;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_swab_to_le_compressed (&rpc->compressed);
break;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode);
break;
}
#endif
#if 0
_mongoc_rpc_printf (rpc);
#endif
}
void
_mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc)
{
#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
mongoc_opcode_t opcode;
opcode = BSON_UINT32_FROM_LE (rpc->header.opcode);
switch (opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_swab_from_le_reply (&rpc->reply);
break;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_swab_from_le_msg (&rpc->msg);
break;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_swab_from_le_update (&rpc->update);
break;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_swab_from_le_insert (&rpc->insert);
break;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_swab_from_le_query (&rpc->query);
break;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_swab_from_le_get_more (&rpc->get_more);
break;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_swab_from_le_delete (&rpc->delete_);
break;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_swab_from_le_kill_cursors (&rpc->kill_cursors);
break;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_swab_from_le_compressed (&rpc->compressed);
break;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode);
break;
}
#endif
#if 0
_mongoc_rpc_printf (rpc);
#endif
}
void
_mongoc_rpc_printf (mongoc_rpc_t *rpc)
{
switch ((mongoc_opcode_t) rpc->header.opcode) {
case MONGOC_OPCODE_REPLY:
_mongoc_rpc_printf_reply (&rpc->reply);
break;
case MONGOC_OPCODE_MSG:
_mongoc_rpc_printf_msg (&rpc->msg);
break;
case MONGOC_OPCODE_UPDATE:
_mongoc_rpc_printf_update (&rpc->update);
break;
case MONGOC_OPCODE_INSERT:
_mongoc_rpc_printf_insert (&rpc->insert);
break;
case MONGOC_OPCODE_QUERY:
_mongoc_rpc_printf_query (&rpc->query);
break;
case MONGOC_OPCODE_GET_MORE:
_mongoc_rpc_printf_get_more (&rpc->get_more);
break;
case MONGOC_OPCODE_DELETE:
_mongoc_rpc_printf_delete (&rpc->delete_);
break;
case MONGOC_OPCODE_KILL_CURSORS:
_mongoc_rpc_printf_kill_cursors (&rpc->kill_cursors);
break;
case MONGOC_OPCODE_COMPRESSED:
_mongoc_rpc_printf_compressed (&rpc->compressed);
break;
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode);
break;
}
printf ("\n");
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_decompress --
*
* Takes a (little endian) rpc struct assumed to be OP_COMPRESSED
* and decompresses the opcode into its original opcode.
* The in-place updated rpc struct remains little endian.
*
* Side effects:
* Overwrites the RPC, along with the provided buf with the
* compressed results.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen)
{
size_t uncompressed_size =
BSON_UINT32_FROM_LE (rpc_le->compressed.uncompressed_size);
bool ok;
size_t msg_len = BSON_UINT32_TO_LE (buflen);
const size_t original_uncompressed_size = uncompressed_size;
BSON_ASSERT (uncompressed_size <= buflen);
memcpy (buf, (void *) (&msg_len), 4);
memcpy (buf + 4, (void *) (&rpc_le->header.request_id), 4);
memcpy (buf + 8, (void *) (&rpc_le->header.response_to), 4);
memcpy (buf + 12, (void *) (&rpc_le->compressed.original_opcode), 4);
ok = mongoc_uncompress (rpc_le->compressed.compressor_id,
rpc_le->compressed.compressed_message,
rpc_le->compressed.compressed_message_len,
buf + 16,
&uncompressed_size);
BSON_ASSERT (original_uncompressed_size == uncompressed_size);
if (ok) {
return _mongoc_rpc_scatter (rpc_le, buf, buflen);
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_compress --
*
* Takes a (little endian) rpc struct and creates a OP_COMPRESSED
* compressed opcode based on the provided compressor_id.
* The in-place updated rpc struct remains little endian.
*
* Side effects:
* Overwrites the RPC, and clears and overwrites the cluster buffer
* with the compressed results.
*
*--------------------------------------------------------------------------
*/
char *
_mongoc_rpc_compress (struct _mongoc_cluster_t *cluster,
int32_t compressor_id,
mongoc_rpc_t *rpc_le,
bson_error_t *error)
{
char *output;
size_t output_length = 0;
size_t allocate = BSON_UINT32_FROM_LE (rpc_le->header.msg_len) - 16;
char *data;
int size;
int32_t compression_level = -1;
if (compressor_id == MONGOC_COMPRESSOR_ZLIB_ID) {
compression_level = mongoc_uri_get_option_as_int32 (
cluster->uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, -1);
}
BSON_ASSERT (allocate > 0);
data = bson_malloc0 (allocate);
size = _mongoc_cluster_buffer_iovec (
cluster->iov.data, cluster->iov.len, 16, data);
BSON_ASSERT (size);
output_length =
mongoc_compressor_max_compressed_length (compressor_id, size);
if (!output_length) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Could not determine compression bounds for %s",
mongoc_compressor_id_to_name (compressor_id));
bson_free (data);
return NULL;
}
output = (char *) bson_malloc0 (output_length);
if (mongoc_compress (compressor_id,
compression_level,
data,
size,
output,
&output_length)) {
rpc_le->header.msg_len = 0;
rpc_le->compressed.original_opcode =
BSON_UINT32_FROM_LE (rpc_le->header.opcode);
rpc_le->header.opcode = MONGOC_OPCODE_COMPRESSED;
rpc_le->header.request_id =
BSON_UINT32_FROM_LE (rpc_le->header.request_id);
rpc_le->header.response_to =
BSON_UINT32_FROM_LE (rpc_le->header.response_to);
rpc_le->compressed.uncompressed_size = size;
rpc_le->compressed.compressor_id = compressor_id;
rpc_le->compressed.compressed_message = (const uint8_t *) output;
rpc_le->compressed.compressed_message_len = output_length;
bson_free (data);
_mongoc_array_destroy (&cluster->iov);
_mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t));
_mongoc_rpc_gather (rpc_le, &cluster->iov);
_mongoc_rpc_swab_to_le (rpc_le);
return output;
} else {
MONGOC_WARNING ("Could not compress data with %s",
mongoc_compressor_id_to_name (compressor_id));
}
bson_free (data);
bson_free (output);
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_scatter --
*
* Takes a (little endian) rpc struct and scatters the buffer.
* Caller should check if resulting opcode is OP_COMPRESSED
* BEFORE swabbing to native endianness.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen)
{
mongoc_opcode_t opcode;
memset (rpc, 0, sizeof *rpc);
if (BSON_UNLIKELY (buflen < 16)) {
return false;
}
mongoc_counter_op_ingress_total_inc ();
if (!_mongoc_rpc_scatter_header (&rpc->header, buf, 16)) {
return false;
}
opcode = (mongoc_opcode_t) BSON_UINT32_FROM_LE (rpc->header.opcode);
switch (opcode) {
case MONGOC_OPCODE_COMPRESSED:
mongoc_counter_op_ingress_compressed_inc ();
return _mongoc_rpc_scatter_compressed (&rpc->compressed, buf, buflen);
case MONGOC_OPCODE_REPLY:
mongoc_counter_op_ingress_reply_inc ();
return _mongoc_rpc_scatter_reply (&rpc->reply, buf, buflen);
case MONGOC_OPCODE_MSG:
mongoc_counter_op_ingress_msg_inc ();
return _mongoc_rpc_scatter_msg (&rpc->msg, buf, buflen);
/* useless, we are never *getting* these opcodes */
case MONGOC_OPCODE_UPDATE:
return _mongoc_rpc_scatter_update (&rpc->update, buf, buflen);
case MONGOC_OPCODE_INSERT:
return _mongoc_rpc_scatter_insert (&rpc->insert, buf, buflen);
case MONGOC_OPCODE_QUERY:
return _mongoc_rpc_scatter_query (&rpc->query, buf, buflen);
case MONGOC_OPCODE_GET_MORE:
return _mongoc_rpc_scatter_get_more (&rpc->get_more, buf, buflen);
case MONGOC_OPCODE_DELETE:
return _mongoc_rpc_scatter_delete (&rpc->delete_, buf, buflen);
case MONGOC_OPCODE_KILL_CURSORS:
return _mongoc_rpc_scatter_kill_cursors (&rpc->kill_cursors, buf, buflen);
default:
MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode);
return false;
}
}
bool
_mongoc_rpc_scatter_reply_header_only (mongoc_rpc_t *rpc,
const uint8_t *buf,
size_t buflen)
{
if (BSON_UNLIKELY (buflen < sizeof (mongoc_rpc_reply_header_t))) {
return false;
}
mongoc_counter_op_ingress_reply_inc ();
mongoc_counter_op_ingress_total_inc ();
return _mongoc_rpc_scatter_reply_header (&rpc->reply_header, buf, buflen);
}
bool
_mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply)
{
+ if (rpc->header.opcode == MONGOC_OPCODE_MSG) {
+ return _mongoc_rpc_reply_get_first_msg (&rpc->msg, reply);
+ }
+
if (rpc->header.opcode == MONGOC_OPCODE_REPLY &&
_mongoc_rpc_reply_get_first (&rpc->reply, reply)) {
return true;
}
return false;
}
+/* Get the first BSON document from an OP_MSG reply: */
+bool
+_mongoc_rpc_reply_get_first_msg (mongoc_rpc_msg_t *reply_msg,
+ bson_t *bson_reply)
+{
+ /* Note that mongo_rpc_reply_t is a union, with a mongo_rpc_msg_t field; see
+ the *.def files and MongoDB Wire Protocol documentation for details. */
+
+ int32_t document_len;
+
+ BSON_ASSERT (0 == reply_msg->sections[0].payload_type);
+
+ /* As per the Wire Protocol documentation, each section has a 32 bit length
+ field: */
+ memcpy (&document_len, reply_msg->sections[0].payload.bson_document, 4);
+ document_len = BSON_UINT32_FROM_LE (document_len);
+
+ bson_init_static (
+ bson_reply, reply_msg->sections[0].payload.bson_document, document_len);
+
+ return true;
+}
+
bool
_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson)
{
int32_t len;
if (!reply->documents || reply->documents_len < 4) {
return false;
}
memcpy (&len, reply->documents, 4);
len = BSON_UINT32_FROM_LE (len);
if (reply->documents_len < len) {
return false;
}
return bson_init_static (bson, reply->documents, len);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_prep_command --
*
* Prepare an RPC for mongoc_cluster_run_command_rpc. @cmd_ns and
* @cmd must not be freed or modified while the RPC is in use.
*
* Side effects:
* Fills out the RPC, including pointers into @cmd_ns and @command.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_rpc_prep_command (mongoc_rpc_t *rpc,
const char *cmd_ns,
mongoc_cmd_t *cmd)
{
rpc->header.msg_len = 0;
rpc->header.request_id = 0;
rpc->header.response_to = 0;
rpc->header.opcode = MONGOC_OPCODE_QUERY;
rpc->query.collection = cmd_ns;
rpc->query.skip = 0;
rpc->query.n_return = -1;
rpc->query.fields = NULL;
rpc->query.query = bson_get_data (cmd->command);
/* Find, getMore And killCursors Commands Spec: "When sending a find command
* rather than a legacy OP_QUERY find, only the secondaryOk flag is honored."
- * For other cursor-typed commands like aggregate, only secondaryOk can be set.
- * Clear bits except secondaryOk; leave secondaryOk set only if it is already.
+ * For other cursor-typed commands like aggregate, only secondaryOk can be
+ * set. Clear bits except secondaryOk; leave secondaryOk set only if it is
+ * already.
*/
rpc->query.flags = cmd->query_flags & MONGOC_QUERY_SECONDARY_OK;
}
/* returns true if an error was found. */
static bool
_parse_error_reply (const bson_t *doc,
bool check_wce,
uint32_t *code,
const char **msg)
{
bson_iter_t iter;
bool found_error = false;
ENTRY;
BSON_ASSERT (doc);
BSON_ASSERT (code);
*code = 0;
/* The server only returns real error codes as int32.
* But it may return as a double or int64 if a failpoint
* based on how it is configured to error. */
if (bson_iter_init_find (&iter, doc, "code") &&
BSON_ITER_HOLDS_NUMBER (&iter)) {
*code = (uint32_t) bson_iter_as_int64 (&iter);
BSON_ASSERT (*code);
found_error = true;
}
if (bson_iter_init_find (&iter, doc, "errmsg") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
*msg = bson_iter_utf8 (&iter, NULL);
found_error = true;
} else if (bson_iter_init_find (&iter, doc, "$err") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
*msg = bson_iter_utf8 (&iter, NULL);
found_error = true;
}
if (found_error) {
/* there was a command error */
RETURN (true);
}
if (check_wce) {
/* check for a write concern error */
if (bson_iter_init_find (&iter, doc, "writeConcernError") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_iter_t child;
BSON_ASSERT (bson_iter_recurse (&iter, &child));
if (bson_iter_find (&child, "code") &&
BSON_ITER_HOLDS_NUMBER (&child)) {
*code = (uint32_t) bson_iter_as_int64 (&child);
BSON_ASSERT (*code);
found_error = true;
}
BSON_ASSERT (bson_iter_recurse (&iter, &child));
if (bson_iter_find (&child, "errmsg") &&
BSON_ITER_HOLDS_UTF8 (&child)) {
*msg = bson_iter_utf8 (&child, NULL);
found_error = true;
}
}
}
RETURN (found_error);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cmd_check_ok --
*
* Check if a server reply document is an error message.
* Optionally fill out a bson_error_t from the server error.
* Does *not* check for writeConcernError.
*
* Returns:
* false if @doc is an error message, true otherwise.
*
* Side effects:
* If @doc is an error reply and @error is not NULL, set its
* domain, code, and message.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cmd_check_ok (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error)
{
mongoc_error_domain_t domain =
error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER
: MONGOC_ERROR_QUERY;
uint32_t code;
bson_iter_t iter;
const char *msg = "Unknown command error";
ENTRY;
BSON_ASSERT (doc);
if (bson_iter_init_find (&iter, doc, "ok") && bson_iter_as_bool (&iter)) {
/* no error */
RETURN (true);
}
if (!_parse_error_reply (doc, false /* check_wce */, &code, &msg)) {
RETURN (true);
}
if (code == MONGOC_ERROR_PROTOCOL_ERROR || code == 13390) {
code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND;
} else if (code == 0) {
code = MONGOC_ERROR_QUERY_FAILURE;
}
bson_set_error (error, domain, code, "%s", msg);
/* there was a command error */
RETURN (false);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_cmd_check_ok_no_wce --
*
* Check if a server reply document is an error message.
* Optionally fill out a bson_error_t from the server error.
* If the response contains a writeConcernError, this is considered
* an error and returns false.
*
* Returns:
* false if @doc is an error message, true otherwise.
*
* Side effects:
* If @doc is an error reply and @error is not NULL, set its
* domain, code, and message.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_cmd_check_ok_no_wce (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error)
{
mongoc_error_domain_t domain =
error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER
: MONGOC_ERROR_QUERY;
uint32_t code;
const char *msg = "Unknown command error";
ENTRY;
BSON_ASSERT (doc);
if (!_parse_error_reply (doc, true /* check_wce */, &code, &msg)) {
RETURN (true);
}
if (code == MONGOC_ERROR_PROTOCOL_ERROR || code == 13390) {
code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND;
} else if (code == 0) {
code = MONGOC_ERROR_QUERY_FAILURE;
}
bson_set_error (error, domain, code, "%s", msg);
/* there was a command error */
RETURN (false);
}
/* helper function to parse error reply document to an OP_QUERY */
static void
_mongoc_populate_query_error (const bson_t *doc,
int32_t error_api_version,
bson_error_t *error)
{
mongoc_error_domain_t domain =
error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER
: MONGOC_ERROR_QUERY;
uint32_t code = MONGOC_ERROR_QUERY_FAILURE;
bson_iter_t iter;
const char *msg = "Unknown query failure";
ENTRY;
BSON_ASSERT (doc);
if (bson_iter_init_find (&iter, doc, "code") &&
BSON_ITER_HOLDS_NUMBER (&iter)) {
code = (uint32_t) bson_iter_as_int64 (&iter);
BSON_ASSERT (code);
}
if (bson_iter_init_find (&iter, doc, "$err") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
msg = bson_iter_utf8 (&iter, NULL);
}
bson_set_error (error, domain, code, "%s", msg);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_rpc_check_ok --
*
* Check if a server OP_REPLY is an error message.
* Optionally fill out a bson_error_t from the server error.
* @error_document must be an initialized bson_t or NULL.
* Does *not* check for writeConcernError.
*
* Returns:
* false if the reply is an error message, true otherwise.
*
* Side effects:
* If rpc is an error reply and @error is not NULL, set its
* domain, code, and message.
*
* If rpc is an error reply and @error_document is not NULL,
* it is reinitialized with the server reply.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_rpc_check_ok (mongoc_rpc_t *rpc,
int32_t error_api_version,
bson_error_t *error /* OUT */,
bson_t *error_doc /* OUT */)
{
bson_t b;
ENTRY;
BSON_ASSERT (rpc);
if (rpc->header.opcode != MONGOC_OPCODE_REPLY) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Received rpc other than OP_REPLY.");
RETURN (false);
}
if (rpc->reply.flags & MONGOC_REPLY_QUERY_FAILURE) {
if (_mongoc_rpc_get_first_document (rpc, &b)) {
_mongoc_populate_query_error (&b, error_api_version, error);
if (error_doc) {
bson_destroy (error_doc);
bson_copy_to (&b, error_doc);
}
bson_destroy (&b);
} else {
bson_set_error (error,
MONGOC_ERROR_QUERY,
MONGOC_ERROR_QUERY_FAILURE,
"Unknown query failure.");
}
RETURN (false);
} else if (rpc->reply.flags & MONGOC_REPLY_CURSOR_NOT_FOUND) {
bson_set_error (error,
MONGOC_ERROR_CURSOR,
MONGOC_ERROR_CURSOR_INVALID_CURSOR,
"The cursor is invalid or has expired.");
RETURN (false);
}
RETURN (true);
}
/* If rpc is OP_COMPRESSED, decompress it into buffer.
*
* Assumes rpc is still in network little-endian representation (i.e.
* _mongoc_rpc_swab_to_le has not been called).
* Returns true if rpc is not OP_COMPRESSED (and is a no-op) or if decompression
* succeeds.
* Return false and sets error otherwise.
*/
bool
_mongoc_rpc_decompress_if_necessary (mongoc_rpc_t *rpc,
mongoc_buffer_t *buffer /* IN/OUT */,
bson_error_t *error /* OUT */)
{
uint8_t *buf = NULL;
size_t len;
if (BSON_UINT32_FROM_LE (rpc->header.opcode) != MONGOC_OPCODE_COMPRESSED) {
return true;
}
len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) +
sizeof (mongoc_rpc_header_t);
buf = bson_malloc0 (len);
if (!_mongoc_rpc_decompress (rpc, buf, len)) {
bson_free (buf);
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Could not decompress server reply");
return false;
}
_mongoc_buffer_destroy (buffer);
_mongoc_buffer_init (buffer, buf, len, NULL, NULL);
return true;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
index df308798..e70e18ea 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c
@@ -1,1149 +1,1148 @@
/* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_CRYPTO
#include <string.h>
#include "mongoc-error.h"
#include "mongoc-scram-private.h"
#include "mongoc-rand-private.h"
#include "mongoc-util-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-crypto-private.h"
#include "common-b64-private.h"
#include "mongoc-memcmp-private.h"
#define MONGOC_SCRAM_SERVER_KEY "Server Key"
#define MONGOC_SCRAM_CLIENT_KEY "Client Key"
static int
_scram_hash_size (mongoc_scram_t *scram)
{
if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_1) {
return MONGOC_SCRAM_SHA_1_HASH_SIZE;
} else if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_256) {
return MONGOC_SCRAM_SHA_256_HASH_SIZE;
}
return 0;
}
/* Copies the cache's secrets to scram */
static void
_mongoc_scram_cache_apply_secrets (mongoc_scram_cache_t *cache,
mongoc_scram_t *scram)
{
BSON_ASSERT (cache);
BSON_ASSERT (scram);
memcpy (scram->client_key, cache->client_key, sizeof (scram->client_key));
memcpy (scram->server_key, cache->server_key, sizeof (scram->server_key));
memcpy (scram->salted_password,
cache->salted_password,
sizeof (scram->salted_password));
}
static mongoc_scram_cache_t *
_mongoc_scram_cache_copy (const mongoc_scram_cache_t *cache)
{
mongoc_scram_cache_t *ret = NULL;
if (cache) {
ret = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*ret));
ret->hashed_password = bson_strdup (cache->hashed_password);
memcpy (
ret->decoded_salt, cache->decoded_salt, sizeof (ret->decoded_salt));
ret->iterations = cache->iterations;
memcpy (ret->client_key, cache->client_key, sizeof (ret->client_key));
memcpy (ret->server_key, cache->server_key, sizeof (ret->server_key));
memcpy (ret->salted_password,
cache->salted_password,
sizeof (ret->salted_password));
}
return ret;
}
#ifdef MONGOC_ENABLE_ICU
#include <unicode/usprep.h>
#include <unicode/ustring.h>
#endif
void
_mongoc_scram_cache_destroy (mongoc_scram_cache_t *cache)
{
BSON_ASSERT (cache);
if (cache->hashed_password) {
bson_zero_free (cache->hashed_password, strlen (cache->hashed_password));
}
bson_free (cache);
}
/* Checks whether the cache contains scram's pre-secrets */
static bool
_mongoc_scram_cache_has_presecrets (mongoc_scram_cache_t *cache,
mongoc_scram_t *scram)
{
BSON_ASSERT (cache);
BSON_ASSERT (scram);
return cache->hashed_password && scram->hashed_password &&
!strcmp (cache->hashed_password, scram->hashed_password) &&
cache->iterations == scram->iterations &&
!memcmp (cache->decoded_salt,
scram->decoded_salt,
sizeof (cache->decoded_salt));
}
mongoc_scram_cache_t *
_mongoc_scram_get_cache (mongoc_scram_t *scram)
{
BSON_ASSERT (scram);
return _mongoc_scram_cache_copy (scram->cache);
}
void
_mongoc_scram_set_cache (mongoc_scram_t *scram, mongoc_scram_cache_t *cache)
{
BSON_ASSERT (scram);
if (scram->cache) {
_mongoc_scram_cache_destroy (scram->cache);
}
scram->cache = _mongoc_scram_cache_copy (cache);
}
void
_mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass)
{
BSON_ASSERT (scram);
if (scram->pass) {
bson_zero_free (scram->pass, strlen (scram->pass));
}
scram->pass = pass ? bson_strdup (pass) : NULL;
}
void
_mongoc_scram_set_user (mongoc_scram_t *scram, const char *user)
{
BSON_ASSERT (scram);
bson_free (scram->user);
scram->user = user ? bson_strdup (user) : NULL;
}
void
_mongoc_scram_init (mongoc_scram_t *scram, mongoc_crypto_hash_algorithm_t algo)
{
BSON_ASSERT (scram);
memset (scram, 0, sizeof *scram);
mongoc_crypto_init (&scram->crypto, algo);
}
void
_mongoc_scram_destroy (mongoc_scram_t *scram)
{
BSON_ASSERT (scram);
bson_free (scram->user);
if (scram->pass) {
bson_zero_free (scram->pass, strlen (scram->pass));
}
if (scram->hashed_password) {
bson_zero_free (scram->hashed_password, strlen (scram->hashed_password));
}
bson_free (scram->auth_message);
if (scram->cache) {
_mongoc_scram_cache_destroy (scram->cache);
}
memset (scram, 0, sizeof *scram);
}
/* Updates the cache with scram's last-used pre-secrets and secrets */
static void
_mongoc_scram_update_cache (mongoc_scram_t *scram)
{
mongoc_scram_cache_t *cache;
BSON_ASSERT (scram);
if (scram->cache) {
_mongoc_scram_cache_destroy (scram->cache);
}
cache = (mongoc_scram_cache_t *) bson_malloc0 (sizeof (*cache));
cache->hashed_password = bson_strdup (scram->hashed_password);
memcpy (
cache->decoded_salt, scram->decoded_salt, sizeof (cache->decoded_salt));
cache->iterations = scram->iterations;
memcpy (cache->client_key, scram->client_key, sizeof (cache->client_key));
memcpy (cache->server_key, scram->server_key, sizeof (cache->server_key));
memcpy (cache->salted_password,
scram->salted_password,
sizeof (cache->salted_password));
scram->cache = cache;
}
static bool
_mongoc_scram_buf_write (const char *src,
int32_t src_len,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen)
{
if (src_len < 0) {
src_len = (int32_t) strlen (src);
}
if (*outbuflen + src_len >= outbufmax) {
return false;
}
memcpy (outbuf + *outbuflen, src, src_len);
*outbuflen += src_len;
return true;
}
/* generate client-first-message:
* n,a=authzid,n=encoded-username,r=client-nonce
*
* note that a= is optional, so we aren't dealing with that here
*/
static bool
_mongoc_scram_start (mongoc_scram_t *scram,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
uint8_t nonce[24];
const char *ptr;
bool rval = true;
BSON_ASSERT (scram);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbufmax);
BSON_ASSERT (outbuflen);
if (!scram->user) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: username is not set");
goto FAIL;
}
/* auth message is as big as the outbuf just because */
scram->auth_message = (uint8_t *) bson_malloc (outbufmax);
scram->auth_messagemax = outbufmax;
/* the server uses a 24 byte random nonce. so we do as well */
if (1 != _mongoc_rand_bytes (nonce, sizeof (nonce))) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not generate a cryptographically "
"secure nonce in sasl step 1");
goto FAIL;
}
- scram->encoded_nonce_len =
- COMMON_PREFIX (bson_b64_ntop (nonce,
- sizeof (nonce),
- scram->encoded_nonce,
- sizeof (scram->encoded_nonce)));
+ scram->encoded_nonce_len = mcommon_b64_ntop (nonce,
+ sizeof (nonce),
+ scram->encoded_nonce,
+ sizeof (scram->encoded_nonce));
if (-1 == scram->encoded_nonce_len) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not encode nonce");
goto FAIL;
}
if (!_mongoc_scram_buf_write ("n,,n=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
for (ptr = scram->user; *ptr; ptr++) {
/* RFC 5802 specifies that ',' and '=' and encoded as '=2C' and '=3D'
* respectively in the user name */
switch (*ptr) {
case ',':
if (!_mongoc_scram_buf_write (
"=2C", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
break;
case '=':
if (!_mongoc_scram_buf_write (
"=3D", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
break;
default:
if (!_mongoc_scram_buf_write (ptr, 1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
break;
}
}
if (!_mongoc_scram_buf_write (",r=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
if (!_mongoc_scram_buf_write (scram->encoded_nonce,
scram->encoded_nonce_len,
outbuf,
outbufmax,
outbuflen)) {
goto BUFFER;
}
/* we have to keep track of the conversation to create a client proof later
* on. This copies the message we're crafting from the 'n=' portion onwards
* into a buffer we're managing */
if (!_mongoc_scram_buf_write ((char *) outbuf + 3,
*outbuflen - 3,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
if (!_mongoc_scram_buf_write (",",
-1,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
goto CLEANUP;
BUFFER_AUTH:
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer auth message in sasl step1");
goto FAIL;
BUFFER:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer sasl step1");
goto FAIL;
FAIL:
rval = false;
CLEANUP:
return rval;
}
/* Compute the SCRAM step Hi() as defined in RFC5802 */
static void
_mongoc_scram_salt_password (mongoc_scram_t *scram,
const char *password,
uint32_t password_len,
const uint8_t *salt,
uint32_t salt_len,
uint32_t iterations)
{
uint8_t intermediate_digest[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t start_key[MONGOC_SCRAM_HASH_MAX_SIZE];
int i;
int k;
uint8_t *output = scram->salted_password;
memcpy (start_key, salt, salt_len);
start_key[salt_len] = 0;
start_key[salt_len + 1] = 0;
start_key[salt_len + 2] = 0;
start_key[salt_len + 3] = 1;
mongoc_crypto_hmac (&scram->crypto,
password,
password_len,
start_key,
_scram_hash_size (scram),
output);
memcpy (intermediate_digest, output, _scram_hash_size (scram));
/* intermediateDigest contains Ui and output contains the accumulated XOR:ed
* result */
for (i = 2; i <= iterations; i++) {
mongoc_crypto_hmac (&scram->crypto,
password,
password_len,
intermediate_digest,
_scram_hash_size (scram),
intermediate_digest);
for (k = 0; k < _scram_hash_size (scram); k++) {
output[k] ^= intermediate_digest[k];
}
}
}
static bool
_mongoc_scram_generate_client_proof (mongoc_scram_t *scram,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen)
{
uint8_t stored_key[MONGOC_SCRAM_HASH_MAX_SIZE];
uint8_t client_signature[MONGOC_SCRAM_HASH_MAX_SIZE];
unsigned char client_proof[MONGOC_SCRAM_HASH_MAX_SIZE];
int i;
int r = 0;
if (!*scram->client_key) {
/* ClientKey := HMAC(saltedPassword, "Client Key") */
mongoc_crypto_hmac (&scram->crypto,
scram->salted_password,
_scram_hash_size (scram),
(uint8_t *) MONGOC_SCRAM_CLIENT_KEY,
(int) strlen (MONGOC_SCRAM_CLIENT_KEY),
scram->client_key);
}
/* StoredKey := H(client_key) */
mongoc_crypto_hash (&scram->crypto,
scram->client_key,
(size_t) _scram_hash_size (scram),
stored_key);
/* ClientSignature := HMAC(StoredKey, AuthMessage) */
mongoc_crypto_hmac (&scram->crypto,
stored_key,
_scram_hash_size (scram),
scram->auth_message,
scram->auth_messagelen,
client_signature);
/* ClientProof := ClientKey XOR ClientSignature */
for (i = 0; i < _scram_hash_size (scram); i++) {
client_proof[i] = scram->client_key[i] ^ client_signature[i];
}
- r = COMMON_PREFIX (bson_b64_ntop (client_proof,
- _scram_hash_size (scram),
- (char *) outbuf + *outbuflen,
- outbufmax - *outbuflen));
+ r = mcommon_b64_ntop (client_proof,
+ _scram_hash_size (scram),
+ (char *) outbuf + *outbuflen,
+ outbufmax - *outbuflen);
if (-1 == r) {
return false;
}
*outbuflen += r;
return true;
}
/* Parse server-first-message of the form:
* r=client-nonce|server-nonce,s=user-salt,i=iteration-count
*
* Generate client-final-message of the form:
* c=channel-binding(base64),r=client-nonce|server-nonce,p=client-proof
*/
static bool
_mongoc_scram_step2 (mongoc_scram_t *scram,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
uint8_t *val_r = NULL;
uint32_t val_r_len;
uint8_t *val_s = NULL;
uint32_t val_s_len;
uint8_t *val_i = NULL;
uint32_t val_i_len;
uint8_t **current_val;
uint32_t *current_val_len;
const uint8_t *ptr;
const uint8_t *next_comma;
char *tmp;
char *hashed_password;
uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_MAX_SIZE] = {0};
int32_t decoded_salt_len;
/* the decoded salt leaves four trailing bytes to add the int32 0x00000001 */
const int32_t expected_salt_length = _scram_hash_size (scram) - 4;
bool rval = true;
int iterations;
BSON_ASSERT (scram);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbufmax);
BSON_ASSERT (outbuflen);
if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_1) {
/* Auth spec for SCRAM-SHA-1: "The password variable MUST be the mongodb
* hashed variant. The mongo hashed variant is computed as hash = HEX(
* MD5( UTF8( username + ':mongo:' + plain_text_password )))" */
tmp = bson_strdup_printf ("%s:mongo:%s", scram->user, scram->pass);
hashed_password = _mongoc_hex_md5 (tmp);
bson_zero_free (tmp, strlen (tmp));
} else if (scram->crypto.algorithm == MONGOC_CRYPTO_ALGORITHM_SHA_256) {
/* Auth spec for SCRAM-SHA-256: "Passwords MUST be prepared with SASLprep,
* per RFC 5802. Passwords are used directly for key derivation; they
* MUST NOT be digested as they are in SCRAM-SHA-1." */
hashed_password =
_mongoc_sasl_prep (scram->pass, (int) strlen (scram->pass), error);
if (!hashed_password) {
goto FAIL;
}
} else {
BSON_ASSERT (false);
}
/* we need all of the incoming message for the final client proof */
if (!_mongoc_scram_buf_write ((char *) inbuf,
inbuflen,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
if (!_mongoc_scram_buf_write (",",
-1,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
for (ptr = inbuf; ptr < inbuf + inbuflen;) {
switch (*ptr) {
case 'r':
current_val = &val_r;
current_val_len = &val_r_len;
break;
case 's':
current_val = &val_s;
current_val_len = &val_s_len;
break;
case 'i':
current_val = &val_i;
current_val_len = &val_i_len;
break;
default:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unknown key (%c) in sasl step 2",
*ptr);
goto FAIL;
}
ptr++;
if (*ptr != '=') {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: invalid parse state in sasl step 2");
goto FAIL;
}
ptr++;
next_comma =
(const uint8_t *) memchr (ptr, ',', (inbuf + inbuflen) - ptr);
if (next_comma) {
*current_val_len = (uint32_t) (next_comma - ptr);
} else {
*current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr);
}
*current_val = (uint8_t *) bson_malloc (*current_val_len + 1);
memcpy (*current_val, ptr, *current_val_len);
(*current_val)[*current_val_len] = '\0';
if (next_comma) {
ptr = next_comma + 1;
} else {
break;
}
}
if (!val_r) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no r param in sasl step 2");
goto FAIL;
}
if (!val_s) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no s param in sasl step 2");
goto FAIL;
}
if (!val_i) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no i param in sasl step 2");
goto FAIL;
}
/* verify our nonce */
if (val_r_len < scram->encoded_nonce_len ||
mongoc_memcmp (val_r, scram->encoded_nonce, scram->encoded_nonce_len)) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: client nonce not repeated in sasl step 2");
}
*outbuflen = 0;
if (!_mongoc_scram_buf_write (
"c=biws,r=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
if (!_mongoc_scram_buf_write (
(char *) val_r, val_r_len, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
if (!_mongoc_scram_buf_write ((char *) outbuf,
*outbuflen,
scram->auth_message,
scram->auth_messagemax,
&scram->auth_messagelen)) {
goto BUFFER_AUTH;
}
if (!_mongoc_scram_buf_write (",p=", -1, outbuf, outbufmax, outbuflen)) {
goto BUFFER;
}
- decoded_salt_len = COMMON_PREFIX (bson_b64_pton (
- (char *) val_s, decoded_salt, sizeof (decoded_salt)));
+ decoded_salt_len =
+ mcommon_b64_pton ((char *) val_s, decoded_salt, sizeof (decoded_salt));
if (-1 == decoded_salt_len) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unable to decode salt in sasl step2");
goto FAIL;
}
if (expected_salt_length != decoded_salt_len) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: invalid salt length of %d in sasl step2",
decoded_salt_len);
goto FAIL;
}
iterations = (int) bson_ascii_strtoll ((char *) val_i, &tmp, 10);
/* tmp holds the location of the failed to parse character. So if it's
* null, we got to the end of the string and didn't have a parse error */
if (*tmp) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unable to parse iterations in sasl step2");
goto FAIL;
}
if (iterations < 0) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: iterations is negative in sasl step2");
goto FAIL;
}
/* drivers MUST enforce a minimum iteration count of 4096 and MUST error if
* the authentication conversation specifies a lower count. This mitigates
* downgrade attacks by a man-in-the-middle attacker. */
if (iterations < 4096) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: iterations must be at least 4096");
goto FAIL;
}
/* Save the presecrets for caching */
scram->hashed_password = bson_strdup (hashed_password);
scram->iterations = iterations;
memcpy (scram->decoded_salt, decoded_salt, sizeof (scram->decoded_salt));
if (scram->cache &&
_mongoc_scram_cache_has_presecrets (scram->cache, scram)) {
_mongoc_scram_cache_apply_secrets (scram->cache, scram);
}
if (!*scram->salted_password) {
_mongoc_scram_salt_password (scram,
hashed_password,
(uint32_t) strlen (hashed_password),
decoded_salt,
decoded_salt_len,
(uint32_t) iterations);
}
_mongoc_scram_generate_client_proof (scram, outbuf, outbufmax, outbuflen);
goto CLEANUP;
BUFFER_AUTH:
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer auth message in sasl step2");
goto FAIL;
BUFFER:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not buffer sasl step2");
goto FAIL;
FAIL:
rval = false;
CLEANUP:
bson_free (val_r);
bson_free (val_s);
bson_free (val_i);
if (hashed_password) {
bson_zero_free (hashed_password, strlen (hashed_password));
}
return rval;
}
static bool
_mongoc_scram_verify_server_signature (mongoc_scram_t *scram,
uint8_t *verification,
uint32_t len)
{
char encoded_server_signature[MONGOC_SCRAM_B64_HASH_MAX_SIZE];
int32_t encoded_server_signature_len;
uint8_t server_signature[MONGOC_SCRAM_HASH_MAX_SIZE];
if (!*scram->server_key) {
/* ServerKey := HMAC(SaltedPassword, "Server Key") */
mongoc_crypto_hmac (&scram->crypto,
scram->salted_password,
_scram_hash_size (scram),
(uint8_t *) MONGOC_SCRAM_SERVER_KEY,
strlen (MONGOC_SCRAM_SERVER_KEY),
scram->server_key);
}
/* ServerSignature := HMAC(ServerKey, AuthMessage) */
mongoc_crypto_hmac (&scram->crypto,
scram->server_key,
_scram_hash_size (scram),
scram->auth_message,
scram->auth_messagelen,
server_signature);
encoded_server_signature_len =
- COMMON_PREFIX (bson_b64_ntop (server_signature,
- _scram_hash_size (scram),
- encoded_server_signature,
- sizeof (encoded_server_signature)));
+ mcommon_b64_ntop (server_signature,
+ _scram_hash_size (scram),
+ encoded_server_signature,
+ sizeof (encoded_server_signature));
if (encoded_server_signature_len == -1) {
return false;
}
return (len == encoded_server_signature_len) &&
(mongoc_memcmp (verification, encoded_server_signature, len) == 0);
}
static bool
_mongoc_scram_step3 (mongoc_scram_t *scram,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
uint8_t *val_e = NULL;
uint32_t val_e_len;
uint8_t *val_v = NULL;
uint32_t val_v_len;
uint8_t **current_val;
uint32_t *current_val_len;
const uint8_t *ptr;
const uint8_t *next_comma;
bool rval = true;
BSON_ASSERT (scram);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbufmax);
BSON_ASSERT (outbuflen);
for (ptr = inbuf; ptr < inbuf + inbuflen;) {
switch (*ptr) {
case 'e':
current_val = &val_e;
current_val_len = &val_e_len;
break;
case 'v':
current_val = &val_v;
current_val_len = &val_v_len;
break;
default:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: unknown key (%c) in sasl step 3",
*ptr);
goto FAIL;
}
ptr++;
if (*ptr != '=') {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: invalid parse state in sasl step 3");
goto FAIL;
}
ptr++;
next_comma =
(const uint8_t *) memchr (ptr, ',', (inbuf + inbuflen) - ptr);
if (next_comma) {
*current_val_len = (uint32_t) (next_comma - ptr);
} else {
*current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr);
}
*current_val = (uint8_t *) bson_malloc (*current_val_len + 1);
memcpy (*current_val, ptr, *current_val_len);
(*current_val)[*current_val_len] = '\0';
if (next_comma) {
ptr = next_comma + 1;
} else {
break;
}
}
*outbuflen = 0;
if (val_e) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: authentication failure in sasl step 3 : %s",
val_e);
goto FAIL;
}
if (!val_v) {
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: no v param in sasl step 3");
goto FAIL;
}
if (!_mongoc_scram_verify_server_signature (scram, val_v, val_v_len)) {
bson_set_error (
error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: could not verify server signature in sasl step 3");
goto FAIL;
}
/* Update the cache if authentication succeeds */
_mongoc_scram_update_cache (scram);
goto CLEANUP;
FAIL:
rval = false;
CLEANUP:
bson_free (val_e);
bson_free (val_v);
return rval;
}
bool
_mongoc_scram_step (mongoc_scram_t *scram,
const uint8_t *inbuf,
uint32_t inbuflen,
uint8_t *outbuf,
uint32_t outbufmax,
uint32_t *outbuflen,
bson_error_t *error)
{
BSON_ASSERT (scram);
BSON_ASSERT (inbuf);
BSON_ASSERT (outbuf);
BSON_ASSERT (outbuflen);
scram->step++;
switch (scram->step) {
case 1:
return _mongoc_scram_start (scram, outbuf, outbufmax, outbuflen, error);
case 2:
return _mongoc_scram_step2 (
scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error);
case 3:
return _mongoc_scram_step3 (
scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error);
default:
bson_set_error (error,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_NOT_DONE,
"SCRAM Failure: maximum steps detected");
return false;
}
}
bool
_mongoc_sasl_prep_required (const char *str)
{
unsigned char c;
while (*str) {
c = (unsigned char) *str;
/* characters below 32 contain all of the control characters.
* characters above 127 are multibyte UTF-8 characters.
* character 127 is the DEL character. */
if (c < 32 || c >= 127) {
return true;
}
str++;
}
return false;
}
#ifdef MONGOC_ENABLE_ICU
char *
_mongoc_sasl_prep_impl (const char *name,
const char *in_utf8,
int in_utf8_len,
bson_error_t *err)
{
/* The flow is in_utf8 -> in_utf16 -> SASLPrep -> out_utf16 -> out_utf8. */
UChar *in_utf16, *out_utf16;
char *out_utf8;
int32_t in_utf16_len, out_utf16_len, out_utf8_len;
UErrorCode error_code = U_ZERO_ERROR;
UStringPrepProfile *prep;
#define SASL_PREP_ERR_RETURN(msg) \
do { \
bson_set_error (err, \
MONGOC_ERROR_SCRAM, \
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, \
(msg), \
name); \
return NULL; \
} while (0)
/* 1. convert str to UTF-16. */
/* preflight to get the destination length. */
(void) u_strFromUTF8 (
NULL, 0, &in_utf16_len, in_utf8, in_utf8_len, &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR) {
SASL_PREP_ERR_RETURN ("could not calculate UTF-16 length of %s");
}
/* convert to UTF-16. */
error_code = U_ZERO_ERROR;
in_utf16 = bson_malloc (sizeof (UChar) *
(in_utf16_len + 1)); /* add one for null byte. */
(void) u_strFromUTF8 (
in_utf16, in_utf16_len + 1, NULL, in_utf8, in_utf8_len, &error_code);
if (error_code) {
bson_free (in_utf16);
SASL_PREP_ERR_RETURN ("could not convert %s to UTF-16");
}
/* 2. perform SASLPrep. */
prep = usprep_openByType (USPREP_RFC4013_SASLPREP, &error_code);
if (error_code) {
bson_free (in_utf16);
SASL_PREP_ERR_RETURN ("could not start SASLPrep for %s");
}
/* preflight. */
out_utf16_len = usprep_prepare (
prep, in_utf16, in_utf16_len, NULL, 0, USPREP_DEFAULT, NULL, &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR) {
bson_free (in_utf16);
usprep_close (prep);
SASL_PREP_ERR_RETURN ("could not calculate SASLPrep length of %s");
}
/* convert. */
error_code = U_ZERO_ERROR;
out_utf16 = bson_malloc (sizeof (UChar) * (out_utf16_len + 1));
(void) usprep_prepare (prep,
in_utf16,
in_utf16_len,
out_utf16,
out_utf16_len + 1,
USPREP_DEFAULT,
NULL,
&error_code);
if (error_code) {
bson_free (in_utf16);
bson_free (out_utf16);
usprep_close (prep);
SASL_PREP_ERR_RETURN ("could not execute SASLPrep for %s");
}
bson_free (in_utf16);
usprep_close (prep);
/* 3. convert back to UTF-8. */
/* preflight. */
(void) u_strToUTF8 (
NULL, 0, &out_utf8_len, out_utf16, out_utf16_len, &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR) {
bson_free (out_utf16);
SASL_PREP_ERR_RETURN ("could not calculate UTF-8 length of %s");
}
/* convert. */
error_code = U_ZERO_ERROR;
out_utf8 = (char *) bson_malloc (
sizeof (char) * (out_utf8_len + 1)); /* add one for null byte. */
(void) u_strToUTF8 (
out_utf8, out_utf8_len + 1, NULL, out_utf16, out_utf16_len, &error_code);
if (error_code) {
bson_free (out_utf8);
bson_free (out_utf16);
SASL_PREP_ERR_RETURN ("could not convert %s back to UTF-8");
}
bson_free (out_utf16);
return out_utf8;
#undef SASL_PREP_ERR_RETURN
}
#endif
char *
_mongoc_sasl_prep (const char *in_utf8, int in_utf8_len, bson_error_t *err)
{
#ifdef MONGOC_ENABLE_ICU
return _mongoc_sasl_prep_impl ("password", in_utf8, in_utf8_len, err);
#else
if (_mongoc_sasl_prep_required (in_utf8)) {
bson_set_error (err,
MONGOC_ERROR_SCRAM,
MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
"SCRAM Failure: ICU required to SASLPrep password");
return NULL;
}
return bson_strdup (in_utf8);
#endif
}
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
index 69b9d8d5..1d608be2 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h
@@ -1,247 +1,250 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_SERVER_DESCRIPTION_PRIVATE_H
#define MONGOC_SERVER_DESCRIPTION_PRIVATE_H
#include "mongoc-server-description.h"
#include "mongoc-generation-map-private.h"
#define MONGOC_DEFAULT_WIRE_VERSION 0
#define MONGOC_DEFAULT_WRITE_BATCH_SIZE 1000
#define MONGOC_DEFAULT_BSON_OBJ_SIZE 16 * 1024 * 1024
#define MONGOC_DEFAULT_MAX_MSG_SIZE 48000000
/* This is slightly out-of-spec as of the current version of the spec (1.0.0),
* but SPEC-1397 plans to amend "Size limits and Wire Protocol Considerations"
* to say that drivers MAY split with a reduced maxBsonObjectSize or
* maxMessageSizeBytes
* depending on the implementation. It is less invasive for libmongoc to split
* OP_MSG payload type 1 with a reduced maxMessageSizeBytes and convert it to a
* payload type 0
* rather than split a payload type 0 with a reduced maxBsonObjectSize.
*/
#define MONGOC_REDUCED_MAX_MSG_SIZE_FOR_FLE 2097152
#define MONGOC_NO_SESSIONS -1
#define MONGOC_IDLE_WRITE_PERIOD_MS 10 * 1000
/* represent a server or topology with no replica set config version */
#define MONGOC_NO_SET_VERSION -1
#define MONGOC_RTT_UNSET -1
+#define MONGOC_NO_SERVER_CONNECTION_ID -1
+
typedef enum {
MONGOC_SERVER_UNKNOWN,
MONGOC_SERVER_STANDALONE,
MONGOC_SERVER_MONGOS,
MONGOC_SERVER_POSSIBLE_PRIMARY,
MONGOC_SERVER_RS_PRIMARY,
MONGOC_SERVER_RS_SECONDARY,
MONGOC_SERVER_RS_ARBITER,
MONGOC_SERVER_RS_OTHER,
MONGOC_SERVER_RS_GHOST,
MONGOC_SERVER_LOAD_BALANCER,
MONGOC_SERVER_DESCRIPTION_TYPES,
} mongoc_server_description_type_t;
struct _mongoc_server_description_t {
uint32_t id;
mongoc_host_list_t host;
int64_t round_trip_time_msec;
int64_t last_update_time_usec;
bson_t last_hello_response;
bool has_hello_response;
bool hello_ok;
const char *connection_address;
/* SDAM dictates storing me/hosts/passives/arbiters after being "normalized
* to lower-case" Instead, they are stored in the casing they are received,
* but compared case insensitively. This should be addressed in CDRIVER-3527.
*/
const char *me;
/* whether an APM server-opened callback has been fired before */
bool opened;
const char *set_name;
bson_error_t error;
mongoc_server_description_type_t type;
int32_t min_wire_version;
int32_t max_wire_version;
int32_t max_msg_size;
int32_t max_bson_obj_size;
int32_t max_write_batch_size;
int64_t session_timeout_minutes;
/* hosts, passives, and arbiters are stored as a BSON array, but compared
* case insensitively. This should be improved in CDRIVER-3527. */
bson_t hosts;
bson_t passives;
bson_t arbiters;
bson_t tags;
const char *current_primary;
int64_t set_version;
bson_oid_t election_id;
int64_t last_write_date_ms;
bson_t compressors;
bson_t topology_version;
/*
The generation is incremented every time connections to this server should be
invalidated.
This happens when:
1. a monitor receives a network error
2. an app thread receives any network error before completing a handshake
3. an app thread receives a non-timeout network error after the handshake
4. an app thread receives a "not primary" or "node is recovering" error from
a pre-4.2 server.
*/
/* generation only applies to a server description tied to a connection.
* It represents the generation number for this connection. */
uint32_t generation;
/* _generation_map_ stores all generations for all service IDs associated
* with this server. _generation_map_ is only accessed on the server
* description for monitoring. In non-load-balanced mode, there are no
* service IDs. The only server generation is mapped from kZeroServiceID */
mongoc_generation_map_t *_generation_map_;
bson_oid_t service_id;
+ int32_t server_connection_id;
};
/** Get a mutable pointer to the server's generation map */
static BSON_INLINE mongoc_generation_map_t *
mc_tpl_sd_generation_map (mongoc_server_description_t *sd)
{
return sd->_generation_map_;
}
/** Get a const pointer to the server's generation map */
static BSON_INLINE const mongoc_generation_map_t *
mc_tpl_sd_generation_map_const (const mongoc_server_description_t *sd)
{
return sd->_generation_map_;
}
/**
* @brief Increment the generation number on the given server for the associated
* service ID.
*/
static BSON_INLINE void
mc_tpl_sd_increment_generation (mongoc_server_description_t *sd,
const bson_oid_t *service_id)
{
mongoc_generation_map_increment (mc_tpl_sd_generation_map (sd), service_id);
}
/**
* @brief Get the generation number of the given server description for the
* associated service ID.
*/
static BSON_INLINE uint32_t
mc_tpl_sd_get_generation (const mongoc_server_description_t *sd,
const bson_oid_t *service_id)
{
return mongoc_generation_map_get (mc_tpl_sd_generation_map_const (sd),
service_id);
}
void
mongoc_server_description_init (mongoc_server_description_t *sd,
const char *address,
uint32_t id);
bool
mongoc_server_description_has_rs_member (
const mongoc_server_description_t *description, const char *address);
bool
mongoc_server_description_has_set_version (
const mongoc_server_description_t *description);
bool
mongoc_server_description_has_election_id (
const mongoc_server_description_t *description);
void
mongoc_server_description_cleanup (mongoc_server_description_t *sd);
void
mongoc_server_description_reset (mongoc_server_description_t *sd);
void
mongoc_server_description_set_state (mongoc_server_description_t *description,
mongoc_server_description_type_t type);
void
mongoc_server_description_set_set_version (
mongoc_server_description_t *description, int64_t set_version);
void
mongoc_server_description_set_election_id (
mongoc_server_description_t *description, const bson_oid_t *election_id);
void
mongoc_server_description_update_rtt (mongoc_server_description_t *server,
int64_t rtt_msec);
void
mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
const bson_t *hello_response,
int64_t rtt_msec,
const bson_error_t *error /* IN */);
void
mongoc_server_description_filter_stale (
const mongoc_server_description_t **sds,
size_t sds_len,
const mongoc_server_description_t *primary,
int64_t heartbeat_frequency_ms,
const mongoc_read_prefs_t *read_prefs);
void
mongoc_server_description_filter_tags (
const mongoc_server_description_t **descriptions,
size_t description_len,
const mongoc_read_prefs_t *read_prefs);
/* Compares server descriptions following the "Server Description Equality"
* rules. Not all fields are considered. */
bool
_mongoc_server_description_equal (mongoc_server_description_t *sd1,
mongoc_server_description_t *sd2);
int
mongoc_server_description_topology_version_cmp (const bson_t *tv1,
const bson_t *tv2);
void
mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
const bson_t *tv);
extern const bson_oid_t kZeroServiceId;
bool
mongoc_server_description_has_service_id (
const mongoc_server_description_t *description);
/* mongoc_global_mock_service_id is only used for testing. The test runner sets
* this to true when testing against a load balanced deployment to mock the
* presence of a serviceId field in the "hello" response. The purpose of this is
* further described in the Load Balancer test README. */
extern bool mongoc_global_mock_service_id;
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
index 540b27a4..ac9afaeb 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c
@@ -1,1282 +1,1288 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-config.h"
#include "mongoc-host-list.h"
#include "mongoc-host-list-private.h"
#include "mongoc-read-prefs.h"
#include "mongoc-read-prefs-private.h"
#include "mongoc-server-description-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-uri.h"
#include "mongoc-util-private.h"
#include "mongoc-compression-private.h"
#include <stdio.h>
#define ALPHA 0.2
static bson_oid_t kObjectIdZero = {{0}};
const bson_oid_t kZeroServiceId = {{0}};
bool mongoc_global_mock_service_id = false;
static bool
_match_tag_set (const mongoc_server_description_t *sd,
bson_iter_t *tag_set_iter);
/* Destroy allocated resources within @description, but don't free it */
void
mongoc_server_description_cleanup (mongoc_server_description_t *sd)
{
BSON_ASSERT (sd);
bson_destroy (&sd->last_hello_response);
bson_destroy (&sd->hosts);
bson_destroy (&sd->passives);
bson_destroy (&sd->arbiters);
bson_destroy (&sd->tags);
bson_destroy (&sd->compressors);
bson_destroy (&sd->topology_version);
mongoc_generation_map_destroy (sd->_generation_map_);
}
/* Reset fields inside this sd, but keep same id, host information, RTT,
generation, topology version, and leave hello in empty inited state */
void
mongoc_server_description_reset (mongoc_server_description_t *sd)
{
BSON_ASSERT (sd);
memset (&sd->error, 0, sizeof sd->error);
sd->set_name = NULL;
sd->type = MONGOC_SERVER_UNKNOWN;
sd->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
sd->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
sd->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE;
sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE;
sd->session_timeout_minutes = MONGOC_NO_SESSIONS;
sd->last_write_date_ms = -1;
sd->hello_ok = false;
/* always leave last hello in an init-ed state until we destroy sd */
bson_destroy (&sd->last_hello_response);
bson_init (&sd->last_hello_response);
sd->has_hello_response = false;
sd->last_update_time_usec = bson_get_monotonic_time ();
bson_destroy (&sd->hosts);
bson_destroy (&sd->passives);
bson_destroy (&sd->arbiters);
bson_destroy (&sd->tags);
bson_destroy (&sd->compressors);
bson_init (&sd->hosts);
bson_init (&sd->passives);
bson_init (&sd->arbiters);
bson_init (&sd->tags);
bson_init (&sd->compressors);
sd->me = NULL;
sd->current_primary = NULL;
sd->set_version = MONGOC_NO_SET_VERSION;
bson_oid_copy_unsafe (&kObjectIdZero, &sd->election_id);
bson_oid_copy_unsafe (&kObjectIdZero, &sd->service_id);
+ sd->server_connection_id = MONGOC_NO_SERVER_CONNECTION_ID;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_init --
*
* Initialize a new server_description_t.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_init (mongoc_server_description_t *sd,
const char *address,
uint32_t id)
{
ENTRY;
BSON_ASSERT (sd);
BSON_ASSERT (address);
sd->id = id;
sd->type = MONGOC_SERVER_UNKNOWN;
sd->round_trip_time_msec = MONGOC_RTT_UNSET;
sd->generation = 0;
sd->opened = 0;
sd->_generation_map_ = mongoc_generation_map_new ();
if (!_mongoc_host_list_from_string (&sd->host, address)) {
MONGOC_WARNING ("Failed to parse uri for %s", address);
return;
}
sd->connection_address = sd->host.host_and_port;
bson_init (&sd->last_hello_response);
bson_init (&sd->hosts);
bson_init (&sd->passives);
bson_init (&sd->arbiters);
bson_init (&sd->tags);
bson_init (&sd->compressors);
bson_init (&sd->topology_version);
mongoc_server_description_reset (sd);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_destroy --
*
* Destroy allocated resources within @description and free
* @description.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_destroy (mongoc_server_description_t *description)
{
ENTRY;
if (!description) {
EXIT;
}
mongoc_server_description_cleanup (description);
bson_free (description);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_has_rs_member --
*
* Return true if this address is included in server's list of rs
* members, false otherwise.
*
* Returns:
* true, false
*
* Side effects:
* None
*
*--------------------------------------------------------------------------
*/
bool
mongoc_server_description_has_rs_member (
const mongoc_server_description_t *server, const char *address)
{
bson_iter_t member_iter;
const bson_t *rs_members[3];
int i;
if (server->type != MONGOC_SERVER_UNKNOWN) {
rs_members[0] = &server->hosts;
rs_members[1] = &server->arbiters;
rs_members[2] = &server->passives;
for (i = 0; i < 3; i++) {
BSON_ASSERT (bson_iter_init (&member_iter, rs_members[i]));
while (bson_iter_next (&member_iter)) {
if (strcasecmp (address, bson_iter_utf8 (&member_iter, NULL)) ==
0) {
return true;
}
}
}
}
return false;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_has_set_version --
*
* Did this server's hello response have a "setVersion" field?
*
* Returns:
* True if the server description's setVersion is set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_server_description_has_set_version (
const mongoc_server_description_t *description)
{
return description->set_version != MONGOC_NO_SET_VERSION;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_has_election_id --
*
* Did this server's hello response have an "electionId" field?
*
* Returns:
* True if the server description's electionId is set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_server_description_has_election_id (
const mongoc_server_description_t *description)
{
return 0 != bson_oid_compare (&description->election_id, &kObjectIdZero);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_id --
*
* Get the id of this server.
*
* Returns:
* Server's id.
*
*--------------------------------------------------------------------------
*/
uint32_t
mongoc_server_description_id (const mongoc_server_description_t *description)
{
return description->id;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_host --
*
* Return a reference to the host associated with this server description.
*
* Returns:
* This server description's host, a mongoc_host_list_t * you must
* not modify or free.
*
*--------------------------------------------------------------------------
*/
mongoc_host_list_t *
mongoc_server_description_host (const mongoc_server_description_t *description)
{
return &((mongoc_server_description_t *) description)->host;
}
int64_t
mongoc_server_description_last_update_time (
const mongoc_server_description_t *description)
{
return description->last_update_time_usec;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_round_trip_time --
*
* Get the round trip time of this server, which is the client's
* measurement of the duration of a "hello" command.
*
* Returns:
* The server's round trip time in milliseconds.
*
*--------------------------------------------------------------------------
*/
int64_t
mongoc_server_description_round_trip_time (
const mongoc_server_description_t *description)
{
return description->round_trip_time_msec;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_type --
*
* Get this server's type, one of the types defined in the Server
* Discovery And Monitoring Spec.
*
* Returns:
* A string.
*
*--------------------------------------------------------------------------
*/
const char *
mongoc_server_description_type (const mongoc_server_description_t *description)
{
switch (description->type) {
case MONGOC_SERVER_UNKNOWN:
return "Unknown";
case MONGOC_SERVER_STANDALONE:
return "Standalone";
case MONGOC_SERVER_MONGOS:
return "Mongos";
case MONGOC_SERVER_POSSIBLE_PRIMARY:
return "PossiblePrimary";
case MONGOC_SERVER_RS_PRIMARY:
return "RSPrimary";
case MONGOC_SERVER_RS_SECONDARY:
return "RSSecondary";
case MONGOC_SERVER_RS_ARBITER:
return "RSArbiter";
case MONGOC_SERVER_RS_OTHER:
return "RSOther";
case MONGOC_SERVER_RS_GHOST:
return "RSGhost";
case MONGOC_SERVER_LOAD_BALANCER:
return "LoadBalancer";
case MONGOC_SERVER_DESCRIPTION_TYPES:
default:
MONGOC_ERROR ("Invalid mongoc_server_description_t type");
return "Invalid";
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_hello_response --
*
* Return this server's most recent "hello" command response.
*
* Returns:
* A reference to a BSON document, owned by the server description.
*
*--------------------------------------------------------------------------
*/
const bson_t *
mongoc_server_description_hello_response (
const mongoc_server_description_t *description)
{
return &description->last_hello_response;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_ismaster --
*
* Return this server's most recent "hello" command response.
*
* Returns:
* A reference to a BSON document, owned by the server description.
*
*--------------------------------------------------------------------------
*/
const bson_t *
mongoc_server_description_ismaster (
const mongoc_server_description_t *description)
{
return mongoc_server_description_hello_response (description);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_set_state --
*
* Set the server description's server type.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_set_state (mongoc_server_description_t *description,
mongoc_server_description_type_t type)
{
description->type = type;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_set_set_version --
*
* Set the replica set version of this server.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_set_set_version (
mongoc_server_description_t *description, int64_t set_version)
{
description->set_version = set_version;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_set_election_id --
*
* Set the election_id of this server. Copies the given ObjectId or,
* if it is NULL, zeroes description's election_id.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
mongoc_server_description_set_election_id (
mongoc_server_description_t *description, const bson_oid_t *election_id)
{
if (election_id) {
bson_oid_copy_unsafe (election_id, &description->election_id);
} else {
bson_oid_copy_unsafe (&kObjectIdZero, &description->election_id);
}
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_update_rtt --
*
* Calculate this server's rtt calculation using an exponentially-
* weighted moving average formula.
*
* Side effects:
* None.
*
* If rtt_msec is MONGOC_RTT_UNSET, the value is not updated.
*
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_update_rtt (mongoc_server_description_t *server,
int64_t rtt_msec)
{
if (rtt_msec == MONGOC_RTT_UNSET) {
return;
}
if (server->round_trip_time_msec == MONGOC_RTT_UNSET) {
bson_atomic_int64_exchange (
&server->round_trip_time_msec, rtt_msec, bson_memory_order_relaxed);
} else {
bson_atomic_int64_exchange (
&server->round_trip_time_msec,
(int64_t) (ALPHA * rtt_msec +
(1 - ALPHA) * server->round_trip_time_msec),
bson_memory_order_relaxed);
}
}
static void
_mongoc_server_description_set_error (mongoc_server_description_t *sd,
const bson_error_t *error)
{
if (error && error->code) {
memcpy (&sd->error, error, sizeof (bson_error_t));
} else {
bson_set_error (&sd->error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"unknown error calling hello");
}
/* Server Discovery and Monitoring Spec: if the server type changes from a
* known type to Unknown its RTT is set to null. */
sd->round_trip_time_msec = MONGOC_RTT_UNSET;
}
/*
*-------------------------------------------------------------------------
*
* Called during SDAM, from topology description's hello handler, or
* when handshaking a connection in _mongoc_cluster_stream_for_server.
*
* If @hello_response is empty, @error must say why hello failed.
*
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
const bson_t *hello_response,
int64_t rtt_msec,
const bson_error_t *error /* IN */)
{
bson_iter_t iter;
bson_iter_t child;
bool is_primary = false;
bool is_shard = false;
bool is_secondary = false;
bool is_arbiter = false;
bool is_replicaset = false;
bool is_hidden = false;
const uint8_t *bytes;
uint32_t len;
int num_keys = 0;
ENTRY;
BSON_ASSERT (sd);
mongoc_server_description_reset (sd);
if (!hello_response) {
_mongoc_server_description_set_error (sd, error);
EXIT;
}
bson_destroy (&sd->last_hello_response);
bson_init (&sd->last_hello_response);
bson_copy_to_excluding_noinit (hello_response,
&sd->last_hello_response,
"speculativeAuthenticate",
NULL);
sd->has_hello_response = true;
/* Only reinitialize the topology version if we have a hello response.
* Resetting a server description should not effect the topology version. */
bson_reinit (&sd->topology_version);
BSON_ASSERT (bson_iter_init (&iter, &sd->last_hello_response));
while (bson_iter_next (&iter)) {
num_keys++;
if (strcmp ("ok", bson_iter_key (&iter)) == 0) {
if (!bson_iter_as_bool (&iter)) {
/* it doesn't really matter what error API we use. the code and
* domain will be overwritten. */
(void) _mongoc_cmd_check_ok (
hello_response, MONGOC_ERROR_API_VERSION_2, &sd->error);
/* TODO CDRIVER-3696: this is an existing bug. If this is handling
* a hello reply that is NOT from a handshake, this should not
* be considered an auth error. */
/* hello response returned ok: 0. According to auth spec: "If the
* hello of the MongoDB Handshake fails with an error, drivers
* MUST treat this an authentication error." */
sd->error.domain = MONGOC_ERROR_CLIENT;
sd->error.code = MONGOC_ERROR_CLIENT_AUTHENTICATE;
goto failure;
}
} else if (strcmp ("isWritablePrimary", bson_iter_key (&iter)) == 0 ||
strcmp (HANDSHAKE_RESPONSE_LEGACY_HELLO,
bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_primary = bson_iter_bool (&iter);
} else if (strcmp ("helloOk", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
sd->hello_ok = bson_iter_bool (&iter);
} else if (strcmp ("me", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
sd->me = bson_iter_utf8 (&iter, NULL);
} else if (strcmp ("maxMessageSizeBytes", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_msg_size = bson_iter_int32 (&iter);
} else if (strcmp ("maxBsonObjectSize", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_bson_obj_size = bson_iter_int32 (&iter);
} else if (strcmp ("maxWriteBatchSize", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_write_batch_size = bson_iter_int32 (&iter);
} else if (strcmp ("logicalSessionTimeoutMinutes",
bson_iter_key (&iter)) == 0) {
if (BSON_ITER_HOLDS_NUMBER (&iter)) {
sd->session_timeout_minutes = bson_iter_as_int64 (&iter);
} else if (BSON_ITER_HOLDS_NULL (&iter)) {
/* this arises executing standard JSON tests */
sd->session_timeout_minutes = MONGOC_NO_SESSIONS;
} else {
goto failure;
}
} else if (strcmp ("minWireVersion", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->min_wire_version = bson_iter_int32 (&iter);
} else if (strcmp ("maxWireVersion", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_INT32 (&iter))
goto failure;
sd->max_wire_version = bson_iter_int32 (&iter);
} else if (strcmp ("msg", bson_iter_key (&iter)) == 0) {
const char *msg;
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
msg = bson_iter_utf8 (&iter, NULL);
if (msg && 0 == strcmp (msg, "isdbgrid")) {
is_shard = true;
}
} else if (strcmp ("setName", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
sd->set_name = bson_iter_utf8 (&iter, NULL);
} else if (strcmp ("setVersion", bson_iter_key (&iter)) == 0) {
mongoc_server_description_set_set_version (sd,
bson_iter_as_int64 (&iter));
} else if (strcmp ("electionId", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_OID (&iter))
goto failure;
mongoc_server_description_set_election_id (sd, bson_iter_oid (&iter));
} else if (strcmp ("secondary", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_secondary = bson_iter_bool (&iter);
} else if (strcmp ("hosts", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->hosts);
BSON_ASSERT (bson_init_static (&sd->hosts, bytes, len));
} else if (strcmp ("passives", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->passives);
BSON_ASSERT (bson_init_static (&sd->passives, bytes, len));
} else if (strcmp ("arbiters", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->arbiters);
BSON_ASSERT (bson_init_static (&sd->arbiters, bytes, len));
} else if (strcmp ("primary", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_UTF8 (&iter))
goto failure;
sd->current_primary = bson_iter_utf8 (&iter, NULL);
} else if (strcmp ("arbiterOnly", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_arbiter = bson_iter_bool (&iter);
} else if (strcmp ("isreplicaset", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_BOOL (&iter))
goto failure;
is_replicaset = bson_iter_bool (&iter);
} else if (strcmp ("tags", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter))
goto failure;
bson_iter_document (&iter, &len, &bytes);
bson_destroy (&sd->tags);
BSON_ASSERT (bson_init_static (&sd->tags, bytes, len));
} else if (strcmp ("hidden", bson_iter_key (&iter)) == 0) {
is_hidden = bson_iter_bool (&iter);
} else if (strcmp ("lastWrite", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_DOCUMENT (&iter) ||
!bson_iter_recurse (&iter, &child) ||
!bson_iter_find (&child, "lastWriteDate") ||
!BSON_ITER_HOLDS_DATE_TIME (&child)) {
goto failure;
}
sd->last_write_date_ms = bson_iter_date_time (&child);
} else if (strcmp ("compression", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_ARRAY (&iter))
goto failure;
bson_iter_array (&iter, &len, &bytes);
bson_destroy (&sd->compressors);
BSON_ASSERT (bson_init_static (&sd->compressors, bytes, len));
} else if (strcmp ("topologyVersion", bson_iter_key (&iter)) == 0) {
bson_t incoming_topology_version;
if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
goto failure;
}
bson_iter_document (&iter, &len, &bytes);
bson_init_static (&incoming_topology_version, bytes, len);
mongoc_server_description_set_topology_version (
sd, &incoming_topology_version);
bson_destroy (&incoming_topology_version);
} else if (strcmp ("serviceId", bson_iter_key (&iter)) == 0) {
if (!BSON_ITER_HOLDS_OID (&iter))
goto failure;
bson_oid_copy_unsafe (bson_iter_oid (&iter), &sd->service_id);
+ } else if (strcmp ("connectionId", bson_iter_key (&iter)) == 0) {
+ if (!BSON_ITER_HOLDS_INT32 (&iter))
+ goto failure;
+ sd->server_connection_id = bson_iter_int32 (&iter);
}
}
if (mongoc_global_mock_service_id) {
bson_iter_t pid_iter;
if (bson_iter_init_find (&pid_iter, &sd->topology_version, "processId") &&
BSON_ITER_HOLDS_OID (&pid_iter)) {
bson_oid_copy (bson_iter_oid (&pid_iter), &sd->service_id);
}
}
if (is_shard) {
sd->type = MONGOC_SERVER_MONGOS;
} else if (sd->set_name) {
if (is_hidden) {
sd->type = MONGOC_SERVER_RS_OTHER;
} else if (is_primary) {
sd->type = MONGOC_SERVER_RS_PRIMARY;
} else if (is_secondary) {
sd->type = MONGOC_SERVER_RS_SECONDARY;
} else if (is_arbiter) {
sd->type = MONGOC_SERVER_RS_ARBITER;
} else {
sd->type = MONGOC_SERVER_RS_OTHER;
}
} else if (is_replicaset) {
sd->type = MONGOC_SERVER_RS_GHOST;
} else if (num_keys > 0) {
sd->type = MONGOC_SERVER_STANDALONE;
} else {
sd->type = MONGOC_SERVER_UNKNOWN;
}
if (!num_keys) {
/* empty reply means hello failed */
_mongoc_server_description_set_error (sd, error);
}
mongoc_server_description_update_rtt (sd, rtt_msec);
EXIT;
failure:
sd->type = MONGOC_SERVER_UNKNOWN;
sd->round_trip_time_msec = MONGOC_RTT_UNSET;
EXIT;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_new_copy --
*
* A copy of a server description that you must destroy, or NULL.
*
*-------------------------------------------------------------------------
*/
mongoc_server_description_t *
mongoc_server_description_new_copy (
const mongoc_server_description_t *description)
{
mongoc_server_description_t *copy;
if (!description) {
return NULL;
}
copy = (mongoc_server_description_t *) bson_malloc0 (sizeof (*copy));
copy->id = description->id;
copy->opened = description->opened;
memcpy (&copy->host, &description->host, sizeof (copy->host));
copy->round_trip_time_msec = MONGOC_RTT_UNSET;
copy->connection_address = copy->host.host_and_port;
bson_init (&copy->last_hello_response);
bson_init (&copy->hosts);
bson_init (&copy->passives);
bson_init (&copy->arbiters);
bson_init (&copy->tags);
bson_init (&copy->compressors);
bson_copy_to (&description->topology_version, &copy->topology_version);
bson_oid_copy (&description->service_id, &copy->service_id);
+ copy->server_connection_id = description->server_connection_id;
if (description->has_hello_response) {
/* calls mongoc_server_description_reset */
int64_t last_rtt_ms = bson_atomic_int64_fetch (
&description->round_trip_time_msec, bson_memory_order_relaxed);
mongoc_server_description_handle_hello (copy,
&description->last_hello_response,
last_rtt_ms,
&description->error);
} else {
mongoc_server_description_reset (copy);
/* preserve the original server description type, which is manually set
* for a LoadBalancer server */
copy->type = description->type;
}
/* Preserve the error */
memcpy (&copy->error, &description->error, sizeof copy->error);
copy->generation = description->generation;
copy->_generation_map_ =
mongoc_generation_map_copy (mc_tpl_sd_generation_map_const (description));
return copy;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_filter_stale --
*
* Estimate servers' staleness according to the Server Selection Spec.
* Determines the number of eligible servers, and sets any servers that
* are too stale to NULL in the descriptions set.
*
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_filter_stale (
const mongoc_server_description_t **sds,
size_t sds_len,
const mongoc_server_description_t *primary,
int64_t heartbeat_frequency_ms,
const mongoc_read_prefs_t *read_prefs)
{
int64_t max_staleness_seconds;
size_t i;
int64_t heartbeat_frequency_usec;
int64_t max_last_write_date_usec;
int64_t staleness_usec;
int64_t max_staleness_usec;
if (!read_prefs) {
/* NULL read_prefs is PRIMARY, no maxStalenessSeconds to filter by */
return;
}
max_staleness_seconds =
mongoc_read_prefs_get_max_staleness_seconds (read_prefs);
if (max_staleness_seconds == MONGOC_NO_MAX_STALENESS) {
return;
}
BSON_ASSERT (max_staleness_seconds > 0);
max_staleness_usec = max_staleness_seconds * 1000 * 1000;
heartbeat_frequency_usec = heartbeat_frequency_ms * 1000;
if (primary) {
for (i = 0; i < sds_len; i++) {
if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) {
continue;
}
/* See max-staleness.rst for explanation of these formulae. */
staleness_usec =
primary->last_write_date_ms * 1000 +
(sds[i]->last_update_time_usec - primary->last_update_time_usec) -
sds[i]->last_write_date_ms * 1000 + heartbeat_frequency_usec;
if (staleness_usec > max_staleness_usec) {
TRACE ("Rejected stale RSSecondary [%s]",
sds[i]->host.host_and_port);
sds[i] = NULL;
}
}
} else {
/* find max last_write_date */
max_last_write_date_usec = 0;
for (i = 0; i < sds_len; i++) {
if (sds[i] && sds[i]->type == MONGOC_SERVER_RS_SECONDARY) {
max_last_write_date_usec = BSON_MAX (
max_last_write_date_usec, sds[i]->last_write_date_ms * 1000);
}
}
/* use max last_write_date to estimate each secondary's staleness */
for (i = 0; i < sds_len; i++) {
if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) {
continue;
}
staleness_usec = max_last_write_date_usec -
sds[i]->last_write_date_ms * 1000 +
heartbeat_frequency_usec;
if (staleness_usec > max_staleness_usec) {
TRACE ("Rejected stale RSSecondary [%s]",
sds[i]->host.host_and_port);
sds[i] = NULL;
}
}
}
}
/*
*-------------------------------------------------------------------------
*
* mongoc_server_description_filter_tags --
*
* Given a set of server descriptions, set to NULL any that don't
* match the read preference's tag sets.
*
* https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#tag-set
*
*-------------------------------------------------------------------------
*/
void
mongoc_server_description_filter_tags (
const mongoc_server_description_t **descriptions,
size_t description_len,
const mongoc_read_prefs_t *read_prefs)
{
const bson_t *rp_tags;
bson_iter_t rp_tagset_iter;
bson_iter_t tag_set_iter;
bool *sd_matched = NULL;
bool found;
size_t i;
if (!read_prefs) {
/* NULL read_prefs is PRIMARY, no tags to filter by */
return;
}
rp_tags = mongoc_read_prefs_get_tags (read_prefs);
if (bson_count_keys (rp_tags) == 0) {
/* no tags to filter by */
return;
}
sd_matched = (bool *) bson_malloc0 (sizeof (bool) * description_len);
bson_iter_init (&rp_tagset_iter, rp_tags);
/* for each read preference tag set */
while (bson_iter_next (&rp_tagset_iter)) {
found = false;
for (i = 0; i < description_len; i++) {
if (!descriptions[i]) {
/* NULLed earlier in mongoc_topology_description_suitable_servers */
continue;
}
BSON_ASSERT (bson_iter_recurse (&rp_tagset_iter, &tag_set_iter));
sd_matched[i] = _match_tag_set (descriptions[i], &tag_set_iter);
if (sd_matched[i]) {
found = true;
}
}
if (found) {
for (i = 0; i < description_len; i++) {
if (!sd_matched[i] && descriptions[i]) {
TRACE ("Rejected [%s] [%s], doesn't match tags",
mongoc_server_description_type (descriptions[i]),
descriptions[i]->host.host_and_port);
descriptions[i] = NULL;
}
}
goto CLEANUP;
}
}
/* tried each */
for (i = 0; i < description_len; i++) {
if (!sd_matched[i]) {
TRACE ("Rejected [%s] [%s], reached end of tags array without match",
mongoc_server_description_type (descriptions[i]),
descriptions[i]->host.host_and_port);
descriptions[i] = NULL;
}
}
CLEANUP:
bson_free (sd_matched);
}
/*
*-------------------------------------------------------------------------
*
* _match_tag_set --
*
* Check if a server's tags match one tag set, like
* {'tag1': 'value1', 'tag2': 'value2'}.
*
*-------------------------------------------------------------------------
*/
static bool
_match_tag_set (const mongoc_server_description_t *sd,
bson_iter_t *tag_set_iter)
{
bson_iter_t sd_iter;
uint32_t read_pref_tag_len;
uint32_t sd_len;
const char *read_pref_tag;
const char *read_pref_val;
const char *server_val;
while (bson_iter_next (tag_set_iter)) {
/* one {'tag': 'value'} pair from the read preference's tag set */
read_pref_tag = bson_iter_key (tag_set_iter);
read_pref_val = bson_iter_utf8 (tag_set_iter, &read_pref_tag_len);
if (bson_iter_init_find (&sd_iter, &sd->tags, read_pref_tag)) {
/* The server has this tag - does it have the right value? */
server_val = bson_iter_utf8 (&sd_iter, &sd_len);
if (sd_len != read_pref_tag_len ||
memcmp (read_pref_val, server_val, read_pref_tag_len)) {
/* If the values don't match, no match */
return false;
}
} else {
/* If the server description doesn't have that key, no match */
return false;
}
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_server_description_compressor_id --
*
* Get the compressor id if compression was negotiated.
*
* Returns:
* The compressor ID, or -1 if none was negotiated.
*
*--------------------------------------------------------------------------
*/
int32_t
mongoc_server_description_compressor_id (
const mongoc_server_description_t *description)
{
int id;
bson_iter_t iter;
BSON_ASSERT (bson_iter_init (&iter, &description->compressors));
while (bson_iter_next (&iter)) {
id = mongoc_compressor_name_to_id (bson_iter_utf8 (&iter, NULL));
if (id != -1) {
return id;
}
}
return -1;
}
/* Returns true if either or both is NULL. out is 1 if exactly one NULL, 0 if
* both NULL */
typedef int (*strcmp_fn) (const char *, const char *);
static int
_nullable_cmp (const char *a, const char *b, strcmp_fn cmp_fn)
{
if (!a && b) {
return 1;
}
if (a && !b) {
return 1;
}
if (!a && !b) {
return 0;
}
/* Both not NULL. */
return cmp_fn (a, b);
}
static int
_nullable_strcasecmp (const char *a, const char *b)
{
return _nullable_cmp (a, b, strcasecmp);
}
static int
_nullable_strcmp (const char *a, const char *b)
{
return _nullable_cmp (a, b, strcmp);
}
bool
_mongoc_server_description_equal (mongoc_server_description_t *sd1,
mongoc_server_description_t *sd2)
{
if (sd1->type != sd2->type) {
return false;
}
if (sd1->min_wire_version != sd2->min_wire_version) {
return false;
}
if (sd1->max_wire_version != sd2->max_wire_version) {
return false;
}
if (0 != _nullable_strcasecmp (sd1->me, sd2->me)) {
return false;
}
/* CDRIVER-3527: The hosts/passives/arbiters checks should really be a set
* comparison of case insensitive hostnames. */
if (!bson_equal (&sd1->hosts, &sd2->hosts)) {
return false;
}
if (!bson_equal (&sd1->passives, &sd2->passives)) {
return false;
}
if (!bson_equal (&sd1->arbiters, &sd2->arbiters)) {
return false;
}
if (!bson_equal (&sd1->tags, &sd2->tags)) {
return false;
}
if (0 != _nullable_strcmp (sd1->set_name, sd2->set_name)) {
return false;
}
if (sd1->set_version != sd2->set_version) {
return false;
}
if (!bson_oid_equal (&sd1->election_id, &sd2->election_id)) {
return false;
}
if (0 != _nullable_strcasecmp (sd1->current_primary, sd2->current_primary)) {
return false;
}
if (sd1->session_timeout_minutes != sd2->session_timeout_minutes) {
return false;
}
if (0 != memcmp (&sd1->error, &sd2->error, sizeof (bson_error_t))) {
return false;
}
if (!bson_equal (&sd1->topology_version, &sd2->topology_version)) {
return false;
}
return true;
}
int
mongoc_server_description_topology_version_cmp (const bson_t *tv1,
const bson_t *tv2)
{
const bson_oid_t *pid1;
const bson_oid_t *pid2;
int64_t counter1;
int64_t counter2;
bson_iter_t iter;
BSON_ASSERT (tv1);
BSON_ASSERT (tv2);
if (bson_empty (tv1) || bson_empty (tv2)) {
return -1;
}
if (!bson_iter_init_find (&iter, tv1, "processId") ||
!BSON_ITER_HOLDS_OID (&iter)) {
return -1;
}
pid1 = bson_iter_oid (&iter);
if (!bson_iter_init_find (&iter, tv2, "processId") ||
!BSON_ITER_HOLDS_OID (&iter)) {
return -1;
}
pid2 = bson_iter_oid (&iter);
if (0 != bson_oid_compare (pid1, pid2)) {
/* Assume greater. */
return -1;
}
if (!bson_iter_init_find (&iter, tv1, "counter") ||
!BSON_ITER_HOLDS_INT (&iter)) {
return -1;
}
counter1 = bson_iter_as_int64 (&iter);
if (!bson_iter_init_find (&iter, tv2, "counter") ||
!BSON_ITER_HOLDS_INT (&iter)) {
return -1;
}
counter2 = bson_iter_as_int64 (&iter);
if (counter1 < counter2) {
return -1;
} else if (counter1 > counter2) {
return 1;
}
return 0;
}
void
mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
const bson_t *tv)
{
BSON_ASSERT (tv);
bson_destroy (&sd->topology_version);
bson_copy_to (tv, &sd->topology_version);
}
bool
mongoc_server_description_has_service_id (
const mongoc_server_description_t *description)
{
if (0 == bson_oid_compare (&description->service_id, &kZeroServiceId)) {
return false;
}
return true;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c
similarity index 90%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c
index 69a7dc2c..fac6280d 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c
@@ -1,1273 +1,1390 @@
/*
* Copyright 2020-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common-thread-private.h"
#include "mongoc-server-monitor-private.h"
#include "mongoc/mongoc-client-private.h"
#include "mongoc/mongoc-error-private.h"
#include "mongoc/mongoc-flags-private.h"
#include "mongoc/mongoc-ssl-private.h"
#include "mongoc/mongoc-stream-private.h"
#include "mongoc/mongoc-topology-background-monitoring-private.h"
#include "mongoc/mongoc-topology-private.h"
#include "mongoc/mongoc-trace-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "monitor"
typedef enum {
MONGOC_THREAD_OFF = 0,
MONGOC_THREAD_RUNNING,
MONGOC_THREAD_SHUTTING_DOWN,
MONGOC_THREAD_JOINABLE
} thread_state_t;
/* Use a signed and wide return type for timeouts as long as you can. Cast only
* when you know what you're doing with it. */
static int64_t
_now_us (void)
{
return bson_get_monotonic_time ();
}
static int64_t
_now_ms (void)
{
return _now_us () / 1000;
}
struct _mongoc_server_monitor_t {
mongoc_topology_t *topology;
bson_thread_t thread;
/* State accessed from multiple threads. */
struct {
bson_mutex_t mutex;
mongoc_cond_t cond;
thread_state_t state;
bool scan_requested;
bool cancel_requested;
} shared;
/* Default time to sleep between hello checks (reduced when a scan is
* requested) */
uint64_t heartbeat_frequency_ms;
/* The minimum time to sleep between hello checks. */
uint64_t min_heartbeat_frequency_ms;
int64_t connect_timeout_ms;
bool use_tls;
#ifdef MONGOC_ENABLE_SSL
mongoc_ssl_opt_t *ssl_opts;
#endif
mongoc_uri_t *uri;
/* A custom initiator may be set if a user provides overrides to create a
* stream. */
mongoc_stream_initiator_t initiator;
void *initiator_context;
int64_t request_id;
mongoc_apm_callbacks_t apm_callbacks;
void *apm_context;
mongoc_stream_t *stream;
bool more_to_come;
mongoc_server_description_t *description;
uint32_t server_id;
bool is_rtt;
};
static BSON_GNUC_PRINTF (3, 4) void _server_monitor_log (
mongoc_server_monitor_t *server_monitor,
mongoc_log_level_t level,
const char *format,
...)
{
va_list ap;
char *msg;
va_start (ap, format);
msg = bson_strdupv_printf (format, ap);
va_end (ap);
mongoc_log (level,
MONGOC_LOG_DOMAIN,
"[%s%s] %s",
server_monitor->description->host.host_and_port,
server_monitor->is_rtt ? "-RTT" : "",
msg);
bson_free (msg);
}
#define MONITOR_LOG(sm, ...) \
do { \
if (MONGOC_TRACE_ENABLED) { \
_server_monitor_log (sm, MONGOC_LOG_LEVEL_TRACE, __VA_ARGS__); \
} \
} while (0)
/* TODO CDRIVER-3710 use MONGOC_LOG_LEVEL_ERROR */
#define MONITOR_LOG_ERROR(sm, ...) \
_server_monitor_log (sm, MONGOC_LOG_LEVEL_DEBUG, __VA_ARGS__)
/* TODO CDRIVER-3710 use MONGOC_LOG_LEVEL_WARNING */
#define MONITOR_LOG_WARNING(sm, ...) \
_server_monitor_log (sm, MONGOC_LOG_LEVEL_DEBUG, __VA_ARGS__)
static void
_server_monitor_heartbeat_started (mongoc_server_monitor_t *server_monitor,
bool awaited)
{
mongoc_apm_server_heartbeat_started_t event;
MONGOC_DEBUG_ASSERT (
- !COMMON_PREFIX (mutex_is_locked) (&server_monitor->topology->apm_mutex));
+ !mcommon_mutex_is_locked (&server_monitor->topology->apm_mutex));
if (!server_monitor->apm_callbacks.server_heartbeat_started) {
return;
}
event.host = &server_monitor->description->host;
event.context = server_monitor->apm_context;
MONITOR_LOG (server_monitor,
"%s heartbeat started",
awaited ? "awaitable" : "regular");
event.awaited = awaited;
bson_mutex_lock (&server_monitor->topology->apm_mutex);
server_monitor->apm_callbacks.server_heartbeat_started (&event);
bson_mutex_unlock (&server_monitor->topology->apm_mutex);
}
static void
_server_monitor_heartbeat_succeeded (mongoc_server_monitor_t *server_monitor,
const bson_t *reply,
int64_t duration_usec,
bool awaited)
{
mongoc_apm_server_heartbeat_succeeded_t event;
if (!server_monitor->apm_callbacks.server_heartbeat_succeeded) {
return;
}
event.host = &server_monitor->description->host;
event.context = server_monitor->apm_context;
event.reply = reply;
event.duration_usec = duration_usec;
MONITOR_LOG (server_monitor,
"%s heartbeat succeeded",
awaited ? "awaitable" : "regular");
event.awaited = awaited;
bson_mutex_lock (&server_monitor->topology->apm_mutex);
server_monitor->apm_callbacks.server_heartbeat_succeeded (&event);
bson_mutex_unlock (&server_monitor->topology->apm_mutex);
}
static void
_server_monitor_heartbeat_failed (mongoc_server_monitor_t *server_monitor,
const bson_error_t *error,
int64_t duration_usec,
bool awaited)
{
mongoc_apm_server_heartbeat_failed_t event;
if (!server_monitor->apm_callbacks.server_heartbeat_failed) {
return;
}
event.host = &server_monitor->description->host;
event.context = server_monitor->apm_context;
event.error = error;
event.duration_usec = duration_usec;
MONITOR_LOG (
server_monitor, "%s heartbeat failed", awaited ? "awaitable" : "regular");
event.awaited = awaited;
bson_mutex_lock (&server_monitor->topology->apm_mutex);
server_monitor->apm_callbacks.server_heartbeat_failed (&event);
bson_mutex_unlock (&server_monitor->topology->apm_mutex);
}
static void
_server_monitor_append_cluster_time (mongoc_server_monitor_t *server_monitor,
bson_t *cmd)
{
mc_shared_tpld td =
mc_tpld_take_ref (BSON_ASSERT_PTR_INLINE (server_monitor)->topology);
/* Cluster time is updated on every reply. */
if (!bson_empty (&td.ptr->cluster_time)) {
bson_append_document (cmd, "$clusterTime", 12, &td.ptr->cluster_time);
}
mc_tpld_drop_ref (&td);
}
+static bool
+_server_monitor_send_and_recv_hello_opmsg (
+ mongoc_server_monitor_t *server_monitor,
+ bson_t *cmd,
+ bson_t *reply,
+ bson_error_t *error)
+{
+ mongoc_rpc_t rpc = {0};
+ mongoc_array_t array_to_write;
+ mongoc_iovec_t *iovec;
+ int niovec;
+
+ mongoc_buffer_t buffer;
+ uint32_t reply_len;
+ bson_t temp_reply;
+ bool ret = false;
+
+ /* First, let's construct and send our OPCODE_MSG: */
+ rpc.header.msg_len = 0;
+ rpc.header.request_id = server_monitor->request_id++;
+ rpc.header.response_to = 0;
+ rpc.header.opcode = MONGOC_OPCODE_MSG;
+ rpc.msg.flags = 0;
+ rpc.msg.n_sections = 1;
+ rpc.msg.sections[0].payload_type = 0;
+ rpc.msg.sections[0].payload.bson_document = bson_get_data (cmd);
+
+ _mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t));
+ _mongoc_rpc_gather (&rpc, &array_to_write);
+
+ iovec = (mongoc_iovec_t *) array_to_write.data;
+ niovec = array_to_write.len;
+ _mongoc_rpc_swab_to_le (&rpc);
+
+ MONITOR_LOG (server_monitor,
+ "sending with timeout %" PRId64,
+ server_monitor->connect_timeout_ms);
+
+ if (!_mongoc_stream_writev_full (server_monitor->stream,
+ iovec,
+ niovec,
+ server_monitor->connect_timeout_ms,
+ error)) {
+ MONITOR_LOG_ERROR (
+ server_monitor, "failed to write polling hello: %s", error->message);
+ _mongoc_array_destroy (&array_to_write);
+ return false;
+ }
+
+ /* Done sending! Now, receive the reply: */
+
+ _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL);
+
+ if (!_mongoc_buffer_append_from_stream (&buffer,
+ server_monitor->stream,
+ 4,
+ server_monitor->connect_timeout_ms,
+ error)) {
+ goto fail;
+ }
+
+ memcpy (&reply_len, buffer.data, 4);
+ reply_len = BSON_UINT32_FROM_LE (reply_len);
+
+ if (!_mongoc_buffer_append_from_stream (&buffer,
+ server_monitor->stream,
+ reply_len - buffer.len,
+ server_monitor->connect_timeout_ms,
+ error)) {
+ goto fail;
+ }
+
+ if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) {
+ bson_set_error (error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Invalid reply from server.");
+
+ goto fail;
+ }
+
+ if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) {
+ goto fail;
+ }
+ _mongoc_rpc_swab_from_le (&rpc);
+
+ if (!_mongoc_rpc_get_first_document (&rpc, &temp_reply)) {
+ bson_set_error (error,
+ MONGOC_ERROR_PROTOCOL,
+ MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
+ "Invalid reply from server");
+ goto fail;
+ }
+ bson_copy_to (&temp_reply, reply);
+
+ ret = true;
+fail:
+ if (!ret) {
+ bson_init (reply);
+ }
+ _mongoc_array_destroy (&array_to_write);
+ _mongoc_buffer_destroy (&buffer);
+ return ret;
+}
static bool
_server_monitor_send_and_recv_opquery (mongoc_server_monitor_t *server_monitor,
const bson_t *cmd,
bson_t *reply,
bson_error_t *error)
{
mongoc_rpc_t rpc;
mongoc_array_t array_to_write;
mongoc_iovec_t *iovec;
int niovec;
mongoc_buffer_t buffer;
uint32_t reply_len;
bson_t temp_reply;
bool ret = false;
rpc.header.msg_len = 0;
rpc.header.request_id = server_monitor->request_id++;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_QUERY;
rpc.query.flags = MONGOC_QUERY_SECONDARY_OK;
rpc.query.collection = "admin.$cmd";
rpc.query.skip = 0;
rpc.query.n_return = -1;
rpc.query.query = bson_get_data (cmd);
rpc.query.fields = NULL;
_mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL);
_mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t));
_mongoc_rpc_gather (&rpc, &array_to_write);
iovec = (mongoc_iovec_t *) array_to_write.data;
niovec = array_to_write.len;
_mongoc_rpc_swab_to_le (&rpc);
if (!_mongoc_stream_writev_full (server_monitor->stream,
iovec,
niovec,
server_monitor->connect_timeout_ms,
error)) {
- GOTO (fail);
+ goto fail;
}
if (!_mongoc_buffer_append_from_stream (&buffer,
server_monitor->stream,
4,
server_monitor->connect_timeout_ms,
error)) {
- GOTO (fail);
+ goto fail;
}
memcpy (&reply_len, buffer.data, 4);
reply_len = BSON_UINT32_FROM_LE (reply_len);
if (!_mongoc_buffer_append_from_stream (&buffer,
server_monitor->stream,
reply_len - buffer.len,
server_monitor->connect_timeout_ms,
error)) {
- GOTO (fail);
+ goto fail;
}
if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server.");
- GOTO (fail);
+ goto fail;
}
if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) {
- GOTO (fail);
+ goto fail;
}
_mongoc_rpc_swab_from_le (&rpc);
if (!_mongoc_rpc_get_first_document (&rpc, &temp_reply)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Invalid reply from server");
- GOTO (fail);
+ goto fail;
}
bson_copy_to (&temp_reply, reply);
ret = true;
fail:
if (!ret) {
bson_init (reply);
}
_mongoc_array_destroy (&array_to_write);
_mongoc_buffer_destroy (&buffer);
return ret;
}
static bool
_server_monitor_polling_hello (mongoc_server_monitor_t *server_monitor,
bool hello_ok,
bson_t *hello_response,
bson_error_t *error)
{
bson_t cmd;
const bson_t *hello;
bool ret;
hello = _mongoc_topology_scanner_get_monitoring_cmd (
server_monitor->topology->scanner, hello_ok);
bson_copy_to (hello, &cmd);
_server_monitor_append_cluster_time (server_monitor, &cmd);
ret = _server_monitor_send_and_recv_opquery (
server_monitor, &cmd, hello_response, error);
bson_destroy (&cmd);
return ret;
}
static bool
_server_monitor_awaitable_hello_send (mongoc_server_monitor_t *server_monitor,
bson_t *cmd,
bson_error_t *error)
{
mongoc_rpc_t rpc = {0};
mongoc_array_t array_to_write;
mongoc_iovec_t *iovec;
int niovec;
rpc.header.msg_len = 0;
rpc.header.request_id = server_monitor->request_id++;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_MSG;
rpc.msg.flags = MONGOC_MSG_EXHAUST_ALLOWED;
rpc.msg.n_sections = 1;
rpc.msg.sections[0].payload_type = 0;
rpc.msg.sections[0].payload.bson_document = bson_get_data (cmd);
_mongoc_array_init (&array_to_write, sizeof (mongoc_iovec_t));
_mongoc_rpc_gather (&rpc, &array_to_write);
iovec = (mongoc_iovec_t *) array_to_write.data;
niovec = array_to_write.len;
_mongoc_rpc_swab_to_le (&rpc);
MONITOR_LOG (server_monitor,
"sending with timeout %" PRId64,
server_monitor->connect_timeout_ms);
if (!_mongoc_stream_writev_full (server_monitor->stream,
iovec,
niovec,
server_monitor->connect_timeout_ms,
error)) {
MONITOR_LOG_ERROR (
server_monitor, "failed to write awaitable hello: %s", error->message);
_mongoc_array_destroy (&array_to_write);
return false;
}
_mongoc_array_destroy (&array_to_write);
return true;
}
/* Poll the server monitor stream for reading. Allows cancellation.
*
* Called only from server monitor thread.
* Locks server monitor mutex.
* Returns true if stream is readable. False on error or cancellation.
* On cancellation, no error is set, but cancelled is set to true.
*/
static bool
_server_monitor_poll_with_interrupt (mongoc_server_monitor_t *server_monitor,
int64_t expire_at_ms,
bool *cancelled,
bson_error_t *error)
{
/* How many milliseconds we should poll for on each tick.
* On every tick, check whether the awaitable hello was cancelled. */
const int32_t monitor_tick_ms = MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS;
int64_t timeleft_ms;
while ((timeleft_ms = expire_at_ms - _now_ms ()) > 0) {
ssize_t ret;
mongoc_stream_poll_t poller[1];
MONITOR_LOG (server_monitor,
"_server_monitor_poll_with_interrupt expires in: %" PRIu64
"ms",
timeleft_ms);
poller[0].stream = server_monitor->stream;
poller[0].events =
POLLIN; /* POLLERR and POLLHUP are added in mongoc_socket_poll. */
poller[0].revents = 0;
MONITOR_LOG (
server_monitor,
"polling for awaitable hello reply with timeleft_ms: %" PRId64,
timeleft_ms);
ret = mongoc_stream_poll (
poller, 1, (int32_t) BSON_MIN (timeleft_ms, monitor_tick_ms));
if (ret == -1) {
MONITOR_LOG (server_monitor, "mongoc_stream_poll error");
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"poll error");
return false;
}
if (poller[0].revents & (POLLERR | POLLHUP)) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"connection closed while polling");
return false;
}
/* Check for cancellation. */
bson_mutex_lock (&server_monitor->shared.mutex);
*cancelled = server_monitor->shared.cancel_requested;
server_monitor->shared.cancel_requested = false;
bson_mutex_unlock (&server_monitor->shared.mutex);
if (*cancelled) {
MONITOR_LOG (server_monitor, "polling cancelled");
return false;
}
if (poller[0].revents & POLLIN) {
MONITOR_LOG (server_monitor, "mongoc_stream_poll ready to read");
return true;
}
}
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"connection timeout while polling");
return false;
}
/* Calculate the timeout between the current time and an absolute expiration
* time in milliseconds.
*
* Returns 0 and sets error if time expired.
*/
int64_t
_get_timeout_ms (int64_t expire_at_ms, bson_error_t *error)
{
int64_t timeout_ms;
timeout_ms = expire_at_ms - _now_ms ();
if (timeout_ms <= 0) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"connection timed out reading message length");
return 0;
}
return timeout_ms;
}
/* Receive an awaitable hello reply.
*
* May be used to receive additional replies when moreToCome is set.
* Called only from server monitor thread.
* May lock server monitor mutex in functions that are called.
* May block for up to heartbeatFrequencyMS + connectTimeoutMS waiting for
* reply.
* Returns true if a reply was received. False on error or cancellation.
* On cancellation, no error is set, but cancelled is set to true.
*/
static bool
_server_monitor_awaitable_hello_recv (mongoc_server_monitor_t *server_monitor,
bson_t *hello_response,
bool *cancelled,
bson_error_t *error)
{
bool ret = false;
mongoc_buffer_t buffer;
int32_t msg_len;
mongoc_rpc_t rpc;
bson_t reply_local;
int64_t expire_at_ms;
int64_t timeout_ms;
expire_at_ms = _now_ms () + server_monitor->heartbeat_frequency_ms +
server_monitor->connect_timeout_ms;
_mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL);
if (!_server_monitor_poll_with_interrupt (
server_monitor, expire_at_ms, cancelled, error)) {
GOTO (fail);
}
timeout_ms = _get_timeout_ms (expire_at_ms, error);
if (!timeout_ms) {
GOTO (fail);
}
MONITOR_LOG (server_monitor,
"reading first 4 bytes with timeout: %" PRId64,
timeout_ms);
if (!_mongoc_buffer_append_from_stream (
&buffer, server_monitor->stream, 4, (int32_t) timeout_ms, error)) {
GOTO (fail);
}
BSON_ASSERT (buffer.len == 4);
memcpy (&msg_len, buffer.data, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if ((msg_len < 16) ||
(msg_len > server_monitor->description->max_msg_size)) {
bson_set_error (
error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Message size %d is not within expected range 16-%d bytes",
msg_len,
server_monitor->description->max_msg_size);
GOTO (fail);
}
timeout_ms = _get_timeout_ms (expire_at_ms, error);
if (!timeout_ms) {
GOTO (fail);
}
MONITOR_LOG (server_monitor,
"reading remaining %d bytes. Timeout %" PRId64,
(int) (msg_len - 4),
timeout_ms);
if (!_mongoc_buffer_append_from_stream (
&buffer, server_monitor->stream, msg_len - 4, timeout_ms, error)) {
GOTO (fail);
}
if (!_mongoc_rpc_scatter (&rpc, buffer.data, buffer.len)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Malformed message from server");
GOTO (fail);
}
if (!_mongoc_rpc_decompress_if_necessary (&rpc, &buffer, error)) {
GOTO (fail);
}
_mongoc_rpc_swab_from_le (&rpc);
memcpy (&msg_len, rpc.msg.sections[0].payload.bson_document, 4);
msg_len = BSON_UINT32_FROM_LE (msg_len);
if (!bson_init_static (
&reply_local, rpc.msg.sections[0].payload.bson_document, msg_len)) {
bson_set_error (error,
MONGOC_ERROR_PROTOCOL,
MONGOC_ERROR_PROTOCOL_INVALID_REPLY,
"Malformed BSON payload from server");
GOTO (fail);
}
bson_copy_to (&reply_local, hello_response);
server_monitor->more_to_come =
(rpc.msg.flags & MONGOC_MSG_MORE_TO_COME) != 0;
ret = true;
fail:
if (!ret) {
bson_init (hello_response);
}
_mongoc_buffer_destroy (&buffer);
return ret;
}
/* Send and receive an awaitable hello.
*
* Called only from server monitor thread.
* May lock server monitor mutex in functions that are called.
* May block for up to heartbeatFrequencyMS waiting for reply.
*/
static bool
_server_monitor_awaitable_hello (mongoc_server_monitor_t *server_monitor,
const mongoc_server_description_t *description,
bson_t *hello_response,
bool *cancelled,
bson_error_t *error)
{
bson_t cmd;
const bson_t *hello;
bool ret = false;
hello = _mongoc_topology_scanner_get_monitoring_cmd (
server_monitor->topology->scanner, description->hello_ok);
bson_copy_to (hello, &cmd);
_server_monitor_append_cluster_time (server_monitor, &cmd);
bson_append_document (
&cmd, "topologyVersion", 15, &description->topology_version);
bson_append_int32 (
&cmd, "maxAwaitTimeMS", 14, server_monitor->heartbeat_frequency_ms);
bson_append_utf8 (&cmd, "$db", 3, "admin", 5);
if (!_server_monitor_awaitable_hello_send (server_monitor, &cmd, error)) {
GOTO (fail);
}
if (!_server_monitor_awaitable_hello_recv (
server_monitor, hello_response, cancelled, error)) {
bson_destroy (hello_response);
GOTO (fail);
}
ret = true;
fail:
if (!ret) {
bson_init (hello_response);
}
bson_destroy (&cmd);
return ret;
}
/* Update the topology description with a reply or an error.
*
* Called only from server monitor thread.
* Caller must hold no locks.
* Locks server monitor mutex.
*/
static void
_update_topology_description (mongoc_server_monitor_t *server_monitor,
mongoc_server_description_t *description)
{
mongoc_topology_t *topology;
bson_t *hello_response = NULL;
mc_tpld_modification tdmod;
topology = server_monitor->topology;
if (description->has_hello_response) {
hello_response = &description->last_hello_response;
}
if (hello_response) {
_mongoc_topology_update_cluster_time (topology, hello_response);
}
if (bson_atomic_int_fetch (&topology->scanner_state,
bson_memory_order_relaxed) ==
MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN) {
return;
}
tdmod = mc_tpld_modify_begin (topology);
bson_mutex_lock (&server_monitor->shared.mutex);
server_monitor->shared.scan_requested = false;
bson_mutex_unlock (&server_monitor->shared.mutex);
mongoc_topology_description_handle_hello (tdmod.new_td,
server_monitor->server_id,
hello_response,
description->round_trip_time_msec,
&description->error);
/* Reconcile server monitors. */
_mongoc_topology_background_monitoring_reconcile (topology, tdmod.new_td);
/* Wake threads performing server selection. */
mongoc_cond_broadcast (&server_monitor->topology->cond_client);
mc_tpld_modify_commit (tdmod);
}
/* Create a new server monitor.
*
* Called during reconcile.
* Caller must hold topology lock.
*/
mongoc_server_monitor_t *
mongoc_server_monitor_new (mongoc_topology_t *topology,
mongoc_topology_description_t *td,
mongoc_server_description_t *init_description)
{
mongoc_server_monitor_t *server_monitor =
bson_malloc0 (sizeof (*server_monitor));
server_monitor->description =
mongoc_server_description_new_copy (init_description);
server_monitor->server_id = init_description->id;
server_monitor->topology = topology;
server_monitor->heartbeat_frequency_ms = td->heartbeat_msec;
server_monitor->min_heartbeat_frequency_ms =
topology->min_heartbeat_frequency_msec;
server_monitor->connect_timeout_ms = topology->connect_timeout_msec;
server_monitor->uri = mongoc_uri_copy (topology->uri);
/* TODO CDRIVER-3682: Do not retrieve ssl opts from topology scanner. They
* should be stored somewhere else. */
#ifdef MONGOC_ENABLE_SSL
if (topology->scanner->ssl_opts) {
server_monitor->ssl_opts = bson_malloc0 (sizeof (mongoc_ssl_opt_t));
_mongoc_ssl_opts_copy_to (
topology->scanner->ssl_opts, server_monitor->ssl_opts, true);
}
#endif
memcpy (&server_monitor->apm_callbacks,
&td->apm_callbacks,
sizeof (mongoc_apm_callbacks_t));
server_monitor->apm_context = td->apm_context;
server_monitor->initiator = topology->scanner->initiator;
server_monitor->initiator_context = topology->scanner->initiator_context;
mongoc_cond_init (&server_monitor->shared.cond);
bson_mutex_init (&server_monitor->shared.mutex);
return server_monitor;
}
/* Creates a stream and performs the initial hello handshake.
*
* Called only by server monitor thread.
* Returns true if both connection and handshake succeeds.
* Returns false and sets error otherwise.
* hello_response is always initialized.
*/
static bool
_server_monitor_setup_connection (mongoc_server_monitor_t *server_monitor,
bson_t *hello_response,
int64_t *start_us,
bson_error_t *error)
{
bson_t cmd = BSON_INITIALIZER;
bool ret = false;
ENTRY;
BSON_ASSERT (!server_monitor->stream);
bson_init (hello_response);
server_monitor->more_to_come = false;
/* Using an initiator isn't really necessary. Users can't set them on
* pools. But it is used for tests. */
if (server_monitor->initiator) {
server_monitor->stream =
server_monitor->initiator (server_monitor->uri,
&server_monitor->description->host,
server_monitor->initiator_context,
error);
} else {
void *ssl_opts_void = NULL;
#ifdef MONGOC_ENABLE_SSL
ssl_opts_void = server_monitor->ssl_opts;
#endif
server_monitor->stream =
mongoc_client_connect (false,
ssl_opts_void != NULL,
ssl_opts_void,
server_monitor->uri,
&server_monitor->description->host,
error);
}
if (!server_monitor->stream) {
GOTO (fail);
}
/* Update the start time just before the handshake. */
*start_us = _now_us ();
/* Perform handshake. */
bson_destroy (&cmd);
_mongoc_topology_dup_handshake_cmd (server_monitor->topology, &cmd);
_server_monitor_append_cluster_time (server_monitor, &cmd);
bson_destroy (hello_response);
- if (!_server_monitor_send_and_recv_opquery (
- server_monitor, &cmd, hello_response, error)) {
- GOTO (fail);
+
+ /* If the user has select a versioned API, we'll assume OPCODE_MSG;
+ otherwise, we'll use the legacy OPCODE_QUERY: */
+ if (mongoc_topology_uses_server_api (server_monitor->topology)) {
+ /* OPCODE_MSG requires a "db" parameter: */
+ bson_append_utf8 (&cmd, "$db", 3, "admin", 5);
+
+ if (!_server_monitor_send_and_recv_hello_opmsg (
+ server_monitor, &cmd, hello_response, error)) {
+ GOTO (fail);
+ }
+ } else {
+ if (!_server_monitor_send_and_recv_opquery (
+ server_monitor, &cmd, hello_response, error)) {
+ GOTO (fail);
+ }
}
ret = true;
fail:
bson_destroy (&cmd);
RETURN (ret);
}
/**
* @brief Perform a hello check on a server
*
* @param server_monitor The server monitor for this server.
* @param previous_description The most recent view of the description of this
* server.
* @param cancelled Output parameter: Whether the monitor check is cancelled.
* @return mongoc_server_description_t* The newly created updated server
* description.
*
* @note May update the topology description associated with the server monitor.
*
* @note In case of error, returns a new server description with the error
* information, but with no hello reply.
*/
static mongoc_server_description_t *
_server_monitor_check_server (
mongoc_server_monitor_t *server_monitor,
const mongoc_server_description_t *previous_description,
bool *cancelled)
{
bool ret = false;
bson_error_t error;
bson_t hello_response;
int64_t duration_us;
int64_t start_us;
bool command_or_network_error = false;
bool awaited = false;
mongoc_server_description_t *description;
mc_tpld_modification tdmod;
ENTRY;
*cancelled = false;
memset (&error, 0, sizeof (bson_error_t));
description = bson_malloc0 (sizeof (mongoc_server_description_t));
mongoc_server_description_init (
description,
server_monitor->description->connection_address,
server_monitor->description->id);
start_us = _now_us ();
if (!server_monitor->stream) {
MONITOR_LOG (server_monitor, "setting up connection");
awaited = false;
_server_monitor_heartbeat_started (server_monitor, awaited);
ret = _server_monitor_setup_connection (
server_monitor, &hello_response, &start_us, &error);
GOTO (exit);
}
if (server_monitor->more_to_come) {
awaited = true;
/* Publish a heartbeat started for each additional response read. */
_server_monitor_heartbeat_started (server_monitor, awaited);
MONITOR_LOG (server_monitor, "more to come");
ret = _server_monitor_awaitable_hello_recv (
server_monitor, &hello_response, cancelled, &error);
GOTO (exit);
}
if (!bson_empty (&previous_description->topology_version)) {
awaited = true;
_server_monitor_heartbeat_started (server_monitor, awaited);
MONITOR_LOG (server_monitor, "awaitable hello");
ret = _server_monitor_awaitable_hello (server_monitor,
previous_description,
&hello_response,
cancelled,
&error);
GOTO (exit);
}
MONITOR_LOG (server_monitor, "polling hello");
awaited = false;
_server_monitor_heartbeat_started (server_monitor, awaited);
ret = _server_monitor_polling_hello (
server_monitor, previous_description->hello_ok, &hello_response, &error);
exit:
duration_us = _now_us () - start_us;
MONITOR_LOG (
server_monitor, "server check duration (us): %" PRId64, duration_us);
/* If ret is true, we have a reply. Check if "ok": 1. */
if (ret && _mongoc_cmd_check_ok (
&hello_response, MONGOC_ERROR_API_VERSION_2, &error)) {
int64_t rtt_ms = MONGOC_RTT_UNSET;
/* rtt remains MONGOC_RTT_UNSET if awaited. */
if (!awaited) {
rtt_ms = duration_us / 1000;
}
mongoc_server_description_handle_hello (
description, &hello_response, rtt_ms, NULL);
/* If the hello reply could not be parsed, consider this a command
* error. */
if (description->error.code) {
MONITOR_LOG_ERROR (server_monitor,
"error parsing server reply: %s",
description->error.message);
command_or_network_error = true;
_server_monitor_heartbeat_failed (
server_monitor, &description->error, duration_us, awaited);
} else {
_server_monitor_heartbeat_succeeded (
server_monitor, &hello_response, duration_us, awaited);
}
} else if (*cancelled) {
MONITOR_LOG (server_monitor, "server monitor cancelled");
if (server_monitor->stream) {
mongoc_stream_destroy (server_monitor->stream);
}
server_monitor->stream = NULL;
server_monitor->more_to_come = false;
_server_monitor_heartbeat_failed (
server_monitor, &description->error, duration_us, awaited);
} else {
/* The hello reply had "ok":0 or a network error occurred. */
MONITOR_LOG_ERROR (server_monitor,
"command or network error occurred: %s",
error.message);
command_or_network_error = true;
mongoc_server_description_handle_hello (
description, NULL, MONGOC_RTT_UNSET, &error);
_server_monitor_heartbeat_failed (
server_monitor, &description->error, duration_us, awaited);
}
if (command_or_network_error) {
if (server_monitor->stream) {
mongoc_stream_failed (server_monitor->stream);
}
server_monitor->stream = NULL;
server_monitor->more_to_come = false;
tdmod = mc_tpld_modify_begin (server_monitor->topology);
/* clear_connection_pool() is a no-op if 'description->id' was already
* removed. */
_mongoc_topology_description_clear_connection_pool (
tdmod.new_td,
server_monitor->description->id,
&server_monitor->description->service_id);
mc_tpld_modify_commit (tdmod);
}
bson_destroy (&hello_response);
return description;
}
/* Request scan of a single server.
*
* Locks server monitor mutex to deliver scan_requested.
*/
void
mongoc_server_monitor_request_scan (mongoc_server_monitor_t *server_monitor)
{
MONITOR_LOG (server_monitor, "requesting scan");
bson_mutex_lock (&server_monitor->shared.mutex);
server_monitor->shared.scan_requested = true;
mongoc_cond_signal (&server_monitor->shared.cond);
bson_mutex_unlock (&server_monitor->shared.mutex);
}
/* Request cancellation of an in progress awaitable hello.
*
* Called from app threads on network errors and during shutdown.
* Locks server monitor mutex.
*/
void
mongoc_server_monitor_request_cancel (mongoc_server_monitor_t *server_monitor)
{
MONITOR_LOG (server_monitor, "requesting cancel");
bson_mutex_lock (&server_monitor->shared.mutex);
server_monitor->shared.cancel_requested = true;
mongoc_cond_signal (&server_monitor->shared.cond);
bson_mutex_unlock (&server_monitor->shared.mutex);
}
/* Wait for heartbeatFrequencyMS or minHeartbeatFrequencyMS if a scan is
* requested.
*
* Locks server monitor mutex.
*/
void
mongoc_server_monitor_wait (mongoc_server_monitor_t *server_monitor)
{
int64_t start_ms;
int64_t scan_due_ms;
start_ms = _now_ms ();
scan_due_ms = start_ms + server_monitor->heartbeat_frequency_ms;
bson_mutex_lock (&server_monitor->shared.mutex);
while (true) {
int64_t sleep_duration_ms;
int cond_ret;
if (server_monitor->shared.state != MONGOC_THREAD_RUNNING) {
break;
}
if (server_monitor->shared.scan_requested) {
server_monitor->shared.scan_requested = false;
scan_due_ms = start_ms + server_monitor->min_heartbeat_frequency_ms;
}
sleep_duration_ms = scan_due_ms - _now_ms ();
if (sleep_duration_ms <= 0) {
break;
}
MONITOR_LOG (server_monitor, "sleeping for %" PRId64, sleep_duration_ms);
cond_ret = mongoc_cond_timedwait (&server_monitor->shared.cond,
&server_monitor->shared.mutex,
sleep_duration_ms);
if (mongo_cond_ret_is_timedout (cond_ret)) {
break;
}
}
bson_mutex_unlock (&server_monitor->shared.mutex);
}
/* The server monitor thread function.
*
* Server monitor must be in state MONGOC_THREAD_OFF.
*/
static BSON_THREAD_FUN (_server_monitor_thread, server_monitor_void)
{
mongoc_server_monitor_t *server_monitor;
mongoc_server_description_t *description;
mongoc_server_description_t *previous_description;
server_monitor = (mongoc_server_monitor_t *) server_monitor_void;
description =
mongoc_server_description_new_copy (server_monitor->description);
previous_description = NULL;
while (true) {
bool cancelled = false;
bson_mutex_lock (&server_monitor->shared.mutex);
if (server_monitor->shared.state != MONGOC_THREAD_RUNNING) {
bson_mutex_unlock (&server_monitor->shared.mutex);
break;
}
bson_mutex_unlock (&server_monitor->shared.mutex);
mongoc_server_description_destroy (previous_description);
previous_description = mongoc_server_description_new_copy (description);
mongoc_server_description_destroy (description);
description = _server_monitor_check_server (
server_monitor, previous_description, &cancelled);
if (cancelled) {
mongoc_server_monitor_wait (server_monitor);
continue;
}
_update_topology_description (server_monitor, description);
/* Immediately proceed to the next check if the previous response was
* successful and included the topologyVersion field. */
if (description->type != MONGOC_SERVER_UNKNOWN &&
!bson_empty (&description->topology_version)) {
MONITOR_LOG (server_monitor,
"immediately proceeding due to topologyVersion");
continue;
}
/* ... or the previous response included the moreToCome flag */
if (server_monitor->more_to_come) {
MONITOR_LOG (server_monitor,
"immediately proceeding due to moreToCome");
continue;
}
/* ... or the server has just transitioned to Unknown due to a network
* error. */
if (_mongoc_error_is_network (&description->error) &&
previous_description->type != MONGOC_SERVER_UNKNOWN) {
MONITOR_LOG (server_monitor,
"immediately proceeding due to network error");
continue;
}
mongoc_server_monitor_wait (server_monitor);
}
bson_mutex_lock (&server_monitor->shared.mutex);
server_monitor->shared.state = MONGOC_THREAD_JOINABLE;
bson_mutex_unlock (&server_monitor->shared.mutex);
mongoc_server_description_destroy (previous_description);
mongoc_server_description_destroy (description);
BSON_THREAD_RETURN;
}
static bool
_server_monitor_ping_server (mongoc_server_monitor_t *server_monitor,
bool hello_ok,
int64_t *rtt_ms)
{
bool ret = false;
int64_t start_us = _now_us ();
bson_t hello_response;
bson_error_t error;
*rtt_ms = MONGOC_RTT_UNSET;
if (!server_monitor->stream) {
MONITOR_LOG (server_monitor, "rtt setting up connection");
ret = _server_monitor_setup_connection (
server_monitor, &hello_response, &start_us, &error);
bson_destroy (&hello_response);
}
if (server_monitor->stream) {
MONITOR_LOG (server_monitor, "rtt polling hello");
ret = _server_monitor_polling_hello (
server_monitor, hello_ok, &hello_response, &error);
if (ret) {
*rtt_ms = (_now_us () - start_us) / 1000;
}
bson_destroy (&hello_response);
}
return ret;
}
/* The RTT monitor thread function.
*
* Server monitor must be in state MONGOC_THREAD_OFF.
*/
static BSON_THREAD_FUN (_server_monitor_rtt_thread, server_monitor_void)
{
mongoc_server_monitor_t *server_monitor = server_monitor_void;
while (true) {
int64_t rtt_ms;
bson_error_t error;
bool hello_ok;
bson_mutex_lock (&server_monitor->shared.mutex);
if (server_monitor->shared.state != MONGOC_THREAD_RUNNING) {
bson_mutex_unlock (&server_monitor->shared.mutex);
break;
}
bson_mutex_unlock (&server_monitor->shared.mutex);
{
mc_shared_tpld td = mc_tpld_take_ref (server_monitor->topology);
const mongoc_server_description_t *sd =
mongoc_topology_description_server_by_id_const (
td.ptr, server_monitor->description->id, &error);
hello_ok = sd ? sd->hello_ok : false;
mc_tpld_drop_ref (&td);
}
_server_monitor_ping_server (server_monitor, hello_ok, &rtt_ms);
if (rtt_ms != MONGOC_RTT_UNSET) {
mc_tpld_modification tdmod =
mc_tpld_modify_begin (server_monitor->topology);
mongoc_server_description_t *const mut_sd =
mongoc_topology_description_server_by_id (
tdmod.new_td, server_monitor->description->id, &error);
if (mut_sd) {
mongoc_server_description_update_rtt (mut_sd, rtt_ms);
mc_tpld_modify_commit (tdmod);
} else {
/* If the server description has been removed, the RTT thread will
* be terminated by background monitoring soon, so we have nothing
* to do but wait until we are about to be stopped. */
mc_tpld_modify_drop (tdmod);
}
}
mongoc_server_monitor_wait (server_monitor);
}
bson_mutex_lock (&server_monitor->shared.mutex);
server_monitor->shared.state = MONGOC_THREAD_JOINABLE;
bson_mutex_unlock (&server_monitor->shared.mutex);
BSON_THREAD_RETURN;
}
void
mongoc_server_monitor_run (mongoc_server_monitor_t *server_monitor)
{
bson_mutex_lock (&server_monitor->shared.mutex);
if (server_monitor->shared.state == MONGOC_THREAD_OFF) {
server_monitor->is_rtt = false;
server_monitor->shared.state = MONGOC_THREAD_RUNNING;
- COMMON_PREFIX (thread_create)
- (&server_monitor->thread, _server_monitor_thread, server_monitor);
+ mcommon_thread_create (
+ &server_monitor->thread, _server_monitor_thread, server_monitor);
}
bson_mutex_unlock (&server_monitor->shared.mutex);
}
void
mongoc_server_monitor_run_as_rtt (mongoc_server_monitor_t *server_monitor)
{
bson_mutex_lock (&server_monitor->shared.mutex);
if (server_monitor->shared.state == MONGOC_THREAD_OFF) {
server_monitor->is_rtt = true;
server_monitor->shared.state = MONGOC_THREAD_RUNNING;
- COMMON_PREFIX (thread_create)
- (&server_monitor->thread, _server_monitor_rtt_thread, server_monitor);
+ mcommon_thread_create (
+ &server_monitor->thread, _server_monitor_rtt_thread, server_monitor);
}
bson_mutex_unlock (&server_monitor->shared.mutex);
}
/* Request thread shutdown.
*
* Returns true if in state MONGOC_THREAD_OFF and the server monitor can be
* safely destroyed.
* Called during topology description reconcile.
* Locks server monitor mutex.
*/
bool
mongoc_server_monitor_request_shutdown (mongoc_server_monitor_t *server_monitor)
{
bool off = false;
bson_mutex_lock (&server_monitor->shared.mutex);
if (server_monitor->shared.state == MONGOC_THREAD_RUNNING) {
server_monitor->shared.state = MONGOC_THREAD_SHUTTING_DOWN;
}
if (server_monitor->shared.state == MONGOC_THREAD_JOINABLE) {
- COMMON_PREFIX (thread_join) (server_monitor->thread);
+ mcommon_thread_join (server_monitor->thread);
server_monitor->shared.state = MONGOC_THREAD_OFF;
}
if (server_monitor->shared.state == MONGOC_THREAD_OFF) {
off = true;
}
mongoc_cond_signal (&server_monitor->shared.cond);
bson_mutex_unlock (&server_monitor->shared.mutex);
/* Cancel an in-progress hello check. */
if (!off) {
mongoc_server_monitor_request_cancel (server_monitor);
}
return off;
}
/* Request thread shutdown and block until the server monitor thread terminates.
*
* Called by one thread.
* Locks the server monitor mutex.
*/
void
mongoc_server_monitor_wait_for_shutdown (
mongoc_server_monitor_t *server_monitor)
{
if (mongoc_server_monitor_request_shutdown (server_monitor)) {
return;
}
/* Shutdown requested, but thread is not yet off. Wait. */
- COMMON_PREFIX (thread_join) (server_monitor->thread);
+ mcommon_thread_join (server_monitor->thread);
bson_mutex_lock (&server_monitor->shared.mutex);
server_monitor->shared.state = MONGOC_THREAD_OFF;
bson_mutex_unlock (&server_monitor->shared.mutex);
}
/* Destroy a server monitor.
*
* Called only by one thread.
* Caller must not hold server monitor lock.
* Server monitor thread is in state MONGOC_THREAD_OFF.
*/
void
mongoc_server_monitor_destroy (mongoc_server_monitor_t *server_monitor)
{
if (!server_monitor) {
return;
}
/* Locking not necessary since this is only called by one thread, and server
* monitor thread is no longer running. */
BSON_ASSERT (server_monitor->shared.state == MONGOC_THREAD_OFF);
mongoc_server_description_destroy (server_monitor->description);
mongoc_stream_destroy (server_monitor->stream);
mongoc_uri_destroy (server_monitor->uri);
mongoc_cond_destroy (&server_monitor->shared.cond);
bson_mutex_destroy (&server_monitor->shared.mutex);
#ifdef MONGOC_ENABLE_SSL
if (server_monitor->ssl_opts) {
_mongoc_ssl_opts_cleanup (server_monitor->ssl_opts, true);
bson_free (server_monitor->ssl_opts);
}
#endif
bson_free (server_monitor);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
similarity index 93%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
index 8ed48168..d9ba2b0e 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c
@@ -1,872 +1,912 @@
/*
* Copyright 2016 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-config.h"
#ifdef MONGOC_ENABLE_SSL_OPENSSL
#include <bson/bson.h>
#include <errno.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "mongoc-counters-private.h"
#include "mongoc-errno-private.h"
#include "mongoc-ssl.h"
#include "mongoc-ssl-private.h"
#include "mongoc-stream-tls.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-tls-private.h"
#include "mongoc-stream-tls-openssl-bio-private.h"
#include "mongoc-stream-tls-openssl-private.h"
#include "mongoc-openssl-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-log.h"
#include "mongoc-error.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "stream-tls-openssl"
#define MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE 4096
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
static void
BIO_meth_free (BIO_METHOD *meth)
{
/* Nothing to free pre OpenSSL 1.1.0 */
}
#endif
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_destroy --
*
* Cleanup after usage of a mongoc_stream_tls_openssl_t. Free all
*allocated
* resources and ensure connections are closed.
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_stream_tls_openssl_destroy (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
BSON_ASSERT (tls);
BIO_free_all (openssl->bio);
openssl->bio = NULL;
BIO_meth_free (openssl->meth);
openssl->meth = NULL;
mongoc_stream_destroy (tls->base_stream);
tls->base_stream = NULL;
SSL_CTX_free (openssl->ctx);
openssl->ctx = NULL;
mongoc_openssl_ocsp_opt_destroy (openssl->ocsp_opts);
openssl->ocsp_opts = NULL;
bson_free (openssl);
bson_free (stream);
mongoc_counter_streams_active_dec ();
mongoc_counter_streams_disposed_inc ();
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_failed --
*
* Called on stream failure. Same as _mongoc_stream_tls_openssl_destroy()
*
* Returns:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static void
_mongoc_stream_tls_openssl_failed (mongoc_stream_t *stream)
{
_mongoc_stream_tls_openssl_destroy (stream);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_close --
*
* Close the underlying socket.
*
* Linus dictates that you should not check the result of close()
* since there is a race condition with EAGAIN and a new file
* descriptor being opened.
*
* Returns:
* 0 on success; otherwise -1.
*
* Side effects:
* The BIO fd is closed.
*
*--------------------------------------------------------------------------
*/
static int
_mongoc_stream_tls_openssl_close (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
int ret = 0;
ENTRY;
BSON_ASSERT (tls);
ret = mongoc_stream_close (tls->base_stream);
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_flush --
*
* Flush the underlying stream.
*
* Returns:
* 0 if successful; otherwise -1.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static int
_mongoc_stream_tls_openssl_flush (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
BSON_ASSERT (openssl);
return BIO_flush (openssl->bio);
}
static ssize_t
_mongoc_stream_tls_openssl_write (mongoc_stream_tls_t *tls,
char *buf,
size_t buf_len)
{
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
ssize_t ret;
int64_t now;
int64_t expire = 0;
ENTRY;
BSON_ASSERT (tls);
BSON_ASSERT (buf);
BSON_ASSERT (buf_len);
if (tls->timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL);
}
ret = BIO_write (openssl->bio, buf, buf_len);
if (ret <= 0) {
return ret;
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (ret < buf_len) {
mongoc_counter_streams_timeout_inc ();
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_writev --
*
* Write the iovec to the stream. This function will try to write
* all of the bytes or fail. If the number of bytes is not equal
* to the number requested, a failure or EOF has occurred.
*
* Returns:
* -1 on failure, otherwise the number of bytes written.
*
* Side effects:
* None.
*
* This function is copied as _mongoc_stream_tls_secure_transport_writev
*--------------------------------------------------------------------------
*/
static ssize_t
_mongoc_stream_tls_openssl_writev (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
char buf[MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE];
ssize_t ret = 0;
ssize_t child_ret;
size_t i;
size_t iov_pos = 0;
/* There's a bit of a dance to coalesce vectorized writes into
* MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE'd writes to avoid lots of small tls
* packets.
*
* The basic idea is that we want to combine writes in the buffer if they're
* smaller than the buffer, flushing as it gets full. For larger writes, or
* the last write in the iovec array, we want to ignore the buffer and just
* write immediately. We take care of doing buffer writes by re-invoking
* ourself with a single iovec_t, pointing at our stack buffer.
*/
char *buf_head = buf;
char *buf_tail = buf;
char *buf_end = buf + MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE;
size_t bytes;
char *to_write = NULL;
size_t to_write_len;
BSON_ASSERT (tls);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
ENTRY;
tls->timeout_msec = timeout_msec;
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
if (buf_head != buf_tail ||
((i + 1 < iovcnt) &&
((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) {
/* If we have either of:
* - buffered bytes already
* - another iovec to send after this one and we don't have more
* bytes to send than the size of the buffer.
*
* copy into the buffer */
bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail);
memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes);
buf_tail += bytes;
iov_pos += bytes;
if (buf_tail == buf_end) {
/* If we're full, request send */
to_write = buf_head;
to_write_len = buf_tail - buf_head;
buf_tail = buf_head = buf;
}
} else {
/* Didn't buffer, so just write it through */
to_write = (char *) iov[i].iov_base + iov_pos;
to_write_len = iov[i].iov_len - iov_pos;
iov_pos += to_write_len;
}
if (to_write) {
/* We get here if we buffered some bytes and filled the buffer, or
* if we didn't buffer and have to send out of the iovec */
child_ret =
_mongoc_stream_tls_openssl_write (tls, to_write, to_write_len);
if (child_ret != to_write_len) {
TRACE ("Got child_ret: %ld while to_write_len is: %ld",
child_ret,
to_write_len);
}
if (child_ret < 0) {
TRACE ("Returning what I had (%ld) as apposed to the error "
"(%ld, errno:%d)",
ret,
child_ret,
errno);
RETURN (ret);
}
ret += child_ret;
if (child_ret < to_write_len) {
/* we timed out, so send back what we could send */
RETURN (ret);
}
to_write = NULL;
}
}
}
if (buf_head != buf_tail) {
/* If we have any bytes buffered, send */
child_ret =
_mongoc_stream_tls_openssl_write (tls, buf_head, buf_tail - buf_head);
if (child_ret < 0) {
RETURN (child_ret);
}
ret += child_ret;
}
if (ret >= 0) {
mongoc_counter_streams_egress_add (ret);
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_readv --
*
* Read from the stream into iov. This function will try to read
* all of the bytes or fail. If the number of bytes is not equal
* to the number requested, a failure or EOF has occurred.
*
* Returns:
* -1 on failure, 0 on EOF, otherwise the number of bytes read.
*
* Side effects:
* iov buffers will be written to.
*
* This function is copied as _mongoc_stream_tls_secure_transport_readv
*
*--------------------------------------------------------------------------
*/
static ssize_t
_mongoc_stream_tls_openssl_readv (mongoc_stream_t *stream,
mongoc_iovec_t *iov,
size_t iovcnt,
size_t min_bytes,
int32_t timeout_msec)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
ssize_t ret = 0;
size_t i;
int read_ret;
size_t iov_pos = 0;
int64_t now;
int64_t expire = 0;
ENTRY;
BSON_ASSERT (tls);
BSON_ASSERT (iov);
BSON_ASSERT (iovcnt);
tls->timeout_msec = timeout_msec;
if (timeout_msec >= 0) {
expire = bson_get_monotonic_time () + (timeout_msec * 1000UL);
}
for (i = 0; i < iovcnt; i++) {
iov_pos = 0;
while (iov_pos < iov[i].iov_len) {
read_ret = BIO_read (openssl->bio,
(char *) iov[i].iov_base + iov_pos,
(int) (iov[i].iov_len - iov_pos));
/* https://www.openssl.org/docs/crypto/BIO_should_retry.html:
*
* If BIO_should_retry() returns false then the precise "error
* condition" depends on the BIO type that caused it and the return
* code of the BIO operation. For example if a call to BIO_read() on a
* socket BIO returns 0 and BIO_should_retry() is false then the cause
* will be that the connection closed.
*/
if (read_ret < 0 ||
(read_ret == 0 && !BIO_should_retry (openssl->bio))) {
return -1;
}
if (expire) {
now = bson_get_monotonic_time ();
if ((expire - now) < 0) {
if (read_ret == 0) {
mongoc_counter_streams_timeout_inc ();
#ifdef _WIN32
errno = WSAETIMEDOUT;
#else
errno = ETIMEDOUT;
#endif
RETURN (-1);
}
tls->timeout_msec = 0;
} else {
tls->timeout_msec = (expire - now) / 1000L;
}
}
ret += read_ret;
if ((size_t) ret >= min_bytes) {
mongoc_counter_streams_ingress_add (ret);
RETURN (ret);
}
iov_pos += read_ret;
}
}
if (ret >= 0) {
mongoc_counter_streams_ingress_add (ret);
}
RETURN (ret);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_stream_tls_openssl_setsockopt --
*
* Perform a setsockopt on the underlying stream.
*
* Returns:
* -1 on failure, otherwise opt specific value.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
static int
_mongoc_stream_tls_openssl_setsockopt (mongoc_stream_t *stream,
int level,
int optname,
void *optval,
mongoc_socklen_t optlen)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
BSON_ASSERT (tls);
return mongoc_stream_setsockopt (
tls->base_stream, level, optname, optval, optlen);
}
static mongoc_stream_t *
_mongoc_stream_tls_openssl_get_base_stream (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
return tls->base_stream;
}
static bool
_mongoc_stream_tls_openssl_check_closed (mongoc_stream_t *stream) /* IN */
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
BSON_ASSERT (stream);
return mongoc_stream_check_closed (tls->base_stream);
}
static bool
-_mongoc_stream_tls_openssl_cert_verify_failed (SSL *ssl, bson_error_t *error)
+_mongoc_stream_tls_openssl_set_verify_cert_error (SSL *ssl, bson_error_t *error)
{
+ long verify_result;
+
BSON_ASSERT_PARAM (ssl);
BSON_ASSERT_PARAM (error);
- const long verify_result = SSL_get_verify_result (ssl);
+ verify_result = SSL_get_verify_result (ssl);
if (verify_result == X509_V_OK) {
return false;
}
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"TLS handshake failed: certificate verify failed (%ld): %s",
verify_result,
X509_verify_cert_error_string (verify_result));
return true;
}
/**
* mongoc_stream_tls_openssl_handshake:
*/
static bool
_mongoc_stream_tls_openssl_handshake (mongoc_stream_t *stream,
const char *host,
int *events,
bson_error_t *error)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
SSL *ssl;
BSON_ASSERT (tls);
BSON_ASSERT (host);
ENTRY;
BIO_get_ssl (openssl->bio, &ssl);
if (BIO_do_handshake (openssl->bio) == 1) {
*events = 0;
#ifdef MONGOC_ENABLE_OCSP_OPENSSL
/* Validate OCSP */
if (openssl->ocsp_opts &&
1 != _mongoc_ocsp_tlsext_status (ssl, openssl->ocsp_opts)) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"TLS handshake failed: Failed OCSP verification");
RETURN (false);
}
#endif
if (_mongoc_openssl_check_peer_hostname (
ssl, host, tls->ssl_opts.allow_invalid_hostname)) {
RETURN (true);
}
- if (!_mongoc_stream_tls_openssl_cert_verify_failed (ssl, error)) {
- bson_set_error (
- error,
- MONGOC_ERROR_STREAM,
- MONGOC_ERROR_STREAM_SOCKET,
- "TLS handshake failed: Failed certificate verification");
+ /* Try to relay certificate failure reason from OpenSSL library if any. */
+ if (_mongoc_stream_tls_openssl_set_verify_cert_error (ssl, error)) {
+ RETURN (false);
}
+ /* Otherwise, use simple error message. */
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "TLS handshake failed: Failed certificate verification");
+
RETURN (false);
}
if (BIO_should_retry (openssl->bio)) {
*events = BIO_should_read (openssl->bio) ? POLLIN : POLLOUT;
RETURN (false);
}
if (!errno) {
#ifdef _WIN32
errno = WSAETIMEDOUT;
#else
errno = ETIMEDOUT;
#endif
}
*events = 0;
- if (!_mongoc_stream_tls_openssl_cert_verify_failed (ssl, error)) {
+ /* Try to relay certificate failure reason from OpenSSL library if any. */
+ if (_mongoc_stream_tls_openssl_set_verify_cert_error (ssl, error)) {
+ RETURN (false);
+ }
+
+ /* Otherwise, try to relay error info from OpenSSL. */
+ if (ERR_peek_error () != 0) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"TLS handshake failed: %s",
ERR_error_string (ERR_get_error (), NULL));
+ RETURN (false);
+ }
+
+ /* Otherwise, use simple error info. */
+ {
+#ifdef _WIN32
+ LPTSTR msg = NULL;
+ FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ NULL,
+ errno, /* WSAETIMEDOUT */
+ LANG_NEUTRAL,
+ (LPTSTR) &msg,
+ 0,
+ NULL);
+#else
+ const char *msg = strerror (errno); /* ETIMEDOUT */
+#endif
+
+ bson_set_error (error,
+ MONGOC_ERROR_STREAM,
+ MONGOC_ERROR_STREAM_SOCKET,
+ "TLS handshake failed: %s",
+ msg);
+
+#ifdef _WIN32
+ LocalFree (msg);
+#endif
}
RETURN (false);
}
/* Callback to get the client provided SNI, if any
* It is only called in SSL "server mode" (e.g. when using the Mock Server),
* and we don't actually use the hostname for anything, just debug print it
*/
static int
_mongoc_stream_tls_openssl_sni (SSL *ssl, int *ad, void *arg)
{
const char *hostname;
if (ssl == NULL) {
TRACE ("%s", "No SNI hostname provided");
return SSL_TLSEXT_ERR_NOACK;
}
hostname = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name);
/* This is intentionally debug since its only used by the mock test server */
MONGOC_DEBUG ("Got SNI: '%s'", hostname);
return SSL_TLSEXT_ERR_OK;
}
static bool
_mongoc_stream_tls_openssl_timed_out (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
ENTRY;
RETURN (mongoc_stream_timed_out (tls->base_stream));
}
static bool
_mongoc_stream_tls_openssl_should_retry (mongoc_stream_t *stream)
{
mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
mongoc_stream_tls_openssl_t *openssl =
(mongoc_stream_tls_openssl_t *) tls->ctx;
ENTRY;
if (BIO_should_retry (openssl->bio)) {
RETURN (true);
}
RETURN (mongoc_stream_should_retry (tls->base_stream));
}
/*
*--------------------------------------------------------------------------
*
* mongoc_stream_tls_openssl_new --
*
* Creates a new mongoc_stream_tls_openssl_t to communicate with a remote
* server using a TLS stream.
*
* @base_stream should be a stream that will become owned by the
* resulting tls stream. It will be used for raw I/O.
*
* @trust_store_dir should be a path to the SSL cert db to use for
* verifying trust of the remote server.
*
* Returns:
* NULL on failure, otherwise a mongoc_stream_t.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
mongoc_stream_t *
mongoc_stream_tls_openssl_new (mongoc_stream_t *base_stream,
const char *host,
mongoc_ssl_opt_t *opt,
int client)
{
mongoc_stream_tls_t *tls;
mongoc_stream_tls_openssl_t *openssl;
mongoc_openssl_ocsp_opt_t *ocsp_opts = NULL;
SSL_CTX *ssl_ctx = NULL;
BIO *bio_ssl = NULL;
BIO *bio_mongoc_shim = NULL;
BIO_METHOD *meth;
BSON_ASSERT (base_stream);
BSON_ASSERT (opt);
ENTRY;
ssl_ctx = _mongoc_openssl_ctx_new (opt);
if (!ssl_ctx) {
RETURN (NULL);
}
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
if (!opt->allow_invalid_hostname) {
struct in_addr addr;
struct in6_addr addr6;
X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new ();
X509_VERIFY_PARAM_set_hostflags (param,
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
if (inet_pton (AF_INET, host, &addr) ||
inet_pton (AF_INET6, host, &addr6)) {
X509_VERIFY_PARAM_set1_ip_asc (param, host);
} else {
X509_VERIFY_PARAM_set1_host (param, host, 0);
}
SSL_CTX_set1_param (ssl_ctx, param);
X509_VERIFY_PARAM_free (param);
}
#endif
if (!client) {
/* Only used by the Mock Server.
* Set a callback to get the SNI, if provided */
SSL_CTX_set_tlsext_servername_callback (ssl_ctx,
_mongoc_stream_tls_openssl_sni);
}
if (opt->weak_cert_validation) {
SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);
} else {
SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, NULL);
}
bio_ssl = BIO_new_ssl (ssl_ctx, client);
if (!bio_ssl) {
SSL_CTX_free (ssl_ctx);
RETURN (NULL);
}
meth = mongoc_stream_tls_openssl_bio_meth_new ();
bio_mongoc_shim = BIO_new (meth);
if (!bio_mongoc_shim) {
BIO_free_all (bio_ssl);
BIO_meth_free (meth);
SSL_CTX_free (ssl_ctx);
RETURN (NULL);
}
/* Added in OpenSSL 0.9.8f, as a build time option */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
if (client) {
SSL *ssl;
/* Set the SNI hostname we are expecting certificate for */
BIO_get_ssl (bio_ssl, &ssl);
SSL_set_tlsext_host_name (ssl, host);
#endif
}
BIO_push (bio_ssl, bio_mongoc_shim);
#ifdef MONGOC_ENABLE_OCSP_OPENSSL
if (client && !opt->weak_cert_validation &&
!_mongoc_ssl_opts_disable_certificate_revocation_check (opt)) {
SSL *ssl;
BIO_get_ssl (bio_ssl, &ssl);
/* Set the status_request extension on the SSL object.
* Do not use SSL_CTX_set_tlsext_status_type, since that requires OpenSSL
* 1.1.0.
*/
if (!SSL_set_tlsext_status_type (ssl, TLSEXT_STATUSTYPE_ocsp)) {
MONGOC_ERROR ("cannot enable OCSP status request extension");
mongoc_openssl_ocsp_opt_destroy (ocsp_opts);
BIO_free_all (bio_ssl);
BIO_meth_free (meth);
SSL_CTX_free (ssl_ctx);
RETURN (NULL);
}
ocsp_opts = bson_malloc0 (sizeof (mongoc_openssl_ocsp_opt_t));
ocsp_opts->allow_invalid_hostname = opt->allow_invalid_hostname;
ocsp_opts->weak_cert_validation = opt->weak_cert_validation;
ocsp_opts->disable_endpoint_check =
_mongoc_ssl_opts_disable_ocsp_endpoint_check (opt);
ocsp_opts->host = bson_strdup (host);
_mongoc_ssl_opts_copy_to (opt, &ocsp_opts->ssl_opts, true);
}
#endif /* MONGOC_ENABLE_OCSP_OPENSSL */
openssl = (mongoc_stream_tls_openssl_t *) bson_malloc0 (sizeof *openssl);
openssl->bio = bio_ssl;
openssl->meth = meth;
openssl->ctx = ssl_ctx;
openssl->ocsp_opts = ocsp_opts;
tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls);
tls->parent.type = MONGOC_STREAM_TLS;
tls->parent.destroy = _mongoc_stream_tls_openssl_destroy;
tls->parent.failed = _mongoc_stream_tls_openssl_failed;
tls->parent.close = _mongoc_stream_tls_openssl_close;
tls->parent.flush = _mongoc_stream_tls_openssl_flush;
tls->parent.writev = _mongoc_stream_tls_openssl_writev;
tls->parent.readv = _mongoc_stream_tls_openssl_readv;
tls->parent.setsockopt = _mongoc_stream_tls_openssl_setsockopt;
tls->parent.get_base_stream = _mongoc_stream_tls_openssl_get_base_stream;
tls->parent.check_closed = _mongoc_stream_tls_openssl_check_closed;
tls->parent.timed_out = _mongoc_stream_tls_openssl_timed_out;
tls->parent.should_retry = _mongoc_stream_tls_openssl_should_retry;
memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts);
tls->handshake = _mongoc_stream_tls_openssl_handshake;
tls->ctx = (void *) openssl;
tls->timeout_msec = -1;
tls->base_stream = base_stream;
mongoc_stream_tls_openssl_bio_set_data (bio_mongoc_shim, tls);
mongoc_counter_streams_active_inc ();
RETURN ((mongoc_stream_t *) tls);
}
void
mongoc_openssl_ocsp_opt_destroy (void *ocsp_opt)
{
mongoc_openssl_ocsp_opt_t *casted;
if (!ocsp_opt) {
return;
}
casted = (mongoc_openssl_ocsp_opt_t *) ocsp_opt;
bson_free (casted->host);
_mongoc_ssl_opts_cleanup (&casted->ssl_opts, true);
bson_free (ocsp_opt);
}
#endif /* MONGOC_ENABLE_SSL_OPENSSL */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c
index 5e2f0948..e9378ecf 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c
@@ -1,387 +1,387 @@
/*
* Copyright 2020-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-topology-background-monitoring-private.h"
#include "mongoc-client-private.h"
#include "mongoc-log-private.h"
#include "mongoc-server-monitor-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-ssl-private.h"
#endif
#include "mongoc-stream-private.h"
#include "mongoc-topology-description-apm-private.h"
#include "mongoc-topology-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "monitor"
static BSON_THREAD_FUN (srv_polling_run, topology_void)
{
mongoc_topology_t *topology;
topology = topology_void;
while (bson_atomic_int_fetch (&topology->scanner_state,
bson_memory_order_relaxed) ==
MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
int64_t now_ms;
int64_t scan_due_ms;
int64_t sleep_duration_ms;
/* This will check if a scan is due. */
if (!mongoc_topology_should_rescan_srv (topology)) {
TRACE ("%s\n", "topology ineligible for SRV polling, stopping");
break;
}
mongoc_topology_rescan_srv (topology);
/* Unlock and sleep until next scan is due, or until shutdown signalled.
*/
now_ms = bson_get_monotonic_time () / 1000;
scan_due_ms = topology->srv_polling_last_scan_ms +
topology->srv_polling_rescan_interval_ms;
sleep_duration_ms = scan_due_ms - now_ms;
if (sleep_duration_ms > 0) {
TRACE ("srv polling thread sleeping for %" PRId64 "ms",
sleep_duration_ms);
}
/* Check for shutdown again here. mongoc_topology_rescan_srv unlocks the
* topology srv_polling_mtx for the scan. The topology may have shut
* down in that time. */
bson_mutex_lock (&topology->srv_polling_mtx);
if (bson_atomic_int_fetch (&topology->scanner_state,
bson_memory_order_relaxed) !=
MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
bson_mutex_unlock (&topology->srv_polling_mtx);
break;
}
/* If shutting down, stop. */
mongoc_cond_timedwait (&topology->srv_polling_cond,
&topology->srv_polling_mtx,
sleep_duration_ms);
bson_mutex_unlock (&topology->srv_polling_mtx);
}
BSON_THREAD_RETURN;
}
/* Create a server monitor if necessary.
*
* Called by monitor threads and application threads when reconciling the
* topology description.
*/
static void
_background_monitor_reconcile_server_monitor (mongoc_topology_t *topology,
mongoc_topology_description_t *td,
mongoc_server_description_t *sd)
{
mongoc_set_t *server_monitors = topology->server_monitors;
mongoc_server_monitor_t *server_monitor =
mongoc_set_get (server_monitors, sd->id);
if (!server_monitor) {
/* Add a new server monitor. */
server_monitor = mongoc_server_monitor_new (topology, td, sd);
mongoc_server_monitor_run (server_monitor);
mongoc_set_add (server_monitors, sd->id, server_monitor);
}
/* Check if an RTT monitor is needed. */
if (!bson_empty (&sd->topology_version)) {
mongoc_set_t *rtt_monitors;
mongoc_server_monitor_t *rtt_monitor;
rtt_monitors = topology->rtt_monitors;
rtt_monitor = mongoc_set_get (rtt_monitors, sd->id);
if (!rtt_monitor) {
rtt_monitor = mongoc_server_monitor_new (topology, td, sd);
mongoc_server_monitor_run_as_rtt (rtt_monitor);
mongoc_set_add (rtt_monitors, sd->id, rtt_monitor);
}
}
return;
}
/* Start background monitoring.
*
* Called by an application thread popping a client from a pool. Safe to
* call repeatedly.
*/
void
_mongoc_topology_background_monitoring_start (mongoc_topology_t *topology)
{
mc_tpld_modification tdmod;
int prev_state;
BSON_ASSERT (!topology->single_threaded);
if (!topology->valid) {
return;
}
prev_state = bson_atomic_int_compare_exchange_strong (
&topology->scanner_state,
MONGOC_TOPOLOGY_SCANNER_OFF,
MONGOC_TOPOLOGY_SCANNER_BG_RUNNING,
bson_memory_order_relaxed);
if (prev_state != MONGOC_TOPOLOGY_SCANNER_OFF) {
/* The topology scanner is already running, or another thread is starting
* it up now. */
return;
}
TRACE ("%s", "background monitoring starting");
tdmod = mc_tpld_modify_begin (topology);
_mongoc_handshake_freeze ();
_mongoc_topology_description_monitor_opening (tdmod.new_td);
if (tdmod.new_td->type == MONGOC_TOPOLOGY_LOAD_BALANCED) {
/* Do not proceed to start monitoring threads. */
TRACE ("%s", "disabling monitoring for load balanced topology");
} else {
/* Reconcile to create the first server monitors. */
_mongoc_topology_background_monitoring_reconcile (topology, tdmod.new_td);
/* Start SRV polling thread. */
if (mongoc_topology_should_rescan_srv (topology)) {
topology->is_srv_polling = true;
- COMMON_PREFIX (thread_create)
- (&topology->srv_polling_thread, srv_polling_run, topology);
+ mcommon_thread_create (
+ &topology->srv_polling_thread, srv_polling_run, topology);
}
}
mc_tpld_modify_commit (tdmod);
}
/* Remove server monitors that are no longer in the set of server descriptions.
*
* Called by monitor threads and application threads when reconciling the
* topology description.
*/
static void
_remove_orphaned_server_monitors (mongoc_set_t *server_monitors,
mongoc_set_t *server_descriptions)
{
uint32_t *server_monitor_ids_to_remove;
uint32_t n_server_monitor_ids_to_remove = 0;
int i;
/* Signal shutdown to server monitors no longer in the topology description.
*/
server_monitor_ids_to_remove =
bson_malloc0 (sizeof (uint32_t) * server_monitors->items_len);
for (i = 0; i < server_monitors->items_len; i++) {
mongoc_server_monitor_t *server_monitor;
uint32_t id;
server_monitor = mongoc_set_get_item_and_id (server_monitors, i, &id);
if (!mongoc_set_get (server_descriptions, id)) {
if (mongoc_server_monitor_request_shutdown (server_monitor)) {
mongoc_server_monitor_wait_for_shutdown (server_monitor);
mongoc_server_monitor_destroy (server_monitor);
server_monitor_ids_to_remove[n_server_monitor_ids_to_remove] = id;
n_server_monitor_ids_to_remove++;
}
}
}
/* Remove freed server monitors that have completed shutdown. */
for (i = 0; i < n_server_monitor_ids_to_remove; i++) {
mongoc_set_rm (server_monitors, server_monitor_ids_to_remove[i]);
}
bson_free (server_monitor_ids_to_remove);
}
/* Reconcile the topology description with the set of server monitors.
*
* Called when the topology description is updated (via handshake, monitoring,
* or invalidation). May be called by server monitor thread or an application
* thread.
* Locks server monitor mutexes. May join / remove server monitors that have
* completed shutdown.
*/
void
_mongoc_topology_background_monitoring_reconcile (
mongoc_topology_t *topology, mongoc_topology_description_t *td)
{
mongoc_set_t *server_descriptions = mc_tpld_servers (td);
int i;
BSON_ASSERT (!topology->single_threaded);
if (bson_atomic_int_fetch (&topology->scanner_state,
bson_memory_order_relaxed) !=
MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
return;
}
/* Add newly discovered server monitors, and update existing ones. */
for (i = 0; i < server_descriptions->items_len; i++) {
mongoc_server_description_t *sd;
sd = mongoc_set_get_item (server_descriptions, i);
_background_monitor_reconcile_server_monitor (topology, td, sd);
}
_remove_orphaned_server_monitors (topology->server_monitors,
server_descriptions);
_remove_orphaned_server_monitors (topology->rtt_monitors,
server_descriptions);
}
/* Request all server monitors to scan.
*
* Called from application threads (during server selection or "not primary"
* errors). Locks server monitor mutexes to deliver scan_requested.
*/
void
_mongoc_topology_background_monitoring_request_scan (
mongoc_topology_t *topology)
{
mongoc_set_t *server_monitors;
int i;
BSON_ASSERT (!topology->single_threaded);
if (bson_atomic_int_fetch (&topology->scanner_state,
bson_memory_order_relaxed) ==
MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN) {
return;
}
server_monitors = topology->server_monitors;
for (i = 0; i < server_monitors->items_len; i++) {
mongoc_server_monitor_t *server_monitor;
uint32_t id;
server_monitor = mongoc_set_get_item_and_id (server_monitors, i, &id);
mongoc_server_monitor_request_scan (server_monitor);
}
}
/* Stop, join, and destroy all server monitors.
*
* Called by application threads when destroying a client pool.
* Locks server monitor mutexes to deliver shutdown. This function is
* thread-safe. But in practice, it is only ever called by one application
* thread (because mongoc_client_pool_destroy is not thread-safe).
*/
void
_mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology)
{
mongoc_server_monitor_t *server_monitor;
int i;
int n_srv_monitors;
int n_rtt_monitors;
BSON_ASSERT (!topology->single_threaded);
if (bson_atomic_int_fetch (&topology->scanner_state,
bson_memory_order_relaxed) !=
MONGOC_TOPOLOGY_SCANNER_BG_RUNNING) {
return;
}
TRACE ("%s", "background monitoring stopping");
/* Tell the srv polling thread to stop */
bson_mutex_lock (&topology->srv_polling_mtx);
bson_atomic_int_exchange (&topology->scanner_state,
MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN,
bson_memory_order_relaxed);
if (topology->is_srv_polling) {
/* Signal the srv poller to break out of waiting */
mongoc_cond_signal (&topology->srv_polling_cond);
}
bson_mutex_unlock (&topology->srv_polling_mtx);
bson_mutex_lock (&topology->tpld_modification_mtx);
n_srv_monitors = topology->server_monitors->items_len;
n_rtt_monitors = topology->rtt_monitors->items_len;
bson_mutex_unlock (&topology->tpld_modification_mtx);
/* Signal all server monitors to shut down. */
for (i = 0; i < n_srv_monitors; i++) {
server_monitor = mongoc_set_get_item (topology->server_monitors, i);
mongoc_server_monitor_request_shutdown (server_monitor);
}
/* Signal all RTT monitors to shut down. */
for (i = 0; i < n_rtt_monitors; i++) {
server_monitor = mongoc_set_get_item (topology->rtt_monitors, i);
mongoc_server_monitor_request_shutdown (server_monitor);
}
for (i = 0; i < n_srv_monitors; i++) {
/* Wait for the thread to shutdown. */
server_monitor = mongoc_set_get_item (topology->server_monitors, i);
mongoc_server_monitor_wait_for_shutdown (server_monitor);
mongoc_server_monitor_destroy (server_monitor);
}
for (i = 0; i < n_rtt_monitors; i++) {
/* Wait for the thread to shutdown. */
server_monitor = mongoc_set_get_item (topology->rtt_monitors, i);
mongoc_server_monitor_wait_for_shutdown (server_monitor);
mongoc_server_monitor_destroy (server_monitor);
}
/* Wait for SRV polling thread. */
if (topology->is_srv_polling) {
- COMMON_PREFIX (thread_join) (topology->srv_polling_thread);
+ mcommon_thread_join (topology->srv_polling_thread);
}
/* Signal clients that are waiting on server selection to stop immediately,
* as there will be no servers available.
* This uses the tpld_modification_mtx as that is the mutex used with the
* condition variable that will wait the waiting client threads. */
bson_mutex_lock (&topology->tpld_modification_mtx);
mongoc_set_destroy (topology->server_monitors);
mongoc_set_destroy (topology->rtt_monitors);
topology->server_monitors = mongoc_set_new (1, NULL, NULL);
topology->rtt_monitors = mongoc_set_new (1, NULL, NULL);
bson_atomic_int_exchange (&topology->scanner_state,
MONGOC_TOPOLOGY_SCANNER_OFF,
bson_memory_order_relaxed);
mongoc_cond_broadcast (&topology->cond_client);
bson_mutex_unlock (&topology->tpld_modification_mtx);
}
/* Cancel an in-progress streaming hello for a specific server (if
* applicable).
*
* Called from application threads on network errors.
*/
void
_mongoc_topology_background_monitoring_cancel_check (
mongoc_topology_t *topology, uint32_t server_id)
{
mongoc_server_monitor_t *server_monitor;
server_monitor = mongoc_set_get (topology->server_monitors, server_id);
if (!server_monitor) {
/* Already removed. */
return;
}
mongoc_server_monitor_request_cancel (server_monitor);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
index d269f1ad..4d37ddf3 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h
@@ -1,611 +1,630 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_TOPOLOGY_PRIVATE_H
#define MONGOC_TOPOLOGY_PRIVATE_H
#include "mongoc-config.h"
#include "mongoc-topology-scanner-private.h"
#include "mongoc-server-description-private.h"
#include "mongoc-topology-description-private.h"
#include "mongoc-thread-private.h"
#include "mongoc-uri.h"
#include "mongoc-client-session-private.h"
#include "mongoc-crypt-private.h"
#include "mongoc-ts-pool-private.h"
#include "mongoc-shared-private.h"
#define MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS 500
#define MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS 5000
#define MONGOC_TOPOLOGY_COOLDOWN_MS 5000
#define MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS 15
#define MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS 30000
#define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED 10000
#define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED 60000
#define MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS 60000
typedef enum {
MONGOC_TOPOLOGY_SCANNER_OFF,
MONGOC_TOPOLOGY_SCANNER_BG_RUNNING,
MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN
} mongoc_topology_scanner_state_t;
typedef enum mongoc_topology_cse_state_t {
MONGOC_CSE_DISABLED,
MONGOC_CSE_STARTING,
MONGOC_CSE_ENABLED,
} mongoc_topology_cse_state_t;
struct _mongoc_background_monitor_t;
struct _mongoc_client_pool_t;
typedef enum { MONGOC_RR_SRV, MONGOC_RR_TXT } mongoc_rr_type_t;
typedef struct _mongoc_rr_data_t {
/* Number of records returned by DNS. */
uint32_t count;
/* Set to lowest TTL found when polling SRV records. */
uint32_t min_ttl;
/* Set to the resulting host list when polling SRV records */
mongoc_host_list_t *hosts;
/* Set to the TXT record when polling for TXT */
char *txt_record_opts;
} mongoc_rr_data_t;
struct _mongoc_topology_t;
MONGOC_DECL_SPECIAL_TS_POOL (
mongoc_server_session_t,
mongoc_server_session_pool,
struct _mongoc_topology_t,
/* ctor/dtor/prune are defined in the new_with_params call */
NULL,
NULL,
NULL)
typedef bool (*_mongoc_rr_resolver_fn) (const char *hostname,
mongoc_rr_type_t rr_type,
mongoc_rr_data_t *rr_data,
size_t initial_buffer_size,
bson_error_t *error);
/**
* @brief A reference-counted reference to a topology description.
*
* The referred-to topology description should be access via the `.ptr` member
* of this object.
*/
typedef union mc_shared_tpld {
/* Private: The reference-counted shared pointer that manages the topology
* description. */
mongoc_shared_ptr _sptr_;
/** The pointed-to topology description */
mongoc_topology_description_t const *ptr;
} mc_shared_tpld;
/** A null-pointer initializer for an `mc_shared_tpld` */
#define MC_SHARED_TPLD_NULL ((mc_shared_tpld){._sptr_ = MONGOC_SHARED_PTR_NULL})
typedef struct _mongoc_topology_t {
/**
* @brief The topology description. Do not access directly. Instead, use
* mc_tpld_take_ref()
*/
mc_shared_tpld _shared_descr_;
/* topology->uri is initialized as a copy of the client/pool's URI.
* For a "mongodb+srv://" URI, topology->uri is then updated in
* mongoc_topology_new() after initial seedlist discovery.
*/
mongoc_uri_t *uri;
mongoc_topology_scanner_t *scanner;
bool server_selection_try_once;
int64_t last_scan;
int64_t local_threshold_msec;
int64_t connect_timeout_msec;
int64_t server_selection_timeout_msec;
/* defaults to 500ms, configurable by tests */
int64_t min_heartbeat_frequency_msec;
/* Minimum of SRV record TTLs, but no lower than 60 seconds.
* May be zero for non-SRV/non-MongoS topology. */
int64_t srv_polling_rescan_interval_ms;
int64_t srv_polling_last_scan_ms;
/* For multi-threaded, srv polling occurs in a separate thread. */
bson_thread_t srv_polling_thread;
bson_mutex_t srv_polling_mtx;
mongoc_cond_t srv_polling_cond;
/**
* @brief Signal for background monitoring threads to signal stop/shutdown.
*
* The values stored are mongoc_topology_scanner_state_t values
*/
int scanner_state;
/**
* @brief This lock is held in order to serialize operations that modify the
* topology description. It *should not* be held while performing read-only
* operations on the topology.
*
* This mutex is also used by server selection to synchronize with threads
* that may update the topology following a failed server selection. It is
* used in conjunction with `cond_client`. This protects _shared_descr_, as
* well as the server_monitors and rtt_monitors.
*/
bson_mutex_t tpld_modification_mtx;
/**
* @brief Condition variable used to signal client threads that the topology
* has been updated by another thread. This CV should be used with
* tpld_modification_mtx, as it signals modifications to the topology.
*
* Note that mc_tpld_modify_begin/commit/drop will acquire/release
* tpld_modification_mtx as well.
*/
mongoc_cond_t cond_client;
bool single_threaded;
bool stale;
mongoc_server_session_pool session_pool;
/* Is client side encryption enabled? */
mongoc_topology_cse_state_t cse_state;
bool is_srv_polling;
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
_mongoc_crypt_t *crypt;
struct _mongoc_client_t *mongocryptd_client; /* single threaded */
struct _mongoc_client_t *keyvault_client; /* single threaded */
struct _mongoc_client_pool_t *mongocryptd_client_pool; /* multi threaded */
struct _mongoc_client_pool_t *keyvault_client_pool; /* multi threaded */
char *keyvault_db;
char *keyvault_coll;
bool bypass_auto_encryption;
bool mongocryptd_bypass_spawn;
char *mongocryptd_spawn_path;
bson_t *mongocryptd_spawn_args;
+ bool bypass_query_analysis;
#endif
+ struct {
+ struct {
+ struct {
+ char *cryptSharedLibPath;
+ bool cryptSharedLibRequired;
+ } extraOptions;
+ } autoOptions;
+ } clientSideEncryption;
+
+ // Corresponds to AutoEncryptionOpts.encryptedFieldsMap.
+ bson_t *encrypted_fields_map;
+
/* For background monitoring. */
mongoc_set_t *server_monitors;
mongoc_set_t *rtt_monitors;
bson_mutex_t apm_mutex;
/* This is overridable for SRV polling tests to mock DNS records. */
_mongoc_rr_resolver_fn rr_resolver;
/* valid is false when mongoc_topology_new failed to construct a valid
* topology. This could occur if the URI is invalid.
* An invalid topology does not monitor servers. */
bool valid;
} mongoc_topology_t;
mongoc_topology_t *
mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded);
void
mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology,
mongoc_topology_description_t *td,
mongoc_apm_callbacks_t *callbacks,
void *context);
void
mongoc_topology_destroy (mongoc_topology_t *topology);
void
mongoc_topology_reconcile (const mongoc_topology_t *topology,
mongoc_topology_description_t *td);
bool
mongoc_topology_compatible (const mongoc_topology_description_t *td,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error);
/**
* @brief Select a server description for an operation. May scan and update the
* topology.
*
* A server description might be returned that matches the given `optype` and
* `read_prefs`. If the topology is out-of-date or due for a scan, then this
* function will perform a scan and update the topology accordingly. If no
* matching server is found, returns a NULL pointer.
*
* @param topology The topology to inspect and/or update.
* @param optype The operation that is intended to be performed.
* @param read_prefs The read preferences for the command.
* @param must_use_primary An optional output parameter. Server selection might
* need to override the caller's read preferences' read mode to 'primary'.
* Whether or not that takes place will be set through this pointer.
* @param error An output parameter for any error information.
* @return mongoc_server_description_t* A copy of the topology's server
* description that matches the request, or NULL if there is no such server.
*
* @note The returned object is a COPY, and should be released with
* `mongoc_server_description_destroy()`
*
* @note This function may update the topology description.
*/
mongoc_server_description_t *
mongoc_topology_select (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bool *must_use_primary,
bson_error_t *error);
/**
* @brief Obtain the integral ID of a server description matching the requested
* ops.
*
* Refer to @see mongoc_topology_select() for more information
*
* @param topology The topology to inspect and/or update.
* @param optype The operation that is intended to be performed.
* @param read_prefs The read preferences for the command.
* @param must_use_primary An optional output parameter. Server selection might
* need to override the caller's read preferences' read mode to 'primary'.
* Whether or not that takes place will be set through this pointer.
* @param error An output parameter for any error information.
* @return uint32_t A non-zero integer ID of the server description. In case of
* error, sets `error` and returns zero.
*
* @note This function may update the topology description.
*/
uint32_t
mongoc_topology_select_server_id (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bool *must_use_primary,
bson_error_t *error);
/**
* @brief Return a new mongoc_host_list_t for the given server matching the
* given ID.
*
* @param topology The topology description to inspect
* @param id The ID of a server in the topology
* @param error Output error information
* @return mongoc_host_list_t* A new host list, or NULL on error
*
* @note The returned list should be freed with
* `_mongoc_host_list_destroy_all()`
*/
mongoc_host_list_t *
_mongoc_topology_host_by_id (const mongoc_topology_description_t *topology,
uint32_t id,
bson_error_t *error);
/**
* @brief Update the topology from the response to a handshake on a new
* application connection.
*
* @note Only applicable to a client pool (single-threaded clients reuse
* monitoring connections).
*
* @param topology The topology that will be updated.
* @param sd The server description that contains the hello response.
* @return true If the server is valid in the topology.
* @return false If the server was already removed from the topology.
*/
bool
_mongoc_topology_update_from_handshake (mongoc_topology_t *topology,
const mongoc_server_description_t *sd);
void
_mongoc_topology_update_last_used (mongoc_topology_t *topology,
uint32_t server_id);
int64_t
mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id);
/**
* @brief Get the current type of the topology
*/
mongoc_topology_description_type_t
_mongoc_topology_get_type (const mongoc_topology_t *topology);
bool
_mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname);
void
_mongoc_topology_update_cluster_time (mongoc_topology_t *topology,
const bson_t *reply);
mongoc_server_session_t *
_mongoc_topology_pop_server_session (mongoc_topology_t *topology,
bson_error_t *error);
void
_mongoc_topology_push_server_session (mongoc_topology_t *topology,
mongoc_server_session_t *server_session);
bool
_mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd);
void
_mongoc_topology_do_blocking_scan (mongoc_topology_t *topology,
bson_error_t *error);
/**
* @brief Duplicate the handshake command of the topology scanner.
*
* @param topology The topology to inspect.
* @param copy_into The destination of the copy. Should be uninitialized storage
* for a bson_t.
*
* @note This API will lazily construct the handshake command for the scanner.
*
* @note This is called at the start of the scan in
* _mongoc_topology_run_background, when a node is added in
* _mongoc_topology_reconcile_add_nodes, or when running a hello directly on a
* node in _mongoc_stream_run_hello.
*/
void
_mongoc_topology_dup_handshake_cmd (const mongoc_topology_t *topology,
bson_t *copy_into);
void
_mongoc_topology_request_scan (mongoc_topology_t *topology);
void
_mongoc_topology_bypass_cooldown (mongoc_topology_t *topology);
typedef enum {
MONGOC_SDAM_APP_ERROR_COMMAND,
MONGOC_SDAM_APP_ERROR_NETWORK,
MONGOC_SDAM_APP_ERROR_TIMEOUT
} _mongoc_sdam_app_error_type_t;
/**
* @brief Handle an error from an app connection
*
* Processes network errors, timeouts, and command replies.
*
* @param topology The topology that will be updated
* @param server_id The ID of the server on which the error occurred.
* @param handshake_complete Whether the handshake was complete for this server
* @param type The type of error to process
* @param reply If checking for a command error, the server reply. Otherwise
* NULL
* @param why An error that will be attached to the server description
* @param max_wire_version
* @param generation The generation of the server description the caller was
* using.
* @param service_id A service ID for a load-balanced deployment. If not
* applicable, pass kZeroServiceID.
* @return true If the topology was updated and the pool was cleared.
* @return false If no modifications were made and the error was ignored.
*
* @note May update the topology description.
*/
bool
_mongoc_topology_handle_app_error (mongoc_topology_t *topology,
uint32_t server_id,
bool handshake_complete,
_mongoc_sdam_app_error_type_t type,
const bson_t *reply,
const bson_error_t *why,
uint32_t max_wire_version,
uint32_t generation,
const bson_oid_t *service_id);
void
mongoc_topology_rescan_srv (mongoc_topology_t *topology);
bool
mongoc_topology_should_rescan_srv (mongoc_topology_t *topology);
/* _mongoc_topology_set_rr_resolver is called by tests to mock DNS responses for
* SRV polling.
* This is necessarily called after initial seedlist discovery completes in
* mongoc_topology_new.
* Callers should call this before monitoring starts.
*/
void
_mongoc_topology_set_rr_resolver (mongoc_topology_t *topology,
_mongoc_rr_resolver_fn rr_resolver);
/* _mongoc_topology_set_srv_polling_rescan_interval_ms is called by tests to
* shorten the rescan interval.
* Callers should call this before monitoring starts.
*/
void
_mongoc_topology_set_srv_polling_rescan_interval_ms (
mongoc_topology_t *topology, int64_t val);
/**
* @brief Return the latest connection generation for the server_id and/or
* service_id.
*
* Use this generation for newly established connections.
*
* @param td The topology that contains the server
* @param server_id The ID of the server to inspect
* @param service_id The service ID of the connection if applicable, or
* kZeroServiceID.
* @returns uint32_t A generation counter for the given server, or zero if the
* server does not exist in the topology.
*/
uint32_t
_mongoc_topology_get_connection_pool_generation (
const mongoc_topology_description_t *td,
uint32_t server_id,
const bson_oid_t *service_id);
/**
* @brief Obtain a reference to the current topology description for the given
* topology.
*
* Returns a ref-counted reference to the topology description. The returned
* reference must later be released with mc_tpld_drop_ref(). The contents of the
* topology description are immutable.
*/
static BSON_INLINE mc_shared_tpld
mc_tpld_take_ref (const mongoc_topology_t *tpl)
{
return (mc_shared_tpld){
._sptr_ = mongoc_atomic_shared_ptr_load (&tpl->_shared_descr_._sptr_)};
}
/**
* @brief Release a reference to a topology description obtained via
* mc_tpld_take_ref().
*
* The pointed-to shared reference will be reset to NULL.
*/
static BSON_INLINE void
mc_tpld_drop_ref (mc_shared_tpld *p)
{
mongoc_shared_ptr_reset_null (&p->_sptr_);
}
/**
* @brief Refresh a reference to a topology description for the given topology.
*
* @param td Pointer-to-shared-pointer of the topology description
* @param tpl The topology to query.
*
* The pointed-to shared pointer will be modified to refer to the topology
* description of the topology.
*
* Equivalent to a call to `mc_tpld_drop_ref()` followed by a call to
* `mc_tpld_take_ref()`.
*/
static BSON_INLINE void
mc_tpld_renew_ref (mc_shared_tpld *td, mongoc_topology_t *tpl)
{
mc_tpld_drop_ref (td);
*td = mc_tpld_take_ref (tpl);
}
/**
* @brief A pending topology description modification.
*
* Create an instance using `mc_tpld_modify_begin()`.
*/
typedef struct mc_tpld_modification {
/** The new topology. Modifications should be applied to this topology
* description. Those modifications will be published by
* `mc_tpld_modify_commit()`. */
mongoc_topology_description_t *new_td;
/** The topology that owns the topology description */
mongoc_topology_t *topology;
} mc_tpld_modification;
/**
* @brief Begin a new modification transaction of the topology description owned
* by `tpl`
*
* @return mc_tpld_modification A pending modification.
*
* @note MUST be followed by a call to `mc_tpld_modify_commit` OR
* `mc_tpld_modify_drop`
*
* @note THIS FUNCTION MAY BLOCK: This call takes a lock, which will only be
* released by mc_tpld_modify_commit() or mc_tpld_modify_drop(). Do not call
* this API while the current thread is already performing a modification!
*/
mc_tpld_modification
mc_tpld_modify_begin (mongoc_topology_t *tpl);
/**
* @brief Commit a topology description modification to the owning topology.
*
* All later calls to mc_tpld_take_ref() will see the new topology.
*/
void mc_tpld_modify_commit (mc_tpld_modification);
/**
* @brief Drop a pending modification to a topology description. No changes will
* be made to the topology.
*/
void mc_tpld_modify_drop (mc_tpld_modification);
/**
* @brief Obtain a pointer-to-mutable mongoc_topology_description_t for the
* given topology.
*
* This call is "unsafe" as the returned pointer may be invalidated by
* concurrent modifications done using mc_tpld_modify_begin() and
* mc_tpld_modify_commit().
*
* To obtain a safe pointer to the topology description, use mc_tpld_take_ref().
*/
static BSON_INLINE mongoc_topology_description_t *
mc_tpld_unsafe_get_mutable (mongoc_topology_t *tpl)
{
return tpl->_shared_descr_._sptr_.ptr;
}
/**
* @brief Obtain a pointer-to-const mongoc_topology_description_t for the
* given topology.
*
* This call is "unsafe" as the returned pointer may be invalidated by
* concurrent modifications done using mc_tpld_modify_begin() and
* mc_tpld_modify_commit().
*
* To obtain a safe pointer to the topology description, use mc_tpld_take_ref().
*
* @return const mongoc_topology_description_t* Pointer to the topology
* description for the given topology.
*/
static BSON_INLINE const mongoc_topology_description_t *
mc_tpld_unsafe_get_const (const mongoc_topology_t *tpl)
{
return tpl->_shared_descr_._sptr_.ptr;
}
/**
* @brief Directly invalidate a server in the topology by its ID.
*
* This is intended for testing purposes, as it provides thread-safe
* direct topology modification.
*
* @param td The topology to modify.
* @param server_id The ID of a server in the topology.
*/
static BSON_INLINE void
_mongoc_topology_invalidate_server (mongoc_topology_t *td, uint32_t server_id)
{
bson_error_t error;
mc_tpld_modification tdmod = mc_tpld_modify_begin (td);
bson_set_error (
&error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "invalidated");
mongoc_topology_description_invalidate_server (
tdmod.new_td, server_id, &error);
mc_tpld_modify_commit (tdmod);
}
/* Return an array view to `max_hosts` or fewer elements of `hl`, or NULL if
* `hl` is empty. The size of the returned array is written to `hl_array_size`
* even if `hl` is empty.
*
* The returned array must be freed with `bson_free()`. The elements of the
* array must not be freed, as they are still owned by `hl`.
*/
const mongoc_host_list_t **
_mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl,
int32_t max_hosts,
size_t *hl_array_size);
+
+/* Returns true if a versioned server API has been selected, otherwise returns
+ * false. */
+bool
+mongoc_topology_uses_server_api (const mongoc_topology_t *topology);
+
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
index 5344da08..ed1e273f 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h
@@ -1,285 +1,292 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_TOPOLOGY_SCANNER_PRIVATE_H
#define MONGOC_TOPOLOGY_SCANNER_PRIVATE_H
/* TODO: rename to TOPOLOGY scanner */
#include <bson/bson.h>
#include "mongoc-async-private.h"
#include "mongoc-async-cmd-private.h"
#include "mongoc-handshake-private.h"
#include "mongoc-host-list.h"
#include "mongoc-apm-private.h"
#include "mongoc-scram-private.h"
#include "mongoc-ssl.h"
#include "mongoc-crypto-private.h"
#include "mongoc-server-description-private.h"
#include "common-thread-private.h"
BSON_BEGIN_DECLS
typedef void (*mongoc_topology_scanner_setup_err_cb_t) (
uint32_t id, void *data, const bson_error_t *error /* IN */);
typedef void (*mongoc_topology_scanner_cb_t) (
uint32_t id,
const bson_t *bson,
int64_t rtt,
void *data,
const bson_error_t *error /* IN */);
struct mongoc_topology_scanner;
struct mongoc_topology_scanner_node;
typedef struct mongoc_topology_scanner_node {
uint32_t id;
/* after scanning, this is set to the successful stream if one exists. */
mongoc_stream_t *stream;
int64_t last_used;
/* last_failed is set upon a network error trying to check a server.
* last_failed is used to enforce cooldownMS.
- * last_failed is not set upon a network error during an application operation on @stream. */
+ * last_failed is not set upon a network error during an application
+ * operation on @stream. */
int64_t last_failed;
bool has_auth;
bool hello_ok;
mongoc_host_list_t host;
struct mongoc_topology_scanner *ts;
struct mongoc_topology_scanner_node *next;
struct mongoc_topology_scanner_node *prev;
bool retired;
bson_error_t last_error;
/* the hostname for a node may resolve to multiple DNS results.
* dns_results has the full list of DNS results, ordered by host preference.
* successful_dns_result is the most recent successful DNS result.
*/
struct addrinfo *dns_results;
struct addrinfo *successful_dns_result;
int64_t last_dns_cache;
/* used by single-threaded clients to store negotiated sasl mechanisms on a
* node. */
mongoc_handshake_sasl_supported_mechs_t sasl_supported_mechs;
bool negotiated_sasl_supported_mechs;
bson_t speculative_auth_response;
mongoc_scram_t scram;
/* handshake_sd is a server description constructed from the response of the
* initial handshake. It is bound to the lifetime of stream. */
mongoc_server_description_t *handshake_sd;
} mongoc_topology_scanner_node_t;
typedef enum handshake_state_t {
/**
* The handshake command has no value. The handshake_cmd pointer will be
* NULL.
*/
HANDSHAKE_CMD_UNINITIALIZED,
/**
* The handshake command could not be constructed because it would be too
* large. The handshake_cmd pointer will be NULL.
*/
HANDSHAKE_CMD_TOO_BIG,
/**
* The handshake command is valid and ready to be copied-from.
*/
HANDSHAKE_CMD_OKAY,
} handshake_state_t;
typedef struct mongoc_topology_scanner {
mongoc_async_t *async;
int64_t connect_timeout_msec;
mongoc_topology_scanner_node_t *nodes;
bson_t hello_cmd;
bson_t legacy_hello_cmd;
bson_mutex_t handshake_cmd_mtx;
bson_t *handshake_cmd;
handshake_state_t handshake_state;
bson_t cluster_time;
const char *appname;
mongoc_topology_scanner_setup_err_cb_t setup_err_cb;
mongoc_topology_scanner_cb_t cb;
void *cb_data;
const mongoc_uri_t *uri;
mongoc_async_cmd_setup_t setup;
mongoc_stream_initiator_t initiator;
void *initiator_context;
bson_error_t error;
#ifdef MONGOC_ENABLE_SSL
mongoc_ssl_opt_t *ssl_opts;
#endif
mongoc_apm_callbacks_t apm_callbacks;
void *apm_context;
int64_t dns_cache_timeout_ms;
/* only used by single-threaded clients to negotiate auth mechanisms. */
bool negotiate_sasl_supported_mechs;
bool bypass_cooldown;
bool speculative_authentication;
mongoc_server_api_t *api;
bool loadbalanced;
} mongoc_topology_scanner_t;
mongoc_topology_scanner_t *
mongoc_topology_scanner_new (
const mongoc_uri_t *uri,
mongoc_topology_scanner_setup_err_cb_t setup_err_cb,
mongoc_topology_scanner_cb_t cb,
void *data,
int64_t connect_timeout_msec);
void
mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts);
bool
mongoc_topology_scanner_valid (mongoc_topology_scanner_t *ts);
void
mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
uint32_t id,
bool hello_ok);
void
mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, uint32_t id);
void
mongoc_topology_scanner_disconnect (mongoc_topology_scanner_t *scanner);
void
mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node);
void
mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node,
bool failed);
void
mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node,
bool failed);
bool
mongoc_topology_scanner_in_cooldown (mongoc_topology_scanner_t *ts,
int64_t when);
void
mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts,
bool obey_cooldown);
void
mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts);
void
_mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts);
void
mongoc_topology_scanner_get_error (mongoc_topology_scanner_t *ts,
bson_error_t *error);
void
mongoc_topology_scanner_reset (mongoc_topology_scanner_t *ts);
void
mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node,
bson_error_t *error);
mongoc_topology_scanner_node_t *
mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id);
void
_mongoc_topology_scanner_add_speculative_authentication (
bson_t *cmd,
const mongoc_uri_t *uri,
const mongoc_ssl_opt_t *ssl_opts,
mongoc_scram_cache_t *scram_cache,
mongoc_scram_t *scram /* OUT */);
void
_mongoc_topology_scanner_parse_speculative_authentication (
const bson_t *hello, bson_t *speculative_authenticate);
const char *
_mongoc_topology_scanner_get_speculative_auth_mechanism (
const mongoc_uri_t *uri);
const bson_t *
_mongoc_topology_scanner_get_monitoring_cmd (mongoc_topology_scanner_t *ts,
bool hello_ok);
/**
* @brief Get the scanner's associated handshake command BSON document.
*
* @param ts The scanner to inspect
* @param copy_into A pointer to an initialized bson_t. The handshake command
* will be copied into the pointee.
*/
void
_mongoc_topology_scanner_dup_handshake_cmd (mongoc_topology_scanner_t *ts,
bson_t *copy_into);
bool
mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts,
mongoc_host_list_t *host);
void
mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts,
mongoc_stream_initiator_t si,
void *ctx);
bool
_mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts,
const char *name);
void
_mongoc_topology_scanner_set_cluster_time (mongoc_topology_scanner_t *ts,
const bson_t *cluster_time);
void
_mongoc_topology_scanner_set_dns_cache_timeout (mongoc_topology_scanner_t *ts,
int64_t timeout_ms);
#ifdef MONGOC_ENABLE_SSL
void
mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts,
mongoc_ssl_opt_t *opts);
#endif
bool
mongoc_topology_scanner_node_in_cooldown (mongoc_topology_scanner_node_t *node,
int64_t when);
void
_mongoc_topology_scanner_set_server_api (mongoc_topology_scanner_t *ts,
const mongoc_server_api_t *api);
void
_mongoc_topology_scanner_set_loadbalanced (mongoc_topology_scanner_t *ts,
bool val);
/* for testing. */
mongoc_stream_t *
_mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd);
+/* Returns true if versioned server API has been selected, otherwise
+ * false. */
+bool
+mongoc_topology_scanner_uses_server_api (
+ const mongoc_topology_scanner_t *topology_scanner);
+
BSON_END_DECLS
#endif /* MONGOC_TOPOLOGY_SCANNER_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
similarity index 96%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
index 553468e2..6d95b20b 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c
@@ -1,1488 +1,1508 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongoc-config.h"
#include "mongoc-error.h"
#include "mongoc-trace-private.h"
#include "mongoc-topology-scanner-private.h"
#include "mongoc-stream-private.h"
#include "mongoc-stream-socket.h"
#include "mongoc-handshake.h"
#include "mongoc-handshake-private.h"
#ifdef MONGOC_ENABLE_SSL
#include "mongoc-stream-tls.h"
#endif
#include "mongoc-counters-private.h"
#include "utlist.h"
#include "mongoc-topology-private.h"
#include "mongoc-host-list-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-cluster-private.h"
#include "mongoc-client-private.h"
#include "mongoc-util-private.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "topology_scanner"
#define DNS_CACHE_TIMEOUT_MS 10 * 60 * 1000
#define HAPPY_EYEBALLS_DELAY_MS 250
/* forward declarations */
static void
_async_connected (mongoc_async_cmd_t *acmd);
static void
_async_success (mongoc_async_cmd_t *acmd,
const bson_t *hello_response,
int64_t duration_usec);
static void
_async_error_or_timeout (mongoc_async_cmd_t *acmd,
int64_t duration_usec,
const char *default_err_msg);
static void
_async_handler (mongoc_async_cmd_t *acmd,
mongoc_async_cmd_result_t async_status,
const bson_t *hello_response,
int64_t duration_usec);
static void
_mongoc_topology_scanner_monitor_heartbeat_started (
const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host);
static void
_mongoc_topology_scanner_monitor_heartbeat_succeeded (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_t *reply,
int64_t duration_usec);
static void
_mongoc_topology_scanner_monitor_heartbeat_failed (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_error_t *error,
int64_t duration_usec);
/* reset "retired" nodes that failed or were removed in the previous scan */
static void
_delete_retired_nodes (mongoc_topology_scanner_t *ts);
/* cancel any pending async commands for a specific node excluding acmd.
* If acmd is NULL, cancel all async commands on the node. */
static void
_cancel_commands_excluding (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd);
/* return the number of pending async commands for a node. */
static int
_count_acmds (mongoc_topology_scanner_node_t *node);
/* if acmd fails, schedule the sibling commands sooner. */
static void
_jumpstart_other_acmds (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd);
static void
_add_hello (mongoc_topology_scanner_t *ts)
{
- mongoc_server_api_t *api = ts->api;
-
BSON_APPEND_INT32 (&ts->hello_cmd, "hello", 1);
BSON_APPEND_BOOL (&ts->hello_cmd, "helloOk", true);
BSON_APPEND_INT32 (&ts->legacy_hello_cmd, HANDSHAKE_CMD_LEGACY_HELLO, 1);
BSON_APPEND_BOOL (&ts->legacy_hello_cmd, "helloOk", true);
- if (api) {
- _mongoc_cmd_append_server_api (&ts->hello_cmd, api);
+ /* Append appropriate server API metadata (such as "serverApi") if selected: */
+ if (mongoc_topology_scanner_uses_server_api (ts)) {
+ _mongoc_cmd_append_server_api (&ts->hello_cmd, ts->api);
}
}
static void
_init_hello (mongoc_topology_scanner_t *ts)
{
bson_init (&ts->hello_cmd);
bson_init (&ts->legacy_hello_cmd);
bson_init (&ts->cluster_time);
ts->handshake_cmd = NULL;
_add_hello (ts);
}
static void
_reset_hello (mongoc_topology_scanner_t *ts)
{
bson_t *prev_cmd;
bson_reinit (&ts->hello_cmd);
bson_reinit (&ts->legacy_hello_cmd);
bson_mutex_lock (&ts->handshake_cmd_mtx);
prev_cmd = ts->handshake_cmd;
ts->handshake_cmd = NULL;
ts->handshake_state = HANDSHAKE_CMD_UNINITIALIZED;
bson_mutex_unlock (&ts->handshake_cmd_mtx);
bson_destroy (prev_cmd);
_add_hello (ts);
}
const char *
_mongoc_topology_scanner_get_speculative_auth_mechanism (
const mongoc_uri_t *uri)
{
const char *mechanism = mongoc_uri_get_auth_mechanism (uri);
bool requires_auth = mechanism || mongoc_uri_get_username (uri);
if (!requires_auth) {
return NULL;
}
if (!mechanism) {
return "SCRAM-SHA-256";
}
return mechanism;
}
void
_mongoc_topology_scanner_add_speculative_authentication (
bson_t *cmd,
const mongoc_uri_t *uri,
const mongoc_ssl_opt_t *ssl_opts,
mongoc_scram_cache_t *scram_cache,
mongoc_scram_t *scram /* OUT */)
{
bson_t auth_cmd;
bson_error_t error;
bool has_auth = false;
const char *mechanism =
_mongoc_topology_scanner_get_speculative_auth_mechanism (uri);
if (!mechanism) {
return;
}
if (strcasecmp (mechanism, "MONGODB-X509") == 0) {
/* Ignore errors while building authentication document: we proceed with
* the handshake as usual and let the subsequent authenticate command
* fail. */
if (_mongoc_cluster_get_auth_cmd_x509 (
uri, ssl_opts, &auth_cmd, &error)) {
has_auth = true;
BSON_APPEND_UTF8 (&auth_cmd, "db", "$external");
}
}
#ifdef MONGOC_ENABLE_CRYPTO
if (strcasecmp (mechanism, "SCRAM-SHA-1") == 0 ||
strcasecmp (mechanism, "SCRAM-SHA-256") == 0) {
mongoc_crypto_hash_algorithm_t algo =
strcasecmp (mechanism, "SCRAM-SHA-1") == 0
? MONGOC_CRYPTO_ALGORITHM_SHA_1
: MONGOC_CRYPTO_ALGORITHM_SHA_256;
_mongoc_uri_init_scram (uri, scram, algo);
if (scram_cache) {
_mongoc_scram_set_cache (scram, scram_cache);
}
if (_mongoc_cluster_get_auth_cmd_scram (algo, scram, &auth_cmd, &error)) {
const char *auth_source;
if (!(auth_source = mongoc_uri_get_auth_source (uri)) ||
(*auth_source == '\0')) {
auth_source = "admin";
}
has_auth = true;
BSON_APPEND_UTF8 (&auth_cmd, "db", auth_source);
}
}
#endif
if (has_auth) {
BSON_APPEND_DOCUMENT (cmd, "speculativeAuthenticate", &auth_cmd);
bson_destroy (&auth_cmd);
}
}
void
_mongoc_topology_scanner_parse_speculative_authentication (
const bson_t *hello, bson_t *speculative_authenticate)
{
bson_iter_t iter;
uint32_t data_len;
const uint8_t *data;
bson_t auth_response;
BSON_ASSERT (hello);
BSON_ASSERT (speculative_authenticate);
if (!bson_iter_init_find (&iter, hello, "speculativeAuthenticate")) {
return;
}
bson_iter_document (&iter, &data_len, &data);
BSON_ASSERT (bson_init_static (&auth_response, data, data_len));
bson_destroy (speculative_authenticate);
bson_copy_to (&auth_response, speculative_authenticate);
}
static bson_t *
_build_handshake_cmd (const bson_t *basis_cmd,
const char *appname,
const mongoc_uri_t *uri,
bool is_loadbalanced)
{
bson_t *doc = bson_copy (basis_cmd);
bson_t subdoc;
bson_iter_t iter;
const char *key;
int keylen;
const bson_t *compressors;
int count = 0;
char buf[16];
bool subdoc_okay;
+ BSON_ASSERT (doc);
+
BSON_APPEND_DOCUMENT_BEGIN (doc, HANDSHAKE_FIELD, &subdoc);
subdoc_okay =
_mongoc_handshake_build_doc_with_application (&subdoc, appname);
bson_append_document_end (doc, &subdoc);
if (!subdoc_okay) {
bson_destroy (doc);
return NULL;
}
BSON_APPEND_ARRAY_BEGIN (doc, "compression", &subdoc);
if (uri) {
compressors = mongoc_uri_get_compressors (uri);
if (bson_iter_init (&iter, compressors)) {
while (bson_iter_next (&iter)) {
keylen = bson_uint32_to_string (count++, &key, buf, sizeof buf);
bson_append_utf8 (
&subdoc, key, (int) keylen, bson_iter_key (&iter), -1);
}
}
}
bson_append_array_end (doc, &subdoc);
if (is_loadbalanced) {
BSON_APPEND_BOOL (doc, "loadBalanced", true);
}
/* Return whether the handshake doc fit the size limit */
return doc;
}
const bson_t *
_mongoc_topology_scanner_get_monitoring_cmd (mongoc_topology_scanner_t *ts,
bool hello_ok)
{
- return hello_ok || ts->api ? &ts->hello_cmd : &ts->legacy_hello_cmd;
+ return hello_ok || mongoc_topology_scanner_uses_server_api (ts)
+ ? &ts->hello_cmd
+ : &ts->legacy_hello_cmd;
}
void
_mongoc_topology_scanner_dup_handshake_cmd (mongoc_topology_scanner_t *ts,
bson_t *copy_into)
{
bson_t *new_cmd;
const char *appname;
BSON_ASSERT_PARAM (ts);
BSON_ASSERT_PARAM (copy_into);
/* appname will only be changed from NULL, so a non-null pointer will never
* be invalidated after this fetch. */
appname =
bson_atomic_ptr_fetch ((void *) &ts->appname, bson_memory_order_relaxed);
bson_mutex_lock (&ts->handshake_cmd_mtx);
/* If this is the first time using the node or if it's the first time
* using it after a failure, build handshake doc */
if (ts->handshake_state != HANDSHAKE_CMD_UNINITIALIZED) {
/* We're good to just return the handshake now */
goto after_init;
}
/* There is not yet a handshake command associated with this scanner.
* Initialize one and set it now. */
/* Note: Don't hold the mutex while we build our command */
/* Construct a new handshake command to be sent */
BSON_ASSERT (ts->handshake_cmd == NULL);
bson_mutex_unlock (&ts->handshake_cmd_mtx);
- new_cmd =
- _build_handshake_cmd (ts->api ? &ts->hello_cmd : &ts->legacy_hello_cmd,
- appname,
- ts->uri,
- ts->loadbalanced);
+ new_cmd = _build_handshake_cmd (mongoc_topology_scanner_uses_server_api (ts)
+ ? &ts->hello_cmd
+ : &ts->legacy_hello_cmd,
+ appname,
+ ts->uri,
+ ts->loadbalanced);
bson_mutex_lock (&ts->handshake_cmd_mtx);
if (ts->handshake_state != HANDSHAKE_CMD_UNINITIALIZED) {
/* Someone else updated the handshake_cmd while we were building ours.
* Defer to their copy and just destroy the one we created. */
bson_destroy (new_cmd);
goto after_init;
}
BSON_ASSERT (ts->handshake_cmd == NULL);
/* We're still the one updating the command */
ts->handshake_cmd = new_cmd;
/* The "_build" may have failed. */
/* Even if new_cmd is NULL, this is still what we want */
ts->handshake_state =
new_cmd == NULL ? HANDSHAKE_CMD_TOO_BIG : HANDSHAKE_CMD_OKAY;
if (ts->handshake_state == HANDSHAKE_CMD_TOO_BIG) {
MONGOC_WARNING ("Handshake doc too big, not including in hello");
}
after_init:
/* If the doc turned out to be too big */
if (ts->handshake_state == HANDSHAKE_CMD_TOO_BIG) {
- bson_t *ret = ts->api ? &ts->hello_cmd : &ts->legacy_hello_cmd;
+ bson_t *ret = mongoc_topology_scanner_uses_server_api (ts)
+ ? &ts->hello_cmd
+ : &ts->legacy_hello_cmd;
bson_copy_to (ret, copy_into);
} else {
BSON_ASSERT (ts->handshake_cmd != NULL);
bson_copy_to (ts->handshake_cmd, copy_into);
}
bson_mutex_unlock (&ts->handshake_cmd_mtx);
}
static void
_begin_hello_cmd (mongoc_topology_scanner_node_t *node,
mongoc_stream_t *stream,
bool is_setup_done,
struct addrinfo *dns_result,
int64_t initiate_delay_ms,
bool use_handshake)
{
mongoc_topology_scanner_t *ts = node->ts;
+ mongoc_opcode_t cmd_opcode_type = MONGOC_OPCODE_QUERY;
bson_t cmd;
+ /* If we're asked to use a specific API version, we should send our
+ hello handshake via op_msg rather than the legacy op_query: */
+ if (mongoc_topology_scanner_uses_server_api (ts)) {
+ cmd_opcode_type = MONGOC_OPCODE_MSG;
+ }
+
if (node->last_used != -1 && node->last_failed == -1 && !use_handshake) {
/* The node's been used before and not failed recently */
bson_copy_to (
_mongoc_topology_scanner_get_monitoring_cmd (ts, node->hello_ok),
&cmd);
} else {
_mongoc_topology_scanner_dup_handshake_cmd (ts, &cmd);
}
if (node->ts->negotiate_sasl_supported_mechs &&
!node->negotiated_sasl_supported_mechs) {
_mongoc_handshake_append_sasl_supported_mechs (ts->uri, &cmd);
}
if (node->ts->speculative_authentication && !node->has_auth &&
bson_empty (&node->speculative_auth_response) && node->scram.step == 0) {
mongoc_ssl_opt_t *ssl_opts = NULL;
#ifdef MONGOC_ENABLE_SSL
ssl_opts = ts->ssl_opts;
#endif
_mongoc_topology_scanner_add_speculative_authentication (
&cmd, ts->uri, ssl_opts, NULL, &node->scram);
}
if (!bson_empty (&ts->cluster_time)) {
bson_append_document (&cmd, "$clusterTime", 12, &ts->cluster_time);
}
/* if the node should connect with a TCP socket, stream will be null, and
* dns_result will be set. The async loop is responsible for calling the
* _tcp_initiator to construct TCP sockets. */
mongoc_async_cmd_new (ts->async,
stream,
is_setup_done,
dns_result,
_mongoc_topology_scanner_tcp_initiate,
initiate_delay_ms,
ts->setup,
node->host.host,
"admin",
&cmd,
+ cmd_opcode_type,
&_async_handler,
node,
ts->connect_timeout_msec);
bson_destroy (&cmd);
}
mongoc_topology_scanner_t *
mongoc_topology_scanner_new (
const mongoc_uri_t *uri,
mongoc_topology_scanner_setup_err_cb_t setup_err_cb,
mongoc_topology_scanner_cb_t cb,
void *data,
int64_t connect_timeout_msec)
{
mongoc_topology_scanner_t *ts =
(mongoc_topology_scanner_t *) bson_malloc0 (sizeof (*ts));
ts->async = mongoc_async_new ();
ts->setup_err_cb = setup_err_cb;
ts->cb = cb;
ts->cb_data = data;
ts->uri = uri;
ts->appname = NULL;
ts->api = NULL;
ts->handshake_state = HANDSHAKE_CMD_UNINITIALIZED;
ts->connect_timeout_msec = connect_timeout_msec;
/* may be overridden for testing. */
ts->dns_cache_timeout_ms = DNS_CACHE_TIMEOUT_MS;
bson_mutex_init (&ts->handshake_cmd_mtx);
_init_hello (ts);
return ts;
}
#ifdef MONGOC_ENABLE_SSL
void
mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts,
mongoc_ssl_opt_t *opts)
{
ts->ssl_opts = opts;
ts->setup = mongoc_async_cmd_tls_setup;
}
#endif
void
mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts,
mongoc_stream_initiator_t si,
void *ctx)
{
ts->initiator = si;
ts->initiator_context = ctx;
ts->setup = NULL;
}
void
mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts)
{
mongoc_topology_scanner_node_t *ele, *tmp;
DL_FOREACH_SAFE (ts->nodes, ele, tmp)
{
mongoc_topology_scanner_node_destroy (ele, false);
}
mongoc_async_destroy (ts->async);
bson_destroy (&ts->hello_cmd);
bson_destroy (&ts->legacy_hello_cmd);
bson_destroy (ts->handshake_cmd);
bson_destroy (&ts->cluster_time);
mongoc_server_api_destroy (ts->api);
bson_mutex_destroy (&ts->handshake_cmd_mtx);
/* This field can be set by a mongoc_client */
bson_free ((char *) ts->appname);
bson_free (ts);
}
/* whether the scanner was successfully initialized - false if a mongodb+srv
* URI failed to resolve to any hosts */
bool
mongoc_topology_scanner_valid (mongoc_topology_scanner_t *ts)
{
return ts->nodes != NULL;
}
void
mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
uint32_t id,
bool hello_ok)
{
mongoc_topology_scanner_node_t *node;
node = (mongoc_topology_scanner_node_t *) bson_malloc0 (sizeof (*node));
memcpy (&node->host, host, sizeof (*host));
node->id = id;
node->ts = ts;
node->last_failed = -1;
node->last_used = -1;
node->hello_ok = hello_ok;
bson_init (&node->speculative_auth_response);
DL_APPEND (ts->nodes, node);
}
void
mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, uint32_t id)
{
mongoc_topology_scanner_node_t *node;
node = mongoc_topology_scanner_get_node (ts, id);
/* begin non-blocking connection, don't wait for success */
if (node) {
mongoc_topology_scanner_node_setup (node, &node->last_error);
}
/* if setup fails the node stays in the scanner. destroyed after the scan. */
}
void
mongoc_topology_scanner_disconnect (mongoc_topology_scanner_t *scanner)
{
mongoc_topology_scanner_node_t *node;
BSON_ASSERT (scanner);
node = scanner->nodes;
while (node) {
mongoc_topology_scanner_node_disconnect (node, false);
node = node->next;
}
}
void
mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node)
{
/* cancel any pending commands. */
_cancel_commands_excluding (node, NULL);
node->retired = true;
}
void
mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node,
bool failed)
{
/* the node may or may not have succeeded in finding a working stream. */
if (node->stream) {
if (failed) {
mongoc_stream_failed (node->stream);
} else {
mongoc_stream_destroy (node->stream);
}
node->stream = NULL;
memset (
&node->sasl_supported_mechs, 0, sizeof (node->sasl_supported_mechs));
node->negotiated_sasl_supported_mechs = false;
bson_reinit (&node->speculative_auth_response);
}
mongoc_server_description_destroy (node->handshake_sd);
node->handshake_sd = NULL;
}
void
mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node,
bool failed)
{
DL_DELETE (node->ts->nodes, node);
mongoc_topology_scanner_node_disconnect (node, failed);
if (node->dns_results) {
freeaddrinfo (node->dns_results);
}
bson_destroy (&node->speculative_auth_response);
#ifdef MONGOC_ENABLE_CRYPTO
_mongoc_scram_destroy (&node->scram);
#endif
bson_free (node);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_get_node --
*
* Return the scanner node with the given id.
*
*--------------------------------------------------------------------------
*/
mongoc_topology_scanner_node_t *
mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id)
{
mongoc_topology_scanner_node_t *ele, *tmp;
DL_FOREACH_SAFE (ts->nodes, ele, tmp)
{
if (ele->id == id) {
return ele;
}
if (ele->id > id) {
break;
}
}
return NULL;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_has_node_for_host --
*
* Whether the scanner has a node for the given host and port.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts,
mongoc_host_list_t *host)
{
mongoc_topology_scanner_node_t *ele, *tmp;
DL_FOREACH_SAFE (ts->nodes, ele, tmp)
{
if (_mongoc_host_list_compare_one (&ele->host, host)) {
return true;
}
}
return false;
}
static void
_async_connected (mongoc_async_cmd_t *acmd)
{
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) acmd->data;
/* this cmd connected successfully, cancel other cmds on this node. */
_cancel_commands_excluding (node, acmd);
node->successful_dns_result = acmd->dns_result;
}
static void
_async_success (mongoc_async_cmd_t *acmd,
const bson_t *hello_response,
int64_t duration_usec)
{
void *data = acmd->data;
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) data;
mongoc_stream_t *stream = acmd->stream;
mongoc_topology_scanner_t *ts = node->ts;
if (node->retired) {
if (stream) {
mongoc_stream_failed (stream);
}
return;
}
node->last_used = bson_get_monotonic_time ();
node->last_failed = -1;
_mongoc_topology_scanner_monitor_heartbeat_succeeded (
ts, &node->host, hello_response, duration_usec);
/* set our successful stream. */
BSON_ASSERT (!node->stream);
node->stream = stream;
if (!node->handshake_sd) {
mongoc_server_description_t sd;
/* Store a server description associated with the handshake. */
mongoc_server_description_init (&sd, node->host.host_and_port, node->id);
mongoc_server_description_handle_hello (
&sd, hello_response, duration_usec / 1000, &acmd->error);
node->handshake_sd = mongoc_server_description_new_copy (&sd);
mongoc_server_description_cleanup (&sd);
}
if (ts->negotiate_sasl_supported_mechs &&
!node->negotiated_sasl_supported_mechs) {
_mongoc_handshake_parse_sasl_supported_mechs (
hello_response, &node->sasl_supported_mechs);
}
if (ts->speculative_authentication) {
_mongoc_topology_scanner_parse_speculative_authentication (
hello_response, &node->speculative_auth_response);
}
/* mongoc_topology_scanner_cb_t takes rtt_msec, not usec */
ts->cb (node->id,
hello_response,
duration_usec / 1000,
ts->cb_data,
&acmd->error);
}
static void
_async_error_or_timeout (mongoc_async_cmd_t *acmd,
int64_t duration_usec,
const char *default_err_msg)
{
void *data = acmd->data;
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) data;
mongoc_stream_t *stream = acmd->stream;
mongoc_topology_scanner_t *ts = node->ts;
bson_error_t *error = &acmd->error;
int64_t now = bson_get_monotonic_time ();
const char *message;
/* the stream may have failed on initiation. */
if (stream) {
mongoc_stream_failed (stream);
}
if (node->retired) {
return;
}
node->last_used = now;
if (!node->stream && _count_acmds (node) == 1) {
/* there are no remaining streams, connecting has failed. */
node->last_failed = now;
if (error->code) {
message = error->message;
} else {
message = default_err_msg;
}
/* invalidate any cached DNS results. */
if (node->dns_results) {
freeaddrinfo (node->dns_results);
node->dns_results = NULL;
node->successful_dns_result = NULL;
}
bson_set_error (&node->last_error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_STREAM_CONNECT,
"%s calling hello on \'%s\'",
message,
node->host.host_and_port);
_mongoc_topology_scanner_monitor_heartbeat_failed (
ts, &node->host, &node->last_error, duration_usec);
/* call the topology scanner callback. cannot connect to this node.
* callback takes rtt_msec, not usec. */
ts->cb (node->id, NULL, duration_usec / 1000, ts->cb_data, error);
mongoc_server_description_destroy (node->handshake_sd);
node->handshake_sd = NULL;
} else {
/* there are still more commands left for this node or it succeeded
* with another stream. skip the topology scanner callback. */
_jumpstart_other_acmds (node, acmd);
}
}
/*
*-----------------------------------------------------------------------
*
* This is the callback passed to async_cmd when we're running
* hellos from within the topology monitor.
*
*-----------------------------------------------------------------------
*/
static void
_async_handler (mongoc_async_cmd_t *acmd,
mongoc_async_cmd_result_t async_status,
const bson_t *hello_response,
int64_t duration_usec)
{
BSON_ASSERT (acmd->data);
switch (async_status) {
case MONGOC_ASYNC_CMD_CONNECTED:
_async_connected (acmd);
return;
case MONGOC_ASYNC_CMD_SUCCESS:
_async_success (acmd, hello_response, duration_usec);
return;
case MONGOC_ASYNC_CMD_TIMEOUT:
_async_error_or_timeout (acmd, duration_usec, "connection timeout");
return;
case MONGOC_ASYNC_CMD_ERROR:
_async_error_or_timeout (acmd, duration_usec, "connection error");
return;
case MONGOC_ASYNC_CMD_IN_PROGRESS:
default:
fprintf (stderr, "unexpected async status: %d\n", async_status);
BSON_ASSERT (false);
return;
}
}
mongoc_stream_t *
_mongoc_topology_scanner_node_setup_stream_for_tls (
mongoc_topology_scanner_node_t *node, mongoc_stream_t *stream)
{
#ifdef MONGOC_ENABLE_SSL
mongoc_stream_t *tls_stream;
#endif
if (!stream) {
return NULL;
}
#ifdef MONGOC_ENABLE_SSL
if (node->ts->ssl_opts) {
tls_stream = mongoc_stream_tls_new_with_hostname (
stream, node->host.host, node->ts->ssl_opts, 1);
if (!tls_stream) {
mongoc_stream_destroy (stream);
return NULL;
} else {
return tls_stream;
}
}
#endif
return stream;
}
/* attempt to create a new socket stream using this dns result. */
mongoc_stream_t *
_mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd)
{
mongoc_topology_scanner_node_t *node =
(mongoc_topology_scanner_node_t *) acmd->data;
struct addrinfo *res = acmd->dns_result;
mongoc_socket_t *sock = NULL;
BSON_ASSERT (acmd->dns_result);
/* create a new non-blocking socket. */
if (!(sock = mongoc_socket_new (
res->ai_family, res->ai_socktype, res->ai_protocol))) {
return NULL;
}
(void) mongoc_socket_connect (
sock, res->ai_addr, (mongoc_socklen_t) res->ai_addrlen, 0);
return _mongoc_topology_scanner_node_setup_stream_for_tls (
node, mongoc_stream_socket_new (sock));
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_node_setup_tcp --
*
* Create an async command for each DNS record found for this node.
*
* Returns:
* A bool. On failure error is set.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_node_setup_tcp (mongoc_topology_scanner_node_t *node,
bson_error_t *error)
{
struct addrinfo hints;
struct addrinfo *iter;
char portstr[8];
mongoc_host_list_t *host;
int s;
int64_t delay = 0;
int64_t now = bson_get_monotonic_time ();
ENTRY;
host = &node->host;
/* if cached dns results are expired, flush. */
if (node->dns_results &&
(now - node->last_dns_cache) > node->ts->dns_cache_timeout_ms * 1000) {
freeaddrinfo (node->dns_results);
node->dns_results = NULL;
node->successful_dns_result = NULL;
}
if (!node->dns_results) {
bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
memset (&hints, 0, sizeof hints);
hints.ai_family = host->family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
s = getaddrinfo (host->host, portstr, &hints, &node->dns_results);
if (s != 0) {
mongoc_counter_dns_failure_inc ();
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"Failed to resolve '%s'",
host->host);
RETURN (false);
}
mongoc_counter_dns_success_inc ();
node->last_dns_cache = now;
}
if (node->successful_dns_result) {
_begin_hello_cmd (node,
NULL /* stream */,
false /* is_setup_done */,
node->successful_dns_result,
0 /* initiate_delay_ms */,
true /* use_handshake */);
} else {
LL_FOREACH2 (node->dns_results, iter, ai_next)
{
_begin_hello_cmd (node,
NULL /* stream */,
false /* is_setup_done */,
iter,
delay,
true /* use_handshake */);
/* each subsequent DNS result will have an additional 250ms delay. */
delay += HAPPY_EYEBALLS_DELAY_MS;
}
}
RETURN (true);
}
bool
mongoc_topology_scanner_node_connect_unix (mongoc_topology_scanner_node_t *node,
bson_error_t *error)
{
#ifdef _WIN32
ENTRY;
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"UNIX domain sockets not supported on win32.");
RETURN (false);
#else
struct sockaddr_un saddr;
mongoc_socket_t *sock;
mongoc_stream_t *stream;
mongoc_host_list_t *host;
ENTRY;
host = &node->host;
memset (&saddr, 0, sizeof saddr);
saddr.sun_family = AF_UNIX;
bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0);
if (sock == NULL) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Failed to create socket.");
RETURN (false);
}
if (-1 == mongoc_socket_connect (
sock, (struct sockaddr *) &saddr, sizeof saddr, -1)) {
char buf[128];
char *errstr;
errstr = bson_strerror_r (mongoc_socket_errno (sock), buf, sizeof (buf));
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"Failed to connect to UNIX domain socket: %s",
errstr);
mongoc_socket_destroy (sock);
RETURN (false);
}
stream = _mongoc_topology_scanner_node_setup_stream_for_tls (
node, mongoc_stream_socket_new (sock));
if (stream) {
_begin_hello_cmd (node,
stream,
false /* is_setup_done */,
NULL /* dns result */,
0 /* delay */,
true /* use_handshake */);
RETURN (true);
}
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_CONNECT,
"Failed to create TLS stream");
RETURN (false);
#endif
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_node_setup --
*
* Create a stream and begin a non-blocking connect.
*
* Returns:
* true on success, or false and error is set.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node,
bson_error_t *error)
{
bool success = false;
mongoc_stream_t *stream;
int64_t start;
_mongoc_topology_scanner_monitor_heartbeat_started (node->ts, &node->host);
start = bson_get_monotonic_time ();
/* if there is already a working stream, push it back to be re-scanned. */
if (node->stream) {
_begin_hello_cmd (node,
node->stream,
true /* is_setup_done */,
NULL /* dns_result */,
0 /* initiate_delay_ms */,
false /* use_handshake */);
node->stream = NULL;
return;
}
BSON_ASSERT (!node->retired);
if (node->ts->initiator) {
stream = node->ts->initiator (
node->ts->uri, &node->host, node->ts->initiator_context, error);
if (stream) {
success = true;
_begin_hello_cmd (node,
stream,
false /* is_setup_done */,
NULL /* dns_result */,
0 /* initiate_delay_ms */,
true /* use_handshake */);
}
} else {
if (node->host.family == AF_UNIX) {
success = mongoc_topology_scanner_node_connect_unix (node, error);
} else {
success = mongoc_topology_scanner_node_setup_tcp (node, error);
}
}
if (!success) {
_mongoc_topology_scanner_monitor_heartbeat_failed (
node->ts,
&node->host,
error,
(bson_get_monotonic_time () - start) / 1000);
node->ts->setup_err_cb (node->id, node->ts->cb_data, error);
return;
}
node->has_auth = false;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_node_in_cooldown --
*
* Return true if @node has experienced a network error attempting
* to call "hello" less than 5 seconds before @when, a timestamp in
* microseconds.
*
* Server Discovery and Monitoring Spec: "After a single-threaded client
* gets a network error trying to check a server, the client skips
* re-checking the server until cooldownMS has passed. This avoids
* spending connectTimeoutMS on each unavailable server during each scan.
* This value MUST be 5000 ms, and it MUST NOT be configurable."
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_node_in_cooldown (mongoc_topology_scanner_node_t *node,
int64_t when)
{
if (node->last_failed == -1 || node->ts->bypass_cooldown) {
return false; /* node is new, or connected */
}
return node->last_failed + 1000 * MONGOC_TOPOLOGY_COOLDOWN_MS >= when;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_in_cooldown --
*
* Return true if all nodes will be in cooldown at time @when, a
* timestamp in microseconds.
*
*--------------------------------------------------------------------------
*/
bool
mongoc_topology_scanner_in_cooldown (mongoc_topology_scanner_t *ts,
int64_t when)
{
mongoc_topology_scanner_node_t *node;
if (ts->bypass_cooldown) {
return false;
}
DL_FOREACH (ts->nodes, node)
{
if (!mongoc_topology_scanner_node_in_cooldown (node, when)) {
return false;
}
}
return true;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_start --
*
* Initializes the scanner and begins a full topology check. This
* should be called once before calling mongoc_topology_scanner_work()
* to complete the scan.
*
* If "obey_cooldown" is true, this is a single-threaded blocking scan
* that must obey the Server Discovery And Monitoring Spec's cooldownMS:
*
* "After a single-threaded client gets a network error trying to check
* a server, the client skips re-checking the server until cooldownMS has
* passed.
*
* "This avoids spending connectTimeoutMS on each unavailable server
* during each scan.
*
* "This value MUST be 5000 ms, and it MUST NOT be configurable."
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts,
bool obey_cooldown)
{
mongoc_topology_scanner_node_t *node, *tmp;
bool skip;
int64_t now;
BSON_ASSERT (ts);
_delete_retired_nodes (ts);
now = bson_get_monotonic_time ();
DL_FOREACH_SAFE (ts->nodes, node, tmp)
{
skip =
obey_cooldown && mongoc_topology_scanner_node_in_cooldown (node, now);
if (!skip) {
mongoc_topology_scanner_node_setup (node, &node->last_error);
}
}
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_finish_scan --
*
* Summarizes all scanner node errors into one error message,
* deletes retired nodes.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts)
{
mongoc_topology_scanner_node_t *node, *tmp;
bson_error_t *error = &ts->error;
bson_string_t *msg;
memset (&ts->error, 0, sizeof (bson_error_t));
msg = bson_string_new (NULL);
DL_FOREACH_SAFE (ts->nodes, node, tmp)
{
if (node->last_error.code) {
if (msg->len) {
bson_string_append_c (msg, ' ');
}
bson_string_append_printf (msg, "[%s]", node->last_error.message);
/* last error domain and code win */
error->domain = node->last_error.domain;
error->code = node->last_error.code;
}
}
bson_strncpy ((char *) &error->message, msg->str, sizeof (error->message));
bson_string_free (msg, true);
_delete_retired_nodes (ts);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_work --
*
* Crank the knob on the topology scanner state machine. This should
* be called only after mongoc_topology_scanner_start() has been used
* to begin the scan.
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts)
{
mongoc_async_run (ts->async);
BSON_ASSERT (ts->async->ncmds == 0);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scanner_get_error --
*
* Copy the scanner's current error; which may no-error (code 0).
*
*--------------------------------------------------------------------------
*/
void
mongoc_topology_scanner_get_error (mongoc_topology_scanner_t *ts,
bson_error_t *error)
{
BSON_ASSERT (ts);
BSON_ASSERT (error);
memcpy (error, &ts->error, sizeof (bson_error_t));
}
/*
* Set a field in the topology scanner.
*/
bool
_mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts,
const char *appname)
{
char *s;
const char *prev;
if (!_mongoc_handshake_appname_is_valid (appname)) {
MONGOC_ERROR ("Cannot set appname: %s is invalid", appname);
return false;
}
s = bson_strdup (appname);
prev = bson_atomic_ptr_compare_exchange_strong (
(void *) &ts->appname, NULL, s, bson_memory_order_relaxed);
if (prev == NULL) {
return true;
}
MONGOC_ERROR ("Cannot set appname more than once");
bson_free (s);
return false;
}
/*
* Set the scanner's clusterTime unconditionally: don't compare with prior
* @cluster_time is like {clusterTime: <timestamp>}
*/
void
_mongoc_topology_scanner_set_cluster_time (mongoc_topology_scanner_t *ts,
const bson_t *cluster_time)
{
bson_destroy (&ts->cluster_time);
bson_copy_to (cluster_time, &ts->cluster_time);
}
/* SDAM Monitoring Spec: send HeartbeatStartedEvent */
static void
_mongoc_topology_scanner_monitor_heartbeat_started (
const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host)
{
if (ts->apm_callbacks.server_heartbeat_started) {
mongoc_apm_server_heartbeat_started_t event;
event.host = host;
event.context = ts->apm_context;
event.awaited = false;
ts->apm_callbacks.server_heartbeat_started (&event);
}
}
/* SDAM Monitoring Spec: send HeartbeatSucceededEvent */
static void
_mongoc_topology_scanner_monitor_heartbeat_succeeded (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_t *reply,
int64_t duration_usec)
{
if (ts->apm_callbacks.server_heartbeat_succeeded) {
mongoc_apm_server_heartbeat_succeeded_t event;
bson_t hello_redacted;
bson_init (&hello_redacted);
bson_copy_to_excluding_noinit (
reply, &hello_redacted, "speculativeAuthenticate", NULL);
event.host = host;
event.context = ts->apm_context;
event.reply = reply;
event.duration_usec = duration_usec;
event.awaited = false;
ts->apm_callbacks.server_heartbeat_succeeded (&event);
bson_destroy (&hello_redacted);
}
}
/* SDAM Monitoring Spec: send HeartbeatFailedEvent */
static void
_mongoc_topology_scanner_monitor_heartbeat_failed (
const mongoc_topology_scanner_t *ts,
const mongoc_host_list_t *host,
const bson_error_t *error,
int64_t duration_usec)
{
if (ts->apm_callbacks.server_heartbeat_failed) {
mongoc_apm_server_heartbeat_failed_t event;
event.host = host;
event.context = ts->apm_context;
event.error = error;
event.duration_usec = duration_usec;
event.awaited = false;
ts->apm_callbacks.server_heartbeat_failed (&event);
}
}
/* this is for testing the dns cache timeout. */
void
_mongoc_topology_scanner_set_dns_cache_timeout (mongoc_topology_scanner_t *ts,
int64_t timeout_ms)
{
ts->dns_cache_timeout_ms = timeout_ms;
}
/* reset "retired" nodes that failed or were removed in the previous scan */
static void
_delete_retired_nodes (mongoc_topology_scanner_t *ts)
{
mongoc_topology_scanner_node_t *node, *tmp;
DL_FOREACH_SAFE (ts->nodes, node, tmp)
{
if (node->retired) {
mongoc_topology_scanner_node_destroy (node, true);
}
}
}
static void
_cancel_commands_excluding (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd)
{
mongoc_async_cmd_t *iter;
DL_FOREACH (node->ts->async->cmds, iter)
{
if ((mongoc_topology_scanner_node_t *) iter->data == node &&
iter != acmd) {
iter->state = MONGOC_ASYNC_CMD_CANCELED_STATE;
}
}
}
static int
_count_acmds (mongoc_topology_scanner_node_t *node)
{
mongoc_async_cmd_t *iter;
int count = 0;
DL_FOREACH (node->ts->async->cmds, iter)
{
if ((mongoc_topology_scanner_node_t *) iter->data == node) {
++count;
}
}
return count;
}
static void
_jumpstart_other_acmds (mongoc_topology_scanner_node_t *node,
mongoc_async_cmd_t *acmd)
{
mongoc_async_cmd_t *iter;
DL_FOREACH (node->ts->async->cmds, iter)
{
if ((mongoc_topology_scanner_node_t *) iter->data == node &&
iter != acmd && acmd->initiate_delay_ms < iter->initiate_delay_ms) {
iter->initiate_delay_ms =
BSON_MAX (iter->initiate_delay_ms - HAPPY_EYEBALLS_DELAY_MS, 0);
}
}
}
void
_mongoc_topology_scanner_set_server_api (mongoc_topology_scanner_t *ts,
const mongoc_server_api_t *api)
{
BSON_ASSERT (ts);
BSON_ASSERT (api);
-
mongoc_server_api_destroy (ts->api);
ts->api = mongoc_server_api_copy (api);
_reset_hello (ts);
}
/* This must be called before the handshake command is constructed. */
void
_mongoc_topology_scanner_set_loadbalanced (mongoc_topology_scanner_t *ts,
bool val)
{
BSON_ASSERT (ts->handshake_cmd == NULL);
ts->loadbalanced = true;
}
+
+bool
+mongoc_topology_scanner_uses_server_api (
+ const mongoc_topology_scanner_t *topology_scanner)
+{
+ return NULL != topology_scanner->api;
+}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
index a9bca4f1..5eb4df8b 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c
@@ -1,2033 +1,2043 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-config.h"
#include "mongoc-handshake.h"
#include "mongoc-handshake-private.h"
#include "mongoc-error.h"
#include "mongoc-host-list-private.h"
#include "mongoc-log.h"
#include "mongoc-topology-private.h"
#include "mongoc-topology-description-apm-private.h"
#include "mongoc-client-private.h"
#include "mongoc-cmd-private.h"
#include "mongoc-uri-private.h"
#include "mongoc-util-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-error-private.h"
#include "mongoc-topology-background-monitoring-private.h"
#include "mongoc-read-prefs-private.h"
#include "utlist.h"
#include <stdint.h>
static void
_topology_collect_errors (const mongoc_topology_description_t *topology,
bson_error_t *error_out);
static bool
_mongoc_topology_reconcile_add_nodes (mongoc_server_description_t *sd,
mongoc_topology_scanner_t *scanner)
{
mongoc_topology_scanner_node_t *node;
/* Search by ID and update hello_ok */
node = mongoc_topology_scanner_get_node (scanner, sd->id);
if (node) {
node->hello_ok = sd->hello_ok;
} else if (!mongoc_topology_scanner_has_node_for_host (scanner, &sd->host)) {
/* A node for this host was retired in this scan. */
mongoc_topology_scanner_add (scanner, &sd->host, sd->id, sd->hello_ok);
mongoc_topology_scanner_scan (scanner, sd->id);
}
return true;
}
/* Called from:
* - the topology scanner callback (when a hello was just received)
* - at the start of a single-threaded scan (mongoc_topology_scan_once)
* Not called for multi threaded monitoring.
*/
void
mongoc_topology_reconcile (const mongoc_topology_t *topology,
mongoc_topology_description_t *td)
{
mongoc_set_t *servers;
mongoc_server_description_t *sd;
int i;
mongoc_topology_scanner_node_t *ele, *tmp;
servers = mc_tpld_servers (td);
/* Add newly discovered nodes */
for (i = 0; i < (int) servers->items_len; i++) {
sd = mongoc_set_get_item (servers, i);
_mongoc_topology_reconcile_add_nodes (sd, topology->scanner);
}
/* Remove removed nodes */
DL_FOREACH_SAFE (topology->scanner->nodes, ele, tmp)
{
if (!mongoc_topology_description_server_by_id (td, ele->id, NULL)) {
mongoc_topology_scanner_node_retire (ele);
}
}
}
/* call this while already holding the lock */
static bool
_mongoc_topology_update_no_lock (uint32_t id,
const bson_t *hello_response,
int64_t rtt_msec,
mongoc_topology_description_t *td,
const bson_error_t *error /* IN */)
{
mongoc_topology_description_handle_hello (
td, id, hello_response, rtt_msec, error);
/* return false if server removed from topology */
return mongoc_topology_description_server_by_id (td, id, NULL) != NULL;
}
/*
*-------------------------------------------------------------------------
*
* _mongoc_topology_scanner_setup_err_cb --
*
* Callback method to handle errors during topology scanner node
* setup, typically DNS or SSL errors.
*
*-------------------------------------------------------------------------
*/
void
_mongoc_topology_scanner_setup_err_cb (uint32_t id,
void *data,
const bson_error_t *error /* IN */)
{
mongoc_topology_t *topology = BSON_ASSERT_PTR_INLINE (data);
if (_mongoc_topology_get_type (topology) == MONGOC_TOPOLOGY_LOAD_BALANCED) {
/* In load balanced mode, scanning is only for connection establishment.
* It must not modify the topology description. */
} else {
/* We need to update the topology description */
mc_tpld_modification mod = mc_tpld_modify_begin (topology);
mongoc_topology_description_handle_hello (
mod.new_td, id, NULL /* hello reply */, -1 /* rtt_msec */, error);
mc_tpld_modify_commit (mod);
}
}
/*
*-------------------------------------------------------------------------
*
* _mongoc_topology_scanner_cb --
*
* Callback method to handle hello responses received by async
* command objects.
*
* Only called for single-threaded monitoring.
*
*-------------------------------------------------------------------------
*/
void
_mongoc_topology_scanner_cb (uint32_t id,
const bson_t *hello_response,
int64_t rtt_msec,
void *data,
const bson_error_t *error /* IN */)
{
mongoc_topology_t *const topology = BSON_ASSERT_PTR_INLINE (data);
mongoc_server_description_t *sd;
mc_tpld_modification tdmod;
if (_mongoc_topology_get_type (topology) == MONGOC_TOPOLOGY_LOAD_BALANCED) {
/* In load balanced mode, scanning is only for connection establishment.
* It must not modify the topology description. */
return;
}
tdmod = mc_tpld_modify_begin (topology);
sd = mongoc_topology_description_server_by_id (tdmod.new_td, id, NULL);
if (!hello_response) {
/* Server monitoring: When a server check fails due to a network error
* (including a network timeout), the client MUST clear its connection
* pool for the server */
_mongoc_topology_description_clear_connection_pool (
tdmod.new_td, id, &kZeroServiceId);
}
/* Server Discovery and Monitoring Spec: "Once a server is connected, the
* client MUST change its type to Unknown only after it has retried the
* server once." */
if (!hello_response && sd && sd->type != MONGOC_SERVER_UNKNOWN) {
_mongoc_topology_update_no_lock (
id, hello_response, rtt_msec, tdmod.new_td, error);
/* add another hello call to the current scan - the scan continues
* until all commands are done */
mongoc_topology_scanner_scan (topology->scanner, sd->id);
} else {
_mongoc_topology_update_no_lock (
id, hello_response, rtt_msec, tdmod.new_td, error);
/* The processing of the hello results above may have added, changed, or
* removed server descriptions. We need to reconcile that with our
* monitoring agents
*/
mongoc_topology_reconcile (topology, tdmod.new_td);
mongoc_cond_broadcast (&topology->cond_client);
}
mc_tpld_modify_commit (tdmod);
}
static void
_server_session_init (mongoc_server_session_t *session,
mongoc_topology_t *unused,
bson_error_t *error)
{
_mongoc_server_session_init (session, error);
}
static void
_server_session_destroy (mongoc_server_session_t *session,
mongoc_topology_t *unused)
{
_mongoc_server_session_destroy (session);
}
static int
_server_session_should_prune (mongoc_server_session_t *session,
mongoc_topology_t *topo)
{
bool is_loadbalanced;
int timeout;
mc_shared_tpld td;
BSON_ASSERT_PARAM (session);
BSON_ASSERT_PARAM (topo);
/** If "dirty" (i.e. contains a network error), it should be dropped */
if (session->dirty) {
return true;
}
/** If the session has never been used, it should be dropped */
if (session->last_used_usec == SESSION_NEVER_USED) {
return true;
}
/* Check for a timeout */
td = mc_tpld_take_ref (topo);
timeout = td.ptr->session_timeout_minutes;
is_loadbalanced = td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED;
mc_tpld_drop_ref (&td);
/** Load balanced topology sessions never expire */
if (is_loadbalanced) {
return false;
}
/* Prune the session if it has hit a timeout */
return _mongoc_server_session_timed_out (session, timeout);
}
static void
_tpld_destroy_and_free (void *tpl_descr)
{
mongoc_topology_description_t *td = tpl_descr;
mongoc_topology_description_destroy (td);
}
const mongoc_host_list_t **
_mongoc_apply_srv_max_hosts (const mongoc_host_list_t *hl,
const int32_t max_hosts,
size_t *const hl_array_size)
{
size_t hl_size;
size_t idx;
const mongoc_host_list_t **hl_array;
BSON_ASSERT (max_hosts >= 0);
BSON_ASSERT_PARAM (hl_array_size);
hl_size = (size_t) _mongoc_host_list_length (hl);
if (hl_size == 0) {
*hl_array_size = 0;
return NULL;
}
hl_array = bson_malloc (hl_size * sizeof (mongoc_host_list_t *));
for (idx = 0u; hl; hl = hl->next) {
hl_array[idx++] = hl;
}
if (max_hosts == 0 || /* Unlimited. */
hl_size == 1u || /* Trivial case. */
hl_size <= (size_t) max_hosts /* Already satisfies limit. */
) {
/* No random shuffle or selection required. */
*hl_array_size = hl_size;
return hl_array;
}
/* Initial DNS Seedlist Discovery Spec: If `srvMaxHosts` is greater than zero
* and less than the number of hosts in the DNS result, the driver MUST
* randomly select that many hosts and use them to populate the seedlist.
* Drivers SHOULD use the `Fisher-Yates shuffle` for randomization. */
for (idx = hl_size - 1u; idx > 0u; --idx) {
/* 0 <= swap_pos <= idx */
const size_t swap_pos =
_mongoc_rand_size_t (0u, idx, _mongoc_simple_rand_size_t);
const mongoc_host_list_t *tmp = hl_array[swap_pos];
hl_array[swap_pos] = hl_array[idx];
hl_array[idx] = tmp;
}
*hl_array_size = max_hosts;
return hl_array;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_new --
*
* Creates and returns a new topology object.
*
* Returns:
* A new topology object.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
mongoc_topology_t *
mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
{
int64_t heartbeat_default;
int64_t heartbeat;
mongoc_topology_t *topology;
mongoc_topology_description_type_t init_type;
mongoc_topology_description_t *td;
const char *srv_hostname;
const mongoc_host_list_t *hl;
mongoc_rr_data_t rr_data;
bool has_directconnection;
bool directconnection;
BSON_ASSERT (uri);
#ifndef MONGOC_ENABLE_CRYPTO
if (mongoc_uri_get_option_as_bool (
uri, MONGOC_URI_RETRYWRITES, MONGOC_DEFAULT_RETRYWRITES)) {
/* retryWrites requires sessions, which require crypto - just warn */
MONGOC_WARNING (
"retryWrites not supported without an SSL crypto library");
}
#endif
topology = (mongoc_topology_t *) bson_malloc0 (sizeof *topology);
topology->session_pool =
mongoc_server_session_pool_new_with_params (_server_session_init,
_server_session_destroy,
_server_session_should_prune,
topology);
topology->valid = false;
heartbeat_default =
single_threaded ? MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED
: MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED;
heartbeat = mongoc_uri_get_option_as_int32 (
uri, MONGOC_URI_HEARTBEATFREQUENCYMS, heartbeat_default);
topology->_shared_descr_._sptr_ = mongoc_shared_ptr_create (
bson_malloc0 (sizeof (mongoc_topology_description_t)),
_tpld_destroy_and_free);
td = mc_tpld_unsafe_get_mutable (topology);
mongoc_topology_description_init (td, heartbeat);
td->set_name = bson_strdup (mongoc_uri_get_replica_set (uri));
topology->uri = mongoc_uri_copy (uri);
topology->cse_state = MONGOC_CSE_DISABLED;
topology->single_threaded = single_threaded;
if (single_threaded) {
/* Server Selection Spec:
*
* "Single-threaded drivers MUST provide a "serverSelectionTryOnce"
* mode, in which the driver scans the topology exactly once after
* server selection fails, then either selects a server or raises an
* error.
*
* "The serverSelectionTryOnce option MUST be true by default."
*/
topology->server_selection_try_once = mongoc_uri_get_option_as_bool (
uri, MONGOC_URI_SERVERSELECTIONTRYONCE, true);
} else {
topology->server_selection_try_once = false;
}
topology->server_selection_timeout_msec = mongoc_uri_get_option_as_int32 (
topology->uri,
MONGOC_URI_SERVERSELECTIONTIMEOUTMS,
MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS);
/* tests can override this */
topology->min_heartbeat_frequency_msec =
MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS;
topology->local_threshold_msec =
mongoc_uri_get_local_threshold_option (topology->uri);
/* Total time allowed to check a server is connectTimeoutMS.
* Server Discovery And Monitoring Spec:
*
* "The socket used to check a server MUST use the same connectTimeoutMS as
* regular sockets. Multi-threaded clients SHOULD set monitoring sockets'
* socketTimeoutMS to the connectTimeoutMS."
*/
topology->connect_timeout_msec =
mongoc_uri_get_option_as_int32 (topology->uri,
MONGOC_URI_CONNECTTIMEOUTMS,
MONGOC_DEFAULT_CONNECTTIMEOUTMS);
topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF;
topology->scanner =
mongoc_topology_scanner_new (topology->uri,
_mongoc_topology_scanner_setup_err_cb,
_mongoc_topology_scanner_cb,
topology,
topology->connect_timeout_msec);
bson_mutex_init (&topology->tpld_modification_mtx);
mongoc_cond_init (&topology->cond_client);
if (single_threaded) {
/* single threaded drivers attempt speculative authentication during a
* topology scan */
topology->scanner->speculative_authentication = true;
/* single threaded clients negotiate sasl supported mechanisms during
* a topology scan. */
if (_mongoc_uri_requires_auth_negotiation (uri)) {
topology->scanner->negotiate_sasl_supported_mechs = true;
}
}
srv_hostname = mongoc_uri_get_srv_hostname (uri);
if (srv_hostname) {
char *prefixed_hostname;
memset (&rr_data, 0, sizeof (mongoc_rr_data_t));
/* Set the default resource record resolver */
topology->rr_resolver = _mongoc_client_get_rr;
/* Initialize the last scan time and interval. Even if the initial DNS
* lookup fails, SRV polling will still start when background monitoring
* starts. */
topology->srv_polling_last_scan_ms = bson_get_monotonic_time () / 1000;
topology->srv_polling_rescan_interval_ms =
MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS;
/* a mongodb+srv URI. try SRV lookup, if no error then also try TXT */
prefixed_hostname = bson_strdup_printf (
"_%s._tcp.%s", mongoc_uri_get_srv_service_name (uri), srv_hostname);
if (!topology->rr_resolver (prefixed_hostname,
MONGOC_RR_SRV,
&rr_data,
MONGOC_RR_DEFAULT_BUFFER_SIZE,
&topology->scanner->error)) {
GOTO (srv_fail);
}
/* Failure to find TXT records will not return an error (since it is only
* for options). But _mongoc_client_get_rr may return an error if
* there is more than one TXT record returned. */
if (!topology->rr_resolver (srv_hostname,
MONGOC_RR_TXT,
&rr_data,
MONGOC_RR_DEFAULT_BUFFER_SIZE,
&topology->scanner->error)) {
GOTO (srv_fail);
}
/* Use rr_data to update the topology's URI. */
if (rr_data.txt_record_opts &&
!mongoc_uri_parse_options (topology->uri,
rr_data.txt_record_opts,
true /* from_dns */,
&topology->scanner->error)) {
GOTO (srv_fail);
}
if (!mongoc_uri_init_with_srv_host_list (
topology->uri, rr_data.hosts, &topology->scanner->error)) {
GOTO (srv_fail);
}
topology->srv_polling_last_scan_ms = bson_get_monotonic_time () / 1000;
/* TODO (CDRIVER-4047) use BSON_MIN */
topology->srv_polling_rescan_interval_ms = BSON_MAX (
rr_data.min_ttl * 1000, MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS);
topology->valid = true;
srv_fail:
bson_free (rr_data.txt_record_opts);
bson_free (prefixed_hostname);
_mongoc_host_list_destroy_all (rr_data.hosts);
} else {
topology->valid = true;
}
if (!mongoc_uri_finalize (topology->uri, &topology->scanner->error)) {
topology->valid = false;
}
td->max_hosts =
mongoc_uri_get_option_as_int32 (uri, MONGOC_URI_SRVMAXHOSTS, 0);
/*
* Set topology type from URI:
* + if directConnection=true
* - whether or not we have a replicaSet name, initialize to SINGLE
* (directConnect with SRV or multiple hosts triggers a URI parse error)
* + if directConnection=false
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
* - otherwise, initialize to UNKNOWN
* + if directConnection was not specified in the URI (old behavior)
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
* - otherwise, if the seed list has a single host, initialize to SINGLE
* - everything else gets initialized to UNKNOWN
*/
has_directconnection =
mongoc_uri_has_option (uri, MONGOC_URI_DIRECTCONNECTION);
directconnection =
has_directconnection &&
mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
hl = mongoc_uri_get_hosts (topology->uri);
/* If loadBalanced is enabled, directConnection is disabled. This was
* validated in mongoc_uri_finalize_loadbalanced, which is called by
* mongoc_uri_finalize. */
if (mongoc_uri_get_option_as_bool (
topology->uri, MONGOC_URI_LOADBALANCED, false)) {
init_type = MONGOC_TOPOLOGY_LOAD_BALANCED;
if (topology->single_threaded) {
/* Cooldown only applies to server monitoring for single-threaded
* clients. In load balanced mode, the topology scanner is used to
* create connections. The cooldown period does not apply. A network
* error to a load balanced connection does not imply subsequent
* connection attempts will be to the same server and that a delay
* should occur. */
_mongoc_topology_bypass_cooldown (topology);
}
_mongoc_topology_scanner_set_loadbalanced (topology->scanner, true);
} else if (srv_hostname && !has_directconnection) {
init_type = MONGOC_TOPOLOGY_UNKNOWN;
} else if (has_directconnection) {
if (directconnection) {
init_type = MONGOC_TOPOLOGY_SINGLE;
} else {
if (mongoc_uri_get_replica_set (topology->uri)) {
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
} else {
init_type = MONGOC_TOPOLOGY_UNKNOWN;
}
}
} else if (mongoc_uri_get_replica_set (topology->uri)) {
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
} else {
if (hl && hl->next) {
init_type = MONGOC_TOPOLOGY_UNKNOWN;
} else {
init_type = MONGOC_TOPOLOGY_SINGLE;
}
}
td->type = init_type;
if (!topology->single_threaded) {
topology->server_monitors = mongoc_set_new (1, NULL, NULL);
topology->rtt_monitors = mongoc_set_new (1, NULL, NULL);
bson_mutex_init (&topology->apm_mutex);
bson_mutex_init (&topology->srv_polling_mtx);
mongoc_cond_init (&topology->srv_polling_cond);
}
if (!topology->valid) {
TRACE ("%s", "topology invalid");
/* add no nodes */
return topology;
}
{
size_t idx = 0u;
size_t hl_array_size = 0u;
uint32_t id = 0u;
const mongoc_host_list_t *const *hl_array =
_mongoc_apply_srv_max_hosts (hl, td->max_hosts, &hl_array_size);
for (idx = 0u; idx < hl_array_size; ++idx) {
const mongoc_host_list_t *const elem = hl_array[idx];
mongoc_topology_description_add_server (td, elem->host_and_port, &id);
mongoc_topology_scanner_add (topology->scanner, elem, id, false);
}
bson_free ((void *) hl_array);
}
return topology;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_set_apm_callbacks --
*
* Set Application Performance Monitoring callbacks.
*
*-------------------------------------------------------------------------
*/
void
mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology,
mongoc_topology_description_t *td,
mongoc_apm_callbacks_t *callbacks,
void *context)
{
if (callbacks) {
memcpy (&td->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
memcpy (&topology->scanner->apm_callbacks,
callbacks,
sizeof (mongoc_apm_callbacks_t));
} else {
memset (&td->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t));
memset (
&topology->scanner->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t));
}
td->apm_context = context;
topology->scanner->apm_context = context;
}
/*
*-------------------------------------------------------------------------
*
* mongoc_topology_destroy --
*
* Free the memory associated with this topology object.
*
* Returns:
* None.
*
* Side effects:
* @topology will be cleaned up.
*
*-------------------------------------------------------------------------
*/
void
mongoc_topology_destroy (mongoc_topology_t *topology)
{
if (!topology) {
return;
}
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
bson_free (topology->keyvault_db);
bson_free (topology->keyvault_coll);
mongoc_client_destroy (topology->mongocryptd_client);
mongoc_client_pool_destroy (topology->mongocryptd_client_pool);
_mongoc_crypt_destroy (topology->crypt);
bson_destroy (topology->mongocryptd_spawn_args);
bson_free (topology->mongocryptd_spawn_path);
#endif
if (!topology->single_threaded) {
_mongoc_topology_background_monitoring_stop (topology);
BSON_ASSERT (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF);
mongoc_set_destroy (topology->server_monitors);
mongoc_set_destroy (topology->rtt_monitors);
bson_mutex_destroy (&topology->apm_mutex);
bson_mutex_destroy (&topology->srv_polling_mtx);
mongoc_cond_destroy (&topology->srv_polling_cond);
}
if (topology->valid) {
/* Do not emit a topology_closed event. A topology opening event was not
* emitted. */
_mongoc_topology_description_monitor_closed (
mc_tpld_unsafe_get_const (topology));
}
mongoc_uri_destroy (topology->uri);
mongoc_shared_ptr_reset_null (&topology->_shared_descr_._sptr_);
mongoc_topology_scanner_destroy (topology->scanner);
mongoc_server_session_pool_free (topology->session_pool);
+ bson_free (topology->clientSideEncryption.autoOptions.extraOptions
+ .cryptSharedLibPath);
mongoc_cond_destroy (&topology->cond_client);
bson_mutex_destroy (&topology->tpld_modification_mtx);
+ bson_destroy (topology->encrypted_fields_map);
+
bson_free (topology);
}
/* Returns false if none of the hosts were valid. */
bool
mongoc_topology_apply_scanned_srv_hosts (mongoc_uri_t *uri,
mongoc_topology_description_t *td,
mongoc_host_list_t *hosts,
bson_error_t *error)
{
mongoc_host_list_t *host;
mongoc_host_list_t *valid_hosts = NULL;
bool had_valid_hosts = false;
/* Validate that the hosts have a matching domain.
* If validation fails, log it.
* If no valid hosts remain, do not update the topology description.
*/
LL_FOREACH (hosts, host)
{
if (mongoc_uri_validate_srv_result (uri, host->host, error)) {
_mongoc_host_list_upsert (&valid_hosts, host);
} else {
MONGOC_ERROR ("Invalid host returned by SRV: %s", host->host_and_port);
/* Continue on, there may still be valid hosts returned. */
}
}
if (valid_hosts) {
/* Reconcile with the topology description. Newly found servers will start
* getting monitored and are eligible to be used by clients. */
mongoc_topology_description_reconcile (td, valid_hosts);
had_valid_hosts = true;
} else {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NAME_RESOLUTION,
"SRV response did not contain any valid hosts");
}
_mongoc_host_list_destroy_all (valid_hosts);
return had_valid_hosts;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_should_rescan_srv --
*
* Checks whether it is valid to rescan SRV records on the topology.
* Namely, that the topology type is Sharded or Unknown, and that
* the topology URI was configured with SRV.
*
* If this returns false, caller can stop scanning SRV records
* and does not need to try again in the future.
*
* --------------------------------------------------------------------------
*/
bool
mongoc_topology_should_rescan_srv (mongoc_topology_t *topology)
{
const char *srv_hostname = mongoc_uri_get_srv_hostname (topology->uri);
mongoc_topology_description_type_t type;
if (!srv_hostname) {
/* Only rescan if we have a mongodb+srv:// URI. */
return false;
}
type = _mongoc_topology_get_type (topology);
/* Only perform rescan for sharded topology. */
return type == MONGOC_TOPOLOGY_SHARDED || type == MONGOC_TOPOLOGY_UNKNOWN;
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_rescan_srv --
*
* Queries SRV records for new hosts in a mongos cluster.
* Caller must call mongoc_topology_should_rescan_srv before calling
* to ensure preconditions are met.
*
* NOTE: This method may update the topology description.
*
* --------------------------------------------------------------------------
*/
void
mongoc_topology_rescan_srv (mongoc_topology_t *topology)
{
mongoc_rr_data_t rr_data = {0};
const char *srv_hostname;
char *prefixed_hostname = NULL;
int64_t scan_time_ms;
bool ret;
mc_shared_tpld td;
mc_tpld_modification tdmod;
BSON_ASSERT (mongoc_topology_should_rescan_srv (topology));
srv_hostname = mongoc_uri_get_srv_hostname (topology->uri);
scan_time_ms = topology->srv_polling_last_scan_ms +
topology->srv_polling_rescan_interval_ms;
if (bson_get_monotonic_time () / 1000 < scan_time_ms) {
/* Query SRV no more frequently than srv_polling_rescan_interval_ms. */
return;
}
TRACE ("%s", "Polling for SRV records");
/* Go forth and query... */
prefixed_hostname =
bson_strdup_printf ("_%s._tcp.%s",
mongoc_uri_get_srv_service_name (topology->uri),
srv_hostname);
ret = topology->rr_resolver (prefixed_hostname,
MONGOC_RR_SRV,
&rr_data,
MONGOC_RR_DEFAULT_BUFFER_SIZE,
&topology->scanner->error);
td = mc_tpld_take_ref (topology);
topology->srv_polling_last_scan_ms = bson_get_monotonic_time () / 1000;
if (!ret) {
/* Failed querying, soldier on and try again next time. */
topology->srv_polling_rescan_interval_ms = td.ptr->heartbeat_msec;
MONGOC_ERROR ("SRV polling error: %s", topology->scanner->error.message);
GOTO (done);
}
/* TODO (CDRIVER-4047) use BSON_MIN */
topology->srv_polling_rescan_interval_ms = BSON_MAX (
rr_data.min_ttl * 1000, MONGOC_TOPOLOGY_MIN_RESCAN_SRV_INTERVAL_MS);
tdmod = mc_tpld_modify_begin (topology);
if (!mongoc_topology_apply_scanned_srv_hosts (topology->uri,
tdmod.new_td,
rr_data.hosts,
&topology->scanner->error)) {
MONGOC_ERROR ("%s", topology->scanner->error.message);
/* Special case when DNS returns zero records successfully or no valid
* hosts exist.
* Leave the toplogy alone and perform another scan at the next interval
* rather than removing all records and having nothing to connect to.
* For no verified hosts drivers "MUST temporarily set
* srv_polling_rescan_interval_ms
* to heartbeatFrequencyMS until at least one verified SRV record is
* obtained."
*/
topology->srv_polling_rescan_interval_ms = td.ptr->heartbeat_msec;
}
mc_tpld_modify_commit (tdmod);
done:
mc_tpld_drop_ref (&td);
bson_free (prefixed_hostname);
_mongoc_host_list_destroy_all (rr_data.hosts);
}
/*
*--------------------------------------------------------------------------
*
* mongoc_topology_scan_once --
*
* Runs a single complete scan.
*
* NOTE: This method updates the topology description.
*
* Only runs for single threaded monitoring. (obey_cooldown is always
* true).
*
*--------------------------------------------------------------------------
*/
static void
mongoc_topology_scan_once (mongoc_topology_t *topology, bool obey_cooldown)
{
mc_tpld_modification tdmod;
if (mongoc_topology_should_rescan_srv (topology)) {
/* Prior to scanning hosts, update the list of SRV hosts, if applicable.
*/
mongoc_topology_rescan_srv (topology);
}
/* since the last scan, members may be added or removed from the topology
* description based on hello responses in connection handshakes, see
* _mongoc_topology_update_from_handshake. retire scanner nodes for removed
* members and create scanner nodes for new ones. */
tdmod = mc_tpld_modify_begin (topology);
mongoc_topology_reconcile (topology, tdmod.new_td);
mc_tpld_modify_commit (tdmod);
mongoc_topology_scanner_start (topology->scanner, obey_cooldown);
mongoc_topology_scanner_work (topology->scanner);
_mongoc_topology_scanner_finish (topology->scanner);
topology->last_scan = bson_get_monotonic_time ();
topology->stale = false;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_do_blocking_scan --
*
* Monitoring entry for single-threaded use case. Assumes the caller
* has checked that it's the right time to scan.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_do_blocking_scan (mongoc_topology_t *topology,
bson_error_t *error)
{
_mongoc_handshake_freeze ();
mongoc_topology_scan_once (topology, true /* obey cooldown */);
mongoc_topology_scanner_get_error (topology->scanner, error);
}
bool
mongoc_topology_compatible (const mongoc_topology_description_t *td,
const mongoc_read_prefs_t *read_prefs,
bson_error_t *error)
{
int64_t max_staleness_seconds;
int32_t max_wire_version;
if (td->compatibility_error.code) {
if (error) {
memcpy (error, &td->compatibility_error, sizeof (bson_error_t));
}
return false;
}
if (!read_prefs) {
/* NULL means read preference Primary */
return true;
}
max_staleness_seconds =
mongoc_read_prefs_get_max_staleness_seconds (read_prefs);
if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
max_wire_version =
mongoc_topology_description_lowest_max_wire_version (td);
if (max_wire_version < WIRE_VERSION_MAX_STALENESS) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Not all servers support maxStalenessSeconds");
return false;
}
/* shouldn't happen if we've properly enforced wire version */
if (!mongoc_topology_description_all_sds_have_write_date (td)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"Not all servers have lastWriteDate");
return false;
}
if (!_mongoc_topology_description_validate_max_staleness (
td, max_staleness_seconds, error)) {
return false;
}
}
return true;
}
static void
_mongoc_server_selection_error (const char *msg,
const bson_error_t *scanner_error,
bson_error_t *error)
{
if (scanner_error && scanner_error->code) {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"%s: %s",
msg,
scanner_error->message);
} else {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"%s",
msg);
}
}
mongoc_server_description_t *
mongoc_topology_select (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bool *must_use_primary,
bson_error_t *error)
{
uint32_t server_id = mongoc_topology_select_server_id (
topology, optype, read_prefs, must_use_primary, error);
if (server_id) {
/* new copy of the server description */
mongoc_server_description_t *ret;
mc_shared_tpld td = mc_tpld_take_ref (topology);
mongoc_server_description_t const *sd =
mongoc_topology_description_server_by_id_const (
td.ptr, server_id, error);
ret = mongoc_server_description_new_copy (sd);
mc_tpld_drop_ref (&td);
return ret;
} else {
return NULL;
}
}
/* Bypasses normal server selection behavior for a load balanced topology.
* Returns the id of the one load balancer server. Returns 0 on failure.
* Successful post-condition: On a single threaded client, a connection will
* have been established. */
static uint32_t
_mongoc_topology_select_server_id_loadbalanced (mongoc_topology_t *topology,
bson_error_t *error)
{
mongoc_server_description_t const *selected_server;
int32_t selected_server_id;
mongoc_topology_scanner_node_t *node;
bson_error_t scanner_error = {0};
mc_shared_tpld td = mc_tpld_take_ref (topology);
BSON_ASSERT (td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED);
/* Emit the opening SDAM events if they have not emitted already. */
if (!td.ptr->opened) {
mc_tpld_modification tdmod = mc_tpld_modify_begin (topology);
_mongoc_topology_description_monitor_opening (tdmod.new_td);
mc_tpld_modify_commit (tdmod);
mc_tpld_renew_ref (&td, topology);
}
selected_server =
mongoc_topology_description_select (td.ptr,
MONGOC_SS_WRITE,
NULL /* read prefs */,
NULL /* chosen read mode */,
0 /* local threshold */);
if (!selected_server) {
_mongoc_server_selection_error (
"No suitable server found in load balanced deployment", NULL, error);
selected_server_id = 0;
goto done;
}
selected_server_id = selected_server->id;
if (!topology->single_threaded) {
goto done;
}
/* If this is a single threaded topology, we must ensure that a connection is
* available to this server. Wrapping drivers make the assumption that
* successful server selection implies a connection is available. */
node =
mongoc_topology_scanner_get_node (topology->scanner, selected_server_id);
if (!node) {
_mongoc_server_selection_error (
"Topology scanner in invalid state; cannot find load balancer",
NULL,
error);
selected_server_id = 0;
goto done;
}
if (!node->stream) {
TRACE ("%s",
"Server selection performing scan since no connection has "
"been established");
_mongoc_topology_do_blocking_scan (topology, &scanner_error);
}
if (!node->stream) {
/* Use the same error domain / code that is returned in mongoc-cluster.c
* when fetching a stream fails. */
if (scanner_error.code) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"Could not establish stream for node %s: %s",
node->host.host_and_port,
scanner_error.message);
} else {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_NOT_ESTABLISHED,
"Could not establish stream for node %s",
node->host.host_and_port);
}
selected_server_id = 0;
goto done;
}
done:
mc_tpld_drop_ref (&td);
return selected_server_id;
}
uint32_t
mongoc_topology_select_server_id (mongoc_topology_t *topology,
mongoc_ss_optype_t optype,
const mongoc_read_prefs_t *read_prefs,
bool *must_use_primary,
bson_error_t *error)
{
static const char *timeout_msg =
"No suitable servers found: `serverSelectionTimeoutMS` expired";
mongoc_topology_scanner_t *ts;
int r;
int64_t local_threshold_ms;
const mongoc_server_description_t *selected_server = NULL;
bool try_once;
int64_t sleep_usec;
bool tried_once;
bson_error_t scanner_error = {0};
int64_t heartbeat_msec;
uint32_t server_id;
mc_shared_tpld td = mc_tpld_take_ref (topology);
/* These names come from the Server Selection Spec pseudocode */
int64_t loop_start; /* when we entered this function */
int64_t loop_end; /* when we last completed a loop (single-threaded) */
int64_t scan_ready; /* the soonest we can do a blocking scan */
int64_t next_update; /* the latest we must do a blocking scan */
int64_t expire_at; /* when server selection timeout expires */
BSON_ASSERT (topology);
ts = topology->scanner;
if (!mongoc_topology_scanner_valid (ts)) {
if (error) {
mongoc_topology_scanner_get_error (ts, error);
error->domain = MONGOC_ERROR_SERVER_SELECTION;
error->code = MONGOC_ERROR_SERVER_SELECTION_FAILURE;
}
server_id = 0;
goto done;
}
if (td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED) {
server_id =
_mongoc_topology_select_server_id_loadbalanced (topology, error);
goto done;
}
heartbeat_msec = td.ptr->heartbeat_msec;
local_threshold_ms = topology->local_threshold_msec;
try_once = topology->server_selection_try_once;
loop_start = loop_end = bson_get_monotonic_time ();
expire_at =
loop_start + ((int64_t) topology->server_selection_timeout_msec * 1000);
if (topology->single_threaded) {
if (!td.ptr->opened) {
mc_tpld_modification tdmod = mc_tpld_modify_begin (topology);
_mongoc_topology_description_monitor_opening (tdmod.new_td);
mc_tpld_modify_commit (tdmod);
mc_tpld_renew_ref (&td, topology);
}
tried_once = false;
next_update = topology->last_scan + heartbeat_msec * 1000;
if (next_update < loop_start) {
/* we must scan now */
topology->stale = true;
}
/* until we find a server or time out */
for (;;) {
if (topology->stale) {
/* how soon are we allowed to scan? */
scan_ready = topology->last_scan +
topology->min_heartbeat_frequency_msec * 1000;
if (scan_ready > expire_at && !try_once) {
/* selection timeout will expire before min heartbeat passes */
_mongoc_server_selection_error (
"No suitable servers found: "
"`serverselectiontimeoutms` timed out",
&scanner_error,
error);
server_id = 0;
goto done;
}
sleep_usec = scan_ready - loop_end;
if (sleep_usec > 0) {
if (try_once &&
mongoc_topology_scanner_in_cooldown (ts, scan_ready)) {
_mongoc_server_selection_error (
"No servers yet eligible for rescan",
&scanner_error,
error);
server_id = 0;
goto done;
}
_mongoc_usleep (sleep_usec);
}
/* takes up to connectTimeoutMS. sets "last_scan", clears "stale" */
_mongoc_topology_do_blocking_scan (topology, &scanner_error);
loop_end = topology->last_scan;
tried_once = true;
}
/* Topology may have just been updated by a scan. */
mc_tpld_renew_ref (&td, topology);
if (!mongoc_topology_compatible (td.ptr, read_prefs, error)) {
server_id = 0;
goto done;
}
selected_server = mongoc_topology_description_select (
td.ptr, optype, read_prefs, must_use_primary, local_threshold_ms);
if (selected_server) {
server_id = selected_server->id;
goto done;
}
topology->stale = true;
if (try_once) {
if (tried_once) {
_mongoc_server_selection_error (
"No suitable servers found (`serverSelectionTryOnce` set)",
&scanner_error,
error);
server_id = 0;
goto done;
}
} else {
loop_end = bson_get_monotonic_time ();
if (loop_end > expire_at) {
/* no time left in server_selection_timeout_msec */
_mongoc_server_selection_error (
timeout_msg, &scanner_error, error);
server_id = 0;
goto done;
}
}
}
}
/* With background thread */
/* we break out when we've found a server or timed out */
for (;;) {
/* Topology may have been updated on a previous loop iteration */
mc_tpld_renew_ref (&td, topology);
if (!mongoc_topology_compatible (td.ptr, read_prefs, error)) {
server_id = 0;
goto done;
}
selected_server = mongoc_topology_description_select (
td.ptr, optype, read_prefs, must_use_primary, local_threshold_ms);
if (selected_server) {
server_id = selected_server->id;
goto done;
}
/* tlpd_modification_mtx is used to synchronize updates to the topology.
* Take that lock to do a wait on the topology to become up-to-date and
* synchronize with a condition variable that will be signalled upon
* topology changes. */
bson_mutex_lock (&topology->tpld_modification_mtx);
/* Now that we have the lock, check again, since a scan may have
* occurred while we were waiting on the lock. */
mc_tpld_renew_ref (&td, topology);
selected_server = mongoc_topology_description_select (
td.ptr, optype, read_prefs, must_use_primary, local_threshold_ms);
if (selected_server) {
server_id = selected_server->id;
bson_mutex_unlock (&topology->tpld_modification_mtx);
goto done;
}
/* Still nothing. Request that the scanner do a scan now. */
TRACE (
"server selection requesting an immediate scan, want %s",
_mongoc_read_mode_as_str (mongoc_read_prefs_get_mode (read_prefs)));
_mongoc_topology_request_scan (topology);
TRACE ("server selection about to wait for %" PRId64 "ms",
(expire_at - loop_start) / 1000);
r = mongoc_cond_timedwait (&topology->cond_client,
&topology->tpld_modification_mtx,
(expire_at - loop_start) / 1000);
TRACE ("%s", "server selection awake");
/* Refresh our topology handle */
mc_tpld_renew_ref (&td, topology);
_topology_collect_errors (td.ptr, &scanner_error);
bson_mutex_unlock (&topology->tpld_modification_mtx);
#ifdef _WIN32
if (r == WSAETIMEDOUT) {
#else
if (r == ETIMEDOUT) {
#endif
/* handle timeouts */
_mongoc_server_selection_error (timeout_msg, &scanner_error, error);
server_id = 0;
goto done;
} else if (r) {
bson_set_error (error,
MONGOC_ERROR_SERVER_SELECTION,
MONGOC_ERROR_SERVER_SELECTION_FAILURE,
"Unknown error '%d' received while waiting on "
"thread condition",
r);
server_id = 0;
goto done;
}
loop_start = bson_get_monotonic_time ();
if (loop_start > expire_at) {
_mongoc_server_selection_error (timeout_msg, &scanner_error, error);
server_id = 0;
goto done;
}
}
done:
mc_tpld_drop_ref (&td);
return server_id;
}
mongoc_host_list_t *
_mongoc_topology_host_by_id (const mongoc_topology_description_t *td,
uint32_t id,
bson_error_t *error)
{
mongoc_server_description_t const *sd;
mongoc_host_list_t *host = NULL;
/* not a copy - direct pointer into topology description data */
sd = mongoc_topology_description_server_by_id_const (td, id, error);
if (sd) {
host = bson_malloc0 (sizeof (mongoc_host_list_t));
memcpy (host, &sd->host, sizeof (mongoc_host_list_t));
}
return host;
}
void
_mongoc_topology_request_scan (mongoc_topology_t *topology)
{
_mongoc_topology_background_monitoring_request_scan (topology);
}
bool
_mongoc_topology_update_from_handshake (mongoc_topology_t *topology,
const mongoc_server_description_t *sd)
{
bool has_server;
mc_tpld_modification tdmod;
BSON_ASSERT (topology);
BSON_ASSERT (sd);
BSON_ASSERT (!topology->single_threaded);
if (_mongoc_topology_get_type (topology) == MONGOC_TOPOLOGY_LOAD_BALANCED) {
/* In load balanced mode, scanning is only for connection establishment.
* It must not modify the topology description. */
return true;
}
tdmod = mc_tpld_modify_begin (topology);
/* return false if server was removed from topology */
has_server = _mongoc_topology_update_no_lock (sd->id,
&sd->last_hello_response,
sd->round_trip_time_msec,
tdmod.new_td,
NULL);
/* if pooled, wake threads waiting in mongoc_topology_server_by_id */
mongoc_cond_broadcast (&topology->cond_client);
/* Update background monitoring. */
_mongoc_topology_background_monitoring_reconcile (topology, tdmod.new_td);
mc_tpld_modify_commit (tdmod);
return has_server;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_update_last_used --
*
* Internal function. In single-threaded mode only, track when the socket
* to a particular server was last used. This is required for
* mongoc_cluster_check_interval to know when a socket has been idle.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_update_last_used (mongoc_topology_t *topology,
uint32_t server_id)
{
mongoc_topology_scanner_node_t *node;
if (!topology->single_threaded) {
return;
}
node = mongoc_topology_scanner_get_node (topology->scanner, server_id);
if (node) {
node->last_used = bson_get_monotonic_time ();
}
}
mongoc_topology_description_type_t
_mongoc_topology_get_type (const mongoc_topology_t *topology)
{
mc_shared_tpld td = mc_tpld_take_ref (topology);
mongoc_topology_description_type_t td_type = td.ptr->type;
mc_tpld_drop_ref (&td);
return td_type;
}
bool
_mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname)
{
bool ret = false;
if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF) {
ret = _mongoc_topology_scanner_set_appname (topology->scanner, appname);
} else {
MONGOC_ERROR ("Cannot set appname after handshake initiated");
}
return ret;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_update_cluster_time --
*
* Internal function. If the server reply has a later $clusterTime than
* any seen before, update the topology's clusterTime. See the Driver
* Sessions Spec.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_update_cluster_time (mongoc_topology_t *topology,
const bson_t *reply)
{
bson_iter_t iter;
bson_iter_t child;
const uint8_t *data;
uint32_t size;
bson_t cluster_time;
mc_shared_tpld td;
if (!reply || !bson_iter_init_find (&iter, reply, "$clusterTime")) {
return;
}
if (!BSON_ITER_HOLDS_DOCUMENT (&iter) ||
!bson_iter_recurse (&iter, &child)) {
MONGOC_ERROR ("Can't parse $clusterTime");
return;
}
bson_iter_document (&iter, &size, &data);
BSON_ASSERT (bson_init_static (&cluster_time, data, (size_t) size));
td = mc_tpld_take_ref (topology);
/* This func is called frequently and repeatedly, but the cluster time itself
* is infrequently updated. mc_tpld_modify_begin() is very expensive, so we
* only want to actually call it if we anticipate performing an update to the
* cluster time.
*
* Check that the cluster time has actually changed from what we have on
* record before opening a topology modification to update it. */
if (bson_empty (&td.ptr->cluster_time) ||
_mongoc_cluster_time_greater (&cluster_time, &td.ptr->cluster_time)) {
mc_tpld_modification tdmod = mc_tpld_modify_begin (topology);
/* Check again if we need to update the cluster time, since it may have
* been updated behind our back. */
if (bson_empty (&tdmod.new_td->cluster_time) ||
_mongoc_cluster_time_greater (&cluster_time,
&tdmod.new_td->cluster_time)) {
bson_destroy (&tdmod.new_td->cluster_time);
bson_copy_to (&cluster_time, &tdmod.new_td->cluster_time);
_mongoc_topology_scanner_set_cluster_time (
topology->scanner, &tdmod.new_td->cluster_time);
mc_tpld_modify_commit (tdmod);
} else {
mc_tpld_modify_drop (tdmod);
}
}
mc_tpld_drop_ref (&td);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_pop_server_session --
*
* Internal function. Get a server session from the pool or create
* one. On error, return NULL and fill out @error.
*
*--------------------------------------------------------------------------
*/
mongoc_server_session_t *
_mongoc_topology_pop_server_session (mongoc_topology_t *topology,
bson_error_t *error)
{
int64_t timeout;
mongoc_server_session_t *ss = NULL;
bool loadbalanced;
mc_shared_tpld td = mc_tpld_take_ref (topology);
ENTRY;
timeout = td.ptr->session_timeout_minutes;
loadbalanced = td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED;
/* When the topology type is LoadBalanced, sessions are always supported. */
if (!loadbalanced && timeout == MONGOC_NO_SESSIONS) {
/* if needed, connect and check for session timeout again */
if (!mongoc_topology_description_has_data_node (td.ptr)) {
if (!mongoc_topology_select_server_id (topology,
MONGOC_SS_READ,
NULL /* read prefs */,
NULL /* chosen read mode */,
error)) {
ss = NULL;
goto done;
}
/* Topology may have been updated by a scan */
mc_tpld_renew_ref (&td, topology);
timeout = td.ptr->session_timeout_minutes;
}
if (timeout == MONGOC_NO_SESSIONS) {
bson_set_error (error,
MONGOC_ERROR_CLIENT,
MONGOC_ERROR_CLIENT_SESSION_FAILURE,
"Server does not support sessions");
ss = NULL;
goto done;
}
}
ss = mongoc_server_session_pool_get (topology->session_pool, error);
done:
mc_tpld_drop_ref (&td);
RETURN (ss);
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_push_server_session --
*
* Internal function. Return a server session to the pool.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_topology_push_server_session (mongoc_topology_t *topology,
mongoc_server_session_t *server_session)
{
ENTRY;
/**
* ! note:
* At time of writing, this diverges from the spec:
* https://github.com/mongodb/specifications/blob/df6be82f865e9b72444488fd62ae1eb5fca18569/source/sessions/driver-sessions.rst#algorithm-to-return-a-serversession-instance-to-the-server-session-pool
*
* The spec notes that before returning a session, we should first inspect
* the back of the pool for expired items and delete them. In this case, we
* simply return the item to the top of the pool and leave the remainder
* unchanged.
*
* The next pop operation that encounters an expired session will clear the
* entire session pool, thus preventing unbounded growth of the pool.
*/
mongoc_server_session_pool_return (server_session);
EXIT;
}
/*
*--------------------------------------------------------------------------
*
* _mongoc_topology_end_sessions_cmd --
*
* Internal function. End up to 10,000 server sessions. @cmd is an
* uninitialized document. Sessions are destroyed as their ids are
* appended to @cmd.
*
* Driver Sessions Spec: "If the number of sessions is very large the
* endSessions command SHOULD be run multiple times to end 10,000
* sessions at a time (in order to avoid creating excessively large
* commands)."
*
* Returns:
* true if any session ids were appended to @cmd.
*
*--------------------------------------------------------------------------
*/
bool
_mongoc_topology_end_sessions_cmd (mongoc_topology_t *topology, bson_t *cmd)
{
bson_t ar;
/* Only end up to 10'000 sessions */
const int ENDED_SESSION_PRUNING_LIMIT = 10000;
int i = 0;
mongoc_server_session_t *ss =
mongoc_server_session_pool_get_existing (topology->session_pool);
bson_init (cmd);
BSON_APPEND_ARRAY_BEGIN (cmd, "endSessions", &ar);
for (; i < ENDED_SESSION_PRUNING_LIMIT && ss != NULL;
++i,
ss = mongoc_server_session_pool_get_existing (topology->session_pool)) {
char buf[16];
const char *key;
bson_uint32_to_string (i, &key, buf, sizeof buf);
BSON_APPEND_DOCUMENT (&ar, key, &ss->lsid);
mongoc_server_session_pool_drop (ss);
}
if (ss) {
/* We deleted at least 10'000 sessions, so we will need to return the
* final session that we didn't drop */
mongoc_server_session_pool_return (ss);
}
bson_append_array_end (cmd, &ar);
return i > 0;
}
void
_mongoc_topology_dup_handshake_cmd (const mongoc_topology_t *topology,
bson_t *copy_into)
{
_mongoc_topology_scanner_dup_handshake_cmd (topology->scanner, copy_into);
}
void
_mongoc_topology_bypass_cooldown (mongoc_topology_t *topology)
{
BSON_ASSERT (topology->single_threaded);
topology->scanner->bypass_cooldown = true;
}
static void
_find_topology_version (const bson_t *reply, bson_t *topology_version)
{
bson_iter_t iter;
const uint8_t *bytes;
uint32_t len;
if (!bson_iter_init_find (&iter, reply, "topologyVersion") ||
!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
bson_init (topology_version);
return;
}
bson_iter_document (&iter, &len, &bytes);
bson_init_static (topology_version, bytes, len);
}
static bool
_handle_sdam_app_error_command (mongoc_topology_t *topology,
const mongoc_topology_description_t *td,
uint32_t server_id,
uint32_t generation,
const bson_oid_t *service_id,
const mongoc_server_description_t *sd,
uint32_t max_wire_version,
const bson_t *reply)
{
bson_error_t cmd_error;
bson_t incoming_topology_version;
bool pool_cleared = false;
bool should_clear_pool = false;
mc_tpld_modification tdmod;
mongoc_server_description_t *mut_sd;
if (_mongoc_cmd_check_ok_no_wce (
reply, MONGOC_ERROR_API_VERSION_2, &cmd_error)) {
/* No error. */
return false;
}
if (!_mongoc_error_is_state_change (&cmd_error)) {
/* Not a "not primary" or "node is recovering" error. */
return false;
}
/* Check if the error is "stale", i.e. the topologyVersion refers to an
* older
* version of the server than we have stored in the topology description.
*/
_find_topology_version (reply, &incoming_topology_version);
if (mongoc_server_description_topology_version_cmp (
&sd->topology_version, &incoming_topology_version) >= 0) {
/* The server description is greater or equal, ignore the error. */
bson_destroy (&incoming_topology_version);
return false;
}
should_clear_pool = (max_wire_version <= WIRE_VERSION_4_0 ||
_mongoc_error_is_shutdown (&cmd_error));
tdmod = mc_tpld_modify_begin (topology);
/* Get the server handle again, which might have been removed. */
mut_sd =
mongoc_topology_description_server_by_id (tdmod.new_td, server_id, NULL);
if (!mut_sd) {
/* Server was already removed/invalidated */
mc_tpld_modify_drop (tdmod);
bson_destroy (&incoming_topology_version);
return false;
}
/* Check the topology version a second time, now that we have an exclusive
* lock on the latest topology description. */
if (mongoc_server_description_topology_version_cmp (
&mut_sd->topology_version, &incoming_topology_version) >= 0) {
/* The server description is greater or equal, ignore the error. */
mc_tpld_modify_drop (tdmod);
bson_destroy (&incoming_topology_version);
return false;
}
if (generation < mc_tpl_sd_get_generation (mut_sd, service_id)) {
/* Our view of the server description is stale. Ignore it. */
mc_tpld_modify_drop (tdmod);
bson_destroy (&incoming_topology_version);
return false;
}
/* Overwrite the topology version. */
mongoc_server_description_set_topology_version (mut_sd,
&incoming_topology_version);
/* SDAM: When handling a "not primary" or "node is recovering" error, the
* client MUST clear the server's connection pool if and only if the error
* is "node is shutting down" or the error originated from server version
* < 4.2.
*/
if (should_clear_pool) {
_mongoc_topology_description_clear_connection_pool (
tdmod.new_td, server_id, service_id);
pool_cleared = true;
}
/*
* SDAM: When the client sees a "not primary" or "node is recovering"
* error and the error's topologyVersion is strictly greater than the
* current ServerDescription's topologyVersion it MUST replace the
* server's description with a ServerDescription of type Unknown.
*/
mongoc_topology_description_invalidate_server (
tdmod.new_td, server_id, &cmd_error);
if (topology->single_threaded) {
/* SDAM: For single-threaded clients, in the case of a "not primary" or
* "node is shutting down" error, the client MUST mark the topology as
* "stale"
*/
if (_mongoc_error_is_not_primary (&cmd_error)) {
topology->stale = true;
}
} else {
/* SDAM Spec: "Multi-threaded and asynchronous clients MUST request an
* immediate check of the server."
* Instead of requesting a check of the one server, request a scan
* to all servers (to find the new primary).
*/
_mongoc_topology_request_scan (topology);
}
mc_tpld_modify_commit (tdmod);
bson_destroy (&incoming_topology_version);
return pool_cleared;
}
bool
_mongoc_topology_handle_app_error (mongoc_topology_t *topology,
uint32_t server_id,
bool handshake_complete,
_mongoc_sdam_app_error_type_t type,
const bson_t *reply,
const bson_error_t *why,
uint32_t max_wire_version,
uint32_t generation,
const bson_oid_t *service_id)
{
bson_error_t server_selection_error;
const mongoc_server_description_t *sd;
bool cleared_pool = false;
mc_shared_tpld td = mc_tpld_take_ref (topology);
/* Start by checking every condition in which we should ignore the error */
sd = mongoc_topology_description_server_by_id_const (
td.ptr, server_id, &server_selection_error);
if (!sd) {
/* The server was already removed from the topology. Ignore error. */
goto ignore_error;
}
/* When establishing a new connection in load balanced mode, drivers MUST NOT
* perform SDAM error handling for any errors that occur before the MongoDB
* Handshake. */
if (td.ptr->type == MONGOC_TOPOLOGY_LOAD_BALANCED && !handshake_complete) {
goto ignore_error;
}
if (generation < mc_tpl_sd_get_generation (sd, service_id)) {
/* This is a stale connection. Ignore. */
goto ignore_error;
}
if (type == MONGOC_SDAM_APP_ERROR_TIMEOUT && handshake_complete) {
/* Timeout errors after handshake are ok, do nothing. */
goto ignore_error;
}
/* Do something with the error */
if (type == MONGOC_SDAM_APP_ERROR_COMMAND) {
cleared_pool = _handle_sdam_app_error_command (topology,
td.ptr,
server_id,
generation,
service_id,
sd,
max_wire_version,
reply);
} else {
/* Invalidate the server that saw the error. */
mc_tpld_modification tdmod = mc_tpld_modify_begin (topology);
sd = mongoc_topology_description_server_by_id_const (
tdmod.new_td, server_id, NULL);
/* Check if the server has already been invalidated */
if (!sd || generation < mc_tpl_sd_get_generation (sd, service_id)) {
mc_tpld_modify_drop (tdmod);
goto ignore_error;
}
/* Mark server as unknown. */
mongoc_topology_description_invalidate_server (
tdmod.new_td, server_id, why);
/* Clear the connection pool */
_mongoc_topology_description_clear_connection_pool (
tdmod.new_td, server_id, service_id);
cleared_pool = true;
if (!topology->single_threaded) {
_mongoc_topology_background_monitoring_cancel_check (topology,
server_id);
}
mc_tpld_modify_commit (tdmod);
}
ignore_error: /* <- Jump taken if we should ignore the error */
mc_tpld_drop_ref (&td);
return cleared_pool;
}
/* Called from application threads
* Caller must hold topology lock.
* For single-threaded monitoring, the topology scanner may include errors for
* servers that were removed from the topology.
*/
static void
_topology_collect_errors (const mongoc_topology_description_t *td,
bson_error_t *error_out)
{
const mongoc_server_description_t *server_description;
bson_string_t *error_message;
int i;
memset (error_out, 0, sizeof (bson_error_t));
error_message = bson_string_new ("");
for (i = 0; i < mc_tpld_servers_const (td)->items_len; i++) {
const bson_error_t *error;
server_description = mc_tpld_servers_const (td)->items[i].item;
error = &server_description->error;
if (error->code) {
if (error_message->len > 0) {
bson_string_append_c (error_message, ' ');
}
bson_string_append_printf (
error_message, "[%s]", server_description->error.message);
/* The last error's code and domain wins. */
error_out->code = error->code;
error_out->domain = error->domain;
}
}
bson_strncpy ((char *) &error_out->message,
error_message->str,
sizeof (error_out->message));
bson_string_free (error_message, true);
}
void
_mongoc_topology_set_rr_resolver (mongoc_topology_t *topology,
_mongoc_rr_resolver_fn rr_resolver)
{
topology->rr_resolver = rr_resolver;
}
void
_mongoc_topology_set_srv_polling_rescan_interval_ms (
mongoc_topology_t *topology, int64_t val)
{
topology->srv_polling_rescan_interval_ms = val;
}
uint32_t
_mongoc_topology_get_connection_pool_generation (
const mongoc_topology_description_t *td,
uint32_t server_id,
const bson_oid_t *service_id)
{
const mongoc_server_description_t *sd;
bson_error_t error;
BSON_ASSERT (service_id);
sd = mongoc_topology_description_server_by_id_const (td, server_id, &error);
if (!sd) {
/* Server removed, ignore and ignore error. */
return 0;
}
return mc_tpl_sd_get_generation (sd, service_id);
}
mc_tpld_modification
mc_tpld_modify_begin (mongoc_topology_t *tpl)
{
mc_shared_tpld prev_td;
mongoc_topology_description_t *new_td;
bson_mutex_lock (&tpl->tpld_modification_mtx);
prev_td = mc_tpld_take_ref (tpl);
new_td = mongoc_topology_description_new_copy (prev_td.ptr),
mc_tpld_drop_ref (&prev_td);
return (mc_tpld_modification){
.new_td = new_td,
.topology = tpl,
};
}
void
mc_tpld_modify_commit (mc_tpld_modification mod)
{
mongoc_shared_ptr old_sptr =
mongoc_shared_ptr_copy (mod.topology->_shared_descr_._sptr_);
mongoc_shared_ptr new_sptr =
mongoc_shared_ptr_create (mod.new_td, _tpld_destroy_and_free);
mongoc_atomic_shared_ptr_store (&mod.topology->_shared_descr_._sptr_,
new_sptr);
bson_mutex_unlock (&mod.topology->tpld_modification_mtx);
mongoc_shared_ptr_reset_null (&new_sptr);
mongoc_shared_ptr_reset_null (&old_sptr);
}
void
mc_tpld_modify_drop (mc_tpld_modification mod)
{
bson_mutex_unlock (&mod.topology->tpld_modification_mtx);
mongoc_topology_description_destroy (mod.new_td);
}
+
+bool
+mongoc_topology_uses_server_api (const mongoc_topology_t *topology)
+{
+ return mongoc_topology_scanner_uses_server_api (topology->scanner);
+}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
similarity index 96%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
index 98d2257a..9bef65a6 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h
@@ -1,239 +1,246 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_UTIL_PRIVATE_H
#define MONGOC_UTIL_PRIVATE_H
#include <bson/bson.h>
#include "mongoc.h"
#ifdef BSON_HAVE_STRINGS_H
#include <strings.h>
#endif
#include <stdint.h>
/* string comparison functions for Windows */
#ifdef _WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#endif
#if BSON_GNUC_CHECK_VERSION(4, 6)
#define BEGIN_IGNORE_DEPRECATIONS \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define END_IGNORE_DEPRECATIONS _Pragma ("GCC diagnostic pop")
#elif defined(__clang__)
#define BEGIN_IGNORE_DEPRECATIONS \
_Pragma ("clang diagnostic push") \
_Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"")
#define END_IGNORE_DEPRECATIONS _Pragma ("clang diagnostic pop")
#else
#define BEGIN_IGNORE_DEPRECATIONS
#define END_IGNORE_DEPRECATIONS
#endif
#ifndef _WIN32
#define MONGOC_PRINTF_FORMAT(a, b) __attribute__ ((format (__printf__, a, b)))
#else
#define MONGOC_PRINTF_FORMAT(a, b) /* no-op */
#endif
#define COALESCE(x, y) ((x == 0) ? (y) : (x))
/* Helper macros for stringifying things */
#define MONGOC_STR(s) #s
#define MONGOC_EVALUATE_STR(s) MONGOC_STR (s)
BSON_BEGIN_DECLS
extern const bson_validate_flags_t _mongoc_default_insert_vflags;
extern const bson_validate_flags_t _mongoc_default_replace_vflags;
extern const bson_validate_flags_t _mongoc_default_update_vflags;
int
_mongoc_rand_simple (unsigned int *seed);
char *
_mongoc_hex_md5 (const char *input);
void
_mongoc_usleep (int64_t usec);
/* Get the current time as a number of milliseconds since the Unix Epoch. */
int64_t
_mongoc_get_real_time_ms (void);
const char *
_mongoc_get_command_name (const bson_t *command);
const char *
_mongoc_get_documents_field_name (const char *command_name);
bool
_mongoc_lookup_bool (const bson_t *bson, const char *key, bool default_value);
/* Returns a database name that the caller must free. */
char *
_mongoc_get_db_name (const char *ns);
void
_mongoc_bson_init_if_set (bson_t *bson);
const char *
_mongoc_bson_type_to_str (bson_type_t t);
const char *
_mongoc_wire_version_to_server_version (int32_t version);
bool
_mongoc_get_server_id_from_opts (const bson_t *opts,
mongoc_error_domain_t domain,
mongoc_error_code_t code,
uint32_t *server_id,
bson_error_t *error);
bool
_mongoc_validate_new_document (const bson_t *insert,
bson_validate_flags_t vflags,
bson_error_t *error);
bool
_mongoc_validate_replace (const bson_t *insert,
bson_validate_flags_t vflags,
bson_error_t *error);
bool
_mongoc_validate_update (const bson_t *update,
bson_validate_flags_t vflags,
bson_error_t *error);
void
mongoc_lowercase (const char *src, char *buf /* OUT */);
bool
mongoc_parse_port (uint16_t *port, const char *str);
void
_mongoc_bson_array_add_label (bson_t *bson, const char *label);
void
_mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst);
void
_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs,
bson_t *reply);
bool
_mongoc_document_is_pipeline (const bson_t *document);
/*
*--------------------------------------------------------------------------
*
* _mongoc_getenv --
*
* Get the value of an environment variable.
*
* Returns:
* A string you must bson_free, or NULL if the variable is not set.
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
char *
_mongoc_getenv (const char *name);
/* Returns a uniformly-distributed uint32_t generated using
* `_mongoc_rand_bytes()` if a source of cryptographic randomness is available
* (defined only if `MONGOC_ENABLE_CRYPTO` is defined).
*/
uint32_t
_mongoc_crypto_rand_uint32_t (void);
/* Returns a uniformly-distributed uint64_t generated using
* `_mongoc_rand_bytes()` if a source of cryptographic randomness is available
* (defined only if `MONGOC_ENABLE_CRYPTO` is defined).
*/
uint64_t
_mongoc_crypto_rand_uint64_t (void);
/* Returns a uniformly-distributed size_t generated using
* `_mongoc_rand_bytes()` if a source of cryptographic randomness is available
* (defined only if `MONGOC_ENABLE_CRYPTO` is defined).
*/
size_t
_mongoc_crypto_rand_size_t (void);
/* Returns a uniformly-distributed random uint32_t generated using `rand()`.
* Note: may invoke `srand()`, which may not be thread-safe. Concurrent calls to
* `_mongoc_simple_rand_*()` functions, however, is thread-safe. */
uint32_t
_mongoc_simple_rand_uint32_t (void);
/* Returns a uniformly-distributed random uint64_t generated using `rand()`.
* Note: may invoke `srand()`, which may not be thread-safe. Concurrent calls to
* `_mongoc_simple_rand_*()` functions, however, is thread-safe. */
uint64_t
_mongoc_simple_rand_uint64_t (void);
/* Returns a uniformly-distributed random size_t generated using `rand()`.
* Note: may invoke `srand()`, which may not be thread-safe. Concurrent calls to
* `_mongoc_simple_rand_*()` functions, however, is thread-safe. */
size_t
_mongoc_simple_rand_size_t (void);
/* Returns a uniformly-distributed random integer in the range [min, max].
*
* The size of the range [min, max] must not equal the size of the representable
* range of uint32_t (`min == 0 && max == UINT32_MAX` must not be true).
*
* The generator `rand` must return a random integer uniformly distributed in
* the full range of representable values of uint32_t.
*/
uint32_t
_mongoc_rand_uint32_t (uint32_t min, uint32_t max, uint32_t (*rand) (void));
/* Returns a uniformly-distributed random integer in the range [min, max].
*
* The size of the range [min, max] must not equal the size of the representable
* range of uint64_t (`min == 0 && max == UINT64_MAX` must not be true).
*
* The generator `rand` must return a random integer uniformly distributed in
* the full range of representable values of uint64_t.
*/
uint64_t
_mongoc_rand_uint64_t (uint64_t min, uint64_t max, uint64_t (*rand) (void));
/* Returns a uniformly-distributed random integer in the range [min, max].
*
* The size of the range [min, max] must not equal the size of the representable
* range of size_t (`min == 0 && max == SIZE_MAX` must not be true).
*
* The generator `rand` must return a random integer uniformly distributed in
* the full range of representable values of size_t.
*/
size_t
_mongoc_rand_size_t (size_t min, size_t max, size_t (*rand) (void));
+/* _mongoc_iter_document_as_bson attempts to read the document from @iter into
+ * @bson. */
+bool
+_mongoc_iter_document_as_bson (const bson_iter_t *iter,
+ bson_t *bson,
+ bson_error_t *error);
+
BSON_END_DECLS
#endif /* MONGOC_UTIL_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
similarity index 94%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
index e68678df..61227e39 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c
@@ -1,865 +1,899 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef _WIN32
#define _CRT_RAND_S
#endif
#include <string.h>
#include "bson/bson.h"
#include "common-md5-private.h"
#include "common-thread-private.h"
#include "mongoc-rand-private.h"
#include "mongoc-util-private.h"
#include "mongoc-client.h"
#include "mongoc-client-session-private.h"
#include "mongoc-trace-private.h"
const bson_validate_flags_t _mongoc_default_insert_vflags =
BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL |
BSON_VALIDATE_EMPTY_KEYS;
const bson_validate_flags_t _mongoc_default_replace_vflags =
BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL |
BSON_VALIDATE_EMPTY_KEYS;
const bson_validate_flags_t _mongoc_default_update_vflags =
BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL |
BSON_VALIDATE_EMPTY_KEYS;
int
_mongoc_rand_simple (unsigned int *seed)
{
#ifdef _WIN32
/* ignore the seed */
unsigned int ret = 0;
errno_t err;
err = rand_s (&ret);
if (0 != err) {
MONGOC_ERROR ("rand_s failed: %s", strerror (err));
}
return (int) ret;
#else
return rand_r (seed);
#endif
}
char *
_mongoc_hex_md5 (const char *input)
{
uint8_t digest[16];
bson_md5_t md5;
char digest_str[33];
int i;
- COMMON_PREFIX (_bson_md5_init (&md5));
- COMMON_PREFIX (_bson_md5_append (
- &md5, (const uint8_t *) input, (uint32_t) strlen (input)));
- COMMON_PREFIX (_bson_md5_finish (&md5, digest));
+ mcommon_md5_init (&md5);
+ mcommon_md5_append (
+ &md5, (const uint8_t *) input, (uint32_t) strlen (input));
+ mcommon_md5_finish (&md5, digest);
for (i = 0; i < sizeof digest; i++) {
bson_snprintf (&digest_str[i * 2], 3, "%02x", digest[i]);
}
digest_str[sizeof digest_str - 1] = '\0';
return bson_strdup (digest_str);
}
void
_mongoc_usleep (int64_t usec)
{
#ifdef _WIN32
LARGE_INTEGER ft;
HANDLE timer;
BSON_ASSERT (usec >= 0);
ft.QuadPart = -(10 * usec);
timer = CreateWaitableTimer (NULL, true, NULL);
SetWaitableTimer (timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject (timer, INFINITE);
CloseHandle (timer);
#else
BSON_ASSERT (usec >= 0);
usleep ((useconds_t) usec);
#endif
}
int64_t
_mongoc_get_real_time_ms (void)
{
struct timeval tv;
const bool rc = bson_gettimeofday (&tv);
if (rc != 0) {
return -1;
}
return tv.tv_sec * (int64_t) 1000 + tv.tv_usec / (int64_t) 1000;
}
const char *
_mongoc_get_command_name (const bson_t *command)
{
bson_iter_t iter;
const char *name;
bson_iter_t child;
const char *wrapper_name = NULL;
BSON_ASSERT (command);
if (!bson_iter_init (&iter, command) || !bson_iter_next (&iter)) {
return NULL;
}
name = bson_iter_key (&iter);
/* wrapped in "$query" or "query"?
*
* {$query: {count: "collection"}, $readPreference: {...}}
*/
if (name[0] == '$') {
wrapper_name = "$query";
} else if (!strcmp (name, "query")) {
wrapper_name = "query";
}
if (wrapper_name && bson_iter_init_find (&iter, command, wrapper_name) &&
BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child) &&
bson_iter_next (&child)) {
name = bson_iter_key (&child);
}
return name;
}
const char *
_mongoc_get_documents_field_name (const char *command_name)
{
if (!strcmp (command_name, "insert")) {
return "documents";
}
if (!strcmp (command_name, "update")) {
return "updates";
}
if (!strcmp (command_name, "delete")) {
return "deletes";
}
return NULL;
}
bool
_mongoc_lookup_bool (const bson_t *bson, const char *key, bool default_value)
{
bson_iter_t iter;
bson_iter_t child;
if (!bson) {
return default_value;
}
BSON_ASSERT (bson_iter_init (&iter, bson));
if (!bson_iter_find_descendant (&iter, key, &child)) {
return default_value;
}
return bson_iter_as_bool (&child);
}
char *
_mongoc_get_db_name (const char *ns)
{
size_t dblen;
const char *dot;
BSON_ASSERT (ns);
dot = strstr (ns, ".");
if (dot) {
dblen = dot - ns;
return bson_strndup (ns, dblen);
} else {
return bson_strdup (ns);
}
}
void
_mongoc_bson_init_if_set (bson_t *bson)
{
if (bson) {
bson_init (bson);
}
}
const char *
_mongoc_bson_type_to_str (bson_type_t t)
{
switch (t) {
case BSON_TYPE_EOD:
return "EOD";
case BSON_TYPE_DOUBLE:
return "DOUBLE";
case BSON_TYPE_UTF8:
return "UTF8";
case BSON_TYPE_DOCUMENT:
return "DOCUMENT";
case BSON_TYPE_ARRAY:
return "ARRAY";
case BSON_TYPE_BINARY:
return "BINARY";
case BSON_TYPE_UNDEFINED:
return "UNDEFINED";
case BSON_TYPE_OID:
return "OID";
case BSON_TYPE_BOOL:
return "BOOL";
case BSON_TYPE_DATE_TIME:
return "DATE_TIME";
case BSON_TYPE_NULL:
return "NULL";
case BSON_TYPE_REGEX:
return "REGEX";
case BSON_TYPE_DBPOINTER:
return "DBPOINTER";
case BSON_TYPE_CODE:
return "CODE";
case BSON_TYPE_SYMBOL:
return "SYMBOL";
case BSON_TYPE_CODEWSCOPE:
return "CODEWSCOPE";
case BSON_TYPE_INT32:
return "INT32";
case BSON_TYPE_TIMESTAMP:
return "TIMESTAMP";
case BSON_TYPE_INT64:
return "INT64";
case BSON_TYPE_MAXKEY:
return "MAXKEY";
case BSON_TYPE_MINKEY:
return "MINKEY";
case BSON_TYPE_DECIMAL128:
return "DECIMAL128";
default:
return "Unknown";
}
}
/* Refer to:
* https://github.com/mongodb/specifications/blob/master/source/wireversion-featurelist.rst
* and:
* https://github.com/mongodb/mongo/blob/master/src/mongo/db/wire_version.h#L57
*/
const char *
_mongoc_wire_version_to_server_version (int32_t version)
{
switch (version) {
case 1:
case 2:
return "2.6";
case 3:
return "3.0";
case 4:
return "3.2";
case 5:
return "3.4";
case 6:
return "3.6";
case 7:
return "4.0";
case 8:
return "4.2";
case 9:
return "4.4";
case 10:
return "4.7";
case 11:
return "4.8";
case 12:
return "4.9";
case 13:
return "5.0";
case 14:
return "5.1";
case 15:
return "5.2";
+ case 16:
+ return "5.3";
+ case 17:
+ return "6.0";
default:
return "Unknown";
}
}
/* Get "serverId" from opts. Sets *server_id to the serverId from "opts" or 0
* if absent. On error, fills out *error with domain and code and return false.
*/
bool
_mongoc_get_server_id_from_opts (const bson_t *opts,
mongoc_error_domain_t domain,
mongoc_error_code_t code,
uint32_t *server_id,
bson_error_t *error)
{
bson_iter_t iter;
ENTRY;
BSON_ASSERT (server_id);
*server_id = 0;
if (!opts || !bson_iter_init_find (&iter, opts, "serverId")) {
RETURN (true);
}
if (!BSON_ITER_HOLDS_INT (&iter)) {
bson_set_error (
error, domain, code, "The serverId option must be an integer");
RETURN (false);
}
if (bson_iter_as_int64 (&iter) <= 0) {
bson_set_error (error, domain, code, "The serverId option must be >= 1");
RETURN (false);
}
*server_id = (uint32_t) bson_iter_as_int64 (&iter);
RETURN (true);
}
bool
_mongoc_validate_new_document (const bson_t *doc,
bson_validate_flags_t vflags,
bson_error_t *error)
{
bson_error_t validate_err;
if (vflags == BSON_VALIDATE_NONE) {
return true;
}
if (!bson_validate_with_error (doc, vflags, &validate_err)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid document for insert: %s",
validate_err.message);
return false;
}
return true;
}
bool
_mongoc_validate_replace (const bson_t *doc,
bson_validate_flags_t vflags,
bson_error_t *error)
{
bson_error_t validate_err;
bson_iter_t iter;
const char *key;
if (vflags == BSON_VALIDATE_NONE) {
return true;
}
if (!bson_validate_with_error (doc, vflags, &validate_err)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid argument for replace: %s",
validate_err.message);
return false;
}
if (!bson_iter_init (&iter, doc)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"replace document is corrupt");
return false;
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (key[0] == '$') {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid key '%s': replace prohibits $ operators",
key);
return false;
}
}
return true;
}
bool
_mongoc_validate_update (const bson_t *update,
bson_validate_flags_t vflags,
bson_error_t *error)
{
bson_error_t validate_err;
bson_iter_t iter;
const char *key;
if (vflags == BSON_VALIDATE_NONE) {
return true;
}
if (!bson_validate_with_error (update, vflags, &validate_err)) {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"invalid argument for update: %s",
validate_err.message);
return false;
}
if (_mongoc_document_is_pipeline (update)) {
return true;
}
if (!bson_iter_init (&iter, update)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"update document is corrupt");
return false;
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
if (key[0] != '$') {
bson_set_error (error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Invalid key '%s': update only works with $ operators"
" and pipelines",
key);
return false;
}
}
return true;
}
void
mongoc_lowercase (const char *src, char *buf /* OUT */)
{
for (; *src; ++src, ++buf) {
/* UTF8 non-ascii characters have a 1 at the leftmost bit. If this is the
* case, just copy */
if ((*src & (0x1 << 7)) == 0) {
*buf = (char) tolower (*src);
} else {
*buf = *src;
}
}
}
bool
mongoc_parse_port (uint16_t *port, const char *str)
{
unsigned long ul_port;
ul_port = strtoul (str, NULL, 10);
if (ul_port == 0 || ul_port > UINT16_MAX) {
/* Parse error or port number out of range. mongod prohibits port 0. */
return false;
}
*port = (uint16_t) ul_port;
return true;
}
/*--------------------------------------------------------------------------
*
* _mongoc_bson_array_add_label --
*
* Append an error label like "TransientTransactionError" to a BSON
* array iff the array does not already contain it.
*
* Side effects:
* Aborts if the array is invalid or contains non-string elements.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_bson_array_add_label (bson_t *bson, const char *label)
{
bson_iter_t iter;
char buf[16];
uint32_t i = 0;
const char *key;
BSON_ASSERT (bson_iter_init (&iter, bson));
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_utf8 (&iter, NULL), label)) {
/* already included once */
return;
}
i++;
}
bson_uint32_to_string (i, &key, buf, sizeof buf);
BSON_APPEND_UTF8 (bson, key, label);
}
/*--------------------------------------------------------------------------
*
* _mongoc_bson_array_copy_labels_to --
*
* Copy error labels like "TransientTransactionError" from a server
* reply to a BSON array iff the array does not already contain it.
*
* Side effects:
* Aborts if @dst is invalid or contains non-string elements.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_bson_array_copy_labels_to (const bson_t *reply, bson_t *dst)
{
bson_iter_t iter;
bson_iter_t label;
if (bson_iter_init_find (&iter, reply, "errorLabels")) {
BSON_ASSERT (bson_iter_recurse (&iter, &label));
while (bson_iter_next (&label)) {
if (BSON_ITER_HOLDS_UTF8 (&label)) {
_mongoc_bson_array_add_label (dst, bson_iter_utf8 (&label, NULL));
}
}
}
}
/*--------------------------------------------------------------------------
*
* _mongoc_bson_init_with_transient_txn_error --
*
* If @reply is not NULL, initialize it. If @cs is not NULL and in a
* transaction, add errorLabels: ["TransientTransactionError"] to @cs.
*
* Transactions Spec: TransientTransactionError includes "server
* selection error encountered running any command besides
* commitTransaction in a transaction. ...in the case of network errors
* or server selection errors where the client receives no server reply,
* the client adds the label."
*
* Side effects:
* None.
*
*--------------------------------------------------------------------------
*/
void
_mongoc_bson_init_with_transient_txn_error (const mongoc_client_session_t *cs,
bson_t *reply)
{
bson_t labels;
if (!reply) {
return;
}
bson_init (reply);
if (_mongoc_client_session_in_txn (cs)) {
BSON_APPEND_ARRAY_BEGIN (reply, "errorLabels", &labels);
BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR);
bson_append_array_end (reply, &labels);
}
}
bool
_mongoc_document_is_pipeline (const bson_t *document)
{
bson_iter_t iter;
bson_iter_t child;
const char *key;
int i = 0;
char *i_str;
if (!bson_iter_init (&iter, document)) {
return false;
}
while (bson_iter_next (&iter)) {
key = bson_iter_key (&iter);
i_str = bson_strdup_printf ("%d", i++);
if (strcmp (key, i_str)) {
bson_free (i_str);
return false;
}
bson_free (i_str);
if (BSON_ITER_HOLDS_DOCUMENT (&iter)) {
if (!bson_iter_recurse (&iter, &child)) {
return false;
}
if (!bson_iter_next (&child)) {
return false;
}
key = bson_iter_key (&child);
if (key[0] != '$') {
return false;
}
} else {
return false;
}
}
/* should return false when the document is empty */
return i != 0;
}
char *
_mongoc_getenv (const char *name)
{
#ifdef _MSC_VER
char buf[2048];
size_t buflen;
if ((0 == getenv_s (&buflen, buf, sizeof buf, name)) && buflen) {
return bson_strdup (buf);
} else {
return NULL;
}
#else
if (getenv (name) && strlen (getenv (name))) {
return bson_strdup (getenv (name));
} else {
return NULL;
}
#endif
}
/* Nearly Divisionless (Algorithm 5): https://arxiv.org/abs/1805.10941 */
static uint32_t
_mongoc_rand_nduid32 (uint32_t s, uint32_t (*rand32) (void))
{
const uint64_t limit = UINT32_MAX; /* 2^L */
uint64_t x, m, l;
x = rand32 ();
m = x * s;
l = m % limit;
if (l < s) {
const uint64_t t = (limit - s) % s;
while (l < t) {
x = rand32 ();
m = x * s;
l = m % limit;
}
}
return (uint32_t) (m / limit);
}
/* Java Algorithm (Algorithm 4): https://arxiv.org/abs/1805.10941
* The 64-bit version of the nearly divisionless algorithm requires 128-bit
* integer arithmetic. Instead of trying to deal with cross-platform support for
* `__int128`, fallback to using the Java algorithm for 64-bit instead. */
static uint64_t
_mongoc_rand_java64 (uint64_t s, uint64_t (*rand64) (void))
{
const uint64_t limit = UINT64_MAX; /* 2^L */
uint64_t x, r;
x = rand64 ();
r = x % s;
while ((x - r) > (limit - s)) {
x = rand64 ();
r = x % s;
}
return r;
}
#if defined(MONGOC_ENABLE_CRYPTO)
uint32_t
_mongoc_crypto_rand_uint32_t (void)
{
uint32_t res;
(void) _mongoc_rand_bytes ((uint8_t *) &res, sizeof (res));
return res;
}
uint64_t
_mongoc_crypto_rand_uint64_t (void)
{
uint64_t res;
(void) _mongoc_rand_bytes ((uint8_t *) &res, sizeof (res));
return res;
}
size_t
_mongoc_crypto_rand_size_t (void)
{
size_t res;
(void) _mongoc_rand_bytes ((uint8_t *) &res, sizeof (res));
return res;
}
#endif /* defined(MONGOC_ENABLE_CRYPTO) */
static BSON_ONCE_FUN (_mongoc_simple_rand_init)
{
struct timeval tv;
unsigned int seed = 0;
bson_gettimeofday (&tv);
seed ^= (unsigned int) tv.tv_sec;
seed ^= (unsigned int) tv.tv_usec;
srand (seed);
BSON_ONCE_RETURN;
}
static bson_once_t _mongoc_simple_rand_init_once = BSON_ONCE_INIT;
uint32_t
_mongoc_simple_rand_uint32_t (void)
{
bson_once (&_mongoc_simple_rand_init_once, _mongoc_simple_rand_init);
/* Ensure *all* bits are random, as RAND_MAX is only required to be at least
* 32767 (2^15). */
return (((uint32_t) rand () & 0x7FFFu) << 0u) |
(((uint32_t) rand () & 0x7FFFu) << 15u) |
(((uint32_t) rand () & 0x0003u) << 30u);
}
uint64_t
_mongoc_simple_rand_uint64_t (void)
{
bson_once (&_mongoc_simple_rand_init_once, _mongoc_simple_rand_init);
/* Ensure *all* bits are random, as RAND_MAX is only required to be at least
* 32767 (2^15). */
return (((uint64_t) rand () & 0x7FFFu) << 0u) |
(((uint64_t) rand () & 0x7FFFu) << 15u) |
(((uint64_t) rand () & 0x7FFFu) << 30u) |
(((uint64_t) rand () & 0x7FFFu) << 45u) |
(((uint64_t) rand () & 0x0003u) << 60u);
}
uint32_t
_mongoc_rand_uint32_t (uint32_t min, uint32_t max, uint32_t (*rand) (void))
{
BSON_ASSERT (min <= max);
BSON_ASSERT (min != 0u || max != UINT32_MAX);
return _mongoc_rand_nduid32 (max - min + 1u, rand) + min;
}
uint64_t
_mongoc_rand_uint64_t (uint64_t min, uint64_t max, uint64_t (*rand) (void))
{
BSON_ASSERT (min <= max);
BSON_ASSERT (min != 0u || max != UINT64_MAX);
return _mongoc_rand_java64 (max - min + 1u, rand) + min;
}
#if SIZE_MAX == UINT64_MAX
BSON_STATIC_ASSERT2 (_mongoc_simple_rand_size_t,
sizeof (size_t) == sizeof (uint64_t));
size_t
_mongoc_simple_rand_size_t (void)
{
return (size_t) _mongoc_simple_rand_uint64_t ();
}
size_t
_mongoc_rand_size_t (size_t min, size_t max, size_t (*rand) (void))
{
BSON_ASSERT (min <= max);
BSON_ASSERT (min != 0u || max != UINT64_MAX);
return _mongoc_rand_java64 (max - min + 1u, (uint64_t (*) (void)) rand) +
min;
}
#elif SIZE_MAX == UINT32_MAX
BSON_STATIC_ASSERT2 (_mongoc_simple_rand_size_t,
sizeof (size_t) == sizeof (uint32_t));
size_t
_mongoc_simple_rand_size_t (void)
{
return (size_t) _mongoc_simple_rand_uint32_t ();
}
size_t
_mongoc_rand_size_t (size_t min, size_t max, size_t (*rand) (void))
{
BSON_ASSERT (min <= max);
BSON_ASSERT (min != 0u || max != UINT32_MAX);
return _mongoc_rand_nduid32 (max - min + 1u, (uint32_t (*) (void)) rand) +
min;
}
#else
#error \
"Implementation of _mongoc_simple_rand_size_t() requires size_t be exactly 32-bit or 64-bit"
#endif
+
+bool
+_mongoc_iter_document_as_bson (const bson_iter_t *iter,
+ bson_t *bson,
+ bson_error_t *error)
+{
+ uint32_t len;
+ const uint8_t *data;
+
+ if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "expected BSON document for field: %s",
+ bson_iter_key (iter));
+ return false;
+ }
+
+ bson_iter_document (iter, &len, &data);
+ if (!bson_init_static (bson, data, len)) {
+ bson_set_error (error,
+ MONGOC_ERROR_COMMAND,
+ MONGOC_ERROR_COMMAND_INVALID_ARG,
+ "unable to initialize BSON document from field: %s",
+ bson_iter_key (iter));
+ return false;
+ }
+
+ return true;
+}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
similarity index 94%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
index f23dece8..9b07ad10 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h
@@ -1,102 +1,102 @@
/*
* Copyright 2013 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION)
#error "Only <mongoc/mongoc.h> can be included directly."
#endif
#ifndef MONGOC_VERSION_H
#define MONGOC_VERSION_H
/**
* MONGOC_MAJOR_VERSION:
*
* MONGOC major version component (e.g. 1 if %MONGOC_VERSION is 1.2.3)
*/
#define MONGOC_MAJOR_VERSION (1)
/**
* MONGOC_MINOR_VERSION:
*
* MONGOC minor version component (e.g. 2 if %MONGOC_VERSION is 1.2.3)
*/
-#define MONGOC_MINOR_VERSION (21)
+#define MONGOC_MINOR_VERSION (22)
/**
* MONGOC_MICRO_VERSION:
*
* MONGOC micro version component (e.g. 3 if %MONGOC_VERSION is 1.2.3)
*/
-#define MONGOC_MICRO_VERSION (1)
+#define MONGOC_MICRO_VERSION (0)
/**
* MONGOC_PRERELEASE_VERSION:
*
* MONGOC prerelease version component (e.g. pre if %MONGOC_VERSION is 1.2.3-pre)
*/
#define MONGOC_PRERELEASE_VERSION ()
/**
* MONGOC_VERSION:
*
* MONGOC version.
*/
-#define MONGOC_VERSION (1.21.1)
+#define MONGOC_VERSION (1.22.0)
/**
* MONGOC_VERSION_S:
*
* MONGOC version, encoded as a string, useful for printing and
* concatenation.
*/
-#define MONGOC_VERSION_S "1.21.1"
+#define MONGOC_VERSION_S "1.22.0"
/**
* MONGOC_VERSION_HEX:
*
* MONGOC version, encoded as an hexadecimal number, useful for
* integer comparisons.
*/
#define MONGOC_VERSION_HEX (MONGOC_MAJOR_VERSION << 24 | \
MONGOC_MINOR_VERSION << 16 | \
MONGOC_MICRO_VERSION << 8)
/**
* MONGOC_CHECK_VERSION:
* @major: required major version
* @minor: required minor version
* @micro: required micro version
*
* Compile-time version checking. Evaluates to %TRUE if the version
* of MONGOC is greater than the required one.
*/
#define MONGOC_CHECK_VERSION(major,minor,micro) \
(MONGOC_MAJOR_VERSION > (major) || \
(MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION > (minor)) || \
(MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION == (minor) && \
MONGOC_MICRO_VERSION >= (micro)))
#endif /* MONGOC_VERSION_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
index 668ffc16..1b3e6673 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c
@@ -1,506 +1,508 @@
/*
* Copyright 2014-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongoc-write-command-legacy-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-util-private.h"
static void
_mongoc_monitor_legacy_write (mongoc_client_t *client,
mongoc_write_command_t *command,
const char *db,
const char *collection,
mongoc_server_stream_t *stream,
int64_t request_id)
{
bson_t doc;
bson_t wc;
mongoc_apm_command_started_t event;
ENTRY;
if (!client->apm_callbacks.started) {
EXIT;
}
bson_init (&doc);
_mongoc_write_command_init (&doc, command, collection);
BSON_APPEND_DOCUMENT_BEGIN (&doc, "writeConcern", &wc);
BSON_APPEND_INT32 (&wc, "w", 0);
bson_append_document_end (&doc, &wc);
_append_array_from_command (command, &doc);
mongoc_apm_command_started_init (
&event,
&doc,
db,
_mongoc_command_type_to_name (command->type),
request_id,
command->operation_id,
&stream->sd->host,
stream->sd->id,
&stream->sd->service_id,
+ stream->sd->server_connection_id,
NULL,
client->apm_context);
client->apm_callbacks.started (&event);
mongoc_apm_command_started_cleanup (&event);
bson_destroy (&doc);
}
/* fire command-succeeded event as if we'd used a modern write command.
* note, cluster.request_id was incremented once for the write, again
* for the getLastError, so cluster.request_id is no longer valid; used the
* passed-in request_id instead.
*/
static void
_mongoc_monitor_legacy_write_succeeded (mongoc_client_t *client,
int64_t duration,
mongoc_write_command_t *command,
mongoc_server_stream_t *stream,
int64_t request_id)
{
bson_t doc;
mongoc_apm_command_succeeded_t event;
ENTRY;
if (!client->apm_callbacks.succeeded) {
EXIT;
}
bson_init (&doc);
/*
* Unacknowledged writes must provide a CommandSucceededEvent with a { ok: 1
* } reply.
* https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#unacknowledged-acknowledged-writes
*/
bson_append_int32 (&doc, "ok", 2, 1);
bson_append_int32 (&doc, "n", 1, (int32_t) command->n_documents);
mongoc_apm_command_succeeded_init (
&event,
duration,
&doc,
_mongoc_command_type_to_name (command->type),
request_id,
command->operation_id,
&stream->sd->host,
stream->sd->id,
&stream->sd->service_id,
+ stream->sd->server_connection_id,
false,
client->apm_context);
client->apm_callbacks.succeeded (&event);
mongoc_apm_command_succeeded_cleanup (&event);
bson_destroy (&doc);
EXIT;
}
void
_mongoc_write_command_delete_legacy (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
int64_t started;
int32_t max_bson_obj_size;
const uint8_t *data;
mongoc_rpc_t rpc;
uint32_t request_id;
bson_iter_t q_iter;
uint32_t len;
int64_t limit = 0;
char *ns;
bool r;
bson_reader_t *reader;
const bson_t *bson;
bool eof;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
started = bson_get_monotonic_time ();
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
if (!command->n_documents) {
bson_set_error (error,
MONGOC_ERROR_COLLECTION,
MONGOC_ERROR_COLLECTION_DELETE_FAILED,
"Cannot do an empty delete.");
result->failed = true;
EXIT;
}
ns = bson_strdup_printf ("%s.%s", database, collection);
reader =
bson_reader_new_from_data (command->payload.data, command->payload.len);
while ((bson = bson_reader_read (reader, &eof))) {
/* the document is like { "q": { <selector> }, limit: <0 or 1> } */
r = (bson_iter_init (&q_iter, bson) && bson_iter_find (&q_iter, "q") &&
BSON_ITER_HOLDS_DOCUMENT (&q_iter));
BSON_ASSERT (r);
bson_iter_document (&q_iter, &len, &data);
BSON_ASSERT (data);
BSON_ASSERT (len >= 5);
if (len > max_bson_obj_size) {
_mongoc_write_command_too_large_error (
error, 0, len, max_bson_obj_size);
result->failed = true;
bson_reader_destroy (reader);
bson_free (ns);
EXIT;
}
request_id = ++client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_DELETE;
rpc.delete_.zero = 0;
rpc.delete_.collection = ns;
if (bson_iter_find (&q_iter, "limit") &&
(BSON_ITER_HOLDS_INT (&q_iter))) {
limit = bson_iter_as_int64 (&q_iter);
}
rpc.delete_.flags =
limit ? MONGOC_DELETE_SINGLE_REMOVE : MONGOC_DELETE_NONE;
rpc.delete_.selector = data;
_mongoc_monitor_legacy_write (
client, command, database, collection, server_stream, request_id);
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&client->cluster, &rpc, server_stream, error)) {
result->failed = true;
bson_free (ns);
bson_reader_destroy (reader);
EXIT;
}
_mongoc_monitor_legacy_write_succeeded (client,
bson_get_monotonic_time () -
started,
command,
server_stream,
request_id);
started = bson_get_monotonic_time ();
}
bson_reader_destroy (reader);
bson_free (ns);
EXIT;
}
void
_mongoc_write_command_insert_legacy (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
int64_t started;
mongoc_iovec_t *iov;
mongoc_rpc_t rpc;
uint32_t size = 0;
bool has_more;
char *ns;
uint32_t n_docs_in_batch;
uint32_t request_id = 0;
uint32_t idx = 0;
int32_t max_msg_size;
int32_t max_bson_obj_size;
bson_reader_t *reader;
const bson_t *bson;
bool eof;
int data_offset = 0;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT);
started = bson_get_monotonic_time ();
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if (!command->n_documents) {
bson_set_error (error,
MONGOC_ERROR_COLLECTION,
MONGOC_ERROR_COLLECTION_INSERT_FAILED,
"Cannot do an empty insert.");
result->failed = true;
EXIT;
}
ns = bson_strdup_printf ("%s.%s", database, collection);
iov = (mongoc_iovec_t *) bson_malloc ((sizeof *iov) * command->n_documents);
again:
has_more = false;
n_docs_in_batch = 0;
size = (uint32_t) (sizeof (mongoc_rpc_header_t) + 4 + strlen (database) + 1 +
strlen (collection) + 1);
reader = bson_reader_new_from_data (command->payload.data + data_offset,
command->payload.len - data_offset);
while ((bson = bson_reader_read (reader, &eof))) {
BSON_ASSERT (n_docs_in_batch <= idx);
BSON_ASSERT (idx <= command->n_documents);
if (bson->len > max_bson_obj_size) {
/* document is too large */
_mongoc_write_command_too_large_error (
error, idx, bson->len, max_bson_obj_size);
data_offset += bson->len;
if (command->flags.ordered) {
/* send the batch so far (if any) and return the error */
break;
}
} else if (size > (max_msg_size - bson->len)) {
/* batch is full, send it and then start the next batch */
has_more = true;
break;
} else {
/* add document to batch and continue building the batch */
iov[n_docs_in_batch].iov_base = (void *) bson_get_data (bson);
iov[n_docs_in_batch].iov_len = bson->len;
size += bson->len;
n_docs_in_batch++;
data_offset += bson->len;
}
idx++;
}
bson_reader_destroy (reader);
if (n_docs_in_batch) {
request_id = ++client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_INSERT;
rpc.insert.flags =
((command->flags.ordered) ? MONGOC_INSERT_NONE
: MONGOC_INSERT_CONTINUE_ON_ERROR);
rpc.insert.collection = ns;
rpc.insert.documents = iov;
rpc.insert.n_documents = n_docs_in_batch;
_mongoc_monitor_legacy_write (
client, command, database, collection, server_stream, request_id);
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&client->cluster, &rpc, server_stream, error)) {
result->failed = true;
GOTO (cleanup);
}
_mongoc_monitor_legacy_write_succeeded (client,
bson_get_monotonic_time () -
started,
command,
server_stream,
request_id);
started = bson_get_monotonic_time ();
}
cleanup:
if (has_more) {
GOTO (again);
}
bson_free (ns);
bson_free (iov);
EXIT;
}
void
_mongoc_write_command_update_legacy (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
int64_t started;
int32_t max_bson_obj_size;
mongoc_rpc_t rpc;
uint32_t request_id = 0;
bson_iter_t subiter;
bson_t update, selector;
const uint8_t *data = NULL;
uint32_t len = 0;
bool val = false;
char *ns;
bool r;
bson_reader_t *reader;
const bson_t *bson;
bool eof;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
started = bson_get_monotonic_time ();
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
ns = bson_strdup_printf ("%s.%s", database, collection);
reader =
bson_reader_new_from_data (command->payload.data, command->payload.len);
while ((bson = bson_reader_read (reader, &eof))) {
/* ensure the document has "q" and "u" document fields in that order */
r = (bson_iter_init (&subiter, bson) && bson_iter_find (&subiter, "q") &&
BSON_ITER_HOLDS_DOCUMENT (&subiter) &&
bson_iter_find (&subiter, "u") &&
BSON_ITER_HOLDS_DOCUMENT (&subiter));
BSON_ASSERT (r);
request_id = ++client->cluster.request_id;
rpc.header.msg_len = 0;
rpc.header.request_id = request_id;
rpc.header.response_to = 0;
rpc.header.opcode = MONGOC_OPCODE_UPDATE;
rpc.update.zero = 0;
rpc.update.collection = ns;
rpc.update.flags = MONGOC_UPDATE_NONE;
BSON_ASSERT (bson_iter_init (&subiter, bson));
while (bson_iter_next (&subiter)) {
if (strcmp (bson_iter_key (&subiter), "u") == 0) {
bson_iter_document (&subiter, &len, &data);
BSON_ASSERT (data);
BSON_ASSERT (len >= 5);
if (len > max_bson_obj_size) {
_mongoc_write_command_too_large_error (
error, 0, len, max_bson_obj_size);
result->failed = true;
bson_reader_destroy (reader);
bson_free (ns);
EXIT;
}
rpc.update.update = data;
BSON_ASSERT (bson_init_static (&update, data, len));
} else if (strcmp (bson_iter_key (&subiter), "q") == 0) {
bson_iter_document (&subiter, &len, &data);
BSON_ASSERT (data);
BSON_ASSERT (len >= 5);
if (len > max_bson_obj_size) {
_mongoc_write_command_too_large_error (
error, 0, len, max_bson_obj_size);
result->failed = true;
bson_reader_destroy (reader);
bson_free (ns);
EXIT;
}
rpc.update.selector = data;
BSON_ASSERT (bson_init_static (&selector, data, len));
} else if (strcmp (bson_iter_key (&subiter), "multi") == 0) {
val = bson_iter_bool (&subiter);
if (val) {
rpc.update.flags = (mongoc_update_flags_t) (
rpc.update.flags | MONGOC_UPDATE_MULTI_UPDATE);
}
} else if (strcmp (bson_iter_key (&subiter), "upsert") == 0) {
val = bson_iter_bool (&subiter);
if (val) {
rpc.update.flags = (mongoc_update_flags_t) (
rpc.update.flags | MONGOC_UPDATE_UPSERT);
}
}
}
_mongoc_monitor_legacy_write (
client, command, database, collection, server_stream, request_id);
if (!mongoc_cluster_legacy_rpc_sendv_to_server (
&client->cluster, &rpc, server_stream, error)) {
result->failed = true;
bson_reader_destroy (reader);
bson_free (ns);
EXIT;
}
_mongoc_monitor_legacy_write_succeeded (client,
bson_get_monotonic_time () -
started,
command,
server_stream,
request_id);
started = bson_get_monotonic_time ();
}
bson_reader_destroy (reader);
bson_free (ns);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
index 89fa3113..04917deb 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h
@@ -1,231 +1,233 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongoc-prelude.h"
#ifndef MONGOC_WRITE_COMMAND_PRIVATE_H
#define MONGOC_WRITE_COMMAND_PRIVATE_H
#include <bson/bson.h>
#include "mongoc-client.h"
#include "mongoc-error.h"
#include "mongoc-write-concern.h"
#include "mongoc-server-stream-private.h"
#include "mongoc-buffer-private.h"
BSON_BEGIN_DECLS
/* forward decl */
struct _mongoc_crud_opts_t;
#define MONGOC_WRITE_COMMAND_DELETE 0
#define MONGOC_WRITE_COMMAND_INSERT 1
#define MONGOC_WRITE_COMMAND_UPDATE 2
/* MongoDB has a extra allowance to allow updating 16mb document, as the update
* operators would otherwise overflow the 16mb object limit. See SERVER-10643
* for context. */
#define BSON_OBJECT_ALLOWANCE (16 * 1024)
#define RETRYABLE_WRITE_ERROR "RetryableWriteError"
struct _mongoc_bulk_write_flags_t {
bool ordered;
bool bypass_document_validation;
bool has_collation;
bool has_multi_write;
bool has_array_filters;
bool has_update_hint;
bool has_delete_hint;
};
typedef struct {
int type;
mongoc_buffer_t payload;
uint32_t n_documents;
mongoc_bulk_write_flags_t flags;
int64_t operation_id;
bson_t cmd_opts;
} mongoc_write_command_t;
typedef struct {
uint32_t nInserted;
uint32_t nMatched;
uint32_t nModified;
uint32_t nRemoved;
uint32_t nUpserted;
/* like [{"index": int, "code": int, "errmsg": str}, ...] */
bson_t writeErrors;
/* like [{"index": int, "_id": value}, ...] */
bson_t upserted;
uint32_t n_writeConcernErrors;
/* like [{"code": 64, "errmsg": "duplicate"}, ...] */
bson_t writeConcernErrors;
/* like ["TransientTransactionError", ...] */
bson_t errorLabels;
bool failed; /* The command failed */
bool must_stop; /* The stream may have been disconnected */
bson_error_t error;
uint32_t upsert_append_count;
/* If the command initially failed with a retryable write, and selected a new
* primary, this contains the server id of the newly selected primary. Only
* applies to OP_MSG. Is left at 0 if no retry occurs. */
uint32_t retry_server_id;
} mongoc_write_result_t;
typedef enum {
MONGOC_WRITE_ERR_NONE,
MONGOC_WRITE_ERR_OTHER,
MONGOC_WRITE_ERR_RETRY,
MONGOC_WRITE_ERR_WRITE_CONCERN,
} mongoc_write_err_type_t;
const char *
_mongoc_command_type_to_field_name (int command_type);
const char *
_mongoc_command_type_to_name (int command_type);
void
_mongoc_write_command_destroy (mongoc_write_command_t *command);
void
_mongoc_write_command_init (bson_t *doc,
mongoc_write_command_t *command,
const char *collection);
void
_mongoc_write_command_init_insert (mongoc_write_command_t *command,
const bson_t *document,
const bson_t *cmd_opts,
mongoc_bulk_write_flags_t flags,
int64_t operation_id);
void
_mongoc_write_command_init_insert_idl (mongoc_write_command_t *command,
const bson_t *document,
const bson_t *cmd_opts,
int64_t operation_id);
void
_mongoc_write_command_init_delete (mongoc_write_command_t *command,
const bson_t *selectors,
const bson_t *cmd_opts,
const bson_t *opts,
mongoc_bulk_write_flags_t flags,
int64_t operation_id);
void
_mongoc_write_command_init_delete_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *cmd_opts,
const bson_t *opts,
int64_t operation_id);
void
_mongoc_write_command_init_update (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
+ const bson_t *cmd_opts,
const bson_t *opts,
mongoc_bulk_write_flags_t flags,
int64_t operation_id);
void
_mongoc_write_command_init_update_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
+ const bson_t *cmd_opts,
const bson_t *opts,
int64_t operation_id);
void
_mongoc_write_command_insert_append (mongoc_write_command_t *command,
const bson_t *document);
void
_mongoc_write_command_update_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
const bson_t *opts);
void
_mongoc_write_command_delete_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *opts);
void
_mongoc_write_command_too_large_error (bson_error_t *error,
int32_t idx,
int32_t len,
int32_t max_bson_size);
void
_mongoc_write_command_execute (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
const mongoc_write_concern_t *write_concern,
uint32_t offset,
mongoc_client_session_t *cs,
mongoc_write_result_t *result);
void
_mongoc_write_command_execute_idl (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
const struct _mongoc_crud_opts_t *crud,
mongoc_write_result_t *result);
void
_mongoc_write_result_init (mongoc_write_result_t *result);
void
_mongoc_write_result_append_upsert (mongoc_write_result_t *result,
int32_t idx,
const bson_value_t *value);
int32_t
_mongoc_write_result_merge_arrays (uint32_t offset,
mongoc_write_result_t *result,
bson_t *dest,
bson_iter_t *iter);
void
_mongoc_write_result_merge (mongoc_write_result_t *result,
mongoc_write_command_t *command,
const bson_t *reply,
uint32_t offset);
#define MONGOC_WRITE_RESULT_COMPLETE(_result, ...) \
_mongoc_write_result_complete (_result, __VA_ARGS__, NULL)
bool
_mongoc_write_result_complete (mongoc_write_result_t *result,
int32_t error_api_version,
const mongoc_write_concern_t *wc,
mongoc_error_domain_t err_domain_override,
bson_t *reply,
bson_error_t *error,
...);
void
_mongoc_write_result_destroy (mongoc_write_result_t *result);
void
_append_array_from_command (mongoc_write_command_t *command, bson_t *bson);
mongoc_write_err_type_t
_mongoc_write_error_get_type (bson_t *reply);
bool
_mongoc_write_error_update_if_unsupported_storage_engine (bool cmd_ret,
bson_error_t *cmd_err,
bson_t *reply);
BSON_END_DECLS
#endif /* MONGOC_WRITE_COMMAND_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
index d30f24b5..5dd6b774 100644
--- a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
+++ b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c
@@ -1,1599 +1,1601 @@
/*
* Copyright 2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongoc-client-private.h"
#include "mongoc-client-session-private.h"
#include "mongoc-client-side-encryption-private.h"
#include "mongoc-error.h"
#include "mongoc-error-private.h"
#include "mongoc-trace-private.h"
#include "mongoc-write-command-private.h"
#include "mongoc-write-command-legacy-private.h"
#include "mongoc-write-concern-private.h"
#include "mongoc-util-private.h"
#include "mongoc-opts-private.h"
/*
* TODO:
*
* - Remove error parameter to ops, favor result->error.
*/
typedef void (*mongoc_write_op_t) (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error);
/* indexed by MONGOC_WRITE_COMMAND_DELETE, INSERT, UPDATE */
static const char *gCommandNames[] = {"delete", "insert", "update"};
static const char *gCommandFields[] = {"deletes", "documents", "updates"};
static const uint32_t gCommandFieldLens[] = {7, 9, 7};
static mongoc_write_op_t gLegacyWriteOps[3] = {
_mongoc_write_command_delete_legacy,
_mongoc_write_command_insert_legacy,
_mongoc_write_command_update_legacy};
const char *
_mongoc_command_type_to_name (int command_type)
{
return gCommandNames[command_type];
}
const char *
_mongoc_command_type_to_field_name (int command_type)
{
return gCommandFields[command_type];
}
void
_mongoc_write_command_insert_append (mongoc_write_command_t *command,
const bson_t *document)
{
bson_iter_t iter;
bson_oid_t oid;
bson_t tmp;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT);
BSON_ASSERT (document);
BSON_ASSERT (document->len >= 5);
/*
* If the document does not contain an "_id" field, we need to generate
* a new oid for "_id".
*/
if (!bson_iter_init_find (&iter, document, "_id")) {
bson_init (&tmp);
bson_oid_init (&oid, NULL);
BSON_APPEND_OID (&tmp, "_id", &oid);
bson_concat (&tmp, document);
_mongoc_buffer_append (&command->payload, bson_get_data (&tmp), tmp.len);
bson_destroy (&tmp);
} else {
_mongoc_buffer_append (
&command->payload, bson_get_data (document), document->len);
}
command->n_documents++;
EXIT;
}
void
_mongoc_write_command_update_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
const bson_t *opts)
{
bson_t document;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_UPDATE);
BSON_ASSERT (selector && update);
bson_init (&document);
BSON_APPEND_DOCUMENT (&document, "q", selector);
if (_mongoc_document_is_pipeline (update)) {
BSON_APPEND_ARRAY (&document, "u", update);
} else {
BSON_APPEND_DOCUMENT (&document, "u", update);
}
if (opts) {
bson_concat (&document, opts);
}
_mongoc_buffer_append (
&command->payload, bson_get_data (&document), document.len);
command->n_documents++;
bson_destroy (&document);
EXIT;
}
void
_mongoc_write_command_delete_append (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *opts)
{
bson_t document;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_DELETE);
BSON_ASSERT (selector);
BSON_ASSERT (selector->len >= 5);
bson_init (&document);
BSON_APPEND_DOCUMENT (&document, "q", selector);
if (opts) {
bson_concat (&document, opts);
}
_mongoc_buffer_append (
&command->payload, bson_get_data (&document), document.len);
command->n_documents++;
bson_destroy (&document);
EXIT;
}
void
_mongoc_write_command_init_bulk (mongoc_write_command_t *command,
int type,
mongoc_bulk_write_flags_t flags,
int64_t operation_id,
const bson_t *opts)
{
ENTRY;
BSON_ASSERT (command);
command->type = type;
command->flags = flags;
command->operation_id = operation_id;
if (!bson_empty0 (opts)) {
bson_copy_to (opts, &command->cmd_opts);
} else {
bson_init (&command->cmd_opts);
}
_mongoc_buffer_init (&command->payload, NULL, 0, NULL, NULL);
command->n_documents = 0;
EXIT;
}
void
_mongoc_write_command_init_insert (mongoc_write_command_t *command, /* IN */
const bson_t *document, /* IN */
const bson_t *cmd_opts, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
int64_t operation_id) /* IN */
{
ENTRY;
BSON_ASSERT (command);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_INSERT, flags, operation_id, cmd_opts);
/* must handle NULL document from mongoc_collection_insert_bulk */
if (document) {
_mongoc_write_command_insert_append (command, document);
}
EXIT;
}
void
_mongoc_write_command_init_insert_idl (mongoc_write_command_t *command,
const bson_t *document,
const bson_t *cmd_opts,
int64_t operation_id)
{
mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT;
ENTRY;
BSON_ASSERT (command);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_INSERT, flags, operation_id, cmd_opts);
/* must handle NULL document from mongoc_collection_insert_bulk */
if (document) {
_mongoc_write_command_insert_append (command, document);
}
EXIT;
}
void
_mongoc_write_command_init_delete (mongoc_write_command_t *command, /* IN */
const bson_t *selector, /* IN */
const bson_t *cmd_opts, /* IN */
const bson_t *opts, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
int64_t operation_id) /* IN */
{
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (selector);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_DELETE, flags, operation_id, cmd_opts);
_mongoc_write_command_delete_append (command, selector, opts);
EXIT;
}
void
_mongoc_write_command_init_delete_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *cmd_opts,
const bson_t *opts,
int64_t operation_id)
{
mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (selector);
_mongoc_write_command_init_bulk (
command, MONGOC_WRITE_COMMAND_DELETE, flags, operation_id, cmd_opts);
_mongoc_write_command_delete_append (command, selector, opts);
EXIT;
}
void
_mongoc_write_command_init_update (mongoc_write_command_t *command, /* IN */
const bson_t *selector, /* IN */
const bson_t *update, /* IN */
+ const bson_t *cmd_opts, /* IN */
const bson_t *opts, /* IN */
mongoc_bulk_write_flags_t flags, /* IN */
int64_t operation_id) /* IN */
{
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (selector);
BSON_ASSERT (update);
_mongoc_write_command_init_bulk (
- command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, NULL);
+ command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, cmd_opts);
_mongoc_write_command_update_append (command, selector, update, opts);
EXIT;
}
void
_mongoc_write_command_init_update_idl (mongoc_write_command_t *command,
const bson_t *selector,
const bson_t *update,
+ const bson_t *cmd_opts,
const bson_t *opts,
int64_t operation_id)
{
mongoc_bulk_write_flags_t flags = MONGOC_BULK_WRITE_FLAGS_INIT;
ENTRY;
BSON_ASSERT (command);
_mongoc_write_command_init_bulk (
- command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, NULL);
+ command, MONGOC_WRITE_COMMAND_UPDATE, flags, operation_id, cmd_opts);
_mongoc_write_command_update_append (command, selector, update, opts);
EXIT;
}
/* takes initialized bson_t *doc and begins formatting a write command */
void
_mongoc_write_command_init (bson_t *doc,
mongoc_write_command_t *command,
const char *collection)
{
ENTRY;
if (!command->n_documents) {
EXIT;
}
BSON_APPEND_UTF8 (doc, gCommandNames[command->type], collection);
BSON_APPEND_BOOL (doc, "ordered", command->flags.ordered);
if (command->flags.bypass_document_validation) {
BSON_APPEND_BOOL (doc,
"bypassDocumentValidation",
command->flags.bypass_document_validation);
}
EXIT;
}
/*
*-------------------------------------------------------------------------
*
* _mongoc_write_command_too_large_error --
*
* Fill a bson_error_t and optional bson_t with error info after
* receiving a document for bulk insert, update, or remove that is
* larger than max_bson_size.
*
* "err_doc" should be NULL or an empty initialized bson_t.
*
* Returns:
* None.
*
* Side effects:
* "error" and optionally "err_doc" are filled out.
*
*-------------------------------------------------------------------------
*/
void
_mongoc_write_command_too_large_error (bson_error_t *error,
int32_t idx,
int32_t len,
int32_t max_bson_size)
{
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Document %u is too large for the cluster. "
"Document is %u bytes, max is %d.",
idx,
len,
max_bson_size);
}
void
_empty_error (mongoc_write_command_t *command, bson_error_t *error)
{
static const uint32_t codes[] = {MONGOC_ERROR_COLLECTION_DELETE_FAILED,
MONGOC_ERROR_COLLECTION_INSERT_FAILED,
MONGOC_ERROR_COLLECTION_UPDATE_FAILED};
bson_set_error (error,
MONGOC_ERROR_COLLECTION,
codes[command->type],
"Cannot do an empty %s",
gCommandNames[command->type]);
}
bool
_mongoc_write_command_will_overflow (uint32_t len_so_far,
uint32_t document_len,
uint32_t n_documents_written,
int32_t max_bson_size,
int32_t max_write_batch_size)
{
/* max BSON object size + 16k bytes.
* server guarantees there is enough room: SERVER-10643
*/
int32_t max_cmd_size = max_bson_size + BSON_OBJECT_ALLOWANCE;
BSON_ASSERT (max_bson_size);
if (len_so_far + document_len > max_cmd_size) {
return true;
} else if (max_write_batch_size > 0 &&
n_documents_written >= max_write_batch_size) {
return true;
}
return false;
}
static void
_mongoc_write_opmsg (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
const mongoc_write_concern_t *write_concern,
uint32_t index_offset,
mongoc_client_session_t *cs,
mongoc_write_result_t *result,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
bson_iter_t iter;
bson_t cmd;
bson_t reply;
bool ret = false;
int32_t max_msg_size;
int32_t max_bson_obj_size;
int32_t max_document_count;
uint32_t header;
uint32_t payload_batch_size = 0;
uint32_t payload_total_offset = 0;
bool ship_it = false;
int document_count = 0;
int32_t len;
mongoc_server_stream_t *retry_server_stream = NULL;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
max_msg_size = mongoc_server_stream_max_msg_size (server_stream);
if (_mongoc_cse_is_enabled (client)) {
max_msg_size = MONGOC_REDUCED_MAX_MSG_SIZE_FOR_FLE;
}
max_document_count =
mongoc_server_stream_max_write_batch_size (server_stream);
bson_init (&cmd);
_mongoc_write_command_init (&cmd, command, collection);
mongoc_cmd_parts_init (&parts, client, database, MONGOC_QUERY_NONE, &cmd);
parts.assembled.operation_id = command->operation_id;
parts.is_write_command = true;
if (!mongoc_cmd_parts_set_write_concern (
&parts, write_concern, server_stream->sd->max_wire_version, error)) {
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
if (parts.assembled.is_acknowledged) {
mongoc_cmd_parts_set_session (&parts, cs);
}
/* Write commands that include multi-document operations are not retryable.
* Set this explicitly so that mongoc_cmd_parts_assemble does not need to
* inspect the command body later. */
parts.allow_txn_number =
(command->flags.has_multi_write || !parts.assembled.is_acknowledged)
? MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_NO
: MONGOC_CMD_PARTS_ALLOW_TXN_NUMBER_YES;
BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts));
if (!mongoc_cmd_parts_append_opts (
&parts, &iter, server_stream->sd->max_wire_version, error)) {
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
if (!mongoc_cmd_parts_assemble (&parts, server_stream, error)) {
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
/*
* OP_MSG header == 16 byte
* + 4 bytes flagBits
* + 1 byte payload type = 1
* + 1 byte payload type = 2
* + 4 byte size of payload
* == 26 bytes opcode overhead
* + X Full command document {insert: "test", writeConcern: {...}}
* + Y command identifier ("documents", "deletes", "updates") ( + \0)
*/
header =
26 + parts.assembled.command->len + gCommandFieldLens[command->type] + 1;
do {
memcpy (&len,
command->payload.data + payload_batch_size + payload_total_offset,
4);
len = BSON_UINT32_FROM_LE (len);
if (len > max_bson_obj_size + BSON_OBJECT_ALLOWANCE) {
/* Quit if the document is too large */
_mongoc_write_command_too_large_error (
error, index_offset, len, max_bson_obj_size);
result->failed = true;
break;
} else if ((payload_batch_size + header) + len <= max_msg_size ||
document_count == 0) {
/* The current batch is still under max batch size in bytes */
payload_batch_size += len;
/* If this document filled the maximum document count */
if (++document_count == max_document_count) {
ship_it = true;
/* If this document is the last document we have */
} else if (payload_batch_size + payload_total_offset ==
command->payload.len) {
ship_it = true;
} else {
ship_it = false;
}
} else {
ship_it = true;
}
if (ship_it) {
bool is_retryable = parts.is_retryable_write;
mongoc_write_err_type_t error_type;
/* Seek past the document offset we have already sent */
parts.assembled.payload = command->payload.data + payload_total_offset;
/* Only send the documents up to this size */
parts.assembled.payload_size = payload_batch_size;
parts.assembled.payload_identifier = gCommandFields[command->type];
/* increment the transaction number for the first attempt of each
* retryable write command */
if (is_retryable) {
bson_iter_t txn_number_iter;
BSON_ASSERT (bson_iter_init_find (
&txn_number_iter, parts.assembled.command, "txnNumber"));
bson_iter_overwrite_int64 (
&txn_number_iter,
++parts.assembled.session->server_session->txn_number);
}
retry:
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts.assembled, &reply, error);
if (parts.is_retryable_write) {
_mongoc_write_error_handle_labels (
ret, error, &reply, server_stream->sd->max_wire_version);
}
/* Add this batch size so we skip these documents next time */
payload_total_offset += payload_batch_size;
payload_batch_size = 0;
/* If a retryable error is encountered and the write is retryable,
* select a new writable stream and retry. If server selection fails or
* the selected server does not support retryable writes, fall through
* and allow the original error to be reported. */
error_type = _mongoc_write_error_get_type (&reply);
if (is_retryable) {
_mongoc_write_error_update_if_unsupported_storage_engine (
ret, error, &reply);
}
if (is_retryable && error_type == MONGOC_WRITE_ERR_RETRY) {
bson_error_t ignored_error;
/* each write command may be retried at most once */
is_retryable = false;
if (retry_server_stream) {
mongoc_server_stream_cleanup (retry_server_stream);
}
retry_server_stream = mongoc_cluster_stream_for_writes (
&client->cluster, cs, NULL, &ignored_error);
if (retry_server_stream &&
retry_server_stream->sd->max_wire_version >=
WIRE_VERSION_RETRY_WRITES) {
parts.assembled.server_stream = retry_server_stream;
bson_destroy (&reply);
GOTO (retry);
}
}
if (!ret) {
result->failed = true;
/* Stop for ordered bulk writes or when the server stream has been
* properly invalidated (e.g., due to a network error). */
if (command->flags.ordered || !mongoc_cluster_stream_valid (
&client->cluster, server_stream)) {
result->must_stop = true;
}
}
/* Result merge needs to know the absolute index for a document
* so it can rewrite the error message which contains the relative
* document index per batch
*/
_mongoc_write_result_merge (result, command, &reply, index_offset);
index_offset += document_count;
document_count = 0;
bson_destroy (&reply);
}
/* While we have more documents to write */
} while (payload_total_offset < command->payload.len && !result->must_stop);
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
if (retry_server_stream) {
if (ret) {
/* if a retry succeeded, report that in the result so bulk write can
* use the newly selected server. */
result->retry_server_id =
mongoc_server_description_id (retry_server_stream->sd);
}
mongoc_server_stream_cleanup (retry_server_stream);
}
if (ret) {
/* if a retry succeeded, clear the initial error */
memset (&result->error, 0, sizeof (bson_error_t));
}
EXIT;
}
void
_append_array_from_command (mongoc_write_command_t *command, bson_t *bson)
{
bson_t ar;
bson_reader_t *reader;
char str[16];
uint32_t i = 0;
const char *key;
bool eof;
const bson_t *current;
reader =
bson_reader_new_from_data (command->payload.data, command->payload.len);
bson_append_array_begin (bson,
gCommandFields[command->type],
gCommandFieldLens[command->type],
&ar);
while ((current = bson_reader_read (reader, &eof))) {
bson_uint32_to_string (i, &key, str, sizeof str);
BSON_APPEND_DOCUMENT (&ar, key, current);
i++;
}
bson_append_array_end (bson, &ar);
bson_reader_destroy (reader);
}
/* Assemble the base @cmd with all of the command options.
* @parts is always initialized, even on error.
* This is called twice in _mongoc_write_opquery.
* Once with no payload documents, to determine the total size. And once with
* payload documents, to send the final command. */
static bool
_assemble_cmd (bson_t *cmd,
mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const mongoc_write_concern_t *write_concern,
mongoc_cmd_parts_t *parts,
bson_error_t *error)
{
bool ret;
bson_iter_t iter;
mongoc_cmd_parts_init (parts, client, database, MONGOC_QUERY_NONE, cmd);
parts->is_write_command = true;
parts->assembled.operation_id = command->operation_id;
ret = mongoc_cmd_parts_set_write_concern (
parts, write_concern, server_stream->sd->max_wire_version, error);
if (ret) {
BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts));
ret = mongoc_cmd_parts_append_opts (
parts, &iter, server_stream->sd->max_wire_version, error);
}
if (ret) {
ret = mongoc_cmd_parts_assemble (parts, server_stream, error);
}
return ret;
}
static void
_mongoc_write_opquery (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
const mongoc_write_concern_t *write_concern,
uint32_t offset,
mongoc_write_result_t *result,
bson_error_t *error)
{
mongoc_cmd_parts_t parts;
const char *key;
uint32_t len = 0;
bson_t ar;
bson_t cmd;
char str[16];
bool has_more;
bool ret = false;
uint32_t i;
int32_t max_bson_obj_size;
int32_t max_write_batch_size;
uint32_t overhead;
uint32_t key_len;
int data_offset = 0;
bson_reader_t *reader;
const bson_t *bson;
bool eof;
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (database);
BSON_ASSERT (server_stream);
BSON_ASSERT (collection);
bson_init (&cmd);
max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
max_write_batch_size =
mongoc_server_stream_max_write_batch_size (server_stream);
again:
has_more = false;
i = 0;
_mongoc_write_command_init (&cmd, command, collection);
/* If any part of assembling failed, return with failure. */
if (!_assemble_cmd (&cmd,
command,
client,
server_stream,
database,
write_concern,
&parts,
error)) {
result->failed = true;
bson_destroy (&cmd);
mongoc_cmd_parts_cleanup (&parts);
EXIT;
}
/* Use the assembled command to compute the overhead, since it may be a new
* BSON document with options applied. If no options were applied, then
* parts.assembled.command points to cmd. The constant 2 is due to 1 byte to
* specify array type and 1 byte for field name's null terminator. */
overhead =
parts.assembled.command->len + 2 + gCommandFieldLens[command->type];
/* Toss out the assembled command, we'll assemble again after adding all of
* the payload documents. */
mongoc_cmd_parts_cleanup (&parts);
reader = bson_reader_new_from_data (command->payload.data + data_offset,
command->payload.len - data_offset);
bson_append_array_begin (&cmd,
gCommandFields[command->type],
gCommandFieldLens[command->type],
&ar);
while ((bson = bson_reader_read (reader, &eof))) {
key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str);
len = bson->len;
/* 1 byte to specify document type, 1 byte for key's null terminator */
if (_mongoc_write_command_will_overflow (overhead,
key_len + len + 2 + ar.len,
i,
max_bson_obj_size,
max_write_batch_size)) {
has_more = true;
break;
}
BSON_APPEND_DOCUMENT (&ar, key, bson);
data_offset += len;
i++;
}
bson_append_array_end (&cmd, &ar);
if (!i) {
_mongoc_write_command_too_large_error (error, i, len, max_bson_obj_size);
result->failed = true;
result->must_stop = true;
ret = false;
if (bson) {
data_offset += len;
}
} else {
bson_t reply;
ret = _assemble_cmd (&cmd,
command,
client,
server_stream,
database,
write_concern,
&parts,
error);
if (ret) {
ret = mongoc_cluster_run_command_monitored (
&client->cluster, &parts.assembled, &reply, error);
} else {
bson_init (&reply);
}
if (!ret) {
result->failed = true;
if (bson_empty (&reply) ||
!mongoc_cluster_stream_valid (&client->cluster, server_stream)) {
/* assembling failed, or a network error running the command */
result->must_stop = true;
}
}
_mongoc_write_result_merge (result, command, &reply, offset);
offset += i;
bson_destroy (&reply);
mongoc_cmd_parts_cleanup (&parts);
}
bson_reader_destroy (reader);
if (has_more && (ret || !command->flags.ordered) && !result->must_stop) {
bson_reinit (&cmd);
GOTO (again);
}
bson_destroy (&cmd);
EXIT;
}
void
_mongoc_write_command_execute (
mongoc_write_command_t *command, /* IN */
mongoc_client_t *client, /* IN */
mongoc_server_stream_t *server_stream, /* IN */
const char *database, /* IN */
const char *collection, /* IN */
const mongoc_write_concern_t *write_concern, /* IN */
uint32_t offset, /* IN */
mongoc_client_session_t *cs, /* IN */
mongoc_write_result_t *result) /* OUT */
{
mongoc_crud_opts_t crud = {0};
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (server_stream);
BSON_ASSERT (database);
BSON_ASSERT (collection);
BSON_ASSERT (result);
if (!write_concern) {
write_concern = client->write_concern;
}
if (!mongoc_write_concern_is_valid (write_concern)) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The write concern is invalid.");
result->failed = true;
EXIT;
}
crud.client_session = cs;
crud.writeConcern = (mongoc_write_concern_t *) write_concern;
_mongoc_write_command_execute_idl (command,
client,
server_stream,
database,
collection,
offset,
&crud,
result);
EXIT;
}
void
_mongoc_write_command_execute_idl (mongoc_write_command_t *command,
mongoc_client_t *client,
mongoc_server_stream_t *server_stream,
const char *database,
const char *collection,
uint32_t offset,
const mongoc_crud_opts_t *crud,
mongoc_write_result_t *result)
{
ENTRY;
BSON_ASSERT (command);
BSON_ASSERT (client);
BSON_ASSERT (server_stream);
BSON_ASSERT (database);
BSON_ASSERT (collection);
BSON_ASSERT (result);
if (command->flags.has_collation) {
if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set collation for unacknowledged writes");
EXIT;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support collation");
result->failed = true;
EXIT;
}
}
if (command->flags.has_array_filters) {
if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot use array filters with unacknowledged writes");
EXIT;
}
if (server_stream->sd->max_wire_version < WIRE_VERSION_ARRAY_FILTERS) {
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support array filters");
result->failed = true;
EXIT;
}
}
if (command->flags.has_update_hint) {
if (server_stream->sd->max_wire_version <
WIRE_VERSION_HINT_SERVER_SIDE_ERROR ||
(server_stream->sd->max_wire_version < WIRE_VERSION_UPDATE_HINT &&
!mongoc_write_concern_is_acknowledged (crud->writeConcern))) {
bson_set_error (
&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
"The selected server does not support hint for update");
result->failed = true;
EXIT;
}
}
if (command->flags.has_delete_hint) {
if (server_stream->sd->max_wire_version <
WIRE_VERSION_HINT_SERVER_SIDE_ERROR ||
(server_stream->sd->max_wire_version < WIRE_VERSION_DELETE_HINT &&
!mongoc_write_concern_is_acknowledged (crud->writeConcern))) {
bson_set_error (
&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"The selected server does not support hint for delete");
result->failed = true;
EXIT;
}
}
if (command->flags.bypass_document_validation) {
if (!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (
&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot set bypassDocumentValidation for unacknowledged writes");
EXIT;
}
}
if (crud->client_session &&
!mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
result->failed = true;
bson_set_error (&result->error,
MONGOC_ERROR_COMMAND,
MONGOC_ERROR_COMMAND_INVALID_ARG,
"Cannot use client session with unacknowledged writes");
EXIT;
}
if (command->payload.len == 0) {
_empty_error (command, &result->error);
EXIT;
}
if (server_stream->sd->max_wire_version >= WIRE_VERSION_OP_MSG) {
_mongoc_write_opmsg (command,
client,
server_stream,
database,
collection,
crud->writeConcern,
offset,
crud->client_session,
result,
&result->error);
} else {
if (mongoc_write_concern_is_acknowledged (crud->writeConcern)) {
_mongoc_write_opquery (command,
client,
server_stream,
database,
collection,
crud->writeConcern,
offset,
result,
&result->error);
} else {
gLegacyWriteOps[command->type](command,
client,
server_stream,
database,
collection,
offset,
result,
&result->error);
}
}
EXIT;
}
void
_mongoc_write_command_destroy (mongoc_write_command_t *command)
{
ENTRY;
if (command) {
bson_destroy (&command->cmd_opts);
_mongoc_buffer_destroy (&command->payload);
}
EXIT;
}
void
_mongoc_write_result_init (mongoc_write_result_t *result) /* IN */
{
ENTRY;
BSON_ASSERT (result);
memset (result, 0, sizeof *result);
bson_init (&result->upserted);
bson_init (&result->writeConcernErrors);
bson_init (&result->writeErrors);
bson_init (&result->errorLabels);
EXIT;
}
void
_mongoc_write_result_destroy (mongoc_write_result_t *result)
{
ENTRY;
BSON_ASSERT (result);
bson_destroy (&result->upserted);
bson_destroy (&result->writeConcernErrors);
bson_destroy (&result->writeErrors);
bson_destroy (&result->errorLabels);
EXIT;
}
void
_mongoc_write_result_append_upsert (mongoc_write_result_t *result,
int32_t idx,
const bson_value_t *value)
{
bson_t child;
const char *keyptr = NULL;
char key[12];
int len;
BSON_ASSERT (result);
BSON_ASSERT (value);
len = (int) bson_uint32_to_string (
result->upsert_append_count, &keyptr, key, sizeof key);
bson_append_document_begin (&result->upserted, keyptr, len, &child);
BSON_APPEND_INT32 (&child, "index", idx);
BSON_APPEND_VALUE (&child, "_id", value);
bson_append_document_end (&result->upserted, &child);
result->upsert_append_count++;
}
int32_t
_mongoc_write_result_merge_arrays (uint32_t offset,
mongoc_write_result_t *result, /* IN */
bson_t *dest, /* IN */
bson_iter_t *iter) /* IN */
{
const bson_value_t *value;
bson_iter_t ar;
bson_iter_t citer;
int32_t idx;
int32_t count = 0;
int32_t aridx;
bson_t child;
const char *keyptr = NULL;
char key[12];
int len;
ENTRY;
BSON_ASSERT (result);
BSON_ASSERT (dest);
BSON_ASSERT (iter);
BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter));
aridx = bson_count_keys (dest);
if (bson_iter_recurse (iter, &ar)) {
while (bson_iter_next (&ar)) {
if (BSON_ITER_HOLDS_DOCUMENT (&ar) &&
bson_iter_recurse (&ar, &citer)) {
len =
(int) bson_uint32_to_string (aridx++, &keyptr, key, sizeof key);
bson_append_document_begin (dest, keyptr, len, &child);
while (bson_iter_next (&citer)) {
if (BSON_ITER_IS_KEY (&citer, "index")) {
idx = bson_iter_int32 (&citer) + offset;
BSON_APPEND_INT32 (&child, "index", idx);
} else {
value = bson_iter_value (&citer);
BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value);
}
}
bson_append_document_end (dest, &child);
count++;
}
}
}
RETURN (count);
}
void
_mongoc_write_result_merge (mongoc_write_result_t *result, /* IN */
mongoc_write_command_t *command, /* IN */
const bson_t *reply, /* IN */
uint32_t offset)
{
int32_t server_index = 0;
const bson_value_t *value;
bson_iter_t iter;
bson_iter_t citer;
bson_iter_t ar;
int32_t n_upserted = 0;
int32_t affected = 0;
ENTRY;
BSON_ASSERT (result);
BSON_ASSERT (reply);
if (bson_iter_init_find (&iter, reply, "n") &&
BSON_ITER_HOLDS_INT32 (&iter)) {
affected = bson_iter_int32 (&iter);
}
if (bson_iter_init_find (&iter, reply, "writeErrors") &&
BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &citer) &&
bson_iter_next (&citer)) {
result->failed = true;
}
switch (command->type) {
case MONGOC_WRITE_COMMAND_INSERT:
result->nInserted += affected;
break;
case MONGOC_WRITE_COMMAND_DELETE:
result->nRemoved += affected;
break;
case MONGOC_WRITE_COMMAND_UPDATE:
/* server returns each upserted _id with its index into this batch
* look for "upserted": [{"index": 4, "_id": ObjectId()}, ...] */
if (bson_iter_init_find (&iter, reply, "upserted")) {
if (BSON_ITER_HOLDS_ARRAY (&iter) &&
(bson_iter_recurse (&iter, &ar))) {
while (bson_iter_next (&ar)) {
if (BSON_ITER_HOLDS_DOCUMENT (&ar) &&
bson_iter_recurse (&ar, &citer) &&
bson_iter_find (&citer, "index") &&
BSON_ITER_HOLDS_INT32 (&citer)) {
server_index = bson_iter_int32 (&citer);
if (bson_iter_recurse (&ar, &citer) &&
bson_iter_find (&citer, "_id")) {
value = bson_iter_value (&citer);
_mongoc_write_result_append_upsert (
result, offset + server_index, value);
n_upserted++;
}
}
}
}
result->nUpserted += n_upserted;
/*
* XXX: The following addition to nMatched needs some checking.
* I'm highly skeptical of it.
*/
result->nMatched += BSON_MAX (0, (affected - n_upserted));
} else {
result->nMatched += affected;
}
if (bson_iter_init_find (&iter, reply, "nModified") &&
BSON_ITER_HOLDS_INT32 (&iter)) {
result->nModified += bson_iter_int32 (&iter);
}
break;
default:
BSON_ASSERT (false);
break;
}
if (bson_iter_init_find (&iter, reply, "writeErrors") &&
BSON_ITER_HOLDS_ARRAY (&iter)) {
_mongoc_write_result_merge_arrays (
offset, result, &result->writeErrors, &iter);
}
if (bson_iter_init_find (&iter, reply, "writeConcernError") &&
BSON_ITER_HOLDS_DOCUMENT (&iter)) {
uint32_t len;
const uint8_t *data;
bson_t write_concern_error;
char str[16];
const char *key;
/* writeConcernError is a subdocument in the server response
* append it to the result->writeConcernErrors array */
bson_iter_document (&iter, &len, &data);
BSON_ASSERT (bson_init_static (&write_concern_error, data, len));
bson_uint32_to_string (
result->n_writeConcernErrors, &key, str, sizeof str);
if (!bson_append_document (
&result->writeConcernErrors, key, -1, &write_concern_error)) {
MONGOC_ERROR ("Error adding \"%s\" to writeConcernErrors.\n", key);
}
result->n_writeConcernErrors++;
}
/* inefficient if there are ever large numbers: for each label in each err,
* we linear-search result->errorLabels to see if it's included yet */
_mongoc_bson_array_copy_labels_to (reply, &result->errorLabels);
EXIT;
}
/*
* If error is not set, set code from first document in array like
* [{"code": 64, "errmsg": "duplicate"}, ...]. Format the error message
* from all errors in array.
*/
static void
_set_error_from_response (bson_t *bson_array,
mongoc_error_domain_t domain,
const char *error_type,
bson_error_t *error /* OUT */)
{
bson_iter_t array_iter;
bson_iter_t doc_iter;
bson_string_t *compound_err;
const char *errmsg = NULL;
int32_t code = 0;
uint32_t n_keys, i;
compound_err = bson_string_new (NULL);
n_keys = bson_count_keys (bson_array);
if (n_keys > 1) {
bson_string_append_printf (
compound_err, "Multiple %s errors: ", error_type);
}
if (!bson_empty0 (bson_array) && bson_iter_init (&array_iter, bson_array)) {
/* get first code and all error messages */
i = 0;
while (bson_iter_next (&array_iter)) {
if (BSON_ITER_HOLDS_DOCUMENT (&array_iter) &&
bson_iter_recurse (&array_iter, &doc_iter)) {
/* parse doc, which is like {"code": 64, "errmsg": "duplicate"} */
while (bson_iter_next (&doc_iter)) {
/* use the first error code we find */
if (BSON_ITER_IS_KEY (&doc_iter, "code") && code == 0) {
code = (uint32_t) bson_iter_as_int64 (&doc_iter);
} else if (BSON_ITER_IS_KEY (&doc_iter, "errmsg")) {
errmsg = bson_iter_utf8 (&doc_iter, NULL);
/* build message like 'Multiple write errors: "foo", "bar"' */
if (n_keys > 1) {
bson_string_append_printf (compound_err, "\"%s\"", errmsg);
if (i < n_keys - 1) {
bson_string_append (compound_err, ", ");
}
} else {
/* single error message */
bson_string_append (compound_err, errmsg);
}
}
}
i++;
}
}
if (code && compound_err->len) {
bson_set_error (
error, domain, (uint32_t) code, "%s", compound_err->str);
}
}
bson_string_free (compound_err, true);
}
/* complete a write result, including only certain fields */
bool
_mongoc_write_result_complete (
mongoc_write_result_t *result, /* IN */
int32_t error_api_version, /* IN */
const mongoc_write_concern_t *wc, /* IN */
mongoc_error_domain_t err_domain_override, /* IN */
bson_t *bson, /* OUT */
bson_error_t *error, /* OUT */
...)
{
mongoc_error_domain_t domain;
va_list args;
const char *field;
int n_args;
bson_iter_t iter;
bson_iter_t child;
ENTRY;
BSON_ASSERT (result);
if (error_api_version >= MONGOC_ERROR_API_VERSION_2) {
domain = MONGOC_ERROR_SERVER;
} else if (err_domain_override) {
domain = err_domain_override;
} else if (result->error.domain) {
domain = (mongoc_error_domain_t) result->error.domain;
} else {
domain = MONGOC_ERROR_COLLECTION;
}
/* produce either old fields like nModified from the deprecated Bulk API Spec
* or new fields like modifiedCount from the CRUD Spec, which we partly obey
*/
if (bson && mongoc_write_concern_is_acknowledged (wc)) {
n_args = 0;
va_start (args, error);
while ((field = va_arg (args, const char *))) {
n_args++;
if (!strcmp (field, "nInserted")) {
BSON_APPEND_INT32 (bson, field, result->nInserted);
} else if (!strcmp (field, "insertedCount")) {
BSON_APPEND_INT32 (bson, field, result->nInserted);
} else if (!strcmp (field, "nMatched")) {
BSON_APPEND_INT32 (bson, field, result->nMatched);
} else if (!strcmp (field, "matchedCount")) {
BSON_APPEND_INT32 (bson, field, result->nMatched);
} else if (!strcmp (field, "nModified")) {
BSON_APPEND_INT32 (bson, field, result->nModified);
} else if (!strcmp (field, "modifiedCount")) {
BSON_APPEND_INT32 (bson, field, result->nModified);
} else if (!strcmp (field, "nRemoved")) {
BSON_APPEND_INT32 (bson, field, result->nRemoved);
} else if (!strcmp (field, "deletedCount")) {
BSON_APPEND_INT32 (bson, field, result->nRemoved);
} else if (!strcmp (field, "nUpserted")) {
BSON_APPEND_INT32 (bson, field, result->nUpserted);
} else if (!strcmp (field, "upsertedCount")) {
BSON_APPEND_INT32 (bson, field, result->nUpserted);
} else if (!strcmp (field, "upserted") &&
!bson_empty0 (&result->upserted)) {
BSON_APPEND_ARRAY (bson, field, &result->upserted);
} else if (!strcmp (field, "upsertedId") &&
!bson_empty0 (&result->upserted) &&
bson_iter_init_find (&iter, &result->upserted, "0") &&
bson_iter_recurse (&iter, &child) &&
bson_iter_find (&child, "_id")) {
/* "upsertedId", singular, for update_one() */
BSON_APPEND_VALUE (bson, "upsertedId", bson_iter_value (&child));
}
}
va_end (args);
/* default: a standard result includes all Bulk API fields */
if (!n_args) {
BSON_APPEND_INT32 (bson, "nInserted", result->nInserted);
BSON_APPEND_INT32 (bson, "nMatched", result->nMatched);
BSON_APPEND_INT32 (bson, "nModified", result->nModified);
BSON_APPEND_INT32 (bson, "nRemoved", result->nRemoved);
BSON_APPEND_INT32 (bson, "nUpserted", result->nUpserted);
if (!bson_empty0 (&result->upserted)) {
BSON_APPEND_ARRAY (bson, "upserted", &result->upserted);
}
}
/* always append errors if there are any */
if (!n_args || !bson_empty (&result->writeErrors)) {
BSON_APPEND_ARRAY (bson, "writeErrors", &result->writeErrors);
}
if (result->n_writeConcernErrors) {
BSON_APPEND_ARRAY (
bson, "writeConcernErrors", &result->writeConcernErrors);
}
}
/* set bson_error_t from first write error or write concern error */
_set_error_from_response (
&result->writeErrors, domain, "write", &result->error);
if (!result->error.code) {
_set_error_from_response (&result->writeConcernErrors,
MONGOC_ERROR_WRITE_CONCERN,
"write concern",
&result->error);
}
if (bson && !bson_empty (&result->errorLabels)) {
BSON_APPEND_ARRAY (bson, "errorLabels", &result->errorLabels);
}
if (error) {
memcpy (error, &result->error, sizeof *error);
}
RETURN (!result->failed && result->error.code == 0);
}
/*--------------------------------------------------------------------------
*
* _mongoc_write_error_get_type --
*
* Checks if the error or reply from a write command is considered
* retryable according to the retryable writes spec. Checks both
* for a client error (a network exception) and a server error in
* the reply. @cmd_ret and @cmd_err come from the result of a
* write_command function. This function should be called after
* error labels are appended in _mongoc_write_error_handle_labels,
* which should be called after mongoc_cluster_run_command_monitored.
*
*
* Return:
* A mongoc_write_error_type_t indicating the type of error (if any).
*
*--------------------------------------------------------------------------
*/
mongoc_write_err_type_t
_mongoc_write_error_get_type (bson_t *reply)
{
bson_error_t error;
if (mongoc_error_has_label (reply, RETRYABLE_WRITE_ERROR)) {
return MONGOC_WRITE_ERR_RETRY;
}
/* check for a server error. */
if (_mongoc_cmd_check_ok_no_wce (
reply, MONGOC_ERROR_API_VERSION_2, &error)) {
return MONGOC_WRITE_ERR_NONE;
}
switch (error.code) {
case 64: /* WriteConcernFailed */
return MONGOC_WRITE_ERR_WRITE_CONCERN;
default:
return MONGOC_WRITE_ERR_OTHER;
}
}
/* Returns true and modifies reply and cmd_err. */
bool
_mongoc_write_error_update_if_unsupported_storage_engine (bool cmd_ret,
bson_error_t *cmd_err,
bson_t *reply)
{
bson_error_t server_error;
if (cmd_ret) {
return false;
}
if (_mongoc_cmd_check_ok_no_wce (
reply, MONGOC_ERROR_API_VERSION_2, &server_error)) {
return false;
}
if (server_error.code == 20 &&
strstr (server_error.message, "Transaction numbers") ==
server_error.message) {
const char *replacement = "This MongoDB deployment does not support "
"retryable writes. Please add "
"retryWrites=false to your connection string.";
strcpy (cmd_err->message, replacement);
if (reply) {
bson_t *new_reply = bson_new ();
bson_copy_to_excluding_noinit (reply, new_reply, "errmsg", NULL);
BSON_APPEND_UTF8 (new_reply, "errmsg", replacement);
bson_destroy (reply);
bson_steal (reply, new_reply);
}
return true;
}
return false;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/mongoc.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-delete.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-header.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-header.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-header.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-header.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-insert.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-msg.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-query.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-query.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-query.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-query.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-reply.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-update.def b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-update.def
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/op-update.def
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/op-update.def
diff --git a/mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/utlist.h b/mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/utlist.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/libmongoc/src/mongoc/utlist.h
rename to mongodb-1.14.0/src/libmongoc/src/libmongoc/src/mongoc/utlist.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/adler32.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/adler32.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/adler32.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/adler32.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/compress.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/compress.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/compress.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/compress.c
diff --git a/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/crc32.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/crc32.c
new file mode 100644
index 00000000..a1bdce5c
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/crc32.c
@@ -0,0 +1,1116 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2022 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * This interleaved implementation of a CRC makes use of pipelined multiple
+ * arithmetic-logic units, commonly found in modern CPU cores. It is due to
+ * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+
+ MAKECRCH can be #defined to write out crc32.h. A main() routine is also
+ produced, so that this one source file can be compiled to an executable.
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */
+
+ /*
+ A CRC of a message is computed on N braids of words in the message, where
+ each word consists of W bytes (4 or 8). If N is 3, for example, then three
+ running sparse CRCs are calculated respectively on each braid, at these
+ indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ...
+ This is done starting at a word boundary, and continues until as many blocks
+ of N * W bytes as are available have been processed. The results are combined
+ into a single CRC at the end. For this code, N must be in the range 1..6 and
+ W must be 4 or 8. The upper limit on N can be increased if desired by adding
+ more #if blocks, extending the patterns apparent in the code. In addition,
+ crc32.h would need to be regenerated, if the maximum N value is increased.
+
+ N and W are chosen empirically by benchmarking the execution time on a given
+ processor. The choices for N and W below were based on testing on Intel Kaby
+ Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64
+ Octeon II processors. The Intel, AMD, and ARM processors were all fastest
+ with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4.
+ They were all tested with either gcc or clang, all using the -O3 optimization
+ level. Your mileage may vary.
+ */
+
+/* Define N */
+#ifdef Z_TESTN
+# define N Z_TESTN
+#else
+# define N 5
+#endif
+#if N < 1 || N > 6
+# error N must be in 1..6
+#endif
+
+/*
+ z_crc_t must be at least 32 bits. z_word_t must be at least as long as
+ z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and
+ that bytes are eight bits.
+ */
+
+/*
+ Define W and the associated z_word_t type. If W is not defined, then a
+ braided calculation is not used, and the associated tables and code are not
+ compiled.
+ */
+#ifdef Z_TESTW
+# if Z_TESTW-1 != -1
+# define W Z_TESTW
+# endif
+#else
+# ifdef MAKECRCH
+# define W 8 /* required for MAKECRCH */
+# else
+# if defined(__x86_64__) || defined(__aarch64__)
+# define W 8
+# else
+# define W 4
+# endif
+# endif
+#endif
+#ifdef W
+# if W == 8 && defined(Z_U8)
+ typedef Z_U8 z_word_t;
+# elif defined(Z_U4)
+# undef W
+# define W 4
+ typedef Z_U4 z_word_t;
+# else
+# undef W
+# endif
+#endif
+
+/* Local functions. */
+local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
+local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
+
+/* If available, use the ARM processor CRC32 instruction. */
+#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
+# define ARMCRC32
+#endif
+
+#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
+/*
+ Swap the bytes in a z_word_t to convert between little and big endian. Any
+ self-respecting compiler will optimize this to a single machine byte-swap
+ instruction, if one is available. This assumes that word_t is either 32 bits
+ or 64 bits.
+ */
+local z_word_t byte_swap(word)
+ z_word_t word;
+{
+# if W == 8
+ return
+ (word & 0xff00000000000000) >> 56 |
+ (word & 0xff000000000000) >> 40 |
+ (word & 0xff0000000000) >> 24 |
+ (word & 0xff00000000) >> 8 |
+ (word & 0xff000000) << 8 |
+ (word & 0xff0000) << 24 |
+ (word & 0xff00) << 40 |
+ (word & 0xff) << 56;
+# else /* W == 4 */
+ return
+ (word & 0xff000000) >> 24 |
+ (word & 0xff0000) >> 8 |
+ (word & 0xff00) << 8 |
+ (word & 0xff) << 24;
+# endif
+}
+#endif
+
+/* CRC polynomial. */
+#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local z_crc_t FAR crc_table[256];
+local z_crc_t FAR x2n_table[32];
+local void make_crc_table OF((void));
+#ifdef W
+ local z_word_t FAR crc_big_table[256];
+ local z_crc_t FAR crc_braid_table[W][256];
+ local z_word_t FAR crc_braid_big_table[W][256];
+ local void braid OF((z_crc_t [][256], z_word_t [][256], int, int));
+#endif
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const z_crc_t FAR *, int));
+ local void write_table32hi OF((FILE *, const z_word_t FAR *, int));
+ local void write_table64 OF((FILE *, const z_word_t FAR *, int));
+#endif /* MAKECRCH */
+
+/*
+ Define a once() function depending on the availability of atomics. If this is
+ compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in
+ multiple threads, and if atomics are not available, then get_crc_table() must
+ be called to initialize the tables and must return before any threads are
+ allowed to compute or combine CRCs.
+ */
+
+/* Definition of once functionality. */
+typedef struct once_s once_t;
+local void once OF((once_t *, void (*)(void)));
+
+/* Check for the availability of atomics. */
+#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
+ !defined(__STDC_NO_ATOMICS__)
+
+#include <stdatomic.h>
+
+/* Structure for once(), which must be initialized with ONCE_INIT. */
+struct once_s {
+ atomic_flag begun;
+ atomic_int done;
+};
+#define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
+
+/*
+ Run the provided init() function exactly once, even if multiple threads
+ invoke once() at the same time. The state must be a once_t initialized with
+ ONCE_INIT.
+ */
+local void once(state, init)
+ once_t *state;
+ void (*init)(void);
+{
+ if (!atomic_load(&state->done)) {
+ if (atomic_flag_test_and_set(&state->begun))
+ while (!atomic_load(&state->done))
+ ;
+ else {
+ init();
+ atomic_store(&state->done, 1);
+ }
+ }
+}
+
+#else /* no atomics */
+
+/* Structure for once(), which must be initialized with ONCE_INIT. */
+struct once_s {
+ volatile int begun;
+ volatile int done;
+};
+#define ONCE_INIT {0, 0}
+
+/* Test and set. Alas, not atomic, but tries to minimize the period of
+ vulnerability. */
+local int test_and_set OF((int volatile *));
+local int test_and_set(flag)
+ int volatile *flag;
+{
+ int was;
+
+ was = *flag;
+ *flag = 1;
+ return was;
+}
+
+/* Run the provided init() function once. This is not thread-safe. */
+local void once(state, init)
+ once_t *state;
+ void (*init)(void);
+{
+ if (!state->done) {
+ if (test_and_set(&state->begun))
+ while (!state->done)
+ ;
+ else {
+ init();
+ state->done = 1;
+ }
+ }
+}
+
+#endif
+
+/* State for once(). */
+local once_t made = ONCE_INIT;
+
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x
+ (which is shifting right by one and adding x^32 mod p if the bit shifted out
+ is a one). We start with the highest power (least significant bit) of q and
+ repeat for all eight bits of q.
+
+ The table is simply the CRC of all possible eight bit values. This is all the
+ information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes.
+ */
+
+local void make_crc_table()
+{
+ unsigned i, j, n;
+ z_crc_t p;
+
+ /* initialize the CRC of bytes tables */
+ for (i = 0; i < 256; i++) {
+ p = i;
+ for (j = 0; j < 8; j++)
+ p = p & 1 ? (p >> 1) ^ POLY : p >> 1;
+ crc_table[i] = p;
+#ifdef W
+ crc_big_table[i] = byte_swap(p);
+#endif
+ }
+
+ /* initialize the x^2^n mod p(x) table */
+ p = (z_crc_t)1 << 30; /* x^1 */
+ x2n_table[0] = p;
+ for (n = 1; n < 32; n++)
+ x2n_table[n] = p = multmodp(p, p);
+
+#ifdef W
+ /* initialize the braiding tables -- needs x2n_table[] */
+ braid(crc_braid_table, crc_braid_big_table, N, W);
+#endif
+
+#ifdef MAKECRCH
+ {
+ /*
+ The crc32.h header file contains tables for both 32-bit and 64-bit
+ z_word_t's, and so requires a 64-bit type be available. In that case,
+ z_word_t must be defined to be 64-bits. This code then also generates
+ and writes out the tables for the case that z_word_t is 32 bits.
+ */
+#if !defined(W) || W != 8
+# error Need a 64-bit integer type in order to generate crc32.h.
+#endif
+ FILE *out;
+ int k, n;
+ z_crc_t ltl[8][256];
+ z_word_t big[8][256];
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+
+ /* write out little-endian CRC table to crc32.h */
+ fprintf(out,
+ "/* crc32.h -- tables for rapid CRC calculation\n"
+ " * Generated automatically by crc32.c\n */\n"
+ "\n"
+ "local const z_crc_t FAR crc_table[] = {\n"
+ " ");
+ write_table(out, crc_table, 256);
+ fprintf(out,
+ "};\n");
+
+ /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */
+ fprintf(out,
+ "\n"
+ "#ifdef W\n"
+ "\n"
+ "#if W == 8\n"
+ "\n"
+ "local const z_word_t FAR crc_big_table[] = {\n"
+ " ");
+ write_table64(out, crc_big_table, 256);
+ fprintf(out,
+ "};\n");
+
+ /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */
+ fprintf(out,
+ "\n"
+ "#else /* W == 4 */\n"
+ "\n"
+ "local const z_word_t FAR crc_big_table[] = {\n"
+ " ");
+ write_table32hi(out, crc_big_table, 256);
+ fprintf(out,
+ "};\n"
+ "\n"
+ "#endif\n");
+
+ /* write out braid tables for each value of N */
+ for (n = 1; n <= 6; n++) {
+ fprintf(out,
+ "\n"
+ "#if N == %d\n", n);
+
+ /* compute braid tables for this N and 64-bit word_t */
+ braid(ltl, big, n, 8);
+
+ /* write out braid tables for 64-bit z_word_t to crc32.h */
+ fprintf(out,
+ "\n"
+ "#if W == 8\n"
+ "\n"
+ "local const z_crc_t FAR crc_braid_table[][256] = {\n");
+ for (k = 0; k < 8; k++) {
+ fprintf(out, " {");
+ write_table(out, ltl[k], 256);
+ fprintf(out, "}%s", k < 7 ? ",\n" : "");
+ }
+ fprintf(out,
+ "};\n"
+ "\n"
+ "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
+ for (k = 0; k < 8; k++) {
+ fprintf(out, " {");
+ write_table64(out, big[k], 256);
+ fprintf(out, "}%s", k < 7 ? ",\n" : "");
+ }
+ fprintf(out,
+ "};\n");
+
+ /* compute braid tables for this N and 32-bit word_t */
+ braid(ltl, big, n, 4);
+
+ /* write out braid tables for 32-bit z_word_t to crc32.h */
+ fprintf(out,
+ "\n"
+ "#else /* W == 4 */\n"
+ "\n"
+ "local const z_crc_t FAR crc_braid_table[][256] = {\n");
+ for (k = 0; k < 4; k++) {
+ fprintf(out, " {");
+ write_table(out, ltl[k], 256);
+ fprintf(out, "}%s", k < 3 ? ",\n" : "");
+ }
+ fprintf(out,
+ "};\n"
+ "\n"
+ "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
+ for (k = 0; k < 4; k++) {
+ fprintf(out, " {");
+ write_table32hi(out, big[k], 256);
+ fprintf(out, "}%s", k < 3 ? ",\n" : "");
+ }
+ fprintf(out,
+ "};\n"
+ "\n"
+ "#endif\n"
+ "\n"
+ "#endif\n");
+ }
+ fprintf(out,
+ "\n"
+ "#endif\n");
+
+ /* write out zeros operator table to crc32.h */
+ fprintf(out,
+ "\n"
+ "local const z_crc_t FAR x2n_table[] = {\n"
+ " ");
+ write_table(out, x2n_table, 32);
+ fprintf(out,
+ "};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+
+/*
+ Write the 32-bit values in table[0..k-1] to out, five per line in
+ hexadecimal separated by commas.
+ */
+local void write_table(out, table, k)
+ FILE *out;
+ const z_crc_t FAR *table;
+ int k;
+{
+ int n;
+
+ for (n = 0; n < k; n++)
+ fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ",
+ (unsigned long)(table[n]),
+ n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
+}
+
+/*
+ Write the high 32-bits of each value in table[0..k-1] to out, five per line
+ in hexadecimal separated by commas.
+ */
+local void write_table32hi(out, table, k)
+FILE *out;
+const z_word_t FAR *table;
+int k;
+{
+ int n;
+
+ for (n = 0; n < k; n++)
+ fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ",
+ (unsigned long)(table[n] >> 32),
+ n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
+}
+
+/*
+ Write the 64-bit values in table[0..k-1] to out, three per line in
+ hexadecimal separated by commas. This assumes that if there is a 64-bit
+ type, then there is also a long long integer type, and it is at least 64
+ bits. If not, then the type cast and format string can be adjusted
+ accordingly.
+ */
+local void write_table64(out, table, k)
+ FILE *out;
+ const z_word_t FAR *table;
+ int k;
+{
+ int n;
+
+ for (n = 0; n < k; n++)
+ fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ",
+ (unsigned long long)(table[n]),
+ n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", "));
+}
+
+/* Actually do the deed. */
+int main()
+{
+ make_crc_table();
+ return 0;
+}
+
+#endif /* MAKECRCH */
+
+#ifdef W
+/*
+ Generate the little and big-endian braid tables for the given n and z_word_t
+ size w. Each array must have room for w blocks of 256 elements.
+ */
+local void braid(ltl, big, n, w)
+ z_crc_t ltl[][256];
+ z_word_t big[][256];
+ int n;
+ int w;
+{
+ int k;
+ z_crc_t i, p, q;
+ for (k = 0; k < w; k++) {
+ p = x2nmodp((n * w + 3 - k) << 3, 0);
+ ltl[k][0] = 0;
+ big[w - 1 - k][0] = 0;
+ for (i = 1; i < 256; i++) {
+ ltl[k][i] = q = multmodp(i << 24, p);
+ big[w - 1 - k][i] = byte_swap(q);
+ }
+ }
+}
+#endif
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
+ * of x for combining CRC-32s, all made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* ========================================================================
+ * Routines used for CRC calculation. Some are also required for the table
+ * generation above.
+ */
+
+/*
+ Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
+ reflected. For speed, this requires that a not be zero.
+ */
+local z_crc_t multmodp(a, b)
+ z_crc_t a;
+ z_crc_t b;
+{
+ z_crc_t m, p;
+
+ m = (z_crc_t)1 << 31;
+ p = 0;
+ for (;;) {
+ if (a & m) {
+ p ^= b;
+ if ((a & (m - 1)) == 0)
+ break;
+ }
+ m >>= 1;
+ b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
+ }
+ return p;
+}
+
+/*
+ Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
+ initialized.
+ */
+local z_crc_t x2nmodp(n, k)
+ z_off64_t n;
+ unsigned k;
+{
+ z_crc_t p;
+
+ p = (z_crc_t)1 << 31; /* x^0 == 1 */
+ while (n) {
+ if (n & 1)
+ p = multmodp(x2n_table[k & 31], p);
+ n >>= 1;
+ k++;
+ }
+ return p;
+}
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32(), and to force the
+ * generation of the CRC tables in a threaded application.
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const z_crc_t FAR *)crc_table;
+}
+
+/* =========================================================================
+ * Use ARM machine instructions if available. This will compute the CRC about
+ * ten times faster than the braided calculation. This code does not check for
+ * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will
+ * only be defined if the compilation specifies an ARM processor architecture
+ * that has the instructions. For example, compiling with -march=armv8.1-a or
+ * -march=armv8-a+crc, or -march=native if the compile machine has the crc32
+ * instructions.
+ */
+#ifdef ARMCRC32
+
+/*
+ Constants empirically determined to maximize speed. These values are from
+ measurements on a Cortex-A57. Your mileage may vary.
+ */
+#define Z_BATCH 3990 /* number of words in a batch */
+#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */
+#define Z_BATCH_MIN 800 /* fewest words in a final batch */
+
+unsigned long ZEXPORT crc32_z(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ z_crc_t val;
+ z_word_t crc1, crc2;
+ const z_word_t *word;
+ z_word_t val0, val1, val2;
+ z_size_t last, last2, i;
+ z_size_t num;
+
+ /* Return initial CRC, if requested. */
+ if (buf == Z_NULL) return 0;
+
+#ifdef DYNAMIC_CRC_TABLE
+ once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+
+ /* Pre-condition the CRC */
+ crc ^= 0xffffffff;
+
+ /* Compute the CRC up to a word boundary. */
+ while (len && ((z_size_t)buf & 7) != 0) {
+ len--;
+ val = *buf++;
+ __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
+ }
+
+ /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */
+ word = (z_word_t const *)buf;
+ num = len >> 3;
+ len &= 7;
+
+ /* Do three interleaved CRCs to realize the throughput of one crc32x
+ instruction per cycle. Each CRC is calcuated on Z_BATCH words. The three
+ CRCs are combined into a single CRC after each set of batches. */
+ while (num >= 3 * Z_BATCH) {
+ crc1 = 0;
+ crc2 = 0;
+ for (i = 0; i < Z_BATCH; i++) {
+ val0 = word[i];
+ val1 = word[i + Z_BATCH];
+ val2 = word[i + 2 * Z_BATCH];
+ __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
+ __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
+ __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
+ }
+ word += 3 * Z_BATCH;
+ num -= 3 * Z_BATCH;
+ crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1;
+ crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2;
+ }
+
+ /* Do one last smaller batch with the remaining words, if there are enough
+ to pay for the combination of CRCs. */
+ last = num / 3;
+ if (last >= Z_BATCH_MIN) {
+ last2 = last << 1;
+ crc1 = 0;
+ crc2 = 0;
+ for (i = 0; i < last; i++) {
+ val0 = word[i];
+ val1 = word[i + last];
+ val2 = word[i + last2];
+ __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
+ __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
+ __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
+ }
+ word += 3 * last;
+ num -= 3 * last;
+ val = x2nmodp(last, 6);
+ crc = multmodp(val, crc) ^ crc1;
+ crc = multmodp(val, crc) ^ crc2;
+ }
+
+ /* Compute the CRC on any remaining words. */
+ for (i = 0; i < num; i++) {
+ val0 = word[i];
+ __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
+ }
+ word += num;
+
+ /* Complete the CRC on any remaining bytes. */
+ buf = (const unsigned char FAR *)word;
+ while (len) {
+ len--;
+ val = *buf++;
+ __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
+ }
+
+ /* Return the CRC, post-conditioned. */
+ return crc ^ 0xffffffff;
+}
+
+#else
+
+#ifdef W
+
+/*
+ Return the CRC of the W bytes in the word_t data, taking the
+ least-significant byte of the word as the first byte of data, without any pre
+ or post conditioning. This is used to combine the CRCs of each braid.
+ */
+local z_crc_t crc_word(data)
+ z_word_t data;
+{
+ int k;
+ for (k = 0; k < W; k++)
+ data = (data >> 8) ^ crc_table[data & 0xff];
+ return (z_crc_t)data;
+}
+
+local z_word_t crc_word_big(data)
+ z_word_t data;
+{
+ int k;
+ for (k = 0; k < W; k++)
+ data = (data << 8) ^
+ crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
+ return data;
+}
+
+#endif
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32_z(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ /* Return initial CRC, if requested. */
+ if (buf == Z_NULL) return 0;
+
+#ifdef DYNAMIC_CRC_TABLE
+ once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+
+ /* Pre-condition the CRC */
+ crc ^= 0xffffffff;
+
+#ifdef W
+
+ /* If provided enough bytes, do a braided CRC calculation. */
+ if (len >= N * W + W - 1) {
+ z_size_t blks;
+ z_word_t const *words;
+ unsigned endian;
+ int k;
+
+ /* Compute the CRC up to a z_word_t boundary. */
+ while (len && ((z_size_t)buf & (W - 1)) != 0) {
+ len--;
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ }
+
+ /* Compute the CRC on as many N z_word_t blocks as are available. */
+ blks = len / (N * W);
+ len -= blks * N * W;
+ words = (z_word_t const *)buf;
+
+ /* Do endian check at execution time instead of compile time, since ARM
+ processors can change the endianess at execution time. If the
+ compiler knows what the endianess will be, it can optimize out the
+ check and the unused branch. */
+ endian = 1;
+ if (*(unsigned char *)&endian) {
+ /* Little endian. */
+
+ z_crc_t crc0;
+ z_word_t word0;
+#if N > 1
+ z_crc_t crc1;
+ z_word_t word1;
+#if N > 2
+ z_crc_t crc2;
+ z_word_t word2;
+#if N > 3
+ z_crc_t crc3;
+ z_word_t word3;
+#if N > 4
+ z_crc_t crc4;
+ z_word_t word4;
+#if N > 5
+ z_crc_t crc5;
+ z_word_t word5;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+ /* Initialize the CRC for each braid. */
+ crc0 = crc;
+#if N > 1
+ crc1 = 0;
+#if N > 2
+ crc2 = 0;
+#if N > 3
+ crc3 = 0;
+#if N > 4
+ crc4 = 0;
+#if N > 5
+ crc5 = 0;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+ /*
+ Process the first blks-1 blocks, computing the CRCs on each braid
+ independently.
+ */
+ while (--blks) {
+ /* Load the word for each braid into registers. */
+ word0 = crc0 ^ words[0];
+#if N > 1
+ word1 = crc1 ^ words[1];
+#if N > 2
+ word2 = crc2 ^ words[2];
+#if N > 3
+ word3 = crc3 ^ words[3];
+#if N > 4
+ word4 = crc4 ^ words[4];
+#if N > 5
+ word5 = crc5 ^ words[5];
+#endif
+#endif
+#endif
+#endif
+#endif
+ words += N;
+
+ /* Compute and update the CRC for each word. The loop should
+ get unrolled. */
+ crc0 = crc_braid_table[0][word0 & 0xff];
+#if N > 1
+ crc1 = crc_braid_table[0][word1 & 0xff];
+#if N > 2
+ crc2 = crc_braid_table[0][word2 & 0xff];
+#if N > 3
+ crc3 = crc_braid_table[0][word3 & 0xff];
+#if N > 4
+ crc4 = crc_braid_table[0][word4 & 0xff];
+#if N > 5
+ crc5 = crc_braid_table[0][word5 & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+ for (k = 1; k < W; k++) {
+ crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff];
+#if N > 1
+ crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff];
+#if N > 2
+ crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff];
+#if N > 3
+ crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff];
+#if N > 4
+ crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff];
+#if N > 5
+ crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+ }
+ }
+
+ /*
+ Process the last block, combining the CRCs of the N braids at the
+ same time.
+ */
+ crc = crc_word(crc0 ^ words[0]);
+#if N > 1
+ crc = crc_word(crc1 ^ words[1] ^ crc);
+#if N > 2
+ crc = crc_word(crc2 ^ words[2] ^ crc);
+#if N > 3
+ crc = crc_word(crc3 ^ words[3] ^ crc);
+#if N > 4
+ crc = crc_word(crc4 ^ words[4] ^ crc);
+#if N > 5
+ crc = crc_word(crc5 ^ words[5] ^ crc);
+#endif
+#endif
+#endif
+#endif
+#endif
+ words += N;
+ }
+ else {
+ /* Big endian. */
+
+ z_word_t crc0, word0, comb;
+#if N > 1
+ z_word_t crc1, word1;
+#if N > 2
+ z_word_t crc2, word2;
+#if N > 3
+ z_word_t crc3, word3;
+#if N > 4
+ z_word_t crc4, word4;
+#if N > 5
+ z_word_t crc5, word5;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+ /* Initialize the CRC for each braid. */
+ crc0 = byte_swap(crc);
+#if N > 1
+ crc1 = 0;
+#if N > 2
+ crc2 = 0;
+#if N > 3
+ crc3 = 0;
+#if N > 4
+ crc4 = 0;
+#if N > 5
+ crc5 = 0;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+ /*
+ Process the first blks-1 blocks, computing the CRCs on each braid
+ independently.
+ */
+ while (--blks) {
+ /* Load the word for each braid into registers. */
+ word0 = crc0 ^ words[0];
+#if N > 1
+ word1 = crc1 ^ words[1];
+#if N > 2
+ word2 = crc2 ^ words[2];
+#if N > 3
+ word3 = crc3 ^ words[3];
+#if N > 4
+ word4 = crc4 ^ words[4];
+#if N > 5
+ word5 = crc5 ^ words[5];
+#endif
+#endif
+#endif
+#endif
+#endif
+ words += N;
+
+ /* Compute and update the CRC for each word. The loop should
+ get unrolled. */
+ crc0 = crc_braid_big_table[0][word0 & 0xff];
+#if N > 1
+ crc1 = crc_braid_big_table[0][word1 & 0xff];
+#if N > 2
+ crc2 = crc_braid_big_table[0][word2 & 0xff];
+#if N > 3
+ crc3 = crc_braid_big_table[0][word3 & 0xff];
+#if N > 4
+ crc4 = crc_braid_big_table[0][word4 & 0xff];
+#if N > 5
+ crc5 = crc_braid_big_table[0][word5 & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+ for (k = 1; k < W; k++) {
+ crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff];
+#if N > 1
+ crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff];
+#if N > 2
+ crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff];
+#if N > 3
+ crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff];
+#if N > 4
+ crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff];
+#if N > 5
+ crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+ }
+ }
+
+ /*
+ Process the last block, combining the CRCs of the N braids at the
+ same time.
+ */
+ comb = crc_word_big(crc0 ^ words[0]);
+#if N > 1
+ comb = crc_word_big(crc1 ^ words[1] ^ comb);
+#if N > 2
+ comb = crc_word_big(crc2 ^ words[2] ^ comb);
+#if N > 3
+ comb = crc_word_big(crc3 ^ words[3] ^ comb);
+#if N > 4
+ comb = crc_word_big(crc4 ^ words[4] ^ comb);
+#if N > 5
+ comb = crc_word_big(crc5 ^ words[5] ^ comb);
+#endif
+#endif
+#endif
+#endif
+#endif
+ words += N;
+ crc = byte_swap(comb);
+ }
+
+ /*
+ Update the pointer to the remaining bytes to process.
+ */
+ buf = (unsigned char const *)words;
+ }
+
+#endif /* W */
+
+ /* Complete the computation of the CRC on any remaining bytes. */
+ while (len >= 8) {
+ len -= 8;
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ }
+ while (len) {
+ len--;
+ crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+ }
+
+ /* Return the CRC, post-conditioned. */
+ return crc ^ 0xffffffff;
+}
+
+#endif
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ uInt len;
+{
+ return crc32_z(crc, buf, len);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+#ifdef DYNAMIC_CRC_TABLE
+ once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+ return multmodp(x2nmodp(len2, 3), crc1) ^ crc2;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ return crc32_combine64(crc1, crc2, len2);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine_gen64(len2)
+ z_off64_t len2;
+{
+#ifdef DYNAMIC_CRC_TABLE
+ once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+ return x2nmodp(len2, 3);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine_gen(len2)
+ z_off_t len2;
+{
+ return crc32_combine_gen64(len2);
+}
+
+/* ========================================================================= */
+uLong crc32_combine_op(crc1, crc2, op)
+ uLong crc1;
+ uLong crc2;
+ uLong op;
+{
+ return multmodp(op, crc1) ^ crc2;
+}
diff --git a/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/crc32.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/crc32.h
new file mode 100644
index 00000000..137df68d
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/crc32.h
@@ -0,0 +1,9446 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d};
+
+#ifdef W
+
+#if W == 8
+
+local const z_word_t FAR crc_big_table[] = {
+ 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000,
+ 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000,
+ 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000,
+ 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000,
+ 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000,
+ 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000,
+ 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000,
+ 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000,
+ 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000,
+ 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000,
+ 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000,
+ 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000,
+ 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000,
+ 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000,
+ 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000,
+ 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000,
+ 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000,
+ 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000,
+ 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000,
+ 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000,
+ 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000,
+ 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000,
+ 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000,
+ 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000,
+ 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000,
+ 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000,
+ 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000,
+ 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000,
+ 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000,
+ 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000,
+ 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000,
+ 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000,
+ 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000,
+ 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000,
+ 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000,
+ 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000,
+ 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000,
+ 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000,
+ 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000,
+ 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000,
+ 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000,
+ 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000,
+ 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000,
+ 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000,
+ 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000,
+ 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000,
+ 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000,
+ 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000,
+ 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000,
+ 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000,
+ 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000,
+ 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000,
+ 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000,
+ 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000,
+ 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000,
+ 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000,
+ 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000,
+ 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000,
+ 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000,
+ 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000,
+ 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000,
+ 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000,
+ 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000,
+ 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000,
+ 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000,
+ 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000,
+ 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000,
+ 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000,
+ 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000,
+ 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000,
+ 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000,
+ 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000,
+ 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000,
+ 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000,
+ 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000,
+ 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000,
+ 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000,
+ 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000,
+ 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000,
+ 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000,
+ 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000,
+ 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000,
+ 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000,
+ 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000,
+ 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000,
+ 0x8def022d00000000};
+
+#else /* W == 4 */
+
+local const z_word_t FAR crc_big_table[] = {
+ 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07,
+ 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79,
+ 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7,
+ 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84,
+ 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13,
+ 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663,
+ 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5,
+ 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5,
+ 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832,
+ 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51,
+ 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf,
+ 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1,
+ 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76,
+ 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606,
+ 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996,
+ 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6,
+ 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c,
+ 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712,
+ 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c,
+ 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4,
+ 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943,
+ 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333,
+ 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe,
+ 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce,
+ 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359,
+ 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a,
+ 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04,
+ 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a,
+ 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0,
+ 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580,
+ 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10,
+ 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060,
+ 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1,
+ 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf,
+ 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31,
+ 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852,
+ 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5,
+ 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5,
+ 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75,
+ 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005,
+ 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292,
+ 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1,
+ 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f,
+ 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111,
+ 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0,
+ 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0,
+ 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40,
+ 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530,
+ 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba,
+ 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4,
+ 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a,
+ 0x8def022d};
+
+#endif
+
+#if N == 1
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa,
+ 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b,
+ 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232,
+ 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,
+ 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,
+ 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa,
+ 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b,
+ 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,
+ 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719,
+ 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3,
+ 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,
+ 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,
+ 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed,
+ 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89,
+ 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25,
+ 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
+ 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,
+ 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed,
+ 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4,
+ 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,
+ 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e,
+ 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a,
+ 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,
+ 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,
+ 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df,
+ 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544,
+ 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d,
+ 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,
+ 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,
+ 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95,
+ 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839,
+ 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
+ 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976,
+ 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7,
+ 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,
+ 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,
+ 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12,
+ 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376,
+ 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a,
+ 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,
+ 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,
+ 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682,
+ 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b,
+ 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,
+ 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561,
+ 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05,
+ 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,
+ 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
+ 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0,
+ 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61,
+ 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678,
+ 0x264b06e6},
+ {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413,
+ 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3,
+ 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d,
+ 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,
+ 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,
+ 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e,
+ 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5,
+ 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,
+ 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8,
+ 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6,
+ 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,
+ 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,
+ 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579,
+ 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade,
+ 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37,
+ 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
+ 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,
+ 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64,
+ 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea,
+ 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,
+ 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282,
+ 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25,
+ 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,
+ 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,
+ 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f,
+ 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146,
+ 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8,
+ 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,
+ 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,
+ 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b,
+ 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972,
+ 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
+ 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d,
+ 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd,
+ 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,
+ 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,
+ 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7,
+ 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60,
+ 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2,
+ 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,
+ 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,
+ 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1,
+ 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f,
+ 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,
+ 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617,
+ 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0,
+ 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,
+ 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
+ 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca,
+ 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a,
+ 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184,
+ 0x92364a30},
+ {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216,
+ 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8,
+ 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170,
+ 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,
+ 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,
+ 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145,
+ 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d,
+ 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,
+ 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d,
+ 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408,
+ 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,
+ 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,
+ 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c,
+ 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf,
+ 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a,
+ 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
+ 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,
+ 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f,
+ 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987,
+ 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,
+ 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37,
+ 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84,
+ 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,
+ 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,
+ 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba,
+ 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d,
+ 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5,
+ 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,
+ 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,
+ 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0,
+ 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525,
+ 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
+ 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8,
+ 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026,
+ 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,
+ 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,
+ 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118,
+ 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab,
+ 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf,
+ 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,
+ 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,
+ 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a,
+ 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32,
+ 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,
+ 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82,
+ 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31,
+ 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,
+ 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
+ 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f,
+ 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1,
+ 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869,
+ 0xe4c4abcc},
+ {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0,
+ 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271,
+ 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61,
+ 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,
+ 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,
+ 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333,
+ 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64,
+ 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,
+ 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205,
+ 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136,
+ 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,
+ 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,
+ 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849,
+ 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739,
+ 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8,
+ 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
+ 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,
+ 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba,
+ 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa,
+ 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,
+ 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c,
+ 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc,
+ 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,
+ 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,
+ 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce,
+ 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922,
+ 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532,
+ 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,
+ 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,
+ 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860,
+ 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1,
+ 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
+ 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956,
+ 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7,
+ 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,
+ 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,
+ 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5,
+ 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5,
+ 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb,
+ 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,
+ 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,
+ 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9,
+ 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9,
+ 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,
+ 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df,
+ 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af,
+ 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,
+ 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
+ 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d,
+ 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c,
+ 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c,
+ 0xca64c78c},
+ {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757,
+ 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a,
+ 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733,
+ 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
+ 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,
+ 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42,
+ 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5,
+ 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
+ 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086,
+ 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4,
+ 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,
+ 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
+ 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d,
+ 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f,
+ 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859,
+ 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
+ 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,
+ 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028,
+ 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891,
+ 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
+ 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec,
+ 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde,
+ 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,
+ 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
+ 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24,
+ 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e,
+ 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7,
+ 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
+ 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,
+ 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196,
+ 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0,
+ 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
+ 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52,
+ 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f,
+ 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,
+ 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
+ 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675,
+ 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647,
+ 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d,
+ 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
+ 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,
+ 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc,
+ 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645,
+ 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
+ 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138,
+ 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a,
+ 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,
+ 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
+ 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0,
+ 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d,
+ 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194,
+ 0xde0506f1},
+ {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc,
+ 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f,
+ 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a,
+ 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
+ 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,
+ 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023,
+ 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e,
+ 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
+ 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84,
+ 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7,
+ 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,
+ 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
+ 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0,
+ 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b,
+ 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816,
+ 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
+ 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,
+ 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f,
+ 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba,
+ 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
+ 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98,
+ 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873,
+ 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,
+ 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
+ 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134,
+ 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7,
+ 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732,
+ 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
+ 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,
+ 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b,
+ 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26,
+ 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
+ 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc,
+ 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef,
+ 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,
+ 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
+ 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8,
+ 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43,
+ 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e,
+ 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
+ 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,
+ 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07,
+ 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982,
+ 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
+ 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0,
+ 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b,
+ 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,
+ 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
+ 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c,
+ 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f,
+ 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda,
+ 0xbe9834ed},
+ {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504,
+ 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49,
+ 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e,
+ 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
+ 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,
+ 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c,
+ 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620,
+ 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
+ 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae,
+ 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2,
+ 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,
+ 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
+ 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05,
+ 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40,
+ 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f,
+ 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
+ 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,
+ 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d,
+ 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da,
+ 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
+ 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af,
+ 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea,
+ 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,
+ 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
+ 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa,
+ 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a,
+ 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd,
+ 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
+ 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,
+ 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f,
+ 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290,
+ 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
+ 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed,
+ 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0,
+ 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,
+ 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
+ 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0,
+ 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5,
+ 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc,
+ 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
+ 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,
+ 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e,
+ 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299,
+ 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
+ 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec,
+ 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9,
+ 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,
+ 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
+ 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9,
+ 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4,
+ 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33,
+ 0x9324fd72},
+ {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000,
+ 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000,
+ 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000,
+ 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000,
+ 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000,
+ 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000,
+ 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000,
+ 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000,
+ 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000,
+ 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000,
+ 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000,
+ 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000,
+ 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000,
+ 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000,
+ 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000,
+ 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000,
+ 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000,
+ 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000,
+ 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000,
+ 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000,
+ 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000,
+ 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000,
+ 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000,
+ 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000,
+ 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000,
+ 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000,
+ 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000,
+ 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000,
+ 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000,
+ 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000,
+ 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000,
+ 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000,
+ 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000,
+ 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000,
+ 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000,
+ 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000,
+ 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000,
+ 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000,
+ 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000,
+ 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000,
+ 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000,
+ 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000,
+ 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000,
+ 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000,
+ 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000,
+ 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000,
+ 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000,
+ 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000,
+ 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000,
+ 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000,
+ 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000,
+ 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000,
+ 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000,
+ 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000,
+ 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000,
+ 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000,
+ 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000,
+ 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000,
+ 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000,
+ 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000,
+ 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000,
+ 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000,
+ 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000,
+ 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000,
+ 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000,
+ 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000,
+ 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000,
+ 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000,
+ 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000,
+ 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000,
+ 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000,
+ 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000,
+ 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000,
+ 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000,
+ 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000,
+ 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000,
+ 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000,
+ 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000,
+ 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000,
+ 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000,
+ 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000,
+ 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000,
+ 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000,
+ 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000,
+ 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000,
+ 0x8def022d00000000},
+ {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000,
+ 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000,
+ 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000,
+ 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000,
+ 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000,
+ 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000,
+ 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000,
+ 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000,
+ 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000,
+ 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000,
+ 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000,
+ 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000,
+ 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000,
+ 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000,
+ 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000,
+ 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000,
+ 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000,
+ 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000,
+ 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000,
+ 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000,
+ 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000,
+ 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000,
+ 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000,
+ 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000,
+ 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000,
+ 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000,
+ 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000,
+ 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000,
+ 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000,
+ 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000,
+ 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000,
+ 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000,
+ 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000,
+ 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000,
+ 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000,
+ 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000,
+ 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000,
+ 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000,
+ 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000,
+ 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000,
+ 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000,
+ 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000,
+ 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000,
+ 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000,
+ 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000,
+ 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000,
+ 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000,
+ 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000,
+ 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000,
+ 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000,
+ 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000,
+ 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000,
+ 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000,
+ 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000,
+ 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000,
+ 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000,
+ 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000,
+ 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000,
+ 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000,
+ 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000,
+ 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000,
+ 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000,
+ 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000,
+ 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000,
+ 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000,
+ 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000,
+ 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000,
+ 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000,
+ 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000,
+ 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000,
+ 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000,
+ 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000,
+ 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000,
+ 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000,
+ 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000,
+ 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000,
+ 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000,
+ 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000,
+ 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000,
+ 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000,
+ 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000,
+ 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000,
+ 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000,
+ 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000,
+ 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000,
+ 0x72fd249300000000},
+ {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000,
+ 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000,
+ 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000,
+ 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000,
+ 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000,
+ 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000,
+ 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000,
+ 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000,
+ 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000,
+ 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000,
+ 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000,
+ 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000,
+ 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000,
+ 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000,
+ 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000,
+ 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000,
+ 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000,
+ 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000,
+ 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000,
+ 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000,
+ 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000,
+ 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000,
+ 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000,
+ 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000,
+ 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000,
+ 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000,
+ 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000,
+ 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000,
+ 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000,
+ 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000,
+ 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000,
+ 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000,
+ 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000,
+ 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000,
+ 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000,
+ 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000,
+ 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000,
+ 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000,
+ 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000,
+ 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000,
+ 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000,
+ 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000,
+ 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000,
+ 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000,
+ 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000,
+ 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000,
+ 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000,
+ 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000,
+ 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000,
+ 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000,
+ 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000,
+ 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000,
+ 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000,
+ 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000,
+ 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000,
+ 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000,
+ 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000,
+ 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000,
+ 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000,
+ 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000,
+ 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000,
+ 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000,
+ 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000,
+ 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000,
+ 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000,
+ 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000,
+ 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000,
+ 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000,
+ 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000,
+ 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000,
+ 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000,
+ 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000,
+ 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000,
+ 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000,
+ 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000,
+ 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000,
+ 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000,
+ 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000,
+ 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000,
+ 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000,
+ 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000,
+ 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000,
+ 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000,
+ 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000,
+ 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000,
+ 0xed3498be00000000},
+ {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000,
+ 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000,
+ 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000,
+ 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000,
+ 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000,
+ 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000,
+ 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000,
+ 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000,
+ 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000,
+ 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000,
+ 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000,
+ 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000,
+ 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000,
+ 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000,
+ 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000,
+ 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000,
+ 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000,
+ 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000,
+ 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000,
+ 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000,
+ 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000,
+ 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000,
+ 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000,
+ 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000,
+ 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000,
+ 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000,
+ 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000,
+ 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000,
+ 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000,
+ 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000,
+ 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000,
+ 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000,
+ 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000,
+ 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000,
+ 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000,
+ 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000,
+ 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000,
+ 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000,
+ 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000,
+ 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000,
+ 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000,
+ 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000,
+ 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000,
+ 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000,
+ 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000,
+ 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000,
+ 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000,
+ 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000,
+ 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000,
+ 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000,
+ 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000,
+ 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000,
+ 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000,
+ 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000,
+ 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000,
+ 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000,
+ 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000,
+ 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000,
+ 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000,
+ 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000,
+ 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000,
+ 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000,
+ 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000,
+ 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000,
+ 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000,
+ 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000,
+ 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000,
+ 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000,
+ 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000,
+ 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000,
+ 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000,
+ 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000,
+ 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000,
+ 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000,
+ 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000,
+ 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000,
+ 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000,
+ 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000,
+ 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000,
+ 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000,
+ 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000,
+ 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000,
+ 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000,
+ 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000,
+ 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000,
+ 0xf10605de00000000},
+ {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000,
+ 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000,
+ 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000,
+ 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000,
+ 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000,
+ 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000,
+ 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000,
+ 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000,
+ 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000,
+ 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000,
+ 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000,
+ 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000,
+ 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000,
+ 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000,
+ 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000,
+ 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000,
+ 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000,
+ 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000,
+ 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000,
+ 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000,
+ 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000,
+ 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000,
+ 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000,
+ 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000,
+ 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000,
+ 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000,
+ 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000,
+ 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000,
+ 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000,
+ 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000,
+ 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000,
+ 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000,
+ 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000,
+ 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000,
+ 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000,
+ 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000,
+ 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000,
+ 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000,
+ 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000,
+ 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000,
+ 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000,
+ 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000,
+ 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000,
+ 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000,
+ 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000,
+ 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000,
+ 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000,
+ 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000,
+ 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000,
+ 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000,
+ 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000,
+ 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000,
+ 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000,
+ 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000,
+ 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000,
+ 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000,
+ 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000,
+ 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000,
+ 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000,
+ 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000,
+ 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000,
+ 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000,
+ 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000,
+ 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000,
+ 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000,
+ 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000,
+ 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000,
+ 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000,
+ 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000,
+ 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000,
+ 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000,
+ 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000,
+ 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000,
+ 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000,
+ 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000,
+ 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000,
+ 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000,
+ 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000,
+ 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000,
+ 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000,
+ 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000,
+ 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000,
+ 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000,
+ 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000,
+ 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000,
+ 0x8cc764ca00000000},
+ {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000,
+ 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000,
+ 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000,
+ 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000,
+ 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000,
+ 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000,
+ 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000,
+ 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000,
+ 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000,
+ 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000,
+ 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000,
+ 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000,
+ 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000,
+ 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000,
+ 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000,
+ 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000,
+ 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000,
+ 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000,
+ 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000,
+ 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000,
+ 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000,
+ 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000,
+ 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000,
+ 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000,
+ 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000,
+ 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000,
+ 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000,
+ 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000,
+ 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000,
+ 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000,
+ 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000,
+ 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000,
+ 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000,
+ 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000,
+ 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000,
+ 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000,
+ 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000,
+ 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000,
+ 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000,
+ 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000,
+ 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000,
+ 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000,
+ 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000,
+ 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000,
+ 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000,
+ 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000,
+ 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000,
+ 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000,
+ 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000,
+ 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000,
+ 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000,
+ 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000,
+ 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000,
+ 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000,
+ 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000,
+ 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000,
+ 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000,
+ 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000,
+ 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000,
+ 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000,
+ 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000,
+ 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000,
+ 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000,
+ 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000,
+ 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000,
+ 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000,
+ 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000,
+ 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000,
+ 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000,
+ 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000,
+ 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000,
+ 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000,
+ 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000,
+ 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000,
+ 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000,
+ 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000,
+ 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000,
+ 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000,
+ 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000,
+ 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000,
+ 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000,
+ 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000,
+ 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000,
+ 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000,
+ 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000,
+ 0xccabc4e400000000},
+ {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000,
+ 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000,
+ 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000,
+ 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000,
+ 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000,
+ 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000,
+ 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000,
+ 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000,
+ 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000,
+ 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000,
+ 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000,
+ 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000,
+ 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000,
+ 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000,
+ 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000,
+ 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000,
+ 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000,
+ 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000,
+ 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000,
+ 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000,
+ 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000,
+ 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000,
+ 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000,
+ 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000,
+ 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000,
+ 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000,
+ 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000,
+ 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000,
+ 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000,
+ 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000,
+ 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000,
+ 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000,
+ 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000,
+ 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000,
+ 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000,
+ 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000,
+ 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000,
+ 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000,
+ 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000,
+ 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000,
+ 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000,
+ 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000,
+ 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000,
+ 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000,
+ 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000,
+ 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000,
+ 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000,
+ 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000,
+ 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000,
+ 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000,
+ 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000,
+ 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000,
+ 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000,
+ 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000,
+ 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000,
+ 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000,
+ 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000,
+ 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000,
+ 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000,
+ 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000,
+ 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000,
+ 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000,
+ 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000,
+ 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000,
+ 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000,
+ 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000,
+ 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000,
+ 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000,
+ 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000,
+ 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000,
+ 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000,
+ 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000,
+ 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000,
+ 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000,
+ 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000,
+ 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000,
+ 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000,
+ 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000,
+ 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000,
+ 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000,
+ 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000,
+ 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000,
+ 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000,
+ 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000,
+ 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000,
+ 0x304a369200000000},
+ {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000,
+ 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000,
+ 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000,
+ 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000,
+ 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000,
+ 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000,
+ 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000,
+ 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000,
+ 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000,
+ 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000,
+ 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000,
+ 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000,
+ 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000,
+ 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000,
+ 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000,
+ 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000,
+ 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000,
+ 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000,
+ 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000,
+ 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000,
+ 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000,
+ 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000,
+ 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000,
+ 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000,
+ 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000,
+ 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000,
+ 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000,
+ 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000,
+ 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000,
+ 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000,
+ 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000,
+ 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000,
+ 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000,
+ 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000,
+ 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000,
+ 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000,
+ 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000,
+ 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000,
+ 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000,
+ 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000,
+ 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000,
+ 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000,
+ 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000,
+ 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000,
+ 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000,
+ 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000,
+ 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000,
+ 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000,
+ 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000,
+ 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000,
+ 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000,
+ 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000,
+ 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000,
+ 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000,
+ 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000,
+ 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000,
+ 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000,
+ 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000,
+ 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000,
+ 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000,
+ 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000,
+ 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000,
+ 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000,
+ 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000,
+ 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000,
+ 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000,
+ 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000,
+ 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000,
+ 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000,
+ 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000,
+ 0x6171384400000000, 0xff71928800000000, 0xe678578200000000,
+ 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000,
+ 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000,
+ 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000,
+ 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000,
+ 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000,
+ 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000,
+ 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000,
+ 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000,
+ 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000,
+ 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000,
+ 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000,
+ 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000,
+ 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000,
+ 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000,
+ 0xe6064b2600000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757,
+ 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a,
+ 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733,
+ 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
+ 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,
+ 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42,
+ 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5,
+ 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
+ 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086,
+ 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4,
+ 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,
+ 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
+ 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d,
+ 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f,
+ 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859,
+ 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
+ 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,
+ 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028,
+ 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891,
+ 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
+ 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec,
+ 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde,
+ 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,
+ 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
+ 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24,
+ 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e,
+ 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7,
+ 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
+ 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,
+ 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196,
+ 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0,
+ 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
+ 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52,
+ 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f,
+ 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,
+ 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
+ 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675,
+ 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647,
+ 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d,
+ 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
+ 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,
+ 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc,
+ 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645,
+ 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
+ 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138,
+ 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a,
+ 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,
+ 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
+ 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0,
+ 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d,
+ 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194,
+ 0xde0506f1},
+ {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc,
+ 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f,
+ 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a,
+ 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
+ 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,
+ 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023,
+ 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e,
+ 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
+ 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84,
+ 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7,
+ 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,
+ 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
+ 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0,
+ 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b,
+ 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816,
+ 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
+ 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,
+ 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f,
+ 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba,
+ 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
+ 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98,
+ 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873,
+ 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,
+ 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
+ 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134,
+ 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7,
+ 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732,
+ 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
+ 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,
+ 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b,
+ 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26,
+ 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
+ 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc,
+ 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef,
+ 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,
+ 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
+ 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8,
+ 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43,
+ 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e,
+ 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
+ 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,
+ 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07,
+ 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982,
+ 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
+ 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0,
+ 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b,
+ 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,
+ 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
+ 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c,
+ 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f,
+ 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda,
+ 0xbe9834ed},
+ {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504,
+ 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49,
+ 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e,
+ 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
+ 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,
+ 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c,
+ 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620,
+ 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
+ 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae,
+ 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2,
+ 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,
+ 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
+ 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05,
+ 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40,
+ 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f,
+ 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
+ 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,
+ 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d,
+ 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da,
+ 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
+ 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af,
+ 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea,
+ 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,
+ 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
+ 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa,
+ 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a,
+ 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd,
+ 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
+ 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,
+ 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f,
+ 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290,
+ 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
+ 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed,
+ 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0,
+ 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,
+ 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
+ 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0,
+ 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5,
+ 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc,
+ 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
+ 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,
+ 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e,
+ 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299,
+ 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
+ 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec,
+ 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9,
+ 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,
+ 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
+ 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9,
+ 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4,
+ 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33,
+ 0x9324fd72},
+ {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07,
+ 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79,
+ 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7,
+ 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84,
+ 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13,
+ 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663,
+ 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5,
+ 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5,
+ 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832,
+ 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51,
+ 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf,
+ 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1,
+ 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76,
+ 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606,
+ 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996,
+ 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6,
+ 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c,
+ 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712,
+ 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c,
+ 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4,
+ 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943,
+ 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333,
+ 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe,
+ 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce,
+ 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359,
+ 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a,
+ 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04,
+ 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a,
+ 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0,
+ 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580,
+ 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10,
+ 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060,
+ 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1,
+ 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf,
+ 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31,
+ 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852,
+ 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5,
+ 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5,
+ 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75,
+ 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005,
+ 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292,
+ 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1,
+ 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f,
+ 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111,
+ 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0,
+ 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0,
+ 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40,
+ 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530,
+ 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba,
+ 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4,
+ 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a,
+ 0x8def022d},
+ {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64,
+ 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1,
+ 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e,
+ 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61,
+ 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82,
+ 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff,
+ 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7,
+ 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da,
+ 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139,
+ 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6,
+ 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89,
+ 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c,
+ 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0,
+ 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d,
+ 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a,
+ 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177,
+ 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de,
+ 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b,
+ 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824,
+ 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e,
+ 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad,
+ 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0,
+ 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d,
+ 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60,
+ 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83,
+ 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822,
+ 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d,
+ 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8,
+ 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171,
+ 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c,
+ 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b,
+ 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6,
+ 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca,
+ 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f,
+ 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430,
+ 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf,
+ 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c,
+ 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51,
+ 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9,
+ 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84,
+ 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67,
+ 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398,
+ 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7,
+ 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62,
+ 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e,
+ 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923,
+ 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4,
+ 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9,
+ 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070,
+ 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5,
+ 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a,
+ 0x72fd2493},
+ {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907,
+ 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f,
+ 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a,
+ 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e,
+ 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512,
+ 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14,
+ 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b,
+ 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d,
+ 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731,
+ 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925,
+ 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620,
+ 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28,
+ 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70,
+ 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176,
+ 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d,
+ 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b,
+ 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b,
+ 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63,
+ 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266,
+ 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a,
+ 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446,
+ 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40,
+ 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557,
+ 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51,
+ 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d,
+ 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0,
+ 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5,
+ 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed,
+ 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd,
+ 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb,
+ 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0,
+ 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6,
+ 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de,
+ 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6,
+ 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3,
+ 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7,
+ 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb,
+ 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd,
+ 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92,
+ 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094,
+ 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598,
+ 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c,
+ 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489,
+ 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81,
+ 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9,
+ 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af,
+ 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4,
+ 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2,
+ 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2,
+ 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba,
+ 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf,
+ 0xed3498be},
+ {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f,
+ 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d,
+ 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0,
+ 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42,
+ 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95,
+ 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2,
+ 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a,
+ 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d,
+ 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea,
+ 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748,
+ 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5,
+ 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27,
+ 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b,
+ 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac,
+ 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4,
+ 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3,
+ 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44,
+ 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6,
+ 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b,
+ 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329,
+ 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe,
+ 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9,
+ 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1,
+ 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6,
+ 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921,
+ 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555,
+ 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8,
+ 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a,
+ 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd,
+ 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a,
+ 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2,
+ 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5,
+ 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2,
+ 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330,
+ 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad,
+ 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f,
+ 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8,
+ 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef,
+ 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc,
+ 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb,
+ 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c,
+ 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e,
+ 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03,
+ 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1,
+ 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6,
+ 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1,
+ 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9,
+ 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e,
+ 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409,
+ 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb,
+ 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966,
+ 0xf10605de}};
+
+#endif
+
+#endif
+
+#if N == 2
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87,
+ 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede,
+ 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab,
+ 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c,
+ 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1,
+ 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7,
+ 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e,
+ 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308,
+ 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5,
+ 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472,
+ 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07,
+ 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e,
+ 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa,
+ 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec,
+ 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6,
+ 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0,
+ 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3,
+ 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba,
+ 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf,
+ 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975,
+ 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8,
+ 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde,
+ 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a,
+ 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c,
+ 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1,
+ 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65,
+ 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410,
+ 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649,
+ 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a,
+ 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c,
+ 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946,
+ 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450,
+ 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e,
+ 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857,
+ 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022,
+ 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5,
+ 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758,
+ 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e,
+ 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d,
+ 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b,
+ 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6,
+ 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401,
+ 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74,
+ 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d,
+ 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073,
+ 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65,
+ 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f,
+ 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749,
+ 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a,
+ 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033,
+ 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846,
+ 0x0d7139d7},
+ {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563,
+ 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f,
+ 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875,
+ 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536,
+ 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8,
+ 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43,
+ 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f,
+ 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184,
+ 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a,
+ 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39,
+ 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523,
+ 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f,
+ 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d,
+ 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6,
+ 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b,
+ 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0,
+ 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151,
+ 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d,
+ 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47,
+ 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a,
+ 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964,
+ 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef,
+ 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d,
+ 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6,
+ 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348,
+ 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53,
+ 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449,
+ 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645,
+ 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4,
+ 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f,
+ 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2,
+ 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69,
+ 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46,
+ 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a,
+ 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650,
+ 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13,
+ 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded,
+ 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366,
+ 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57,
+ 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc,
+ 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222,
+ 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61,
+ 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b,
+ 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277,
+ 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558,
+ 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3,
+ 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e,
+ 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5,
+ 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74,
+ 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78,
+ 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262,
+ 0x1c53e98a},
+ {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b,
+ 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40,
+ 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580,
+ 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7,
+ 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a,
+ 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37,
+ 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75,
+ 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218,
+ 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5,
+ 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2,
+ 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02,
+ 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59,
+ 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1,
+ 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c,
+ 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a,
+ 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307,
+ 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486,
+ 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd,
+ 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d,
+ 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2,
+ 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f,
+ 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72,
+ 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8,
+ 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985,
+ 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268,
+ 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94,
+ 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454,
+ 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f,
+ 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e,
+ 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3,
+ 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915,
+ 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778,
+ 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821,
+ 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a,
+ 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba,
+ 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d,
+ 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560,
+ 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d,
+ 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe,
+ 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3,
+ 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e,
+ 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509,
+ 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9,
+ 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92,
+ 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb,
+ 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6,
+ 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50,
+ 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d,
+ 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc,
+ 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7,
+ 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927,
+ 0x3f88e851},
+ {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96,
+ 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8,
+ 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0,
+ 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14,
+ 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7,
+ 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4,
+ 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe,
+ 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad,
+ 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e,
+ 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa,
+ 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2,
+ 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c,
+ 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab,
+ 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8,
+ 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d,
+ 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e,
+ 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7,
+ 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99,
+ 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1,
+ 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690,
+ 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933,
+ 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20,
+ 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf,
+ 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc,
+ 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f,
+ 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92,
+ 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca,
+ 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4,
+ 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd,
+ 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de,
+ 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb,
+ 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8,
+ 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474,
+ 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a,
+ 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252,
+ 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6,
+ 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55,
+ 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846,
+ 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7,
+ 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4,
+ 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47,
+ 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3,
+ 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb,
+ 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5,
+ 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49,
+ 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a,
+ 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f,
+ 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c,
+ 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305,
+ 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b,
+ 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523,
+ 0x3dee8ca6},
+ {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f,
+ 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91,
+ 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e,
+ 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c,
+ 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02,
+ 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12,
+ 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567,
+ 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277,
+ 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679,
+ 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b,
+ 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4,
+ 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a,
+ 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0,
+ 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0,
+ 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91,
+ 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881,
+ 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173,
+ 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d,
+ 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912,
+ 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8,
+ 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6,
+ 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6,
+ 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b,
+ 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b,
+ 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75,
+ 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f,
+ 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00,
+ 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee,
+ 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c,
+ 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c,
+ 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d,
+ 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d,
+ 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67,
+ 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89,
+ 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706,
+ 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14,
+ 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a,
+ 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a,
+ 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f,
+ 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f,
+ 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591,
+ 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983,
+ 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c,
+ 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2,
+ 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8,
+ 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8,
+ 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89,
+ 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99,
+ 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b,
+ 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485,
+ 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a,
+ 0x36197165},
+ {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382,
+ 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85,
+ 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06,
+ 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca,
+ 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e,
+ 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc,
+ 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616,
+ 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54,
+ 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10,
+ 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc,
+ 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f,
+ 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58,
+ 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef,
+ 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad,
+ 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b,
+ 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29,
+ 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6,
+ 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1,
+ 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622,
+ 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039,
+ 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d,
+ 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f,
+ 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32,
+ 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770,
+ 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034,
+ 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f,
+ 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc,
+ 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db,
+ 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154,
+ 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16,
+ 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0,
+ 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592,
+ 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca,
+ 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd,
+ 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e,
+ 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882,
+ 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6,
+ 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384,
+ 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1,
+ 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3,
+ 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7,
+ 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b,
+ 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8,
+ 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff,
+ 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7,
+ 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5,
+ 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23,
+ 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761,
+ 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee,
+ 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9,
+ 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a,
+ 0x1a3b93aa},
+ {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a,
+ 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca,
+ 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3,
+ 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb,
+ 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c,
+ 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58,
+ 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed,
+ 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9,
+ 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e,
+ 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906,
+ 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f,
+ 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf,
+ 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0,
+ 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4,
+ 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769,
+ 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d,
+ 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632,
+ 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82,
+ 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb,
+ 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73,
+ 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484,
+ 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0,
+ 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5,
+ 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1,
+ 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516,
+ 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f,
+ 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946,
+ 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6,
+ 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9,
+ 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad,
+ 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820,
+ 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364,
+ 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab,
+ 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b,
+ 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62,
+ 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a,
+ 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd,
+ 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089,
+ 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c,
+ 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8,
+ 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f,
+ 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477,
+ 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e,
+ 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be,
+ 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71,
+ 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635,
+ 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8,
+ 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc,
+ 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3,
+ 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753,
+ 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a,
+ 0xe147d714},
+ {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c,
+ 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b,
+ 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92,
+ 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4,
+ 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069,
+ 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526,
+ 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25,
+ 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a,
+ 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7,
+ 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491,
+ 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958,
+ 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f,
+ 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307,
+ 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648,
+ 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999,
+ 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6,
+ 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a,
+ 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d,
+ 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4,
+ 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61,
+ 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc,
+ 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3,
+ 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53,
+ 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c,
+ 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1,
+ 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c,
+ 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5,
+ 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92,
+ 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e,
+ 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771,
+ 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0,
+ 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def,
+ 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0,
+ 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7,
+ 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e,
+ 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58,
+ 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285,
+ 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca,
+ 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce,
+ 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81,
+ 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c,
+ 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a,
+ 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3,
+ 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4,
+ 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb,
+ 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4,
+ 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75,
+ 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a,
+ 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296,
+ 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1,
+ 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808,
+ 0x494f0c4b}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000,
+ 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000,
+ 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000,
+ 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000,
+ 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000,
+ 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000,
+ 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000,
+ 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000,
+ 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000,
+ 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000,
+ 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000,
+ 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000,
+ 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000,
+ 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000,
+ 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000,
+ 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000,
+ 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000,
+ 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000,
+ 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000,
+ 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000,
+ 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000,
+ 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000,
+ 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000,
+ 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000,
+ 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000,
+ 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000,
+ 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000,
+ 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000,
+ 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000,
+ 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000,
+ 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000,
+ 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000,
+ 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000,
+ 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000,
+ 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000,
+ 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000,
+ 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000,
+ 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000,
+ 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000,
+ 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000,
+ 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000,
+ 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000,
+ 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000,
+ 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000,
+ 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000,
+ 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000,
+ 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000,
+ 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000,
+ 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000,
+ 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000,
+ 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000,
+ 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000,
+ 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000,
+ 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000,
+ 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000,
+ 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000,
+ 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000,
+ 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000,
+ 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000,
+ 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000,
+ 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000,
+ 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000,
+ 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000,
+ 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000,
+ 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000,
+ 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000,
+ 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000,
+ 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000,
+ 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000,
+ 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000,
+ 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000,
+ 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000,
+ 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000,
+ 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000,
+ 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000,
+ 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000,
+ 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000,
+ 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000,
+ 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000,
+ 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000,
+ 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000,
+ 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000,
+ 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000,
+ 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000,
+ 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000,
+ 0x4b0c4f4900000000},
+ {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000,
+ 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000,
+ 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000,
+ 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000,
+ 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000,
+ 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000,
+ 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000,
+ 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000,
+ 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000,
+ 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000,
+ 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000,
+ 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000,
+ 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000,
+ 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000,
+ 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000,
+ 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000,
+ 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000,
+ 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000,
+ 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000,
+ 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000,
+ 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000,
+ 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000,
+ 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000,
+ 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000,
+ 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000,
+ 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000,
+ 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000,
+ 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000,
+ 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000,
+ 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000,
+ 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000,
+ 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000,
+ 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000,
+ 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000,
+ 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000,
+ 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000,
+ 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000,
+ 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000,
+ 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000,
+ 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000,
+ 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000,
+ 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000,
+ 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000,
+ 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000,
+ 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000,
+ 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000,
+ 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000,
+ 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000,
+ 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000,
+ 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000,
+ 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000,
+ 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000,
+ 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000,
+ 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000,
+ 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000,
+ 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000,
+ 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000,
+ 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000,
+ 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000,
+ 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000,
+ 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000,
+ 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000,
+ 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000,
+ 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000,
+ 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000,
+ 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000,
+ 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000,
+ 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000,
+ 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000,
+ 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000,
+ 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000,
+ 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000,
+ 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000,
+ 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000,
+ 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000,
+ 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000,
+ 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000,
+ 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000,
+ 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000,
+ 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000,
+ 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000,
+ 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000,
+ 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000,
+ 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000,
+ 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000,
+ 0x14d747e100000000},
+ {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000,
+ 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000,
+ 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000,
+ 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000,
+ 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000,
+ 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000,
+ 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000,
+ 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000,
+ 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000,
+ 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000,
+ 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000,
+ 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000,
+ 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000,
+ 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000,
+ 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000,
+ 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000,
+ 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000,
+ 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000,
+ 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000,
+ 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000,
+ 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000,
+ 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000,
+ 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000,
+ 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000,
+ 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000,
+ 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000,
+ 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000,
+ 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000,
+ 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000,
+ 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000,
+ 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000,
+ 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000,
+ 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000,
+ 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000,
+ 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000,
+ 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000,
+ 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000,
+ 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000,
+ 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000,
+ 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000,
+ 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000,
+ 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000,
+ 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000,
+ 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000,
+ 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000,
+ 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000,
+ 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000,
+ 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000,
+ 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000,
+ 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000,
+ 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000,
+ 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000,
+ 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000,
+ 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000,
+ 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000,
+ 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000,
+ 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000,
+ 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000,
+ 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000,
+ 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000,
+ 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000,
+ 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000,
+ 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000,
+ 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000,
+ 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000,
+ 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000,
+ 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000,
+ 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000,
+ 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000,
+ 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000,
+ 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000,
+ 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000,
+ 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000,
+ 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000,
+ 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000,
+ 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000,
+ 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000,
+ 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000,
+ 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000,
+ 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000,
+ 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000,
+ 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000,
+ 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000,
+ 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000,
+ 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000,
+ 0xaa933b1a00000000},
+ {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000,
+ 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000,
+ 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000,
+ 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000,
+ 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000,
+ 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000,
+ 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000,
+ 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000,
+ 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000,
+ 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000,
+ 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000,
+ 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000,
+ 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000,
+ 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000,
+ 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000,
+ 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000,
+ 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000,
+ 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000,
+ 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000,
+ 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000,
+ 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000,
+ 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000,
+ 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000,
+ 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000,
+ 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000,
+ 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000,
+ 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000,
+ 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000,
+ 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000,
+ 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000,
+ 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000,
+ 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000,
+ 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000,
+ 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000,
+ 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000,
+ 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000,
+ 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000,
+ 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000,
+ 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000,
+ 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000,
+ 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000,
+ 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000,
+ 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000,
+ 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000,
+ 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000,
+ 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000,
+ 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000,
+ 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000,
+ 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000,
+ 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000,
+ 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000,
+ 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000,
+ 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000,
+ 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000,
+ 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000,
+ 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000,
+ 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000,
+ 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000,
+ 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000,
+ 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000,
+ 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000,
+ 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000,
+ 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000,
+ 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000,
+ 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000,
+ 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000,
+ 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000,
+ 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000,
+ 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000,
+ 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000,
+ 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000,
+ 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000,
+ 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000,
+ 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000,
+ 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000,
+ 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000,
+ 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000,
+ 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000,
+ 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000,
+ 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000,
+ 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000,
+ 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000,
+ 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000,
+ 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000,
+ 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000,
+ 0x6571193600000000},
+ {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000,
+ 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000,
+ 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000,
+ 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000,
+ 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000,
+ 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000,
+ 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000,
+ 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000,
+ 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000,
+ 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000,
+ 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000,
+ 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000,
+ 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000,
+ 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000,
+ 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000,
+ 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000,
+ 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000,
+ 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000,
+ 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000,
+ 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000,
+ 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000,
+ 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000,
+ 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000,
+ 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000,
+ 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000,
+ 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000,
+ 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000,
+ 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000,
+ 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000,
+ 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000,
+ 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000,
+ 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000,
+ 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000,
+ 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000,
+ 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000,
+ 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000,
+ 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000,
+ 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000,
+ 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000,
+ 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000,
+ 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000,
+ 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000,
+ 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000,
+ 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000,
+ 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000,
+ 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000,
+ 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000,
+ 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000,
+ 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000,
+ 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000,
+ 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000,
+ 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000,
+ 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000,
+ 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000,
+ 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000,
+ 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000,
+ 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000,
+ 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000,
+ 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000,
+ 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000,
+ 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000,
+ 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000,
+ 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000,
+ 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000,
+ 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000,
+ 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000,
+ 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000,
+ 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000,
+ 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000,
+ 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000,
+ 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000,
+ 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000,
+ 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000,
+ 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000,
+ 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000,
+ 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000,
+ 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000,
+ 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000,
+ 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000,
+ 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000,
+ 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000,
+ 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000,
+ 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000,
+ 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000,
+ 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000,
+ 0xa68cee3d00000000},
+ {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000,
+ 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000,
+ 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000,
+ 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000,
+ 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000,
+ 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000,
+ 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000,
+ 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000,
+ 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000,
+ 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000,
+ 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000,
+ 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000,
+ 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000,
+ 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000,
+ 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000,
+ 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000,
+ 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000,
+ 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000,
+ 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000,
+ 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000,
+ 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000,
+ 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000,
+ 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000,
+ 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000,
+ 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000,
+ 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000,
+ 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000,
+ 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000,
+ 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000,
+ 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000,
+ 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000,
+ 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000,
+ 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000,
+ 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000,
+ 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000,
+ 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000,
+ 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000,
+ 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000,
+ 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000,
+ 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000,
+ 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000,
+ 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000,
+ 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000,
+ 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000,
+ 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000,
+ 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000,
+ 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000,
+ 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000,
+ 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000,
+ 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000,
+ 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000,
+ 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000,
+ 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000,
+ 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000,
+ 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000,
+ 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000,
+ 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000,
+ 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000,
+ 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000,
+ 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000,
+ 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000,
+ 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000,
+ 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000,
+ 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000,
+ 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000,
+ 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000,
+ 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000,
+ 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000,
+ 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000,
+ 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000,
+ 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000,
+ 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000,
+ 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000,
+ 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000,
+ 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000,
+ 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000,
+ 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000,
+ 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000,
+ 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000,
+ 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000,
+ 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000,
+ 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000,
+ 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000,
+ 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000,
+ 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000,
+ 0x51e8883f00000000},
+ {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000,
+ 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000,
+ 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000,
+ 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000,
+ 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000,
+ 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000,
+ 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000,
+ 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000,
+ 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000,
+ 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000,
+ 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000,
+ 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000,
+ 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000,
+ 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000,
+ 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000,
+ 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000,
+ 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000,
+ 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000,
+ 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000,
+ 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000,
+ 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000,
+ 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000,
+ 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000,
+ 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000,
+ 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000,
+ 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000,
+ 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000,
+ 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000,
+ 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000,
+ 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000,
+ 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000,
+ 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000,
+ 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000,
+ 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000,
+ 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000,
+ 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000,
+ 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000,
+ 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000,
+ 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000,
+ 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000,
+ 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000,
+ 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000,
+ 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000,
+ 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000,
+ 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000,
+ 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000,
+ 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000,
+ 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000,
+ 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000,
+ 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000,
+ 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000,
+ 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000,
+ 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000,
+ 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000,
+ 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000,
+ 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000,
+ 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000,
+ 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000,
+ 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000,
+ 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000,
+ 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000,
+ 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000,
+ 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000,
+ 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000,
+ 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000,
+ 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000,
+ 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000,
+ 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000,
+ 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000,
+ 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000,
+ 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000,
+ 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000,
+ 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000,
+ 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000,
+ 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000,
+ 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000,
+ 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000,
+ 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000,
+ 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000,
+ 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000,
+ 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000,
+ 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000,
+ 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000,
+ 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000,
+ 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000,
+ 0x8ae9531c00000000},
+ {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000,
+ 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000,
+ 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000,
+ 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000,
+ 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000,
+ 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000,
+ 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000,
+ 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000,
+ 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000,
+ 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000,
+ 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000,
+ 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000,
+ 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000,
+ 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000,
+ 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000,
+ 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000,
+ 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000,
+ 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000,
+ 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000,
+ 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000,
+ 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000,
+ 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000,
+ 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000,
+ 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000,
+ 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000,
+ 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000,
+ 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000,
+ 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000,
+ 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000,
+ 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000,
+ 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000,
+ 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000,
+ 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000,
+ 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000,
+ 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000,
+ 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000,
+ 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000,
+ 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000,
+ 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000,
+ 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000,
+ 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000,
+ 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000,
+ 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000,
+ 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000,
+ 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000,
+ 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000,
+ 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000,
+ 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000,
+ 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000,
+ 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000,
+ 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000,
+ 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000,
+ 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000,
+ 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000,
+ 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000,
+ 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000,
+ 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000,
+ 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000,
+ 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000,
+ 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000,
+ 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000,
+ 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000,
+ 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000,
+ 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000,
+ 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000,
+ 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000,
+ 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000,
+ 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000,
+ 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000,
+ 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000,
+ 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000,
+ 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000,
+ 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000,
+ 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000,
+ 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000,
+ 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000,
+ 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000,
+ 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000,
+ 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000,
+ 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000,
+ 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000,
+ 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000,
+ 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000,
+ 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000,
+ 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000,
+ 0xd739710d00000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa,
+ 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b,
+ 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232,
+ 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,
+ 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,
+ 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa,
+ 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b,
+ 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,
+ 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719,
+ 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3,
+ 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,
+ 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,
+ 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed,
+ 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89,
+ 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25,
+ 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
+ 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,
+ 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed,
+ 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4,
+ 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,
+ 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e,
+ 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a,
+ 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,
+ 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,
+ 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df,
+ 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544,
+ 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d,
+ 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,
+ 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,
+ 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95,
+ 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839,
+ 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
+ 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976,
+ 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7,
+ 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,
+ 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,
+ 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12,
+ 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376,
+ 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a,
+ 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,
+ 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,
+ 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682,
+ 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b,
+ 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,
+ 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561,
+ 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05,
+ 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,
+ 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
+ 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0,
+ 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61,
+ 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678,
+ 0x264b06e6},
+ {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413,
+ 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3,
+ 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d,
+ 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,
+ 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,
+ 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e,
+ 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5,
+ 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,
+ 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8,
+ 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6,
+ 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,
+ 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,
+ 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579,
+ 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade,
+ 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37,
+ 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
+ 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,
+ 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64,
+ 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea,
+ 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,
+ 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282,
+ 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25,
+ 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,
+ 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,
+ 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f,
+ 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146,
+ 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8,
+ 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,
+ 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,
+ 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b,
+ 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972,
+ 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
+ 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d,
+ 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd,
+ 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,
+ 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,
+ 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7,
+ 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60,
+ 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2,
+ 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,
+ 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,
+ 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1,
+ 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f,
+ 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,
+ 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617,
+ 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0,
+ 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,
+ 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
+ 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca,
+ 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a,
+ 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184,
+ 0x92364a30},
+ {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216,
+ 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8,
+ 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170,
+ 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,
+ 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,
+ 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145,
+ 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d,
+ 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,
+ 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d,
+ 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408,
+ 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,
+ 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,
+ 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c,
+ 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf,
+ 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a,
+ 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
+ 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,
+ 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f,
+ 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987,
+ 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,
+ 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37,
+ 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84,
+ 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,
+ 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,
+ 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba,
+ 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d,
+ 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5,
+ 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,
+ 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,
+ 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0,
+ 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525,
+ 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
+ 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8,
+ 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026,
+ 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,
+ 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,
+ 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118,
+ 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab,
+ 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf,
+ 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,
+ 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,
+ 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a,
+ 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32,
+ 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,
+ 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82,
+ 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31,
+ 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,
+ 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
+ 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f,
+ 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1,
+ 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869,
+ 0xe4c4abcc},
+ {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0,
+ 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271,
+ 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61,
+ 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,
+ 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,
+ 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333,
+ 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64,
+ 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,
+ 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205,
+ 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136,
+ 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,
+ 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,
+ 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849,
+ 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739,
+ 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8,
+ 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
+ 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,
+ 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba,
+ 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa,
+ 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,
+ 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c,
+ 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc,
+ 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,
+ 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,
+ 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce,
+ 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922,
+ 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532,
+ 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,
+ 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,
+ 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860,
+ 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1,
+ 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
+ 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956,
+ 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7,
+ 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,
+ 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,
+ 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5,
+ 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5,
+ 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb,
+ 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,
+ 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,
+ 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9,
+ 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9,
+ 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,
+ 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df,
+ 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af,
+ 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,
+ 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
+ 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d,
+ 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c,
+ 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c,
+ 0xca64c78c}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5,
+ 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d,
+ 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf,
+ 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027,
+ 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050,
+ 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098,
+ 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb,
+ 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173,
+ 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104,
+ 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c,
+ 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e,
+ 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6,
+ 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358,
+ 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390,
+ 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312,
+ 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da,
+ 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd,
+ 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335,
+ 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387,
+ 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de,
+ 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9,
+ 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261,
+ 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283,
+ 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b,
+ 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c,
+ 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c,
+ 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e,
+ 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6,
+ 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1,
+ 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619,
+ 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b,
+ 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653,
+ 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785,
+ 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d,
+ 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf,
+ 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757,
+ 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720,
+ 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8,
+ 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593,
+ 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b,
+ 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c,
+ 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4,
+ 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506,
+ 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe,
+ 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428,
+ 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0,
+ 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462,
+ 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa,
+ 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd,
+ 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445,
+ 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7,
+ 0x8cc764ca},
+ {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b,
+ 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27,
+ 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a,
+ 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285,
+ 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef,
+ 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf,
+ 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a,
+ 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a,
+ 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70,
+ 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf,
+ 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2,
+ 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e,
+ 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f,
+ 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f,
+ 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae,
+ 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe,
+ 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97,
+ 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b,
+ 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436,
+ 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e,
+ 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4,
+ 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4,
+ 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46,
+ 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716,
+ 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c,
+ 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5,
+ 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8,
+ 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774,
+ 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d,
+ 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d,
+ 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc,
+ 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec,
+ 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82,
+ 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e,
+ 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623,
+ 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c,
+ 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6,
+ 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6,
+ 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c,
+ 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c,
+ 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66,
+ 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9,
+ 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4,
+ 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978,
+ 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416,
+ 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946,
+ 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7,
+ 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7,
+ 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e,
+ 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32,
+ 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f,
+ 0xccabc4e4},
+ {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4,
+ 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895,
+ 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50,
+ 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656,
+ 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154,
+ 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906,
+ 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258,
+ 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a,
+ 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08,
+ 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e,
+ 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb,
+ 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa,
+ 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44,
+ 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316,
+ 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0,
+ 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2,
+ 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7,
+ 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6,
+ 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73,
+ 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba,
+ 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8,
+ 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea,
+ 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b,
+ 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29,
+ 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b,
+ 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e,
+ 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb,
+ 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a,
+ 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef,
+ 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd,
+ 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b,
+ 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019,
+ 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3,
+ 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2,
+ 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417,
+ 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11,
+ 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13,
+ 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241,
+ 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b,
+ 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09,
+ 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b,
+ 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d,
+ 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8,
+ 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9,
+ 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003,
+ 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851,
+ 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7,
+ 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5,
+ 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190,
+ 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1,
+ 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134,
+ 0x304a3692},
+ {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84,
+ 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f,
+ 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15,
+ 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2,
+ 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf,
+ 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7,
+ 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb,
+ 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3,
+ 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae,
+ 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749,
+ 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243,
+ 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8,
+ 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29,
+ 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61,
+ 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8,
+ 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0,
+ 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1,
+ 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a,
+ 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40,
+ 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e,
+ 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03,
+ 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b,
+ 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee,
+ 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6,
+ 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb,
+ 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f,
+ 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495,
+ 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e,
+ 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f,
+ 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067,
+ 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be,
+ 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6,
+ 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e,
+ 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5,
+ 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf,
+ 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958,
+ 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305,
+ 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d,
+ 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338,
+ 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370,
+ 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d,
+ 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca,
+ 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0,
+ 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b,
+ 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083,
+ 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb,
+ 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012,
+ 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a,
+ 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b,
+ 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0,
+ 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea,
+ 0xe6064b26}};
+
+#endif
+
+#endif
+
+#if N == 3
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f,
+ 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999,
+ 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee,
+ 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615,
+ 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383,
+ 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb,
+ 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275,
+ 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d,
+ 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b,
+ 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460,
+ 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317,
+ 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1,
+ 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5,
+ 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd,
+ 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04,
+ 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c,
+ 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7,
+ 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11,
+ 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66,
+ 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7,
+ 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871,
+ 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309,
+ 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd,
+ 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85,
+ 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913,
+ 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d,
+ 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a,
+ 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc,
+ 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57,
+ 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f,
+ 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6,
+ 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e,
+ 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f,
+ 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289,
+ 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe,
+ 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05,
+ 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893,
+ 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb,
+ 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0,
+ 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8,
+ 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e,
+ 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5,
+ 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2,
+ 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574,
+ 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5,
+ 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add,
+ 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114,
+ 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c,
+ 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7,
+ 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701,
+ 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076,
+ 0x09cd8551},
+ {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193,
+ 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2,
+ 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c,
+ 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71,
+ 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a,
+ 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d,
+ 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71,
+ 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436,
+ 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d,
+ 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000,
+ 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae,
+ 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf,
+ 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930,
+ 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277,
+ 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff,
+ 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8,
+ 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef,
+ 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e,
+ 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20,
+ 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95,
+ 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e,
+ 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9,
+ 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d,
+ 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a,
+ 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151,
+ 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4,
+ 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a,
+ 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b,
+ 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c,
+ 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b,
+ 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3,
+ 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4,
+ 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b,
+ 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a,
+ 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4,
+ 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189,
+ 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92,
+ 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5,
+ 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9,
+ 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe,
+ 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5,
+ 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8,
+ 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66,
+ 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707,
+ 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8,
+ 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f,
+ 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707,
+ 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40,
+ 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017,
+ 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876,
+ 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8,
+ 0x7bc97a0c},
+ {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300,
+ 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0,
+ 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80,
+ 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701,
+ 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41,
+ 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81,
+ 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43,
+ 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83,
+ 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3,
+ 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42,
+ 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202,
+ 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2,
+ 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7,
+ 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407,
+ 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47,
+ 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87,
+ 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86,
+ 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46,
+ 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506,
+ 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44,
+ 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704,
+ 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4,
+ 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5,
+ 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505,
+ 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45,
+ 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f,
+ 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f,
+ 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f,
+ 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e,
+ 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e,
+ 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e,
+ 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce,
+ 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c,
+ 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc,
+ 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c,
+ 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d,
+ 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d,
+ 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d,
+ 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88,
+ 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48,
+ 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708,
+ 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89,
+ 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9,
+ 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309,
+ 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb,
+ 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b,
+ 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b,
+ 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b,
+ 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a,
+ 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a,
+ 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a,
+ 0x7851a2ca},
+ {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb,
+ 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8,
+ 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0,
+ 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f,
+ 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a,
+ 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf,
+ 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5,
+ 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380,
+ 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815,
+ 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa,
+ 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2,
+ 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1,
+ 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1,
+ 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4,
+ 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa,
+ 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df,
+ 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6,
+ 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5,
+ 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad,
+ 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca,
+ 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f,
+ 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a,
+ 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8,
+ 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d,
+ 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708,
+ 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d,
+ 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865,
+ 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636,
+ 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f,
+ 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a,
+ 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744,
+ 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061,
+ 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0,
+ 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293,
+ 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb,
+ 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874,
+ 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1,
+ 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4,
+ 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f,
+ 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a,
+ 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f,
+ 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120,
+ 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778,
+ 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b,
+ 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a,
+ 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af,
+ 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81,
+ 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4,
+ 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd,
+ 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e,
+ 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6,
+ 0x566b6848},
+ {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59,
+ 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4,
+ 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67,
+ 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef,
+ 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97,
+ 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88,
+ 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687,
+ 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698,
+ 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0,
+ 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068,
+ 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb,
+ 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056,
+ 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016,
+ 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009,
+ 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028,
+ 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037,
+ 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a,
+ 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7,
+ 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054,
+ 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7,
+ 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af,
+ 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0,
+ 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4,
+ 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab,
+ 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3,
+ 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a,
+ 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9,
+ 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54,
+ 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09,
+ 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16,
+ 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37,
+ 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28,
+ 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e,
+ 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3,
+ 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40,
+ 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8,
+ 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0,
+ 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf,
+ 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6,
+ 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9,
+ 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1,
+ 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059,
+ 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca,
+ 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067,
+ 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031,
+ 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e,
+ 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f,
+ 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010,
+ 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d,
+ 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0,
+ 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073,
+ 0xd8ac6b35},
+ {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2,
+ 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd,
+ 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696,
+ 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3,
+ 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f,
+ 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35,
+ 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5,
+ 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f,
+ 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673,
+ 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46,
+ 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d,
+ 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632,
+ 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28,
+ 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192,
+ 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c,
+ 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6,
+ 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0,
+ 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff,
+ 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4,
+ 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95,
+ 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9,
+ 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03,
+ 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7,
+ 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d,
+ 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151,
+ 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808,
+ 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343,
+ 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c,
+ 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a,
+ 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0,
+ 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e,
+ 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594,
+ 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6,
+ 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399,
+ 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2,
+ 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7,
+ 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb,
+ 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571,
+ 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289,
+ 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33,
+ 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f,
+ 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a,
+ 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461,
+ 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e,
+ 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c,
+ 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6,
+ 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918,
+ 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2,
+ 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484,
+ 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb,
+ 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0,
+ 0xa140efa8},
+ {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706,
+ 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed,
+ 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289,
+ 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a,
+ 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214,
+ 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3,
+ 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3,
+ 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254,
+ 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a,
+ 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9,
+ 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad,
+ 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746,
+ 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060,
+ 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187,
+ 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef,
+ 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408,
+ 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e,
+ 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495,
+ 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1,
+ 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532,
+ 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c,
+ 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb,
+ 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb,
+ 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c,
+ 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42,
+ 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060,
+ 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04,
+ 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef,
+ 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99,
+ 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e,
+ 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16,
+ 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1,
+ 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7,
+ 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c,
+ 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38,
+ 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb,
+ 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5,
+ 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42,
+ 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62,
+ 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85,
+ 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb,
+ 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18,
+ 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c,
+ 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997,
+ 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1,
+ 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36,
+ 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e,
+ 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9,
+ 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf,
+ 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24,
+ 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040,
+ 0x917cd6a1},
+ {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf,
+ 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd,
+ 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896,
+ 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9,
+ 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3,
+ 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f,
+ 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d,
+ 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1,
+ 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab,
+ 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4,
+ 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f,
+ 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d,
+ 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4,
+ 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978,
+ 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad,
+ 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621,
+ 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46,
+ 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854,
+ 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f,
+ 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a,
+ 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890,
+ 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c,
+ 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4,
+ 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238,
+ 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622,
+ 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab,
+ 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0,
+ 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2,
+ 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295,
+ 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19,
+ 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc,
+ 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140,
+ 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd,
+ 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf,
+ 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184,
+ 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb,
+ 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1,
+ 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d,
+ 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb,
+ 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257,
+ 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d,
+ 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22,
+ 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069,
+ 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b,
+ 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6,
+ 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a,
+ 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf,
+ 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33,
+ 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254,
+ 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146,
+ 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d,
+ 0x18ba364e}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000,
+ 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000,
+ 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000,
+ 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000,
+ 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000,
+ 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000,
+ 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000,
+ 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000,
+ 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000,
+ 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000,
+ 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000,
+ 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000,
+ 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000,
+ 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000,
+ 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000,
+ 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000,
+ 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000,
+ 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000,
+ 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000,
+ 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000,
+ 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000,
+ 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000,
+ 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000,
+ 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000,
+ 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000,
+ 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000,
+ 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000,
+ 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000,
+ 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000,
+ 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000,
+ 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000,
+ 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000,
+ 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000,
+ 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000,
+ 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000,
+ 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000,
+ 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000,
+ 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000,
+ 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000,
+ 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000,
+ 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000,
+ 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000,
+ 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000,
+ 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000,
+ 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000,
+ 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000,
+ 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000,
+ 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000,
+ 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000,
+ 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000,
+ 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000,
+ 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000,
+ 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000,
+ 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000,
+ 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000,
+ 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000,
+ 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000,
+ 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000,
+ 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000,
+ 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000,
+ 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000,
+ 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000,
+ 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000,
+ 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000,
+ 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000,
+ 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000,
+ 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000,
+ 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000,
+ 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000,
+ 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000,
+ 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000,
+ 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000,
+ 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000,
+ 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000,
+ 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000,
+ 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000,
+ 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000,
+ 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000,
+ 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000,
+ 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000,
+ 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000,
+ 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000,
+ 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000,
+ 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000,
+ 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000,
+ 0x4e36ba1800000000},
+ {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000,
+ 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000,
+ 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000,
+ 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000,
+ 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000,
+ 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000,
+ 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000,
+ 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000,
+ 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000,
+ 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000,
+ 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000,
+ 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000,
+ 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000,
+ 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000,
+ 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000,
+ 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000,
+ 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000,
+ 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000,
+ 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000,
+ 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000,
+ 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000,
+ 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000,
+ 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000,
+ 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000,
+ 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000,
+ 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000,
+ 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000,
+ 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000,
+ 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000,
+ 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000,
+ 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000,
+ 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000,
+ 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000,
+ 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000,
+ 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000,
+ 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000,
+ 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000,
+ 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000,
+ 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000,
+ 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000,
+ 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000,
+ 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000,
+ 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000,
+ 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000,
+ 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000,
+ 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000,
+ 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000,
+ 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000,
+ 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000,
+ 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000,
+ 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000,
+ 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000,
+ 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000,
+ 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000,
+ 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000,
+ 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000,
+ 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000,
+ 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000,
+ 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000,
+ 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000,
+ 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000,
+ 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000,
+ 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000,
+ 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000,
+ 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000,
+ 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000,
+ 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000,
+ 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000,
+ 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000,
+ 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000,
+ 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000,
+ 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000,
+ 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000,
+ 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000,
+ 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000,
+ 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000,
+ 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000,
+ 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000,
+ 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000,
+ 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000,
+ 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000,
+ 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000,
+ 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000,
+ 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000,
+ 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000,
+ 0xa1d67c9100000000},
+ {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000,
+ 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000,
+ 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000,
+ 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000,
+ 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000,
+ 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000,
+ 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000,
+ 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000,
+ 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000,
+ 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000,
+ 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000,
+ 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000,
+ 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000,
+ 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000,
+ 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000,
+ 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000,
+ 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000,
+ 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000,
+ 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000,
+ 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000,
+ 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000,
+ 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000,
+ 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000,
+ 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000,
+ 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000,
+ 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000,
+ 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000,
+ 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000,
+ 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000,
+ 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000,
+ 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000,
+ 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000,
+ 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000,
+ 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000,
+ 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000,
+ 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000,
+ 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000,
+ 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000,
+ 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000,
+ 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000,
+ 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000,
+ 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000,
+ 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000,
+ 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000,
+ 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000,
+ 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000,
+ 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000,
+ 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000,
+ 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000,
+ 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000,
+ 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000,
+ 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000,
+ 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000,
+ 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000,
+ 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000,
+ 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000,
+ 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000,
+ 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000,
+ 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000,
+ 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000,
+ 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000,
+ 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000,
+ 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000,
+ 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000,
+ 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000,
+ 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000,
+ 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000,
+ 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000,
+ 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000,
+ 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000,
+ 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000,
+ 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000,
+ 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000,
+ 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000,
+ 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000,
+ 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000,
+ 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000,
+ 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000,
+ 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000,
+ 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000,
+ 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000,
+ 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000,
+ 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000,
+ 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000,
+ 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000,
+ 0xa8ef40a100000000},
+ {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000,
+ 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000,
+ 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000,
+ 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000,
+ 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000,
+ 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000,
+ 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000,
+ 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000,
+ 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000,
+ 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000,
+ 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000,
+ 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000,
+ 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000,
+ 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000,
+ 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000,
+ 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000,
+ 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000,
+ 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000,
+ 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000,
+ 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000,
+ 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000,
+ 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000,
+ 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000,
+ 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000,
+ 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000,
+ 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000,
+ 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000,
+ 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000,
+ 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000,
+ 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000,
+ 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000,
+ 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000,
+ 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000,
+ 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000,
+ 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000,
+ 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000,
+ 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000,
+ 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000,
+ 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000,
+ 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000,
+ 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000,
+ 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000,
+ 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000,
+ 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000,
+ 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000,
+ 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000,
+ 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000,
+ 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000,
+ 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000,
+ 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000,
+ 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000,
+ 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000,
+ 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000,
+ 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000,
+ 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000,
+ 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000,
+ 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000,
+ 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000,
+ 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000,
+ 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000,
+ 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000,
+ 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000,
+ 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000,
+ 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000,
+ 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000,
+ 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000,
+ 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000,
+ 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000,
+ 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000,
+ 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000,
+ 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000,
+ 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000,
+ 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000,
+ 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000,
+ 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000,
+ 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000,
+ 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000,
+ 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000,
+ 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000,
+ 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000,
+ 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000,
+ 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000,
+ 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000,
+ 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000,
+ 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000,
+ 0x356bacd800000000},
+ {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000,
+ 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000,
+ 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000,
+ 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000,
+ 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000,
+ 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000,
+ 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000,
+ 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000,
+ 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000,
+ 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000,
+ 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000,
+ 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000,
+ 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000,
+ 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000,
+ 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000,
+ 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000,
+ 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000,
+ 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000,
+ 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000,
+ 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000,
+ 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000,
+ 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000,
+ 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000,
+ 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000,
+ 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000,
+ 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000,
+ 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000,
+ 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000,
+ 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000,
+ 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000,
+ 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000,
+ 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000,
+ 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000,
+ 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000,
+ 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000,
+ 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000,
+ 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000,
+ 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000,
+ 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000,
+ 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000,
+ 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000,
+ 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000,
+ 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000,
+ 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000,
+ 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000,
+ 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000,
+ 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000,
+ 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000,
+ 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000,
+ 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000,
+ 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000,
+ 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000,
+ 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000,
+ 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000,
+ 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000,
+ 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000,
+ 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000,
+ 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000,
+ 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000,
+ 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000,
+ 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000,
+ 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000,
+ 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000,
+ 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000,
+ 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000,
+ 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000,
+ 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000,
+ 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000,
+ 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000,
+ 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000,
+ 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000,
+ 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000,
+ 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000,
+ 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000,
+ 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000,
+ 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000,
+ 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000,
+ 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000,
+ 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000,
+ 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000,
+ 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000,
+ 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000,
+ 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000,
+ 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000,
+ 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000,
+ 0x48686b5600000000},
+ {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000,
+ 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000,
+ 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000,
+ 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000,
+ 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000,
+ 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000,
+ 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000,
+ 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000,
+ 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000,
+ 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000,
+ 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000,
+ 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000,
+ 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000,
+ 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000,
+ 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000,
+ 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000,
+ 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000,
+ 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000,
+ 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000,
+ 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000,
+ 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000,
+ 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000,
+ 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000,
+ 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000,
+ 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000,
+ 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000,
+ 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000,
+ 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000,
+ 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000,
+ 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000,
+ 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000,
+ 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000,
+ 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000,
+ 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000,
+ 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000,
+ 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000,
+ 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000,
+ 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000,
+ 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000,
+ 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000,
+ 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000,
+ 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000,
+ 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000,
+ 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000,
+ 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000,
+ 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000,
+ 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000,
+ 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000,
+ 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000,
+ 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000,
+ 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000,
+ 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000,
+ 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000,
+ 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000,
+ 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000,
+ 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000,
+ 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000,
+ 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000,
+ 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000,
+ 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000,
+ 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000,
+ 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000,
+ 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000,
+ 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000,
+ 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000,
+ 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000,
+ 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000,
+ 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000,
+ 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000,
+ 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000,
+ 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000,
+ 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000,
+ 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000,
+ 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000,
+ 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000,
+ 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000,
+ 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000,
+ 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000,
+ 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000,
+ 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000,
+ 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000,
+ 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000,
+ 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000,
+ 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000,
+ 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000,
+ 0xcaa2517800000000},
+ {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000,
+ 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000,
+ 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000,
+ 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000,
+ 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000,
+ 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000,
+ 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000,
+ 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000,
+ 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000,
+ 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000,
+ 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000,
+ 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000,
+ 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000,
+ 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000,
+ 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000,
+ 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000,
+ 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000,
+ 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000,
+ 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000,
+ 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000,
+ 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000,
+ 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000,
+ 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000,
+ 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000,
+ 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000,
+ 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000,
+ 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000,
+ 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000,
+ 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000,
+ 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000,
+ 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000,
+ 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000,
+ 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000,
+ 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000,
+ 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000,
+ 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000,
+ 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000,
+ 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000,
+ 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000,
+ 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000,
+ 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000,
+ 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000,
+ 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000,
+ 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000,
+ 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000,
+ 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000,
+ 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000,
+ 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000,
+ 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000,
+ 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000,
+ 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000,
+ 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000,
+ 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000,
+ 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000,
+ 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000,
+ 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000,
+ 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000,
+ 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000,
+ 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000,
+ 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000,
+ 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000,
+ 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000,
+ 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000,
+ 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000,
+ 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000,
+ 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000,
+ 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000,
+ 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000,
+ 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000,
+ 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000,
+ 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000,
+ 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000,
+ 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000,
+ 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000,
+ 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000,
+ 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000,
+ 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000,
+ 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000,
+ 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000,
+ 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000,
+ 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000,
+ 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000,
+ 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000,
+ 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000,
+ 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000,
+ 0x0c7ac97b00000000},
+ {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000,
+ 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000,
+ 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000,
+ 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000,
+ 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000,
+ 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000,
+ 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000,
+ 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000,
+ 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000,
+ 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000,
+ 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000,
+ 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000,
+ 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000,
+ 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000,
+ 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000,
+ 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000,
+ 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000,
+ 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000,
+ 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000,
+ 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000,
+ 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000,
+ 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000,
+ 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000,
+ 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000,
+ 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000,
+ 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000,
+ 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000,
+ 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000,
+ 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000,
+ 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000,
+ 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000,
+ 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000,
+ 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000,
+ 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000,
+ 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000,
+ 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000,
+ 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000,
+ 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000,
+ 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000,
+ 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000,
+ 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000,
+ 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000,
+ 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000,
+ 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000,
+ 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000,
+ 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000,
+ 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000,
+ 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000,
+ 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000,
+ 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000,
+ 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000,
+ 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000,
+ 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000,
+ 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000,
+ 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000,
+ 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000,
+ 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000,
+ 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000,
+ 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000,
+ 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000,
+ 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000,
+ 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000,
+ 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000,
+ 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000,
+ 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000,
+ 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000,
+ 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000,
+ 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000,
+ 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000,
+ 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000,
+ 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000,
+ 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000,
+ 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000,
+ 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000,
+ 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000,
+ 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000,
+ 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000,
+ 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000,
+ 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000,
+ 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000,
+ 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000,
+ 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000,
+ 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000,
+ 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000,
+ 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000,
+ 0x5185cd0900000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f,
+ 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91,
+ 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e,
+ 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c,
+ 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02,
+ 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12,
+ 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567,
+ 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277,
+ 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679,
+ 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b,
+ 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4,
+ 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a,
+ 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0,
+ 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0,
+ 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91,
+ 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881,
+ 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173,
+ 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d,
+ 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912,
+ 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8,
+ 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6,
+ 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6,
+ 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b,
+ 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b,
+ 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75,
+ 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f,
+ 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00,
+ 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee,
+ 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c,
+ 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c,
+ 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d,
+ 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d,
+ 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67,
+ 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89,
+ 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706,
+ 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14,
+ 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a,
+ 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a,
+ 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f,
+ 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f,
+ 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591,
+ 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983,
+ 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c,
+ 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2,
+ 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8,
+ 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8,
+ 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89,
+ 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99,
+ 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b,
+ 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485,
+ 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a,
+ 0x36197165},
+ {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382,
+ 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85,
+ 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06,
+ 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca,
+ 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e,
+ 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc,
+ 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616,
+ 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54,
+ 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10,
+ 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc,
+ 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f,
+ 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58,
+ 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef,
+ 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad,
+ 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b,
+ 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29,
+ 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6,
+ 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1,
+ 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622,
+ 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039,
+ 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d,
+ 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f,
+ 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32,
+ 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770,
+ 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034,
+ 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f,
+ 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc,
+ 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db,
+ 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154,
+ 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16,
+ 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0,
+ 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592,
+ 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca,
+ 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd,
+ 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e,
+ 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882,
+ 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6,
+ 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384,
+ 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1,
+ 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3,
+ 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7,
+ 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b,
+ 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8,
+ 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff,
+ 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7,
+ 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5,
+ 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23,
+ 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761,
+ 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee,
+ 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9,
+ 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a,
+ 0x1a3b93aa},
+ {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a,
+ 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca,
+ 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3,
+ 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb,
+ 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c,
+ 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58,
+ 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed,
+ 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9,
+ 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e,
+ 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906,
+ 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f,
+ 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf,
+ 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0,
+ 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4,
+ 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769,
+ 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d,
+ 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632,
+ 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82,
+ 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb,
+ 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73,
+ 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484,
+ 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0,
+ 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5,
+ 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1,
+ 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516,
+ 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f,
+ 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946,
+ 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6,
+ 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9,
+ 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad,
+ 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820,
+ 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364,
+ 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab,
+ 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b,
+ 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62,
+ 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a,
+ 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd,
+ 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089,
+ 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c,
+ 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8,
+ 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f,
+ 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477,
+ 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e,
+ 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be,
+ 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71,
+ 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635,
+ 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8,
+ 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc,
+ 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3,
+ 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753,
+ 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a,
+ 0xe147d714},
+ {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c,
+ 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b,
+ 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92,
+ 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4,
+ 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069,
+ 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526,
+ 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25,
+ 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a,
+ 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7,
+ 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491,
+ 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958,
+ 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f,
+ 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307,
+ 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648,
+ 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999,
+ 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6,
+ 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a,
+ 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d,
+ 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4,
+ 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61,
+ 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc,
+ 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3,
+ 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53,
+ 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c,
+ 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1,
+ 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c,
+ 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5,
+ 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92,
+ 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e,
+ 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771,
+ 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0,
+ 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def,
+ 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0,
+ 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7,
+ 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e,
+ 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58,
+ 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285,
+ 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca,
+ 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce,
+ 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81,
+ 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c,
+ 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a,
+ 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3,
+ 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4,
+ 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb,
+ 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4,
+ 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75,
+ 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a,
+ 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296,
+ 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1,
+ 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808,
+ 0x494f0c4b}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d,
+ 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac,
+ 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8,
+ 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95,
+ 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817,
+ 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d,
+ 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac,
+ 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6,
+ 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564,
+ 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39,
+ 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d,
+ 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac,
+ 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de,
+ 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594,
+ 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b,
+ 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01,
+ 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f,
+ 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de,
+ 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba,
+ 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65,
+ 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7,
+ 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad,
+ 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de,
+ 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294,
+ 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716,
+ 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71,
+ 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15,
+ 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4,
+ 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca,
+ 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280,
+ 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f,
+ 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15,
+ 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9,
+ 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748,
+ 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c,
+ 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971,
+ 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3,
+ 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9,
+ 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196,
+ 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc,
+ 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e,
+ 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03,
+ 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67,
+ 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296,
+ 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a,
+ 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170,
+ 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af,
+ 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5,
+ 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb,
+ 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a,
+ 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e,
+ 0x4b0c4f49},
+ {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09,
+ 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc,
+ 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e,
+ 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc,
+ 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934,
+ 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2,
+ 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b,
+ 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad,
+ 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155,
+ 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187,
+ 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65,
+ 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390,
+ 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e,
+ 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378,
+ 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889,
+ 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f,
+ 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0,
+ 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145,
+ 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7,
+ 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a,
+ 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2,
+ 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924,
+ 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2,
+ 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514,
+ 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec,
+ 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709,
+ 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb,
+ 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e,
+ 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1,
+ 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227,
+ 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6,
+ 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030,
+ 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0,
+ 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55,
+ 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7,
+ 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165,
+ 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d,
+ 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b,
+ 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c,
+ 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a,
+ 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362,
+ 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0,
+ 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52,
+ 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7,
+ 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237,
+ 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1,
+ 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020,
+ 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6,
+ 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719,
+ 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec,
+ 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e,
+ 0x14d747e1},
+ {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0,
+ 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b,
+ 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652,
+ 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437,
+ 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514,
+ 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265,
+ 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de,
+ 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af,
+ 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c,
+ 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9,
+ 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0,
+ 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b,
+ 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6,
+ 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7,
+ 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734,
+ 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045,
+ 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8,
+ 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303,
+ 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a,
+ 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9,
+ 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea,
+ 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b,
+ 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6,
+ 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7,
+ 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4,
+ 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6,
+ 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f,
+ 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054,
+ 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9,
+ 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8,
+ 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b,
+ 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a,
+ 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441,
+ 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a,
+ 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3,
+ 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6,
+ 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5,
+ 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94,
+ 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9,
+ 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288,
+ 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab,
+ 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce,
+ 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7,
+ 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c,
+ 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527,
+ 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256,
+ 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5,
+ 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4,
+ 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39,
+ 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2,
+ 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db,
+ 0xaa933b1a},
+ {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603,
+ 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d,
+ 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9,
+ 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b,
+ 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a,
+ 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792,
+ 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4,
+ 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c,
+ 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d,
+ 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f,
+ 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb,
+ 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65,
+ 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330,
+ 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8,
+ 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da,
+ 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742,
+ 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f,
+ 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1,
+ 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5,
+ 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f,
+ 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e,
+ 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6,
+ 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8,
+ 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250,
+ 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021,
+ 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb,
+ 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f,
+ 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511,
+ 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c,
+ 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4,
+ 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886,
+ 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e,
+ 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b,
+ 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5,
+ 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791,
+ 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003,
+ 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272,
+ 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea,
+ 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc,
+ 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24,
+ 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55,
+ 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7,
+ 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3,
+ 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d,
+ 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548,
+ 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0,
+ 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2,
+ 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a,
+ 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47,
+ 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9,
+ 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad,
+ 0x65711936}};
+
+#endif
+
+#endif
+
+#if N == 4
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a,
+ 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe,
+ 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b,
+ 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656,
+ 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd,
+ 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d,
+ 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7,
+ 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47,
+ 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac,
+ 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691,
+ 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404,
+ 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0,
+ 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4,
+ 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424,
+ 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5,
+ 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65,
+ 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67,
+ 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3,
+ 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626,
+ 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9,
+ 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222,
+ 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2,
+ 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a,
+ 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a,
+ 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1,
+ 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2,
+ 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077,
+ 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3,
+ 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1,
+ 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621,
+ 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0,
+ 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60,
+ 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0,
+ 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64,
+ 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1,
+ 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc,
+ 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027,
+ 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7,
+ 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9,
+ 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79,
+ 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292,
+ 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af,
+ 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a,
+ 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee,
+ 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e,
+ 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe,
+ 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f,
+ 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff,
+ 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd,
+ 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29,
+ 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc,
+ 0xe3c45916},
+ {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344,
+ 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59,
+ 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e,
+ 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463,
+ 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98,
+ 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d,
+ 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3,
+ 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656,
+ 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad,
+ 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0,
+ 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397,
+ 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a,
+ 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2,
+ 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357,
+ 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8,
+ 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d,
+ 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696,
+ 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b,
+ 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc,
+ 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0,
+ 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b,
+ 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be,
+ 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811,
+ 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384,
+ 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f,
+ 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955,
+ 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362,
+ 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f,
+ 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94,
+ 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701,
+ 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe,
+ 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b,
+ 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1,
+ 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc,
+ 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b,
+ 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986,
+ 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d,
+ 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8,
+ 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4,
+ 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371,
+ 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a,
+ 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87,
+ 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0,
+ 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad,
+ 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527,
+ 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2,
+ 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d,
+ 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998,
+ 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73,
+ 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e,
+ 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59,
+ 0xa7520488},
+ {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20,
+ 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09,
+ 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431,
+ 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a,
+ 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203,
+ 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b,
+ 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14,
+ 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c,
+ 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25,
+ 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e,
+ 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36,
+ 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f,
+ 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649,
+ 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961,
+ 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58,
+ 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170,
+ 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b,
+ 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742,
+ 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a,
+ 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55,
+ 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c,
+ 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64,
+ 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f,
+ 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77,
+ 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e,
+ 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a,
+ 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2,
+ 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b,
+ 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090,
+ 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8,
+ 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881,
+ 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9,
+ 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6,
+ 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f,
+ 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7,
+ 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c,
+ 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695,
+ 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd,
+ 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb,
+ 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3,
+ 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa,
+ 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1,
+ 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9,
+ 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0,
+ 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df,
+ 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7,
+ 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace,
+ 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6,
+ 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd,
+ 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4,
+ 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec,
+ 0x3522e9e4},
+ {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1,
+ 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86,
+ 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b,
+ 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669,
+ 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7,
+ 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352,
+ 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03,
+ 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6,
+ 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38,
+ 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a,
+ 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7,
+ 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80,
+ 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7,
+ 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522,
+ 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d,
+ 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8,
+ 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103,
+ 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54,
+ 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9,
+ 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0,
+ 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e,
+ 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb,
+ 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1,
+ 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624,
+ 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea,
+ 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a,
+ 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37,
+ 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360,
+ 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab,
+ 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e,
+ 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741,
+ 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4,
+ 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334,
+ 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63,
+ 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de,
+ 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c,
+ 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942,
+ 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7,
+ 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131,
+ 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4,
+ 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a,
+ 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758,
+ 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5,
+ 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2,
+ 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32,
+ 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7,
+ 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8,
+ 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d,
+ 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6,
+ 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1,
+ 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c,
+ 0x97411e28},
+ {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474,
+ 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5,
+ 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6,
+ 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7,
+ 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938,
+ 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051,
+ 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a,
+ 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3,
+ 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c,
+ 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d,
+ 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e,
+ 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf,
+ 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740,
+ 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29,
+ 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592,
+ 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb,
+ 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4,
+ 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365,
+ 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036,
+ 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7,
+ 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08,
+ 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561,
+ 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a,
+ 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663,
+ 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac,
+ 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d,
+ 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce,
+ 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f,
+ 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50,
+ 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639,
+ 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82,
+ 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb,
+ 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954,
+ 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5,
+ 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86,
+ 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7,
+ 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418,
+ 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71,
+ 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa,
+ 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93,
+ 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c,
+ 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d,
+ 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e,
+ 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df,
+ 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60,
+ 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309,
+ 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2,
+ 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db,
+ 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4,
+ 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45,
+ 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16,
+ 0x93c7a00b},
+ {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45,
+ 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb,
+ 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d,
+ 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696,
+ 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf,
+ 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb,
+ 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028,
+ 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c,
+ 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65,
+ 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be,
+ 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038,
+ 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6,
+ 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15,
+ 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11,
+ 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d,
+ 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19,
+ 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05,
+ 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b,
+ 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d,
+ 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c,
+ 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35,
+ 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31,
+ 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068,
+ 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c,
+ 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25,
+ 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a,
+ 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac,
+ 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22,
+ 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e,
+ 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a,
+ 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36,
+ 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32,
+ 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84,
+ 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a,
+ 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c,
+ 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057,
+ 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e,
+ 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a,
+ 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc,
+ 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8,
+ 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1,
+ 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a,
+ 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec,
+ 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62,
+ 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4,
+ 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0,
+ 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc,
+ 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8,
+ 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4,
+ 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a,
+ 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc,
+ 0xce5f968d},
+ {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de,
+ 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b,
+ 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d,
+ 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680,
+ 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4,
+ 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d,
+ 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde,
+ 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97,
+ 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3,
+ 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e,
+ 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678,
+ 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d,
+ 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723,
+ 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a,
+ 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0,
+ 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9,
+ 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85,
+ 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770,
+ 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56,
+ 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a,
+ 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e,
+ 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67,
+ 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785,
+ 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc,
+ 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788,
+ 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90,
+ 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6,
+ 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843,
+ 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f,
+ 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336,
+ 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac,
+ 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5,
+ 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68,
+ 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d,
+ 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb,
+ 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36,
+ 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72,
+ 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b,
+ 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b,
+ 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402,
+ 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446,
+ 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb,
+ 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed,
+ 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418,
+ 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95,
+ 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc,
+ 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946,
+ 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f,
+ 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233,
+ 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6,
+ 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0,
+ 0x3e721277},
+ {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb,
+ 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9,
+ 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11,
+ 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d,
+ 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9,
+ 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c,
+ 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881,
+ 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274,
+ 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790,
+ 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc,
+ 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514,
+ 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56,
+ 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9,
+ 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c,
+ 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13,
+ 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6,
+ 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c,
+ 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e,
+ 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386,
+ 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376,
+ 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692,
+ 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67,
+ 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416,
+ 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3,
+ 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07,
+ 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd,
+ 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15,
+ 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457,
+ 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd,
+ 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28,
+ 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337,
+ 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2,
+ 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594,
+ 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6,
+ 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e,
+ 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52,
+ 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6,
+ 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143,
+ 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17,
+ 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2,
+ 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306,
+ 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a,
+ 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182,
+ 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0,
+ 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496,
+ 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63,
+ 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c,
+ 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89,
+ 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903,
+ 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041,
+ 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9,
+ 0x1c65ace7}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000,
+ 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000,
+ 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000,
+ 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000,
+ 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000,
+ 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000,
+ 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000,
+ 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000,
+ 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000,
+ 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000,
+ 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000,
+ 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000,
+ 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000,
+ 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000,
+ 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000,
+ 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000,
+ 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000,
+ 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000,
+ 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000,
+ 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000,
+ 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000,
+ 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000,
+ 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000,
+ 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000,
+ 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000,
+ 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000,
+ 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000,
+ 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000,
+ 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000,
+ 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000,
+ 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000,
+ 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000,
+ 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000,
+ 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000,
+ 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000,
+ 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000,
+ 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000,
+ 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000,
+ 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000,
+ 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000,
+ 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000,
+ 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000,
+ 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000,
+ 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000,
+ 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000,
+ 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000,
+ 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000,
+ 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000,
+ 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000,
+ 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000,
+ 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000,
+ 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000,
+ 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000,
+ 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000,
+ 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000,
+ 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000,
+ 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000,
+ 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000,
+ 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000,
+ 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000,
+ 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000,
+ 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000,
+ 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000,
+ 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000,
+ 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000,
+ 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000,
+ 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000,
+ 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000,
+ 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000,
+ 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000,
+ 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000,
+ 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000,
+ 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000,
+ 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000,
+ 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000,
+ 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000,
+ 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000,
+ 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000,
+ 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000,
+ 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000,
+ 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000,
+ 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000,
+ 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000,
+ 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000,
+ 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000,
+ 0xe7ac651c00000000},
+ {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000,
+ 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000,
+ 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000,
+ 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000,
+ 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000,
+ 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000,
+ 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000,
+ 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000,
+ 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000,
+ 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000,
+ 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000,
+ 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000,
+ 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000,
+ 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000,
+ 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000,
+ 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000,
+ 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000,
+ 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000,
+ 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000,
+ 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000,
+ 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000,
+ 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000,
+ 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000,
+ 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000,
+ 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000,
+ 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000,
+ 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000,
+ 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000,
+ 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000,
+ 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000,
+ 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000,
+ 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000,
+ 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000,
+ 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000,
+ 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000,
+ 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000,
+ 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000,
+ 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000,
+ 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000,
+ 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000,
+ 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000,
+ 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000,
+ 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000,
+ 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000,
+ 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000,
+ 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000,
+ 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000,
+ 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000,
+ 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000,
+ 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000,
+ 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000,
+ 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000,
+ 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000,
+ 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000,
+ 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000,
+ 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000,
+ 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000,
+ 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000,
+ 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000,
+ 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000,
+ 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000,
+ 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000,
+ 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000,
+ 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000,
+ 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000,
+ 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000,
+ 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000,
+ 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000,
+ 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000,
+ 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000,
+ 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000,
+ 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000,
+ 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000,
+ 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000,
+ 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000,
+ 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000,
+ 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000,
+ 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000,
+ 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000,
+ 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000,
+ 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000,
+ 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000,
+ 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000,
+ 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000,
+ 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000,
+ 0x7712723e00000000},
+ {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000,
+ 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000,
+ 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000,
+ 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000,
+ 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000,
+ 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000,
+ 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000,
+ 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000,
+ 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000,
+ 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000,
+ 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000,
+ 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000,
+ 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000,
+ 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000,
+ 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000,
+ 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000,
+ 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000,
+ 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000,
+ 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000,
+ 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000,
+ 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000,
+ 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000,
+ 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000,
+ 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000,
+ 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000,
+ 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000,
+ 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000,
+ 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000,
+ 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000,
+ 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000,
+ 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000,
+ 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000,
+ 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000,
+ 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000,
+ 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000,
+ 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000,
+ 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000,
+ 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000,
+ 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000,
+ 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000,
+ 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000,
+ 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000,
+ 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000,
+ 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000,
+ 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000,
+ 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000,
+ 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000,
+ 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000,
+ 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000,
+ 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000,
+ 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000,
+ 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000,
+ 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000,
+ 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000,
+ 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000,
+ 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000,
+ 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000,
+ 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000,
+ 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000,
+ 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000,
+ 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000,
+ 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000,
+ 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000,
+ 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000,
+ 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000,
+ 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000,
+ 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000,
+ 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000,
+ 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000,
+ 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000,
+ 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000,
+ 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000,
+ 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000,
+ 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000,
+ 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000,
+ 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000,
+ 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000,
+ 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000,
+ 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000,
+ 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000,
+ 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000,
+ 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000,
+ 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000,
+ 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000,
+ 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000,
+ 0x8d965fce00000000},
+ {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000,
+ 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000,
+ 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000,
+ 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000,
+ 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000,
+ 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000,
+ 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000,
+ 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000,
+ 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000,
+ 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000,
+ 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000,
+ 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000,
+ 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000,
+ 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000,
+ 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000,
+ 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000,
+ 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000,
+ 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000,
+ 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000,
+ 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000,
+ 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000,
+ 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000,
+ 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000,
+ 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000,
+ 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000,
+ 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000,
+ 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000,
+ 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000,
+ 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000,
+ 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000,
+ 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000,
+ 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000,
+ 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000,
+ 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000,
+ 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000,
+ 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000,
+ 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000,
+ 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000,
+ 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000,
+ 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000,
+ 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000,
+ 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000,
+ 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000,
+ 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000,
+ 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000,
+ 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000,
+ 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000,
+ 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000,
+ 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000,
+ 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000,
+ 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000,
+ 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000,
+ 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000,
+ 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000,
+ 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000,
+ 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000,
+ 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000,
+ 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000,
+ 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000,
+ 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000,
+ 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000,
+ 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000,
+ 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000,
+ 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000,
+ 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000,
+ 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000,
+ 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000,
+ 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000,
+ 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000,
+ 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000,
+ 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000,
+ 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000,
+ 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000,
+ 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000,
+ 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000,
+ 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000,
+ 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000,
+ 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000,
+ 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000,
+ 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000,
+ 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000,
+ 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000,
+ 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000,
+ 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000,
+ 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000,
+ 0x0ba0c79300000000},
+ {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000,
+ 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000,
+ 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000,
+ 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000,
+ 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000,
+ 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000,
+ 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000,
+ 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000,
+ 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000,
+ 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000,
+ 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000,
+ 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000,
+ 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000,
+ 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000,
+ 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000,
+ 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000,
+ 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000,
+ 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000,
+ 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000,
+ 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000,
+ 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000,
+ 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000,
+ 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000,
+ 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000,
+ 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000,
+ 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000,
+ 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000,
+ 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000,
+ 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000,
+ 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000,
+ 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000,
+ 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000,
+ 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000,
+ 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000,
+ 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000,
+ 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000,
+ 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000,
+ 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000,
+ 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000,
+ 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000,
+ 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000,
+ 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000,
+ 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000,
+ 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000,
+ 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000,
+ 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000,
+ 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000,
+ 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000,
+ 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000,
+ 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000,
+ 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000,
+ 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000,
+ 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000,
+ 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000,
+ 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000,
+ 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000,
+ 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000,
+ 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000,
+ 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000,
+ 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000,
+ 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000,
+ 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000,
+ 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000,
+ 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000,
+ 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000,
+ 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000,
+ 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000,
+ 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000,
+ 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000,
+ 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000,
+ 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000,
+ 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000,
+ 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000,
+ 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000,
+ 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000,
+ 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000,
+ 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000,
+ 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000,
+ 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000,
+ 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000,
+ 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000,
+ 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000,
+ 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000,
+ 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000,
+ 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000,
+ 0x281e419700000000},
+ {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000,
+ 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000,
+ 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000,
+ 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000,
+ 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000,
+ 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000,
+ 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000,
+ 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000,
+ 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000,
+ 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000,
+ 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000,
+ 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000,
+ 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000,
+ 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000,
+ 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000,
+ 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000,
+ 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000,
+ 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000,
+ 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000,
+ 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000,
+ 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000,
+ 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000,
+ 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000,
+ 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000,
+ 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000,
+ 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000,
+ 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000,
+ 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000,
+ 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000,
+ 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000,
+ 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000,
+ 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000,
+ 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000,
+ 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000,
+ 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000,
+ 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000,
+ 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000,
+ 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000,
+ 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000,
+ 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000,
+ 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000,
+ 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000,
+ 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000,
+ 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000,
+ 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000,
+ 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000,
+ 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000,
+ 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000,
+ 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000,
+ 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000,
+ 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000,
+ 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000,
+ 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000,
+ 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000,
+ 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000,
+ 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000,
+ 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000,
+ 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000,
+ 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000,
+ 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000,
+ 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000,
+ 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000,
+ 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000,
+ 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000,
+ 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000,
+ 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000,
+ 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000,
+ 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000,
+ 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000,
+ 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000,
+ 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000,
+ 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000,
+ 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000,
+ 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000,
+ 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000,
+ 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000,
+ 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000,
+ 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000,
+ 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000,
+ 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000,
+ 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000,
+ 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000,
+ 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000,
+ 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000,
+ 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000,
+ 0xe4e9223500000000},
+ {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000,
+ 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000,
+ 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000,
+ 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000,
+ 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000,
+ 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000,
+ 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000,
+ 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000,
+ 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000,
+ 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000,
+ 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000,
+ 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000,
+ 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000,
+ 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000,
+ 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000,
+ 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000,
+ 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000,
+ 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000,
+ 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000,
+ 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000,
+ 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000,
+ 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000,
+ 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000,
+ 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000,
+ 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000,
+ 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000,
+ 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000,
+ 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000,
+ 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000,
+ 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000,
+ 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000,
+ 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000,
+ 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000,
+ 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000,
+ 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000,
+ 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000,
+ 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000,
+ 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000,
+ 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000,
+ 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000,
+ 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000,
+ 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000,
+ 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000,
+ 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000,
+ 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000,
+ 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000,
+ 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000,
+ 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000,
+ 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000,
+ 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000,
+ 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000,
+ 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000,
+ 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000,
+ 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000,
+ 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000,
+ 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000,
+ 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000,
+ 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000,
+ 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000,
+ 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000,
+ 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000,
+ 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000,
+ 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000,
+ 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000,
+ 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000,
+ 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000,
+ 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000,
+ 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000,
+ 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000,
+ 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000,
+ 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000,
+ 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000,
+ 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000,
+ 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000,
+ 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000,
+ 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000,
+ 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000,
+ 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000,
+ 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000,
+ 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000,
+ 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000,
+ 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000,
+ 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000,
+ 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000,
+ 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000,
+ 0x880452a700000000},
+ {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000,
+ 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000,
+ 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000,
+ 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000,
+ 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000,
+ 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000,
+ 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000,
+ 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000,
+ 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000,
+ 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000,
+ 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000,
+ 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000,
+ 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000,
+ 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000,
+ 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000,
+ 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000,
+ 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000,
+ 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000,
+ 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000,
+ 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000,
+ 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000,
+ 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000,
+ 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000,
+ 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000,
+ 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000,
+ 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000,
+ 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000,
+ 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000,
+ 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000,
+ 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000,
+ 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000,
+ 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000,
+ 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000,
+ 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000,
+ 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000,
+ 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000,
+ 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000,
+ 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000,
+ 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000,
+ 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000,
+ 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000,
+ 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000,
+ 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000,
+ 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000,
+ 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000,
+ 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000,
+ 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000,
+ 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000,
+ 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000,
+ 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000,
+ 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000,
+ 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000,
+ 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000,
+ 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000,
+ 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000,
+ 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000,
+ 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000,
+ 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000,
+ 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000,
+ 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000,
+ 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000,
+ 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000,
+ 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000,
+ 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000,
+ 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000,
+ 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000,
+ 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000,
+ 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000,
+ 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000,
+ 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000,
+ 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000,
+ 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000,
+ 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000,
+ 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000,
+ 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000,
+ 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000,
+ 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000,
+ 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000,
+ 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000,
+ 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000,
+ 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000,
+ 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000,
+ 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000,
+ 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000,
+ 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000,
+ 0x1659c4e300000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87,
+ 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede,
+ 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab,
+ 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c,
+ 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1,
+ 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7,
+ 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e,
+ 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308,
+ 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5,
+ 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472,
+ 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07,
+ 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e,
+ 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa,
+ 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec,
+ 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6,
+ 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0,
+ 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3,
+ 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba,
+ 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf,
+ 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975,
+ 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8,
+ 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde,
+ 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a,
+ 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c,
+ 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1,
+ 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65,
+ 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410,
+ 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649,
+ 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a,
+ 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c,
+ 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946,
+ 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450,
+ 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e,
+ 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857,
+ 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022,
+ 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5,
+ 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758,
+ 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e,
+ 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d,
+ 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b,
+ 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6,
+ 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401,
+ 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74,
+ 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d,
+ 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073,
+ 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65,
+ 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f,
+ 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749,
+ 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a,
+ 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033,
+ 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846,
+ 0x0d7139d7},
+ {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563,
+ 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f,
+ 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875,
+ 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536,
+ 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8,
+ 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43,
+ 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f,
+ 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184,
+ 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a,
+ 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39,
+ 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523,
+ 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f,
+ 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d,
+ 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6,
+ 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b,
+ 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0,
+ 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151,
+ 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d,
+ 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47,
+ 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a,
+ 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964,
+ 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef,
+ 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d,
+ 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6,
+ 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348,
+ 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53,
+ 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449,
+ 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645,
+ 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4,
+ 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f,
+ 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2,
+ 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69,
+ 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46,
+ 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a,
+ 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650,
+ 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13,
+ 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded,
+ 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366,
+ 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57,
+ 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc,
+ 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222,
+ 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61,
+ 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b,
+ 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277,
+ 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558,
+ 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3,
+ 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e,
+ 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5,
+ 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74,
+ 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78,
+ 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262,
+ 0x1c53e98a},
+ {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b,
+ 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40,
+ 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580,
+ 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7,
+ 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a,
+ 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37,
+ 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75,
+ 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218,
+ 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5,
+ 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2,
+ 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02,
+ 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59,
+ 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1,
+ 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c,
+ 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a,
+ 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307,
+ 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486,
+ 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd,
+ 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d,
+ 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2,
+ 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f,
+ 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72,
+ 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8,
+ 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985,
+ 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268,
+ 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94,
+ 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454,
+ 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f,
+ 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e,
+ 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3,
+ 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915,
+ 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778,
+ 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821,
+ 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a,
+ 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba,
+ 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d,
+ 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560,
+ 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d,
+ 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe,
+ 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3,
+ 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e,
+ 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509,
+ 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9,
+ 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92,
+ 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb,
+ 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6,
+ 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50,
+ 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d,
+ 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc,
+ 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7,
+ 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927,
+ 0x3f88e851},
+ {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96,
+ 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8,
+ 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0,
+ 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14,
+ 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7,
+ 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4,
+ 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe,
+ 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad,
+ 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e,
+ 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa,
+ 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2,
+ 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c,
+ 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab,
+ 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8,
+ 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d,
+ 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e,
+ 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7,
+ 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99,
+ 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1,
+ 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690,
+ 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933,
+ 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20,
+ 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf,
+ 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc,
+ 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f,
+ 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92,
+ 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca,
+ 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4,
+ 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd,
+ 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de,
+ 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb,
+ 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8,
+ 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474,
+ 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a,
+ 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252,
+ 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6,
+ 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55,
+ 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846,
+ 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7,
+ 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4,
+ 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47,
+ 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3,
+ 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb,
+ 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5,
+ 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49,
+ 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a,
+ 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f,
+ 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c,
+ 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305,
+ 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b,
+ 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523,
+ 0x3dee8ca6}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0,
+ 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587,
+ 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa,
+ 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09,
+ 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee,
+ 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3,
+ 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3,
+ 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce,
+ 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429,
+ 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda,
+ 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7,
+ 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0,
+ 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd,
+ 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0,
+ 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287,
+ 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a,
+ 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9,
+ 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e,
+ 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3,
+ 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3,
+ 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054,
+ 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49,
+ 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da,
+ 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7,
+ 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20,
+ 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d,
+ 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00,
+ 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347,
+ 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14,
+ 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209,
+ 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e,
+ 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33,
+ 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3,
+ 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194,
+ 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9,
+ 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a,
+ 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd,
+ 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0,
+ 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d,
+ 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460,
+ 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87,
+ 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674,
+ 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509,
+ 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e,
+ 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae,
+ 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3,
+ 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694,
+ 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989,
+ 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da,
+ 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d,
+ 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0,
+ 0xa68cee3d},
+ {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19,
+ 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae,
+ 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb,
+ 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a,
+ 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55,
+ 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1,
+ 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c,
+ 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8,
+ 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7,
+ 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936,
+ 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453,
+ 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4,
+ 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941,
+ 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5,
+ 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93,
+ 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17,
+ 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e,
+ 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89,
+ 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec,
+ 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0,
+ 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf,
+ 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b,
+ 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b,
+ 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f,
+ 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0,
+ 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e,
+ 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b,
+ 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc,
+ 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5,
+ 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261,
+ 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637,
+ 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3,
+ 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57,
+ 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0,
+ 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85,
+ 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454,
+ 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b,
+ 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f,
+ 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423,
+ 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7,
+ 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8,
+ 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739,
+ 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c,
+ 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb,
+ 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f,
+ 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b,
+ 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd,
+ 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59,
+ 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070,
+ 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7,
+ 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2,
+ 0x51e8883f},
+ {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a,
+ 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276,
+ 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed,
+ 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55,
+ 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b,
+ 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8,
+ 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320,
+ 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413,
+ 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd,
+ 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75,
+ 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee,
+ 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312,
+ 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca,
+ 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9,
+ 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad,
+ 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e,
+ 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504,
+ 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8,
+ 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63,
+ 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353,
+ 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d,
+ 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be,
+ 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae,
+ 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d,
+ 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943,
+ 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7,
+ 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c,
+ 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390,
+ 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a,
+ 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239,
+ 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d,
+ 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e,
+ 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c,
+ 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0,
+ 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b,
+ 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93,
+ 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d,
+ 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e,
+ 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c,
+ 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f,
+ 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1,
+ 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579,
+ 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2,
+ 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e,
+ 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c,
+ 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f,
+ 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b,
+ 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158,
+ 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2,
+ 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e,
+ 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5,
+ 0x8ae9531c},
+ {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4,
+ 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd,
+ 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220,
+ 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf,
+ 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495,
+ 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def,
+ 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90,
+ 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea,
+ 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0,
+ 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f,
+ 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2,
+ 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab,
+ 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e,
+ 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754,
+ 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda,
+ 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0,
+ 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c,
+ 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215,
+ 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8,
+ 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910,
+ 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a,
+ 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30,
+ 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658,
+ 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22,
+ 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478,
+ 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2,
+ 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f,
+ 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606,
+ 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba,
+ 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0,
+ 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e,
+ 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034,
+ 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f,
+ 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996,
+ 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b,
+ 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84,
+ 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de,
+ 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4,
+ 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5,
+ 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f,
+ 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5,
+ 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a,
+ 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7,
+ 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce,
+ 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65,
+ 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f,
+ 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91,
+ 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb,
+ 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57,
+ 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e,
+ 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3,
+ 0xd739710d}};
+
+#endif
+
+#endif
+
+#if N == 5
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df,
+ 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8,
+ 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef,
+ 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376,
+ 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201,
+ 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399,
+ 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372,
+ 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea,
+ 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d,
+ 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004,
+ 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353,
+ 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334,
+ 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a,
+ 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2,
+ 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a,
+ 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2,
+ 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b,
+ 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c,
+ 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b,
+ 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f,
+ 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338,
+ 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0,
+ 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6,
+ 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e,
+ 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319,
+ 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3,
+ 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4,
+ 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783,
+ 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a,
+ 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492,
+ 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a,
+ 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2,
+ 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496,
+ 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1,
+ 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6,
+ 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f,
+ 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548,
+ 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0,
+ 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741,
+ 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9,
+ 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae,
+ 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437,
+ 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760,
+ 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707,
+ 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433,
+ 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab,
+ 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703,
+ 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b,
+ 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412,
+ 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475,
+ 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722,
+ 0xe9947565},
+ {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5,
+ 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22,
+ 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c,
+ 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed,
+ 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d,
+ 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1,
+ 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e,
+ 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32,
+ 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142,
+ 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93,
+ 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d,
+ 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a,
+ 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58,
+ 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14,
+ 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81,
+ 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd,
+ 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab,
+ 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c,
+ 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72,
+ 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f,
+ 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff,
+ 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3,
+ 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30,
+ 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c,
+ 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c,
+ 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558,
+ 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146,
+ 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581,
+ 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7,
+ 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab,
+ 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e,
+ 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272,
+ 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838,
+ 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff,
+ 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1,
+ 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330,
+ 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840,
+ 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c,
+ 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb,
+ 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7,
+ 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7,
+ 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616,
+ 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208,
+ 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf,
+ 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85,
+ 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9,
+ 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c,
+ 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10,
+ 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76,
+ 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1,
+ 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf,
+ 0xf7d05006},
+ {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b,
+ 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774,
+ 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58,
+ 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a,
+ 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb,
+ 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952,
+ 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e,
+ 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7,
+ 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746,
+ 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14,
+ 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338,
+ 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907,
+ 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777,
+ 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de,
+ 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064,
+ 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd,
+ 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951,
+ 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e,
+ 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42,
+ 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b,
+ 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a,
+ 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3,
+ 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904,
+ 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad,
+ 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c,
+ 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d,
+ 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861,
+ 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e,
+ 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2,
+ 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b,
+ 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1,
+ 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78,
+ 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f,
+ 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40,
+ 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c,
+ 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e,
+ 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf,
+ 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166,
+ 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d,
+ 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4,
+ 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805,
+ 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157,
+ 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b,
+ 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644,
+ 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43,
+ 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea,
+ 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850,
+ 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9,
+ 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165,
+ 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a,
+ 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676,
+ 0xb2075b94},
+ {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf,
+ 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61,
+ 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be,
+ 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd,
+ 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3,
+ 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063,
+ 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105,
+ 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5,
+ 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb,
+ 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8,
+ 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07,
+ 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9,
+ 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5,
+ 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515,
+ 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4,
+ 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014,
+ 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7,
+ 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269,
+ 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6,
+ 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af,
+ 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1,
+ 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111,
+ 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d,
+ 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad,
+ 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3,
+ 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75,
+ 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa,
+ 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74,
+ 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7,
+ 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477,
+ 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6,
+ 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176,
+ 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af,
+ 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71,
+ 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae,
+ 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd,
+ 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3,
+ 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073,
+ 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0,
+ 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400,
+ 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e,
+ 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d,
+ 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2,
+ 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c,
+ 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5,
+ 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505,
+ 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4,
+ 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004,
+ 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7,
+ 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279,
+ 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6,
+ 0xba50bcb9},
+ {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897,
+ 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb,
+ 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2,
+ 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2,
+ 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372,
+ 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70,
+ 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92,
+ 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190,
+ 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40,
+ 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430,
+ 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759,
+ 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75,
+ 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2,
+ 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0,
+ 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7,
+ 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5,
+ 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39,
+ 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215,
+ 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c,
+ 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5,
+ 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625,
+ 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27,
+ 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c,
+ 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e,
+ 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee,
+ 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71,
+ 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18,
+ 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134,
+ 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8,
+ 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba,
+ 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd,
+ 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff,
+ 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a,
+ 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6,
+ 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf,
+ 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf,
+ 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f,
+ 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d,
+ 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d,
+ 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f,
+ 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af,
+ 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df,
+ 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6,
+ 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a,
+ 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef,
+ 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed,
+ 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa,
+ 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8,
+ 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624,
+ 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08,
+ 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861,
+ 0x808abcf4},
+ {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2,
+ 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd,
+ 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76,
+ 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52,
+ 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e,
+ 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124,
+ 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147,
+ 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d,
+ 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31,
+ 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15,
+ 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae,
+ 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1,
+ 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d,
+ 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307,
+ 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9,
+ 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3,
+ 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084,
+ 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb,
+ 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850,
+ 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2,
+ 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe,
+ 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94,
+ 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261,
+ 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b,
+ 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917,
+ 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53,
+ 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8,
+ 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787,
+ 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0,
+ 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba,
+ 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404,
+ 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e,
+ 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af,
+ 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0,
+ 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b,
+ 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f,
+ 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543,
+ 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129,
+ 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627,
+ 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d,
+ 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51,
+ 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75,
+ 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce,
+ 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1,
+ 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760,
+ 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a,
+ 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4,
+ 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde,
+ 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089,
+ 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6,
+ 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d,
+ 0xefdb3f95},
+ {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8,
+ 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7,
+ 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945,
+ 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9,
+ 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652,
+ 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc,
+ 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a,
+ 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4,
+ 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f,
+ 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3,
+ 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51,
+ 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e,
+ 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c,
+ 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362,
+ 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11,
+ 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff,
+ 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7,
+ 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8,
+ 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a,
+ 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690,
+ 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b,
+ 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5,
+ 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05,
+ 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb,
+ 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740,
+ 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f,
+ 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded,
+ 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2,
+ 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa,
+ 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714,
+ 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67,
+ 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89,
+ 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7,
+ 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8,
+ 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a,
+ 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6,
+ 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d,
+ 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3,
+ 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9,
+ 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57,
+ 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc,
+ 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540,
+ 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2,
+ 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd,
+ 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93,
+ 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d,
+ 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e,
+ 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0,
+ 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8,
+ 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7,
+ 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75,
+ 0x0e2fbf43},
+ {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc,
+ 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a,
+ 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3,
+ 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7,
+ 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b,
+ 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154,
+ 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3,
+ 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc,
+ 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330,
+ 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264,
+ 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd,
+ 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b,
+ 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a,
+ 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175,
+ 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275,
+ 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a,
+ 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234,
+ 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2,
+ 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b,
+ 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a,
+ 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6,
+ 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189,
+ 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b,
+ 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204,
+ 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8,
+ 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226,
+ 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff,
+ 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219,
+ 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167,
+ 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258,
+ 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158,
+ 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267,
+ 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c,
+ 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da,
+ 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003,
+ 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157,
+ 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b,
+ 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4,
+ 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179,
+ 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246,
+ 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a,
+ 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de,
+ 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107,
+ 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1,
+ 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba,
+ 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285,
+ 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185,
+ 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba,
+ 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4,
+ 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322,
+ 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb,
+ 0xf4377108}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000,
+ 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000,
+ 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000,
+ 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000,
+ 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000,
+ 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000,
+ 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000,
+ 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000,
+ 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000,
+ 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000,
+ 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000,
+ 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000,
+ 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000,
+ 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000,
+ 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000,
+ 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000,
+ 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000,
+ 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000,
+ 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000,
+ 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000,
+ 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000,
+ 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000,
+ 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000,
+ 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000,
+ 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000,
+ 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000,
+ 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000,
+ 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000,
+ 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000,
+ 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000,
+ 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000,
+ 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000,
+ 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000,
+ 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000,
+ 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000,
+ 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000,
+ 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000,
+ 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000,
+ 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000,
+ 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000,
+ 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000,
+ 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000,
+ 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000,
+ 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000,
+ 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000,
+ 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000,
+ 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000,
+ 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000,
+ 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000,
+ 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000,
+ 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000,
+ 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000,
+ 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000,
+ 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000,
+ 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000,
+ 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000,
+ 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000,
+ 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000,
+ 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000,
+ 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000,
+ 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000,
+ 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000,
+ 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000,
+ 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000,
+ 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000,
+ 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000,
+ 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000,
+ 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000,
+ 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000,
+ 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000,
+ 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000,
+ 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000,
+ 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000,
+ 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000,
+ 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000,
+ 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000,
+ 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000,
+ 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000,
+ 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000,
+ 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000,
+ 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000,
+ 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000,
+ 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000,
+ 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000,
+ 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000,
+ 0x087137f400000000},
+ {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000,
+ 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000,
+ 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000,
+ 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000,
+ 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000,
+ 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000,
+ 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000,
+ 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000,
+ 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000,
+ 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000,
+ 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000,
+ 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000,
+ 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000,
+ 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000,
+ 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000,
+ 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000,
+ 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000,
+ 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000,
+ 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000,
+ 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000,
+ 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000,
+ 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000,
+ 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000,
+ 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000,
+ 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000,
+ 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000,
+ 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000,
+ 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000,
+ 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000,
+ 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000,
+ 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000,
+ 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000,
+ 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000,
+ 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000,
+ 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000,
+ 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000,
+ 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000,
+ 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000,
+ 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000,
+ 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000,
+ 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000,
+ 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000,
+ 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000,
+ 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000,
+ 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000,
+ 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000,
+ 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000,
+ 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000,
+ 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000,
+ 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000,
+ 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000,
+ 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000,
+ 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000,
+ 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000,
+ 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000,
+ 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000,
+ 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000,
+ 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000,
+ 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000,
+ 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000,
+ 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000,
+ 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000,
+ 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000,
+ 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000,
+ 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000,
+ 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000,
+ 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000,
+ 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000,
+ 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000,
+ 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000,
+ 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000,
+ 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000,
+ 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000,
+ 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000,
+ 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000,
+ 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000,
+ 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000,
+ 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000,
+ 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000,
+ 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000,
+ 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000,
+ 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000,
+ 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000,
+ 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000,
+ 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000,
+ 0x43bf2f0e00000000},
+ {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000,
+ 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000,
+ 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000,
+ 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000,
+ 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000,
+ 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000,
+ 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000,
+ 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000,
+ 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000,
+ 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000,
+ 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000,
+ 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000,
+ 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000,
+ 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000,
+ 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000,
+ 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000,
+ 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000,
+ 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000,
+ 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000,
+ 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000,
+ 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000,
+ 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000,
+ 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000,
+ 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000,
+ 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000,
+ 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000,
+ 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000,
+ 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000,
+ 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000,
+ 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000,
+ 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000,
+ 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000,
+ 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000,
+ 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000,
+ 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000,
+ 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000,
+ 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000,
+ 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000,
+ 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000,
+ 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000,
+ 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000,
+ 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000,
+ 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000,
+ 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000,
+ 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000,
+ 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000,
+ 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000,
+ 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000,
+ 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000,
+ 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000,
+ 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000,
+ 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000,
+ 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000,
+ 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000,
+ 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000,
+ 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000,
+ 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000,
+ 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000,
+ 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000,
+ 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000,
+ 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000,
+ 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000,
+ 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000,
+ 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000,
+ 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000,
+ 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000,
+ 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000,
+ 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000,
+ 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000,
+ 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000,
+ 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000,
+ 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000,
+ 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000,
+ 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000,
+ 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000,
+ 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000,
+ 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000,
+ 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000,
+ 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000,
+ 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000,
+ 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000,
+ 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000,
+ 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000,
+ 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000,
+ 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000,
+ 0x953fdbef00000000},
+ {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000,
+ 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000,
+ 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000,
+ 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000,
+ 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000,
+ 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000,
+ 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000,
+ 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000,
+ 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000,
+ 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000,
+ 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000,
+ 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000,
+ 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000,
+ 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000,
+ 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000,
+ 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000,
+ 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000,
+ 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000,
+ 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000,
+ 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000,
+ 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000,
+ 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000,
+ 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000,
+ 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000,
+ 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000,
+ 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000,
+ 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000,
+ 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000,
+ 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000,
+ 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000,
+ 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000,
+ 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000,
+ 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000,
+ 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000,
+ 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000,
+ 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000,
+ 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000,
+ 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000,
+ 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000,
+ 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000,
+ 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000,
+ 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000,
+ 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000,
+ 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000,
+ 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000,
+ 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000,
+ 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000,
+ 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000,
+ 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000,
+ 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000,
+ 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000,
+ 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000,
+ 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000,
+ 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000,
+ 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000,
+ 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000,
+ 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000,
+ 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000,
+ 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000,
+ 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000,
+ 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000,
+ 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000,
+ 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000,
+ 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000,
+ 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000,
+ 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000,
+ 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000,
+ 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000,
+ 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000,
+ 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000,
+ 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000,
+ 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000,
+ 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000,
+ 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000,
+ 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000,
+ 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000,
+ 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000,
+ 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000,
+ 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000,
+ 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000,
+ 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000,
+ 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000,
+ 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000,
+ 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000,
+ 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000,
+ 0xf4bc8a8000000000},
+ {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000,
+ 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000,
+ 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000,
+ 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000,
+ 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000,
+ 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000,
+ 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000,
+ 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000,
+ 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000,
+ 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000,
+ 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000,
+ 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000,
+ 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000,
+ 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000,
+ 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000,
+ 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000,
+ 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000,
+ 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000,
+ 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000,
+ 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000,
+ 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000,
+ 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000,
+ 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000,
+ 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000,
+ 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000,
+ 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000,
+ 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000,
+ 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000,
+ 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000,
+ 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000,
+ 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000,
+ 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000,
+ 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000,
+ 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000,
+ 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000,
+ 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000,
+ 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000,
+ 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000,
+ 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000,
+ 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000,
+ 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000,
+ 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000,
+ 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000,
+ 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000,
+ 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000,
+ 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000,
+ 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000,
+ 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000,
+ 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000,
+ 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000,
+ 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000,
+ 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000,
+ 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000,
+ 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000,
+ 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000,
+ 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000,
+ 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000,
+ 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000,
+ 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000,
+ 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000,
+ 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000,
+ 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000,
+ 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000,
+ 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000,
+ 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000,
+ 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000,
+ 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000,
+ 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000,
+ 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000,
+ 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000,
+ 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000,
+ 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000,
+ 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000,
+ 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000,
+ 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000,
+ 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000,
+ 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000,
+ 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000,
+ 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000,
+ 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000,
+ 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000,
+ 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000,
+ 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000,
+ 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000,
+ 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000,
+ 0xb9bc50ba00000000},
+ {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000,
+ 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000,
+ 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000,
+ 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000,
+ 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000,
+ 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000,
+ 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000,
+ 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000,
+ 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000,
+ 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000,
+ 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000,
+ 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000,
+ 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000,
+ 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000,
+ 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000,
+ 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000,
+ 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000,
+ 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000,
+ 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000,
+ 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000,
+ 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000,
+ 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000,
+ 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000,
+ 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000,
+ 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000,
+ 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000,
+ 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000,
+ 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000,
+ 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000,
+ 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000,
+ 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000,
+ 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000,
+ 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000,
+ 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000,
+ 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000,
+ 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000,
+ 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000,
+ 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000,
+ 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000,
+ 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000,
+ 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000,
+ 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000,
+ 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000,
+ 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000,
+ 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000,
+ 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000,
+ 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000,
+ 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000,
+ 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000,
+ 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000,
+ 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000,
+ 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000,
+ 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000,
+ 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000,
+ 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000,
+ 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000,
+ 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000,
+ 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000,
+ 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000,
+ 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000,
+ 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000,
+ 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000,
+ 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000,
+ 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000,
+ 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000,
+ 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000,
+ 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000,
+ 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000,
+ 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000,
+ 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000,
+ 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000,
+ 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000,
+ 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000,
+ 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000,
+ 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000,
+ 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000,
+ 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000,
+ 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000,
+ 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000,
+ 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000,
+ 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000,
+ 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000,
+ 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000,
+ 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000,
+ 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000,
+ 0x945b07b200000000},
+ {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000,
+ 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000,
+ 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000,
+ 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000,
+ 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000,
+ 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000,
+ 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000,
+ 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000,
+ 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000,
+ 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000,
+ 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000,
+ 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000,
+ 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000,
+ 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000,
+ 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000,
+ 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000,
+ 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000,
+ 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000,
+ 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000,
+ 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000,
+ 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000,
+ 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000,
+ 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000,
+ 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000,
+ 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000,
+ 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000,
+ 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000,
+ 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000,
+ 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000,
+ 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000,
+ 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000,
+ 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000,
+ 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000,
+ 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000,
+ 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000,
+ 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000,
+ 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000,
+ 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000,
+ 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000,
+ 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000,
+ 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000,
+ 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000,
+ 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000,
+ 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000,
+ 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000,
+ 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000,
+ 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000,
+ 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000,
+ 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000,
+ 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000,
+ 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000,
+ 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000,
+ 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000,
+ 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000,
+ 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000,
+ 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000,
+ 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000,
+ 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000,
+ 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000,
+ 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000,
+ 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000,
+ 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000,
+ 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000,
+ 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000,
+ 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000,
+ 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000,
+ 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000,
+ 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000,
+ 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000,
+ 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000,
+ 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000,
+ 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000,
+ 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000,
+ 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000,
+ 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000,
+ 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000,
+ 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000,
+ 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000,
+ 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000,
+ 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000,
+ 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000,
+ 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000,
+ 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000,
+ 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000,
+ 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000,
+ 0x0650d0f700000000},
+ {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000,
+ 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000,
+ 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000,
+ 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000,
+ 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000,
+ 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000,
+ 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000,
+ 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000,
+ 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000,
+ 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000,
+ 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000,
+ 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000,
+ 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000,
+ 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000,
+ 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000,
+ 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000,
+ 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000,
+ 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000,
+ 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000,
+ 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000,
+ 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000,
+ 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000,
+ 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000,
+ 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000,
+ 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000,
+ 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000,
+ 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000,
+ 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000,
+ 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000,
+ 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000,
+ 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000,
+ 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000,
+ 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000,
+ 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000,
+ 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000,
+ 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000,
+ 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000,
+ 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000,
+ 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000,
+ 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000,
+ 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000,
+ 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000,
+ 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000,
+ 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000,
+ 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000,
+ 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000,
+ 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000,
+ 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000,
+ 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000,
+ 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000,
+ 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000,
+ 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000,
+ 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000,
+ 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000,
+ 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000,
+ 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000,
+ 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000,
+ 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000,
+ 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000,
+ 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000,
+ 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000,
+ 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000,
+ 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000,
+ 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000,
+ 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000,
+ 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000,
+ 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000,
+ 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000,
+ 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000,
+ 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000,
+ 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000,
+ 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000,
+ 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000,
+ 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000,
+ 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000,
+ 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000,
+ 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000,
+ 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000,
+ 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000,
+ 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000,
+ 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000,
+ 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000,
+ 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000,
+ 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000,
+ 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000,
+ 0x657594e900000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59,
+ 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4,
+ 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67,
+ 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef,
+ 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97,
+ 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88,
+ 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687,
+ 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698,
+ 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0,
+ 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068,
+ 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb,
+ 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056,
+ 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016,
+ 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009,
+ 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028,
+ 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037,
+ 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a,
+ 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7,
+ 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054,
+ 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7,
+ 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af,
+ 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0,
+ 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4,
+ 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab,
+ 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3,
+ 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a,
+ 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9,
+ 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54,
+ 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09,
+ 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16,
+ 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37,
+ 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28,
+ 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e,
+ 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3,
+ 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40,
+ 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8,
+ 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0,
+ 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf,
+ 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6,
+ 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9,
+ 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1,
+ 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059,
+ 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca,
+ 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067,
+ 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031,
+ 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e,
+ 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f,
+ 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010,
+ 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d,
+ 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0,
+ 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073,
+ 0xd8ac6b35},
+ {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2,
+ 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd,
+ 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696,
+ 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3,
+ 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f,
+ 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35,
+ 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5,
+ 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f,
+ 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673,
+ 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46,
+ 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d,
+ 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632,
+ 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28,
+ 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192,
+ 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c,
+ 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6,
+ 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0,
+ 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff,
+ 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4,
+ 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95,
+ 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9,
+ 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03,
+ 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7,
+ 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d,
+ 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151,
+ 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808,
+ 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343,
+ 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c,
+ 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a,
+ 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0,
+ 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e,
+ 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594,
+ 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6,
+ 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399,
+ 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2,
+ 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7,
+ 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb,
+ 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571,
+ 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289,
+ 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33,
+ 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f,
+ 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a,
+ 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461,
+ 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e,
+ 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c,
+ 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6,
+ 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918,
+ 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2,
+ 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484,
+ 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb,
+ 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0,
+ 0xa140efa8},
+ {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706,
+ 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed,
+ 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289,
+ 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a,
+ 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214,
+ 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3,
+ 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3,
+ 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254,
+ 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a,
+ 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9,
+ 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad,
+ 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746,
+ 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060,
+ 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187,
+ 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef,
+ 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408,
+ 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e,
+ 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495,
+ 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1,
+ 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532,
+ 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c,
+ 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb,
+ 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb,
+ 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c,
+ 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42,
+ 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060,
+ 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04,
+ 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef,
+ 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99,
+ 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e,
+ 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16,
+ 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1,
+ 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7,
+ 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c,
+ 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38,
+ 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb,
+ 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5,
+ 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42,
+ 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62,
+ 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85,
+ 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb,
+ 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18,
+ 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c,
+ 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997,
+ 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1,
+ 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36,
+ 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e,
+ 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9,
+ 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf,
+ 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24,
+ 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040,
+ 0x917cd6a1},
+ {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf,
+ 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd,
+ 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896,
+ 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9,
+ 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3,
+ 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f,
+ 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d,
+ 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1,
+ 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab,
+ 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4,
+ 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f,
+ 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d,
+ 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4,
+ 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978,
+ 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad,
+ 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621,
+ 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46,
+ 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854,
+ 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f,
+ 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a,
+ 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890,
+ 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c,
+ 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4,
+ 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238,
+ 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622,
+ 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab,
+ 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0,
+ 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2,
+ 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295,
+ 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19,
+ 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc,
+ 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140,
+ 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd,
+ 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf,
+ 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184,
+ 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb,
+ 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1,
+ 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d,
+ 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb,
+ 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257,
+ 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d,
+ 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22,
+ 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069,
+ 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b,
+ 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6,
+ 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a,
+ 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf,
+ 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33,
+ 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254,
+ 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146,
+ 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d,
+ 0x18ba364e}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873,
+ 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661,
+ 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441,
+ 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44,
+ 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1,
+ 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05,
+ 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa,
+ 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e,
+ 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb,
+ 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be,
+ 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e,
+ 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c,
+ 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d,
+ 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9,
+ 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f,
+ 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b,
+ 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39,
+ 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b,
+ 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b,
+ 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20,
+ 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595,
+ 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61,
+ 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0,
+ 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644,
+ 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1,
+ 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d,
+ 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d,
+ 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f,
+ 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad,
+ 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359,
+ 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f,
+ 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b,
+ 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7,
+ 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5,
+ 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5,
+ 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0,
+ 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65,
+ 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091,
+ 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633,
+ 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7,
+ 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272,
+ 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77,
+ 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57,
+ 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145,
+ 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9,
+ 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d,
+ 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb,
+ 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f,
+ 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad,
+ 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf,
+ 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f,
+ 0x4e36ba18},
+ {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b,
+ 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8,
+ 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19,
+ 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4,
+ 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239,
+ 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd,
+ 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258,
+ 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc,
+ 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41,
+ 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c,
+ 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d,
+ 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e,
+ 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba,
+ 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e,
+ 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8,
+ 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c,
+ 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f,
+ 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c,
+ 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d,
+ 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d,
+ 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0,
+ 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014,
+ 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc,
+ 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628,
+ 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5,
+ 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941,
+ 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0,
+ 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53,
+ 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880,
+ 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264,
+ 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92,
+ 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776,
+ 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8,
+ 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b,
+ 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea,
+ 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837,
+ 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca,
+ 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e,
+ 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211,
+ 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5,
+ 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08,
+ 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5,
+ 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934,
+ 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7,
+ 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049,
+ 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad,
+ 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b,
+ 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf,
+ 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c,
+ 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f,
+ 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e,
+ 0xa1d67c91},
+ {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9,
+ 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de,
+ 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94,
+ 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0,
+ 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a,
+ 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924,
+ 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052,
+ 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c,
+ 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6,
+ 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2,
+ 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8,
+ 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f,
+ 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d,
+ 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273,
+ 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30,
+ 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e,
+ 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7,
+ 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980,
+ 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca,
+ 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8,
+ 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62,
+ 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c,
+ 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c,
+ 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032,
+ 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798,
+ 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d,
+ 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07,
+ 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630,
+ 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389,
+ 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7,
+ 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4,
+ 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca,
+ 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55,
+ 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662,
+ 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828,
+ 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c,
+ 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6,
+ 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98,
+ 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3,
+ 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d,
+ 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037,
+ 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913,
+ 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759,
+ 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e,
+ 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1,
+ 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf,
+ 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c,
+ 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2,
+ 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b,
+ 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c,
+ 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276,
+ 0xa8ef40a1},
+ {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e,
+ 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8,
+ 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819,
+ 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f,
+ 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d,
+ 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756,
+ 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0,
+ 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb,
+ 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9,
+ 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f,
+ 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e,
+ 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8,
+ 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835,
+ 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e,
+ 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62,
+ 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749,
+ 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b,
+ 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d,
+ 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc,
+ 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80,
+ 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2,
+ 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599,
+ 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05,
+ 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e,
+ 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c,
+ 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e,
+ 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef,
+ 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359,
+ 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b,
+ 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0,
+ 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc,
+ 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7,
+ 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f,
+ 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189,
+ 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568,
+ 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e,
+ 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c,
+ 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27,
+ 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794,
+ 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf,
+ 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d,
+ 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db,
+ 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a,
+ 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c,
+ 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544,
+ 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f,
+ 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013,
+ 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38,
+ 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea,
+ 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c,
+ 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd,
+ 0x356bacd8}};
+
+#endif
+
+#endif
+
+#if N == 6
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370,
+ 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d,
+ 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69,
+ 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426,
+ 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3,
+ 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f,
+ 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c,
+ 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490,
+ 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155,
+ 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a,
+ 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e,
+ 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603,
+ 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349,
+ 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5,
+ 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50,
+ 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc,
+ 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b,
+ 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76,
+ 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862,
+ 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9,
+ 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c,
+ 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0,
+ 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937,
+ 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b,
+ 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e,
+ 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e,
+ 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a,
+ 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357,
+ 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0,
+ 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c,
+ 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9,
+ 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165,
+ 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766,
+ 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b,
+ 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f,
+ 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030,
+ 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5,
+ 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59,
+ 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63,
+ 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf,
+ 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a,
+ 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845,
+ 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51,
+ 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c,
+ 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f,
+ 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3,
+ 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46,
+ 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea,
+ 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d,
+ 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60,
+ 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74,
+ 0x8568a0a8},
+ {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5,
+ 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf,
+ 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5,
+ 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba,
+ 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf,
+ 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f,
+ 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0,
+ 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450,
+ 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55,
+ 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a,
+ 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620,
+ 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a,
+ 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454,
+ 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4,
+ 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534,
+ 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584,
+ 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694,
+ 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e,
+ 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4,
+ 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1,
+ 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4,
+ 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164,
+ 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1,
+ 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911,
+ 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314,
+ 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c,
+ 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6,
+ 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec,
+ 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc,
+ 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c,
+ 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c,
+ 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c,
+ 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716,
+ 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c,
+ 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676,
+ 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879,
+ 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c,
+ 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc,
+ 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77,
+ 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7,
+ 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2,
+ 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd,
+ 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7,
+ 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad,
+ 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897,
+ 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827,
+ 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7,
+ 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947,
+ 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57,
+ 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d,
+ 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37,
+ 0x0d907052},
+ {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d,
+ 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89,
+ 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31,
+ 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81,
+ 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e,
+ 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0,
+ 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f,
+ 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291,
+ 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e,
+ 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e,
+ 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936,
+ 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2,
+ 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13,
+ 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d,
+ 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f,
+ 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1,
+ 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a,
+ 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae,
+ 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516,
+ 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f,
+ 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20,
+ 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe,
+ 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28,
+ 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6,
+ 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419,
+ 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5,
+ 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d,
+ 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889,
+ 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412,
+ 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c,
+ 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e,
+ 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0,
+ 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02,
+ 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986,
+ 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e,
+ 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e,
+ 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221,
+ 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf,
+ 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913,
+ 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d,
+ 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622,
+ 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592,
+ 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a,
+ 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae,
+ 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c,
+ 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82,
+ 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20,
+ 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe,
+ 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025,
+ 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1,
+ 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719,
+ 0xfd1a6c8a},
+ {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3,
+ 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb,
+ 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d,
+ 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb,
+ 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9,
+ 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156,
+ 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045,
+ 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa,
+ 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8,
+ 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e,
+ 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8,
+ 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0,
+ 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38,
+ 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87,
+ 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46,
+ 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9,
+ 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585,
+ 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d,
+ 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb,
+ 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531,
+ 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03,
+ 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc,
+ 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33,
+ 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c,
+ 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be,
+ 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d,
+ 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b,
+ 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303,
+ 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f,
+ 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0,
+ 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801,
+ 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe,
+ 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e,
+ 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346,
+ 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620,
+ 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776,
+ 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844,
+ 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb,
+ 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0,
+ 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f,
+ 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d,
+ 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b,
+ 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d,
+ 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75,
+ 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795,
+ 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a,
+ 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb,
+ 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354,
+ 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28,
+ 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30,
+ 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856,
+ 0x7895f01a},
+ {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188,
+ 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33,
+ 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d,
+ 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445,
+ 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2,
+ 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058,
+ 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43,
+ 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9,
+ 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e,
+ 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06,
+ 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228,
+ 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93,
+ 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e,
+ 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4,
+ 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b,
+ 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371,
+ 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265,
+ 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede,
+ 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0,
+ 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f,
+ 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8,
+ 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32,
+ 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae,
+ 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544,
+ 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3,
+ 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f,
+ 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911,
+ 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa,
+ 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be,
+ 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54,
+ 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b,
+ 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1,
+ 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652,
+ 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9,
+ 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7,
+ 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f,
+ 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68,
+ 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782,
+ 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797,
+ 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d,
+ 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a,
+ 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2,
+ 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc,
+ 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647,
+ 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4,
+ 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e,
+ 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41,
+ 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab,
+ 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf,
+ 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904,
+ 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a,
+ 0x9239b848},
+ {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad,
+ 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0,
+ 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40,
+ 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b,
+ 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d,
+ 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b,
+ 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb,
+ 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d,
+ 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b,
+ 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0,
+ 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840,
+ 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d,
+ 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b,
+ 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d,
+ 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6,
+ 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0,
+ 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580,
+ 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd,
+ 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d,
+ 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b,
+ 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d,
+ 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b,
+ 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6,
+ 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0,
+ 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6,
+ 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c,
+ 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c,
+ 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461,
+ 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841,
+ 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317,
+ 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac,
+ 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa,
+ 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7,
+ 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba,
+ 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a,
+ 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161,
+ 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777,
+ 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21,
+ 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a,
+ 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc,
+ 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da,
+ 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1,
+ 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01,
+ 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c,
+ 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241,
+ 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917,
+ 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac,
+ 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa,
+ 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da,
+ 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397,
+ 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537,
+ 0xeb36d3cc},
+ {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b,
+ 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059,
+ 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251,
+ 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d,
+ 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9,
+ 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c,
+ 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41,
+ 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4,
+ 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10,
+ 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c,
+ 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54,
+ 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476,
+ 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8,
+ 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d,
+ 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92,
+ 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307,
+ 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad,
+ 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f,
+ 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87,
+ 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17,
+ 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3,
+ 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46,
+ 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197,
+ 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02,
+ 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6,
+ 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e,
+ 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96,
+ 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4,
+ 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e,
+ 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b,
+ 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934,
+ 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1,
+ 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7,
+ 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5,
+ 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd,
+ 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1,
+ 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475,
+ 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0,
+ 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155,
+ 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0,
+ 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304,
+ 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348,
+ 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140,
+ 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862,
+ 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14,
+ 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181,
+ 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e,
+ 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab,
+ 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01,
+ 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523,
+ 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b,
+ 0x38e5f3c5},
+ {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06,
+ 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad,
+ 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509,
+ 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba,
+ 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414,
+ 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3,
+ 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733,
+ 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994,
+ 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a,
+ 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889,
+ 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d,
+ 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386,
+ 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621,
+ 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886,
+ 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e,
+ 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389,
+ 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f,
+ 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294,
+ 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30,
+ 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3,
+ 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d,
+ 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba,
+ 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a,
+ 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad,
+ 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03,
+ 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2,
+ 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306,
+ 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad,
+ 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b,
+ 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc,
+ 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914,
+ 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3,
+ 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435,
+ 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e,
+ 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a,
+ 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589,
+ 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27,
+ 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080,
+ 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21,
+ 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586,
+ 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28,
+ 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b,
+ 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f,
+ 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94,
+ 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12,
+ 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5,
+ 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d,
+ 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba,
+ 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c,
+ 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7,
+ 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103,
+ 0x3d3101a2}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000,
+ 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000,
+ 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000,
+ 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000,
+ 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000,
+ 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000,
+ 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000,
+ 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000,
+ 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000,
+ 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000,
+ 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000,
+ 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000,
+ 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000,
+ 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000,
+ 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000,
+ 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000,
+ 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000,
+ 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000,
+ 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000,
+ 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000,
+ 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000,
+ 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000,
+ 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000,
+ 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000,
+ 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000,
+ 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000,
+ 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000,
+ 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000,
+ 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000,
+ 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000,
+ 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000,
+ 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000,
+ 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000,
+ 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000,
+ 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000,
+ 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000,
+ 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000,
+ 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000,
+ 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000,
+ 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000,
+ 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000,
+ 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000,
+ 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000,
+ 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000,
+ 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000,
+ 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000,
+ 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000,
+ 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000,
+ 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000,
+ 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000,
+ 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000,
+ 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000,
+ 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000,
+ 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000,
+ 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000,
+ 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000,
+ 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000,
+ 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000,
+ 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000,
+ 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000,
+ 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000,
+ 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000,
+ 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000,
+ 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000,
+ 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000,
+ 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000,
+ 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000,
+ 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000,
+ 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000,
+ 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000,
+ 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000,
+ 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000,
+ 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000,
+ 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000,
+ 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000,
+ 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000,
+ 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000,
+ 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000,
+ 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000,
+ 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000,
+ 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000,
+ 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000,
+ 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000,
+ 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000,
+ 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000,
+ 0xa201313d00000000},
+ {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000,
+ 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000,
+ 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000,
+ 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000,
+ 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000,
+ 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000,
+ 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000,
+ 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000,
+ 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000,
+ 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000,
+ 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000,
+ 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000,
+ 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000,
+ 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000,
+ 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000,
+ 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000,
+ 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000,
+ 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000,
+ 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000,
+ 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000,
+ 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000,
+ 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000,
+ 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000,
+ 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000,
+ 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000,
+ 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000,
+ 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000,
+ 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000,
+ 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000,
+ 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000,
+ 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000,
+ 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000,
+ 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000,
+ 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000,
+ 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000,
+ 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000,
+ 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000,
+ 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000,
+ 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000,
+ 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000,
+ 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000,
+ 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000,
+ 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000,
+ 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000,
+ 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000,
+ 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000,
+ 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000,
+ 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000,
+ 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000,
+ 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000,
+ 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000,
+ 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000,
+ 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000,
+ 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000,
+ 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000,
+ 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000,
+ 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000,
+ 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000,
+ 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000,
+ 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000,
+ 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000,
+ 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000,
+ 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000,
+ 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000,
+ 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000,
+ 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000,
+ 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000,
+ 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000,
+ 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000,
+ 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000,
+ 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000,
+ 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000,
+ 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000,
+ 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000,
+ 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000,
+ 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000,
+ 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000,
+ 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000,
+ 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000,
+ 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000,
+ 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000,
+ 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000,
+ 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000,
+ 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000,
+ 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000,
+ 0xc5f3e53800000000},
+ {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000,
+ 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000,
+ 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000,
+ 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000,
+ 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000,
+ 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000,
+ 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000,
+ 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000,
+ 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000,
+ 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000,
+ 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000,
+ 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000,
+ 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000,
+ 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000,
+ 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000,
+ 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000,
+ 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000,
+ 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000,
+ 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000,
+ 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000,
+ 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000,
+ 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000,
+ 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000,
+ 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000,
+ 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000,
+ 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000,
+ 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000,
+ 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000,
+ 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000,
+ 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000,
+ 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000,
+ 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000,
+ 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000,
+ 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000,
+ 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000,
+ 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000,
+ 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000,
+ 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000,
+ 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000,
+ 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000,
+ 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000,
+ 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000,
+ 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000,
+ 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000,
+ 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000,
+ 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000,
+ 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000,
+ 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000,
+ 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000,
+ 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000,
+ 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000,
+ 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000,
+ 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000,
+ 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000,
+ 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000,
+ 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000,
+ 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000,
+ 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000,
+ 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000,
+ 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000,
+ 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000,
+ 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000,
+ 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000,
+ 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000,
+ 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000,
+ 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000,
+ 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000,
+ 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000,
+ 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000,
+ 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000,
+ 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000,
+ 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000,
+ 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000,
+ 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000,
+ 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000,
+ 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000,
+ 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000,
+ 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000,
+ 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000,
+ 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000,
+ 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000,
+ 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000,
+ 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000,
+ 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000,
+ 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000,
+ 0xccd336eb00000000},
+ {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000,
+ 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000,
+ 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000,
+ 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000,
+ 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000,
+ 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000,
+ 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000,
+ 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000,
+ 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000,
+ 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000,
+ 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000,
+ 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000,
+ 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000,
+ 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000,
+ 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000,
+ 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000,
+ 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000,
+ 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000,
+ 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000,
+ 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000,
+ 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000,
+ 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000,
+ 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000,
+ 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000,
+ 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000,
+ 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000,
+ 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000,
+ 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000,
+ 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000,
+ 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000,
+ 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000,
+ 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000,
+ 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000,
+ 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000,
+ 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000,
+ 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000,
+ 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000,
+ 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000,
+ 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000,
+ 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000,
+ 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000,
+ 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000,
+ 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000,
+ 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000,
+ 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000,
+ 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000,
+ 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000,
+ 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000,
+ 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000,
+ 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000,
+ 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000,
+ 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000,
+ 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000,
+ 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000,
+ 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000,
+ 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000,
+ 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000,
+ 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000,
+ 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000,
+ 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000,
+ 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000,
+ 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000,
+ 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000,
+ 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000,
+ 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000,
+ 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000,
+ 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000,
+ 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000,
+ 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000,
+ 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000,
+ 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000,
+ 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000,
+ 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000,
+ 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000,
+ 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000,
+ 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000,
+ 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000,
+ 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000,
+ 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000,
+ 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000,
+ 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000,
+ 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000,
+ 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000,
+ 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000,
+ 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000,
+ 0x48b8399200000000},
+ {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000,
+ 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000,
+ 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000,
+ 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000,
+ 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000,
+ 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000,
+ 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000,
+ 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000,
+ 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000,
+ 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000,
+ 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000,
+ 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000,
+ 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000,
+ 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000,
+ 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000,
+ 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000,
+ 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000,
+ 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000,
+ 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000,
+ 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000,
+ 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000,
+ 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000,
+ 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000,
+ 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000,
+ 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000,
+ 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000,
+ 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000,
+ 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000,
+ 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000,
+ 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000,
+ 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000,
+ 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000,
+ 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000,
+ 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000,
+ 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000,
+ 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000,
+ 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000,
+ 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000,
+ 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000,
+ 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000,
+ 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000,
+ 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000,
+ 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000,
+ 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000,
+ 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000,
+ 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000,
+ 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000,
+ 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000,
+ 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000,
+ 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000,
+ 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000,
+ 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000,
+ 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000,
+ 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000,
+ 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000,
+ 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000,
+ 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000,
+ 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000,
+ 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000,
+ 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000,
+ 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000,
+ 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000,
+ 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000,
+ 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000,
+ 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000,
+ 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000,
+ 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000,
+ 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000,
+ 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000,
+ 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000,
+ 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000,
+ 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000,
+ 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000,
+ 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000,
+ 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000,
+ 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000,
+ 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000,
+ 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000,
+ 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000,
+ 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000,
+ 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000,
+ 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000,
+ 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000,
+ 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000,
+ 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000,
+ 0x1af0957800000000},
+ {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000,
+ 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000,
+ 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000,
+ 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000,
+ 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000,
+ 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000,
+ 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000,
+ 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000,
+ 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000,
+ 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000,
+ 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000,
+ 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000,
+ 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000,
+ 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000,
+ 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000,
+ 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000,
+ 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000,
+ 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000,
+ 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000,
+ 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000,
+ 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000,
+ 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000,
+ 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000,
+ 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000,
+ 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000,
+ 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000,
+ 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000,
+ 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000,
+ 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000,
+ 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000,
+ 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000,
+ 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000,
+ 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000,
+ 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000,
+ 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000,
+ 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000,
+ 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000,
+ 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000,
+ 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000,
+ 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000,
+ 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000,
+ 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000,
+ 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000,
+ 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000,
+ 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000,
+ 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000,
+ 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000,
+ 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000,
+ 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000,
+ 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000,
+ 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000,
+ 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000,
+ 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000,
+ 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000,
+ 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000,
+ 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000,
+ 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000,
+ 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000,
+ 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000,
+ 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000,
+ 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000,
+ 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000,
+ 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000,
+ 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000,
+ 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000,
+ 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000,
+ 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000,
+ 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000,
+ 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000,
+ 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000,
+ 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000,
+ 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000,
+ 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000,
+ 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000,
+ 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000,
+ 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000,
+ 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000,
+ 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000,
+ 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000,
+ 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000,
+ 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000,
+ 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000,
+ 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000,
+ 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000,
+ 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000,
+ 0x8a6c1afd00000000},
+ {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000,
+ 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000,
+ 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000,
+ 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000,
+ 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000,
+ 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000,
+ 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000,
+ 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000,
+ 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000,
+ 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000,
+ 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000,
+ 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000,
+ 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000,
+ 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000,
+ 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000,
+ 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000,
+ 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000,
+ 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000,
+ 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000,
+ 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000,
+ 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000,
+ 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000,
+ 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000,
+ 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000,
+ 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000,
+ 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000,
+ 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000,
+ 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000,
+ 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000,
+ 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000,
+ 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000,
+ 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000,
+ 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000,
+ 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000,
+ 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000,
+ 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000,
+ 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000,
+ 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000,
+ 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000,
+ 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000,
+ 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000,
+ 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000,
+ 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000,
+ 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000,
+ 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000,
+ 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000,
+ 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000,
+ 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000,
+ 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000,
+ 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000,
+ 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000,
+ 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000,
+ 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000,
+ 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000,
+ 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000,
+ 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000,
+ 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000,
+ 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000,
+ 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000,
+ 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000,
+ 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000,
+ 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000,
+ 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000,
+ 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000,
+ 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000,
+ 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000,
+ 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000,
+ 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000,
+ 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000,
+ 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000,
+ 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000,
+ 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000,
+ 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000,
+ 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000,
+ 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000,
+ 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000,
+ 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000,
+ 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000,
+ 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000,
+ 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000,
+ 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000,
+ 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000,
+ 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000,
+ 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000,
+ 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000,
+ 0x5270900d00000000},
+ {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000,
+ 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000,
+ 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000,
+ 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000,
+ 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000,
+ 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000,
+ 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000,
+ 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000,
+ 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000,
+ 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000,
+ 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000,
+ 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000,
+ 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000,
+ 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000,
+ 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000,
+ 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000,
+ 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000,
+ 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000,
+ 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000,
+ 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000,
+ 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000,
+ 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000,
+ 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000,
+ 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000,
+ 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000,
+ 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000,
+ 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000,
+ 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000,
+ 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000,
+ 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000,
+ 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000,
+ 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000,
+ 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000,
+ 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000,
+ 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000,
+ 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000,
+ 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000,
+ 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000,
+ 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000,
+ 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000,
+ 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000,
+ 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000,
+ 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000,
+ 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000,
+ 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000,
+ 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000,
+ 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000,
+ 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000,
+ 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000,
+ 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000,
+ 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000,
+ 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000,
+ 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000,
+ 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000,
+ 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000,
+ 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000,
+ 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000,
+ 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000,
+ 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000,
+ 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000,
+ 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000,
+ 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000,
+ 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000,
+ 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000,
+ 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000,
+ 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000,
+ 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000,
+ 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000,
+ 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000,
+ 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000,
+ 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000,
+ 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000,
+ 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000,
+ 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000,
+ 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000,
+ 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000,
+ 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000,
+ 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000,
+ 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000,
+ 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000,
+ 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000,
+ 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000,
+ 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000,
+ 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000,
+ 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000,
+ 0xa8a0688500000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+ {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f,
+ 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999,
+ 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee,
+ 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615,
+ 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383,
+ 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb,
+ 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275,
+ 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d,
+ 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b,
+ 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460,
+ 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317,
+ 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1,
+ 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5,
+ 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd,
+ 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04,
+ 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c,
+ 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7,
+ 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11,
+ 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66,
+ 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7,
+ 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871,
+ 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309,
+ 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd,
+ 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85,
+ 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913,
+ 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d,
+ 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a,
+ 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc,
+ 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57,
+ 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f,
+ 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6,
+ 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e,
+ 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f,
+ 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289,
+ 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe,
+ 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05,
+ 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893,
+ 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb,
+ 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0,
+ 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8,
+ 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e,
+ 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5,
+ 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2,
+ 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574,
+ 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5,
+ 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add,
+ 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114,
+ 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c,
+ 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7,
+ 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701,
+ 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076,
+ 0x09cd8551},
+ {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193,
+ 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2,
+ 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c,
+ 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71,
+ 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a,
+ 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d,
+ 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71,
+ 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436,
+ 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d,
+ 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000,
+ 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae,
+ 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf,
+ 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930,
+ 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277,
+ 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff,
+ 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8,
+ 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef,
+ 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e,
+ 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20,
+ 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95,
+ 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e,
+ 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9,
+ 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d,
+ 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a,
+ 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151,
+ 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4,
+ 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a,
+ 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b,
+ 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c,
+ 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b,
+ 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3,
+ 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4,
+ 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b,
+ 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a,
+ 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4,
+ 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189,
+ 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92,
+ 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5,
+ 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9,
+ 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe,
+ 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5,
+ 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8,
+ 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66,
+ 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707,
+ 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8,
+ 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f,
+ 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707,
+ 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40,
+ 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017,
+ 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876,
+ 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8,
+ 0x7bc97a0c},
+ {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300,
+ 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0,
+ 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80,
+ 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701,
+ 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41,
+ 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81,
+ 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43,
+ 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83,
+ 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3,
+ 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42,
+ 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202,
+ 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2,
+ 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7,
+ 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407,
+ 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47,
+ 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87,
+ 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86,
+ 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46,
+ 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506,
+ 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44,
+ 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704,
+ 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4,
+ 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5,
+ 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505,
+ 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45,
+ 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f,
+ 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f,
+ 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f,
+ 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e,
+ 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e,
+ 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e,
+ 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce,
+ 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c,
+ 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc,
+ 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c,
+ 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d,
+ 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d,
+ 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d,
+ 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88,
+ 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48,
+ 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708,
+ 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89,
+ 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9,
+ 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309,
+ 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb,
+ 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b,
+ 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b,
+ 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b,
+ 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a,
+ 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a,
+ 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a,
+ 0x7851a2ca},
+ {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb,
+ 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8,
+ 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0,
+ 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f,
+ 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a,
+ 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf,
+ 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5,
+ 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380,
+ 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815,
+ 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa,
+ 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2,
+ 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1,
+ 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1,
+ 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4,
+ 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa,
+ 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df,
+ 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6,
+ 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5,
+ 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad,
+ 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca,
+ 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f,
+ 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a,
+ 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8,
+ 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d,
+ 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708,
+ 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d,
+ 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865,
+ 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636,
+ 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f,
+ 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a,
+ 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744,
+ 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061,
+ 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0,
+ 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293,
+ 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb,
+ 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874,
+ 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1,
+ 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4,
+ 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f,
+ 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a,
+ 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f,
+ 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120,
+ 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778,
+ 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b,
+ 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a,
+ 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af,
+ 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81,
+ 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4,
+ 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd,
+ 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e,
+ 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6,
+ 0x566b6848}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+ {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912,
+ 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba,
+ 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3,
+ 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30,
+ 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e,
+ 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3,
+ 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73,
+ 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe,
+ 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0,
+ 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643,
+ 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a,
+ 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082,
+ 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4,
+ 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279,
+ 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735,
+ 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8,
+ 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad,
+ 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05,
+ 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c,
+ 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718,
+ 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46,
+ 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb,
+ 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc,
+ 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41,
+ 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f,
+ 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad,
+ 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4,
+ 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c,
+ 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779,
+ 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4,
+ 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8,
+ 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235,
+ 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7,
+ 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f,
+ 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476,
+ 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195,
+ 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb,
+ 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46,
+ 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622,
+ 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af,
+ 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1,
+ 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12,
+ 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b,
+ 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3,
+ 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51,
+ 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc,
+ 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90,
+ 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d,
+ 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708,
+ 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0,
+ 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9,
+ 0x48686b56},
+ {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c,
+ 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae,
+ 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb,
+ 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90,
+ 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410,
+ 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b,
+ 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6,
+ 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed,
+ 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d,
+ 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036,
+ 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953,
+ 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1,
+ 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca,
+ 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781,
+ 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d,
+ 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416,
+ 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f,
+ 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd,
+ 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8,
+ 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b,
+ 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb,
+ 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0,
+ 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5,
+ 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e,
+ 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e,
+ 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558,
+ 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d,
+ 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf,
+ 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6,
+ 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad,
+ 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971,
+ 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a,
+ 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b,
+ 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969,
+ 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c,
+ 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57,
+ 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7,
+ 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c,
+ 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab,
+ 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0,
+ 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160,
+ 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b,
+ 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e,
+ 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac,
+ 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d,
+ 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546,
+ 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a,
+ 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1,
+ 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8,
+ 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a,
+ 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f,
+ 0xcaa25178},
+ {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00,
+ 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b,
+ 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed,
+ 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777,
+ 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01,
+ 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a,
+ 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef,
+ 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74,
+ 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002,
+ 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498,
+ 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee,
+ 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75,
+ 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05,
+ 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e,
+ 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8,
+ 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73,
+ 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404,
+ 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f,
+ 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9,
+ 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71,
+ 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607,
+ 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c,
+ 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb,
+ 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470,
+ 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806,
+ 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790,
+ 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6,
+ 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d,
+ 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a,
+ 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991,
+ 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7,
+ 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c,
+ 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09,
+ 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92,
+ 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4,
+ 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e,
+ 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08,
+ 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593,
+ 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3,
+ 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778,
+ 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e,
+ 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94,
+ 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2,
+ 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079,
+ 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c,
+ 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497,
+ 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1,
+ 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a,
+ 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d,
+ 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396,
+ 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0,
+ 0x0c7ac97b},
+ {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669,
+ 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853,
+ 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062,
+ 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527,
+ 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad,
+ 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545,
+ 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27,
+ 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf,
+ 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45,
+ 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800,
+ 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031,
+ 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b,
+ 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26,
+ 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce,
+ 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d,
+ 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5,
+ 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130,
+ 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a,
+ 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b,
+ 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480,
+ 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a,
+ 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2,
+ 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e,
+ 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996,
+ 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c,
+ 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc,
+ 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd,
+ 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7,
+ 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232,
+ 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da,
+ 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439,
+ 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1,
+ 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da,
+ 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0,
+ 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1,
+ 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94,
+ 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e,
+ 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6,
+ 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2,
+ 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a,
+ 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0,
+ 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95,
+ 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4,
+ 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e,
+ 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395,
+ 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d,
+ 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e,
+ 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676,
+ 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83,
+ 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9,
+ 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888,
+ 0x5185cd09}};
+
+#endif
+
+#endif
+
+#endif
+
+local const z_crc_t FAR x2n_table[] = {
+ 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000,
+ 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467,
+ 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0,
+ 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169,
+ 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37,
+ 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a,
+ 0xc40ba6d0, 0xc4e22c3c};
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/deflate.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/deflate.c
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/deflate.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/deflate.c
index 1ec76144..799fb93c 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/deflate.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/deflate.c
@@ -1,2163 +1,2211 @@
/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
* ALGORITHM
*
* The "deflation" process depends on being able to identify portions
* of the input text which are identical to earlier input (within a
* sliding window trailing behind the input currently being processed).
*
* The most straightforward technique turns out to be the fastest for
* most input files: try all possible matches and select the longest.
* The key feature of this algorithm is that insertions into the string
* dictionary are very simple and thus fast, and deletions are avoided
* completely. Insertions are performed at each input character, whereas
* string matches are performed only when the previous match ends. So it
* is preferable to spend more time in matches to allow very fast string
* insertions and avoid deletions. The matching algorithm for small
* strings is inspired from that of Rabin & Karp. A brute force approach
* is used to find longer strings when a small match has been found.
* A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
* (by Leonid Broukhis).
* A previous version of this file used a more sophisticated algorithm
* (by Fiala and Greene) which is guaranteed to run in linear amortized
* time, but has a larger average cost, uses more memory and is patented.
* However the F&G algorithm may be faster for some highly redundant
* files if the parameter max_chain_length (described below) is too large.
*
* ACKNOWLEDGEMENTS
*
* The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
* I found it in 'freeze' written by Leonid Broukhis.
* Thanks to many people for bug reports and testing.
*
* REFERENCES
*
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
* Available in http://tools.ietf.org/html/rfc1951
*
* A description of the Rabin and Karp algorithm is given in the book
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
*
* Fiala,E.R., and Greene,D.H.
* Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
*
*/
/* @(#) $Id$ */
#include "deflate.h"
const char deflate_copyright[] =
- " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
+ " deflate 1.2.12 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
/* ===========================================================================
* Function prototypes.
*/
typedef enum {
need_more, /* block not completed, need more input or more output */
block_done, /* block flush performed */
finish_started, /* finish started, need only more output at next deflate */
finish_done /* finish done, accept no more input or output */
} block_state;
typedef block_state (*compress_func) OF((deflate_state *s, int flush));
/* Compression function. Returns the block state after the call. */
local int deflateStateCheck OF((z_streamp strm));
local void slide_hash OF((deflate_state *s));
local void fill_window OF((deflate_state *s));
local block_state deflate_stored OF((deflate_state *s, int flush));
local block_state deflate_fast OF((deflate_state *s, int flush));
#ifndef FASTEST
local block_state deflate_slow OF((deflate_state *s, int flush));
#endif
local block_state deflate_rle OF((deflate_state *s, int flush));
local block_state deflate_huff OF((deflate_state *s, int flush));
local void lm_init OF((deflate_state *s));
local void putShortMSB OF((deflate_state *s, uInt b));
local void flush_pending OF((z_streamp strm));
local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
#ifdef ASMV
# pragma message("Assembler code may have bugs -- use at your own risk")
void match_init OF((void)); /* asm code initialization */
uInt longest_match OF((deflate_state *s, IPos cur_match));
#else
local uInt longest_match OF((deflate_state *s, IPos cur_match));
#endif
#ifdef ZLIB_DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match,
int length));
#endif
/* ===========================================================================
* Local data
*/
#define NIL 0
/* Tail of hash chains */
#ifndef TOO_FAR
# define TOO_FAR 4096
#endif
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
/* Values for max_lazy_match, good_match and max_chain_length, depending on
* the desired pack level (0..9). The values given below have been tuned to
* exclude worst case performance for pathological files. Better values may be
* found for specific files.
*/
typedef struct config_s {
ush good_length; /* reduce lazy search above this match length */
ush max_lazy; /* do not perform lazy search above this match length */
ush nice_length; /* quit search above this match length */
ush max_chain;
compress_func func;
} config;
#ifdef FASTEST
local const config configuration_table[2] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
#else
local const config configuration_table[10] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
/* 2 */ {4, 5, 16, 8, deflate_fast},
/* 3 */ {4, 6, 32, 32, deflate_fast},
/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
/* 5 */ {8, 16, 32, 32, deflate_slow},
/* 6 */ {8, 16, 128, 128, deflate_slow},
/* 7 */ {8, 32, 128, 256, deflate_slow},
/* 8 */ {32, 128, 258, 1024, deflate_slow},
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
#endif
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different
* meaning.
*/
/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
/* ===========================================================================
* Update a hash value with the given input byte
* IN assertion: all calls to UPDATE_HASH are made with consecutive input
* characters, so that a running hash key can be computed from the previous
* key instead of complete recalculation each time.
*/
#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
/* ===========================================================================
* Insert string str in the dictionary and set match_head to the previous head
* of the hash chain (the most recent string with same hash key). Return
* the previous length of the hash chain.
* If this file is compiled with -DFASTEST, the compression level is forced
* to 1, and no hash chains are maintained.
* IN assertion: all calls to INSERT_STRING are made with consecutive input
* characters and the first MIN_MATCH bytes of str are valid (except for
* the last MIN_MATCH-1 bytes of the input file).
*/
#ifdef FASTEST
#define INSERT_STRING(s, str, match_head) \
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
match_head = s->head[s->ins_h], \
s->head[s->ins_h] = (Pos)(str))
#else
#define INSERT_STRING(s, str, match_head) \
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
s->head[s->ins_h] = (Pos)(str))
#endif
/* ===========================================================================
* Initialize the hash table (avoiding 64K overflow for 16 bit systems).
* prev[] will be initialized on the fly.
*/
#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+ do { \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, \
+ (unsigned)(s->hash_size-1)*sizeof(*s->head)); \
+ } while (0)
/* ===========================================================================
* Slide the hash table when sliding the window down (could be avoided with 32
* bit values at the expense of memory usage). We slide even when level == 0 to
* keep the hash table consistent if we switch back to level > 0 later.
*/
local void slide_hash(s)
deflate_state *s;
{
unsigned n, m;
Posf *p;
uInt wsize = s->w_size;
n = s->hash_size;
p = &s->head[n];
do {
m = *--p;
*p = (Pos)(m >= wsize ? m - wsize : NIL);
} while (--n);
n = wsize;
#ifndef FASTEST
p = &s->prev[n];
do {
m = *--p;
*p = (Pos)(m >= wsize ? m - wsize : NIL);
/* If n is not on any hash chain, prev[n] is garbage but
* its value will never be used.
*/
} while (--n);
#endif
}
/* ========================================================================= */
int ZEXPORT deflateInit_(strm, level, version, stream_size)
z_streamp strm;
int level;
const char *version;
int stream_size;
{
return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY, version, stream_size);
/* To do: ignore strm->next_in if we use it as window */
}
/* ========================================================================= */
int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
version, stream_size)
z_streamp strm;
int level;
int method;
int windowBits;
int memLevel;
int strategy;
const char *version;
int stream_size;
{
deflate_state *s;
int wrap = 1;
static const char my_version[] = ZLIB_VERSION;
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
if (version == Z_NULL || version[0] != my_version[0] ||
stream_size != sizeof(z_stream)) {
return Z_VERSION_ERROR;
}
if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL;
if (strm->zalloc == (alloc_func)0) {
#ifdef Z_SOLO
return Z_STREAM_ERROR;
#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
#endif
}
if (strm->zfree == (free_func)0)
#ifdef Z_SOLO
return Z_STREAM_ERROR;
#else
strm->zfree = zcfree;
#endif
#ifdef FASTEST
if (level != 0) level = 1;
#else
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
if (windowBits < 0) { /* suppress zlib wrapper */
wrap = 0;
windowBits = -windowBits;
}
#ifdef GZIP
else if (windowBits > 15) {
wrap = 2; /* write gzip wrapper instead */
windowBits -= 16;
}
#endif
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {
return Z_STREAM_ERROR;
}
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
if (s == Z_NULL) return Z_MEM_ERROR;
strm->state = (struct internal_state FAR *)s;
s->strm = strm;
s->status = INIT_STATE; /* to pass state test in deflateReset() */
s->wrap = wrap;
s->gzhead = Z_NULL;
s->w_bits = (uInt)windowBits;
s->w_size = 1 << s->w_bits;
s->w_mask = s->w_size - 1;
s->hash_bits = (uInt)memLevel + 7;
s->hash_size = 1 << s->hash_bits;
s->hash_mask = s->hash_size - 1;
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
s->high_water = 0; /* nothing written to s->window yet */
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+ /* We overlay pending_buf and sym_buf. This works since the average size
+ * for length/distance pairs over any compressed block is assured to be 31
+ * bits or less.
+ *
+ * Analysis: The longest fixed codes are a length code of 8 bits plus 5
+ * extra bits, for lengths 131 to 257. The longest fixed distance codes are
+ * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
+ * possible fixed-codes length/distance pair is then 31 bits total.
+ *
+ * sym_buf starts one-fourth of the way into pending_buf. So there are
+ * three bytes in sym_buf for every four bytes in pending_buf. Each symbol
+ * in sym_buf is three bytes -- two for the distance and one for the
+ * literal/length. As each symbol is consumed, the pointer to the next
+ * sym_buf value to read moves forward three bytes. From that symbol, up to
+ * 31 bits are written to pending_buf. The closest the written pending_buf
+ * bits gets to the next sym_buf symbol to read is just before the last
+ * code is written. At that time, 31*(n-2) bits have been written, just
+ * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
+ * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
+ * symbols are written.) The closest the writing gets to what is unread is
+ * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
+ * can range from 128 to 32768.
+ *
+ * Therefore, at a minimum, there are 142 bits of space between what is
+ * written and what is read in the overlain buffers, so the symbols cannot
+ * be overwritten by the compressed data. That space is actually 139 bits,
+ * due to the three-bit fixed-code block header.
+ *
+ * That covers the case where either Z_FIXED is specified, forcing fixed
+ * codes, or when the use of fixed codes is chosen, because that choice
+ * results in a smaller compressed block than dynamic codes. That latter
+ * condition then assures that the above analysis also covers all dynamic
+ * blocks. A dynamic-code block will only be chosen to be emitted if it has
+ * fewer bits than a fixed-code block would for the same set of symbols.
+ * Therefore its average symbol length is assured to be less than 31. So
+ * the compressed data for a dynamic block also cannot overwrite the
+ * symbols from which it is being constructed.
+ */
+
+ s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
+ s->pending_buf_size = (ulg)s->lit_bufsize * 4;
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
s->pending_buf == Z_NULL) {
s->status = FINISH_STATE;
strm->msg = ERR_MSG(Z_MEM_ERROR);
deflateEnd (strm);
return Z_MEM_ERROR;
}
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+ s->sym_buf = s->pending_buf + s->lit_bufsize;
+ s->sym_end = (s->lit_bufsize - 1) * 3;
+ /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
s->level = level;
s->strategy = strategy;
s->method = (Byte)method;
return deflateReset(strm);
}
/* =========================================================================
* Check for a valid deflate stream state. Return 0 if ok, 1 if not.
*/
local int deflateStateCheck (strm)
z_streamp strm;
{
deflate_state *s;
if (strm == Z_NULL ||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
return 1;
s = strm->state;
if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
#ifdef GZIP
s->status != GZIP_STATE &&
#endif
s->status != EXTRA_STATE &&
s->status != NAME_STATE &&
s->status != COMMENT_STATE &&
s->status != HCRC_STATE &&
s->status != BUSY_STATE &&
s->status != FINISH_STATE))
return 1;
return 0;
}
/* ========================================================================= */
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
deflate_state *s;
uInt str, n;
int wrap;
unsigned avail;
z_const unsigned char *next;
if (deflateStateCheck(strm) || dictionary == Z_NULL)
return Z_STREAM_ERROR;
s = strm->state;
wrap = s->wrap;
if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
return Z_STREAM_ERROR;
/* when using zlib wrappers, compute Adler-32 for provided dictionary */
if (wrap == 1)
strm->adler = adler32(strm->adler, dictionary, dictLength);
s->wrap = 0; /* avoid computing Adler-32 in read_buf */
/* if dictionary would fill window, just replace the history */
if (dictLength >= s->w_size) {
if (wrap == 0) { /* already empty otherwise */
CLEAR_HASH(s);
s->strstart = 0;
s->block_start = 0L;
s->insert = 0;
}
dictionary += dictLength - s->w_size; /* use the tail */
dictLength = s->w_size;
}
/* insert dictionary into window and hash */
avail = strm->avail_in;
next = strm->next_in;
strm->avail_in = dictLength;
strm->next_in = (z_const Bytef *)dictionary;
fill_window(s);
while (s->lookahead >= MIN_MATCH) {
str = s->strstart;
n = s->lookahead - (MIN_MATCH-1);
do {
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
#ifndef FASTEST
s->prev[str & s->w_mask] = s->head[s->ins_h];
#endif
s->head[s->ins_h] = (Pos)str;
str++;
} while (--n);
s->strstart = str;
s->lookahead = MIN_MATCH-1;
fill_window(s);
}
s->strstart += s->lookahead;
s->block_start = (long)s->strstart;
s->insert = s->lookahead;
s->lookahead = 0;
s->match_length = s->prev_length = MIN_MATCH-1;
s->match_available = 0;
strm->next_in = next;
strm->avail_in = avail;
s->wrap = wrap;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
z_streamp strm;
Bytef *dictionary;
uInt *dictLength;
{
deflate_state *s;
uInt len;
if (deflateStateCheck(strm))
return Z_STREAM_ERROR;
s = strm->state;
len = s->strstart + s->lookahead;
if (len > s->w_size)
len = s->w_size;
if (dictionary != Z_NULL && len)
zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
if (dictLength != Z_NULL)
*dictLength = len;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateResetKeep (strm)
z_streamp strm;
{
deflate_state *s;
if (deflateStateCheck(strm)) {
return Z_STREAM_ERROR;
}
strm->total_in = strm->total_out = 0;
strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
strm->data_type = Z_UNKNOWN;
s = (deflate_state *)strm->state;
s->pending = 0;
s->pending_out = s->pending_buf;
if (s->wrap < 0) {
s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
}
s->status =
#ifdef GZIP
s->wrap == 2 ? GZIP_STATE :
#endif
- s->wrap ? INIT_STATE : BUSY_STATE;
+ INIT_STATE;
strm->adler =
#ifdef GZIP
s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
#endif
adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
+ s->last_flush = -2;
_tr_init(s);
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateReset (strm)
z_streamp strm;
{
int ret;
ret = deflateResetKeep(strm);
if (ret == Z_OK)
lm_init(strm->state);
return ret;
}
/* ========================================================================= */
int ZEXPORT deflateSetHeader (strm, head)
z_streamp strm;
gz_headerp head;
{
if (deflateStateCheck(strm) || strm->state->wrap != 2)
return Z_STREAM_ERROR;
strm->state->gzhead = head;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflatePending (strm, pending, bits)
unsigned *pending;
int *bits;
z_streamp strm;
{
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
if (pending != Z_NULL)
*pending = strm->state->pending;
if (bits != Z_NULL)
*bits = strm->state->bi_valid;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm;
int bits;
int value;
{
deflate_state *s;
int put;
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
- if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+ if (bits < 0 || bits > 16 ||
+ s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
do {
put = Buf_size - s->bi_valid;
if (put > bits)
put = bits;
s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
s->bi_valid += put;
_tr_flush_bits(s);
value >>= put;
bits -= put;
} while (bits);
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateParams(strm, level, strategy)
z_streamp strm;
int level;
int strategy;
{
deflate_state *s;
compress_func func;
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
#ifdef FASTEST
if (level != 0) level = 1;
#else
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
func = configuration_table[s->level].func;
if ((strategy != s->strategy || func != configuration_table[level].func) &&
- s->high_water) {
+ s->last_flush != -2) {
/* Flush the last buffer: */
int err = deflate(strm, Z_BLOCK);
if (err == Z_STREAM_ERROR)
return err;
- if (strm->avail_out == 0)
+ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
return Z_BUF_ERROR;
}
if (s->level != level) {
if (s->level == 0 && s->matches != 0) {
if (s->matches == 1)
slide_hash(s);
else
CLEAR_HASH(s);
s->matches = 0;
}
s->level = level;
s->max_lazy_match = configuration_table[level].max_lazy;
s->good_match = configuration_table[level].good_length;
s->nice_match = configuration_table[level].nice_length;
s->max_chain_length = configuration_table[level].max_chain;
}
s->strategy = strategy;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
z_streamp strm;
int good_length;
int max_lazy;
int nice_length;
int max_chain;
{
deflate_state *s;
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
s->good_match = (uInt)good_length;
s->max_lazy_match = (uInt)max_lazy;
s->nice_match = nice_length;
s->max_chain_length = (uInt)max_chain;
return Z_OK;
}
/* =========================================================================
* For the default windowBits of 15 and memLevel of 8, this function returns
* a close to exact, as well as small, upper bound on the compressed size.
* They are coded as constants here for a reason--if the #define's are
* changed, then this function needs to be changed as well. The return
* value for 15 and 8 only works for those exact settings.
*
* For any setting other than those defaults for windowBits and memLevel,
* the value returned is a conservative worst case for the maximum expansion
* resulting from using fixed blocks instead of stored blocks, which deflate
* can emit on compressed data for some combinations of the parameters.
*
* This function could be more sophisticated to provide closer upper bounds for
* every combination of windowBits and memLevel. But even the conservative
* upper bound of about 14% expansion does not seem onerous for output buffer
* allocation.
*/
uLong ZEXPORT deflateBound(strm, sourceLen)
z_streamp strm;
uLong sourceLen;
{
deflate_state *s;
uLong complen, wraplen;
/* conservative upper bound for compressed data */
complen = sourceLen +
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
/* if can't get parameters, return conservative bound plus zlib wrapper */
if (deflateStateCheck(strm))
return complen + 6;
/* compute wrapper length */
s = strm->state;
switch (s->wrap) {
case 0: /* raw deflate */
wraplen = 0;
break;
case 1: /* zlib wrapper */
wraplen = 6 + (s->strstart ? 4 : 0);
break;
#ifdef GZIP
case 2: /* gzip wrapper */
wraplen = 18;
if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
Bytef *str;
if (s->gzhead->extra != Z_NULL)
wraplen += 2 + s->gzhead->extra_len;
str = s->gzhead->name;
if (str != Z_NULL)
do {
wraplen++;
} while (*str++);
str = s->gzhead->comment;
if (str != Z_NULL)
do {
wraplen++;
} while (*str++);
if (s->gzhead->hcrc)
wraplen += 2;
}
break;
#endif
default: /* for compiler happiness */
wraplen = 6;
}
/* if not default parameters, return conservative bound */
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
return complen + wraplen;
/* default settings: return tight bound for that case */
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
(sourceLen >> 25) + 13 - 6 + wraplen;
}
/* =========================================================================
* Put a short in the pending buffer. The 16-bit value is put in MSB order.
* IN assertion: the stream state is correct and there is enough room in
* pending_buf.
*/
local void putShortMSB (s, b)
deflate_state *s;
uInt b;
{
put_byte(s, (Byte)(b >> 8));
put_byte(s, (Byte)(b & 0xff));
}
/* =========================================================================
* Flush as much pending output as possible. All deflate() output, except for
* some deflate_stored() output, goes through this function so some
* applications may wish to modify it to avoid allocating a large
* strm->next_out buffer and copying into it. (See also read_buf()).
*/
local void flush_pending(strm)
z_streamp strm;
{
unsigned len;
deflate_state *s = strm->state;
_tr_flush_bits(s);
len = s->pending;
if (len > strm->avail_out) len = strm->avail_out;
if (len == 0) return;
zmemcpy(strm->next_out, s->pending_out, len);
strm->next_out += len;
s->pending_out += len;
strm->total_out += len;
strm->avail_out -= len;
s->pending -= len;
if (s->pending == 0) {
s->pending_out = s->pending_buf;
}
}
/* ===========================================================================
* Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
*/
#define HCRC_UPDATE(beg) \
do { \
if (s->gzhead->hcrc && s->pending > (beg)) \
strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
s->pending - (beg)); \
} while (0)
/* ========================================================================= */
int ZEXPORT deflate (strm, flush)
z_streamp strm;
int flush;
{
int old_flush; /* value of flush param for previous deflate call */
deflate_state *s;
if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
return Z_STREAM_ERROR;
}
s = strm->state;
if (strm->next_out == Z_NULL ||
(strm->avail_in != 0 && strm->next_in == Z_NULL) ||
(s->status == FINISH_STATE && flush != Z_FINISH)) {
ERR_RETURN(strm, Z_STREAM_ERROR);
}
if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
old_flush = s->last_flush;
s->last_flush = flush;
/* Flush as much pending output as possible */
if (s->pending != 0) {
flush_pending(strm);
if (strm->avail_out == 0) {
/* Since avail_out is 0, deflate will be called again with
* more output space, but possibly with both pending and
* avail_in equal to zero. There won't be anything to do,
* but this is not an error situation so make sure we
* return OK instead of BUF_ERROR at next call of deflate:
*/
s->last_flush = -1;
return Z_OK;
}
/* Make sure there is something to do and avoid duplicate consecutive
* flushes. For repeated and useless calls with Z_FINISH, we keep
* returning Z_STREAM_END instead of Z_BUF_ERROR.
*/
} else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
flush != Z_FINISH) {
ERR_RETURN(strm, Z_BUF_ERROR);
}
/* User must not provide more input after the first FINISH: */
if (s->status == FINISH_STATE && strm->avail_in != 0) {
ERR_RETURN(strm, Z_BUF_ERROR);
}
/* Write the header */
+ if (s->status == INIT_STATE && s->wrap == 0)
+ s->status = BUSY_STATE;
if (s->status == INIT_STATE) {
/* zlib header */
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
uInt level_flags;
if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
level_flags = 0;
else if (s->level < 6)
level_flags = 1;
else if (s->level == 6)
level_flags = 2;
else
level_flags = 3;
header |= (level_flags << 6);
if (s->strstart != 0) header |= PRESET_DICT;
header += 31 - (header % 31);
putShortMSB(s, header);
/* Save the adler32 of the preset dictionary: */
if (s->strstart != 0) {
putShortMSB(s, (uInt)(strm->adler >> 16));
putShortMSB(s, (uInt)(strm->adler & 0xffff));
}
strm->adler = adler32(0L, Z_NULL, 0);
s->status = BUSY_STATE;
/* Compression must start with an empty pending buffer */
flush_pending(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
}
#ifdef GZIP
if (s->status == GZIP_STATE) {
/* gzip header */
strm->adler = crc32(0L, Z_NULL, 0);
put_byte(s, 31);
put_byte(s, 139);
put_byte(s, 8);
if (s->gzhead == Z_NULL) {
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, OS_CODE);
s->status = BUSY_STATE;
/* Compression must start with an empty pending buffer */
flush_pending(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
}
else {
put_byte(s, (s->gzhead->text ? 1 : 0) +
(s->gzhead->hcrc ? 2 : 0) +
(s->gzhead->extra == Z_NULL ? 0 : 4) +
(s->gzhead->name == Z_NULL ? 0 : 8) +
(s->gzhead->comment == Z_NULL ? 0 : 16)
);
put_byte(s, (Byte)(s->gzhead->time & 0xff));
put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, s->gzhead->os & 0xff);
if (s->gzhead->extra != Z_NULL) {
put_byte(s, s->gzhead->extra_len & 0xff);
put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
}
if (s->gzhead->hcrc)
strm->adler = crc32(strm->adler, s->pending_buf,
s->pending);
s->gzindex = 0;
s->status = EXTRA_STATE;
}
}
if (s->status == EXTRA_STATE) {
if (s->gzhead->extra != Z_NULL) {
ulg beg = s->pending; /* start of bytes to update crc */
uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
while (s->pending + left > s->pending_buf_size) {
uInt copy = s->pending_buf_size - s->pending;
zmemcpy(s->pending_buf + s->pending,
s->gzhead->extra + s->gzindex, copy);
s->pending = s->pending_buf_size;
HCRC_UPDATE(beg);
s->gzindex += copy;
flush_pending(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
beg = 0;
left -= copy;
}
zmemcpy(s->pending_buf + s->pending,
s->gzhead->extra + s->gzindex, left);
s->pending += left;
HCRC_UPDATE(beg);
s->gzindex = 0;
}
s->status = NAME_STATE;
}
if (s->status == NAME_STATE) {
if (s->gzhead->name != Z_NULL) {
ulg beg = s->pending; /* start of bytes to update crc */
int val;
do {
if (s->pending == s->pending_buf_size) {
HCRC_UPDATE(beg);
flush_pending(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
beg = 0;
}
val = s->gzhead->name[s->gzindex++];
put_byte(s, val);
} while (val != 0);
HCRC_UPDATE(beg);
s->gzindex = 0;
}
s->status = COMMENT_STATE;
}
if (s->status == COMMENT_STATE) {
if (s->gzhead->comment != Z_NULL) {
ulg beg = s->pending; /* start of bytes to update crc */
int val;
do {
if (s->pending == s->pending_buf_size) {
HCRC_UPDATE(beg);
flush_pending(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
beg = 0;
}
val = s->gzhead->comment[s->gzindex++];
put_byte(s, val);
} while (val != 0);
HCRC_UPDATE(beg);
}
s->status = HCRC_STATE;
}
if (s->status == HCRC_STATE) {
if (s->gzhead->hcrc) {
if (s->pending + 2 > s->pending_buf_size) {
flush_pending(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
}
put_byte(s, (Byte)(strm->adler & 0xff));
put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
strm->adler = crc32(0L, Z_NULL, 0);
}
s->status = BUSY_STATE;
/* Compression must start with an empty pending buffer */
flush_pending(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
}
#endif
/* Start a new block or continue the current one.
*/
if (strm->avail_in != 0 || s->lookahead != 0 ||
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
block_state bstate;
bstate = s->level == 0 ? deflate_stored(s, flush) :
s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
s->strategy == Z_RLE ? deflate_rle(s, flush) :
(*(configuration_table[s->level].func))(s, flush);
if (bstate == finish_started || bstate == finish_done) {
s->status = FINISH_STATE;
}
if (bstate == need_more || bstate == finish_started) {
if (strm->avail_out == 0) {
s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
}
return Z_OK;
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call
* of deflate should use the same flush parameter to make sure
* that the flush is complete. So we don't have to output an
* empty block here, this will be done at next call. This also
* ensures that for a very small output buffer, we emit at most
* one empty block.
*/
}
if (bstate == block_done) {
if (flush == Z_PARTIAL_FLUSH) {
_tr_align(s);
} else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
_tr_stored_block(s, (char*)0, 0L, 0);
/* For a full flush, this empty block will be recognized
* as a special marker by inflate_sync().
*/
if (flush == Z_FULL_FLUSH) {
CLEAR_HASH(s); /* forget history */
if (s->lookahead == 0) {
s->strstart = 0;
s->block_start = 0L;
s->insert = 0;
}
}
}
flush_pending(strm);
if (strm->avail_out == 0) {
s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
return Z_OK;
}
}
}
if (flush != Z_FINISH) return Z_OK;
if (s->wrap <= 0) return Z_STREAM_END;
/* Write the trailer */
#ifdef GZIP
if (s->wrap == 2) {
put_byte(s, (Byte)(strm->adler & 0xff));
put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
put_byte(s, (Byte)(strm->total_in & 0xff));
put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
}
else
#endif
{
putShortMSB(s, (uInt)(strm->adler >> 16));
putShortMSB(s, (uInt)(strm->adler & 0xffff));
}
flush_pending(strm);
/* If avail_out is zero, the application will call deflate again
* to flush the rest.
*/
if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
return s->pending != 0 ? Z_OK : Z_STREAM_END;
}
/* ========================================================================= */
int ZEXPORT deflateEnd (strm)
z_streamp strm;
{
int status;
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
status = strm->state->status;
/* Deallocate in reverse order of allocations: */
TRY_FREE(strm, strm->state->pending_buf);
TRY_FREE(strm, strm->state->head);
TRY_FREE(strm, strm->state->prev);
TRY_FREE(strm, strm->state->window);
ZFREE(strm, strm->state);
strm->state = Z_NULL;
return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
}
/* =========================================================================
* Copy the source state to the destination state.
* To simplify the source, this is not supported for 16-bit MSDOS (which
* doesn't have enough memory anyway to duplicate compression states).
*/
int ZEXPORT deflateCopy (dest, source)
z_streamp dest;
z_streamp source;
{
#ifdef MAXSEG_64K
return Z_STREAM_ERROR;
#else
deflate_state *ds;
deflate_state *ss;
- ushf *overlay;
if (deflateStateCheck(source) || dest == Z_NULL) {
return Z_STREAM_ERROR;
}
ss = source->state;
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
if (ds == Z_NULL) return Z_MEM_ERROR;
dest->state = (struct internal_state FAR *) ds;
zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
ds->strm = dest;
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
+ ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
ds->pending_buf == Z_NULL) {
deflateEnd (dest);
return Z_MEM_ERROR;
}
/* following zmemcpy do not work for 16-bit MSDOS */
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+ ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
ds->l_desc.dyn_tree = ds->dyn_ltree;
ds->d_desc.dyn_tree = ds->dyn_dtree;
ds->bl_desc.dyn_tree = ds->bl_tree;
return Z_OK;
#endif /* MAXSEG_64K */
}
/* ===========================================================================
* Read a new buffer from the current input stream, update the adler32
* and total number of bytes read. All deflate() input goes through
* this function so some applications may wish to modify it to avoid
* allocating a large strm->next_in buffer and copying from it.
* (See also flush_pending()).
*/
local unsigned read_buf(strm, buf, size)
z_streamp strm;
Bytef *buf;
unsigned size;
{
unsigned len = strm->avail_in;
if (len > size) len = size;
if (len == 0) return 0;
strm->avail_in -= len;
zmemcpy(buf, strm->next_in, len);
if (strm->state->wrap == 1) {
strm->adler = adler32(strm->adler, buf, len);
}
#ifdef GZIP
else if (strm->state->wrap == 2) {
strm->adler = crc32(strm->adler, buf, len);
}
#endif
strm->next_in += len;
strm->total_in += len;
return len;
}
/* ===========================================================================
* Initialize the "longest match" routines for a new zlib stream
*/
local void lm_init (s)
deflate_state *s;
{
s->window_size = (ulg)2L*s->w_size;
CLEAR_HASH(s);
/* Set the default configuration parameters:
*/
s->max_lazy_match = configuration_table[s->level].max_lazy;
s->good_match = configuration_table[s->level].good_length;
s->nice_match = configuration_table[s->level].nice_length;
s->max_chain_length = configuration_table[s->level].max_chain;
s->strstart = 0;
s->block_start = 0L;
s->lookahead = 0;
s->insert = 0;
s->match_length = s->prev_length = MIN_MATCH-1;
s->match_available = 0;
s->ins_h = 0;
#ifndef FASTEST
#ifdef ASMV
match_init(); /* initialize the asm code */
#endif
#endif
}
#ifndef FASTEST
/* ===========================================================================
* Set match_start to the longest match starting at the given string and
* return its length. Matches shorter or equal to prev_length are discarded,
* in which case the result is equal to prev_length and match_start is
* garbage.
* IN assertions: cur_match is the head of the hash chain for the current
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
* OUT assertion: the match length is not greater than s->lookahead.
*/
#ifndef ASMV
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
* match.S. The code will be functionally equivalent.
*/
local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
unsigned chain_length = s->max_chain_length;/* max hash chain length */
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
int best_len = (int)s->prev_length; /* best match length so far */
int nice_match = s->nice_match; /* stop if match long enough */
IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
s->strstart - (IPos)MAX_DIST(s) : NIL;
/* Stop when cur_match becomes <= limit. To simplify the code,
* we prevent matches with the string of window index 0.
*/
Posf *prev = s->prev;
uInt wmask = s->w_mask;
#ifdef UNALIGNED_OK
/* Compare two bytes at a time. Note: this is not always beneficial.
* Try with and without -DUNALIGNED_OK to check.
*/
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
register ush scan_start = *(ushf*)scan;
register ush scan_end = *(ushf*)(scan+best_len-1);
#else
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
register Byte scan_end1 = scan[best_len-1];
register Byte scan_end = scan[best_len];
#endif
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
*/
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
/* Do not waste too much time if we already have a good match: */
if (s->prev_length >= s->good_match) {
chain_length >>= 2;
}
/* Do not look for matches beyond the end of the input. This is necessary
* to make deflate deterministic.
*/
if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
do {
Assert(cur_match < s->strstart, "no future");
match = s->window + cur_match;
/* Skip to next match if the match length cannot increase
* or if the match length is less than 2. Note that the checks below
* for insufficient lookahead only occur occasionally for performance
* reasons. Therefore uninitialized memory will be accessed, and
* conditional jumps will be made that depend on those values.
* However the length of the match is limited to the lookahead, so
* the output of deflate is not affected by the uninitialized values.
*/
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
* UNALIGNED_OK if your compiler uses a different size.
*/
if (*(ushf*)(match+best_len-1) != scan_end ||
*(ushf*)match != scan_start) continue;
/* It is not necessary to compare scan[2] and match[2] since they are
* always equal when the other bytes match, given that the hash keys
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
* strstart+3, +5, ... up to strstart+257. We check for insufficient
* lookahead only every 4th comparison; the 128th check will be made
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
* necessary to put more guard bytes at the end of the window, or
* to check more often for insufficient lookahead.
*/
Assert(scan[2] == match[2], "scan[2]?");
scan++, match++;
do {
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
scan < strend);
/* The funny "do {}" generates better code on most compilers */
/* Here, scan <= window+strstart+257 */
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
if (*scan == *match) scan++;
len = (MAX_MATCH - 1) - (int)(strend-scan);
scan = strend - (MAX_MATCH-1);
#else /* UNALIGNED_OK */
if (match[best_len] != scan_end ||
match[best_len-1] != scan_end1 ||
*match != *scan ||
*++match != scan[1]) continue;
/* The check at best_len-1 can be removed because it will be made
* again later. (This heuristic is not always a win.)
* It is not necessary to compare scan[2] and match[2] since they
* are always equal when the other bytes match, given that
* the hash keys are equal and that HASH_BITS >= 8.
*/
scan += 2, match++;
Assert(*scan == *match, "match[2]?");
/* We check for insufficient lookahead only every 8th comparison;
* the 256th check will be made at strstart+258.
*/
do {
} while (*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
scan < strend);
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
len = MAX_MATCH - (int)(strend - scan);
scan = strend - MAX_MATCH;
#endif /* UNALIGNED_OK */
if (len > best_len) {
s->match_start = cur_match;
best_len = len;
if (len >= nice_match) break;
#ifdef UNALIGNED_OK
scan_end = *(ushf*)(scan+best_len-1);
#else
scan_end1 = scan[best_len-1];
scan_end = scan[best_len];
#endif
}
} while ((cur_match = prev[cur_match & wmask]) > limit
&& --chain_length != 0);
if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
return s->lookahead;
}
#endif /* ASMV */
#else /* FASTEST */
/* ---------------------------------------------------------------------------
* Optimized version for FASTEST only
*/
local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
*/
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
Assert(cur_match < s->strstart, "no future");
match = s->window + cur_match;
/* Return failure if the match length is less than 2:
*/
if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
/* The check at best_len-1 can be removed because it will be made
* again later. (This heuristic is not always a win.)
* It is not necessary to compare scan[2] and match[2] since they
* are always equal when the other bytes match, given that
* the hash keys are equal and that HASH_BITS >= 8.
*/
scan += 2, match += 2;
Assert(*scan == *match, "match[2]?");
/* We check for insufficient lookahead only every 8th comparison;
* the 256th check will be made at strstart+258.
*/
do {
} while (*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
scan < strend);
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
len = MAX_MATCH - (int)(strend - scan);
if (len < MIN_MATCH) return MIN_MATCH - 1;
s->match_start = cur_match;
return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
}
#endif /* FASTEST */
#ifdef ZLIB_DEBUG
#define EQUAL 0
/* result of memcmp for equal strings */
/* ===========================================================================
* Check that the match at match_start is indeed a match.
*/
local void check_match(s, start, match, length)
deflate_state *s;
IPos start, match;
int length;
{
/* check that the match is indeed a match */
if (zmemcmp(s->window + match,
s->window + start, length) != EQUAL) {
fprintf(stderr, " start %u, match %u, length %d\n",
start, match, length);
do {
fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
} while (--length != 0);
z_error("invalid match");
}
if (z_verbose > 1) {
fprintf(stderr,"\\[%d,%d]", start-match, length);
do { putc(s->window[start++], stderr); } while (--length != 0);
}
}
#else
# define check_match(s, start, match, length)
#endif /* ZLIB_DEBUG */
/* ===========================================================================
* Fill the window when the lookahead becomes insufficient.
* Updates strstart and lookahead.
*
* IN assertion: lookahead < MIN_LOOKAHEAD
* OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
* At least one byte has been read, or avail_in == 0; reads are
* performed for at least two bytes (required for the zip translate_eol
* option -- not supported here).
*/
local void fill_window(s)
deflate_state *s;
{
unsigned n;
unsigned more; /* Amount of free space at the end of the window. */
uInt wsize = s->w_size;
Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
do {
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
/* Deal with !@#$% 64K limit: */
if (sizeof(int) <= 2) {
if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
more = wsize;
} else if (more == (unsigned)(-1)) {
/* Very unlikely, but possible on 16 bit machine if
* strstart == 0 && lookahead == 1 (input done a byte at time)
*/
more--;
}
}
/* If the window is almost full and there is insufficient lookahead,
* move the upper half to the lower one to make room in the upper half.
*/
if (s->strstart >= wsize+MAX_DIST(s)) {
zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
s->match_start -= wsize;
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
s->block_start -= (long) wsize;
+ if (s->insert > s->strstart)
+ s->insert = s->strstart;
slide_hash(s);
more += wsize;
}
if (s->strm->avail_in == 0) break;
/* If there was no sliding:
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
* more == window_size - lookahead - strstart
* => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
* => more >= window_size - 2*WSIZE + 2
* In the BIG_MEM or MMAP case (not yet supported),
* window_size == input_size + MIN_LOOKAHEAD &&
* strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
* Otherwise, window_size == 2*WSIZE so more >= 2.
* If there was sliding, more >= WSIZE. So in all cases, more >= 2.
*/
Assert(more >= 2, "more < 2");
n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
s->lookahead += n;
/* Initialize the hash value now that we have some input: */
if (s->lookahead + s->insert >= MIN_MATCH) {
uInt str = s->strstart - s->insert;
s->ins_h = s->window[str];
UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
#if MIN_MATCH != 3
Call UPDATE_HASH() MIN_MATCH-3 more times
#endif
while (s->insert) {
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
#ifndef FASTEST
s->prev[str & s->w_mask] = s->head[s->ins_h];
#endif
s->head[s->ins_h] = (Pos)str;
str++;
s->insert--;
if (s->lookahead + s->insert < MIN_MATCH)
break;
}
}
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
* but this is not important since only literal bytes will be emitted.
*/
} while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
/* If the WIN_INIT bytes after the end of the current data have never been
* written, then zero those bytes in order to avoid memory check reports of
* the use of uninitialized (or uninitialised as Julian writes) bytes by
* the longest match routines. Update the high water mark for the next
* time through here. WIN_INIT is set to MAX_MATCH since the longest match
* routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
*/
if (s->high_water < s->window_size) {
ulg curr = s->strstart + (ulg)(s->lookahead);
ulg init;
if (s->high_water < curr) {
/* Previous high water mark below current data -- zero WIN_INIT
* bytes or up to end of window, whichever is less.
*/
init = s->window_size - curr;
if (init > WIN_INIT)
init = WIN_INIT;
zmemzero(s->window + curr, (unsigned)init);
s->high_water = curr + init;
}
else if (s->high_water < (ulg)curr + WIN_INIT) {
/* High water mark at or above current data, but below current data
* plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
* to end of window, whichever is less.
*/
init = (ulg)curr + WIN_INIT - s->high_water;
if (init > s->window_size - s->high_water)
init = s->window_size - s->high_water;
zmemzero(s->window + s->high_water, (unsigned)init);
s->high_water += init;
}
}
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
"not enough room for search");
}
/* ===========================================================================
* Flush the current block, with given end-of-file flag.
* IN assertion: strstart is set to the end of the current match.
*/
#define FLUSH_BLOCK_ONLY(s, last) { \
_tr_flush_block(s, (s->block_start >= 0L ? \
(charf *)&s->window[(unsigned)s->block_start] : \
(charf *)Z_NULL), \
(ulg)((long)s->strstart - s->block_start), \
(last)); \
s->block_start = s->strstart; \
flush_pending(s->strm); \
Tracev((stderr,"[FLUSH]")); \
}
/* Same but force premature exit if necessary. */
#define FLUSH_BLOCK(s, last) { \
FLUSH_BLOCK_ONLY(s, last); \
if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
}
/* Maximum stored block length in deflate format (not including header). */
#define MAX_STORED 65535
/* Minimum of a and b. */
#define MIN(a, b) ((a) > (b) ? (b) : (a))
/* ===========================================================================
* Copy without compression as much as possible from the input stream, return
* the current block state.
*
* In case deflateParams() is used to later switch to a non-zero compression
* level, s->matches (otherwise unused when storing) keeps track of the number
* of hash table slides to perform. If s->matches is 1, then one hash table
* slide will be done when switching. If s->matches is 2, the maximum value
* allowed here, then the hash table will be cleared, since two or more slides
* is the same as a clear.
*
* deflate_stored() is written to minimize the number of times an input byte is
* copied. It is most efficient with large input and output buffers, which
* maximizes the opportunites to have a single copy from next_in to next_out.
*/
local block_state deflate_stored(s, flush)
deflate_state *s;
int flush;
{
/* Smallest worthy block size when not flushing or finishing. By default
* this is 32K. This can be as small as 507 bytes for memLevel == 1. For
* large input and output buffers, the stored block size will be larger.
*/
unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
/* Copy as many min_block or larger stored blocks directly to next_out as
* possible. If flushing, copy the remaining available input to next_out as
* stored blocks, if there is enough space.
*/
unsigned len, left, have, last = 0;
unsigned used = s->strm->avail_in;
do {
/* Set len to the maximum size block that we can copy directly with the
* available input data and output space. Set left to how much of that
* would be copied from what's left in the window.
*/
len = MAX_STORED; /* maximum deflate stored block length */
have = (s->bi_valid + 42) >> 3; /* number of header bytes */
if (s->strm->avail_out < have) /* need room for header */
break;
/* maximum stored block length that will fit in avail_out: */
have = s->strm->avail_out - have;
left = s->strstart - s->block_start; /* bytes left in window */
if (len > (ulg)left + s->strm->avail_in)
len = left + s->strm->avail_in; /* limit len to the input */
if (len > have)
len = have; /* limit len to the output */
/* If the stored block would be less than min_block in length, or if
* unable to copy all of the available input when flushing, then try
* copying to the window and the pending buffer instead. Also don't
* write an empty block when flushing -- deflate() does that.
*/
if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
flush == Z_NO_FLUSH ||
len != left + s->strm->avail_in))
break;
/* Make a dummy stored block in pending to get the header bytes,
* including any pending bits. This also updates the debugging counts.
*/
last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
_tr_stored_block(s, (char *)0, 0L, last);
/* Replace the lengths in the dummy stored block with len. */
s->pending_buf[s->pending - 4] = len;
s->pending_buf[s->pending - 3] = len >> 8;
s->pending_buf[s->pending - 2] = ~len;
s->pending_buf[s->pending - 1] = ~len >> 8;
/* Write the stored block header bytes. */
flush_pending(s->strm);
#ifdef ZLIB_DEBUG
/* Update debugging counts for the data about to be copied. */
s->compressed_len += len << 3;
s->bits_sent += len << 3;
#endif
/* Copy uncompressed bytes from the window to next_out. */
if (left) {
if (left > len)
left = len;
zmemcpy(s->strm->next_out, s->window + s->block_start, left);
s->strm->next_out += left;
s->strm->avail_out -= left;
s->strm->total_out += left;
s->block_start += left;
len -= left;
}
/* Copy uncompressed bytes directly from next_in to next_out, updating
* the check value.
*/
if (len) {
read_buf(s->strm, s->strm->next_out, len);
s->strm->next_out += len;
s->strm->avail_out -= len;
s->strm->total_out += len;
}
} while (last == 0);
/* Update the sliding window with the last s->w_size bytes of the copied
* data, or append all of the copied data to the existing window if less
* than s->w_size bytes were copied. Also update the number of bytes to
* insert in the hash tables, in the event that deflateParams() switches to
* a non-zero compression level.
*/
used -= s->strm->avail_in; /* number of input bytes directly copied */
if (used) {
/* If any input was used, then no unused input remains in the window,
* therefore s->block_start == s->strstart.
*/
if (used >= s->w_size) { /* supplant the previous history */
s->matches = 2; /* clear hash */
zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
s->strstart = s->w_size;
+ s->insert = s->strstart;
}
else {
if (s->window_size - s->strstart <= used) {
/* Slide the window down. */
s->strstart -= s->w_size;
zmemcpy(s->window, s->window + s->w_size, s->strstart);
if (s->matches < 2)
s->matches++; /* add a pending slide_hash() */
+ if (s->insert > s->strstart)
+ s->insert = s->strstart;
}
zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
s->strstart += used;
+ s->insert += MIN(used, s->w_size - s->insert);
}
s->block_start = s->strstart;
- s->insert += MIN(used, s->w_size - s->insert);
}
if (s->high_water < s->strstart)
s->high_water = s->strstart;
/* If the last block was written to next_out, then done. */
if (last)
return finish_done;
/* If flushing and all input has been consumed, then done. */
if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
s->strm->avail_in == 0 && (long)s->strstart == s->block_start)
return block_done;
/* Fill the window with any remaining input. */
- have = s->window_size - s->strstart - 1;
+ have = s->window_size - s->strstart;
if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
/* Slide the window down. */
s->block_start -= s->w_size;
s->strstart -= s->w_size;
zmemcpy(s->window, s->window + s->w_size, s->strstart);
if (s->matches < 2)
s->matches++; /* add a pending slide_hash() */
have += s->w_size; /* more space now */
+ if (s->insert > s->strstart)
+ s->insert = s->strstart;
}
if (have > s->strm->avail_in)
have = s->strm->avail_in;
if (have) {
read_buf(s->strm, s->window + s->strstart, have);
s->strstart += have;
+ s->insert += MIN(have, s->w_size - s->insert);
}
if (s->high_water < s->strstart)
s->high_water = s->strstart;
/* There was not enough avail_out to write a complete worthy or flushed
* stored block to next_out. Write a stored block to pending instead, if we
* have enough input for a worthy block, or if flushing and there is enough
* room for the remaining input as a stored block in the pending buffer.
*/
have = (s->bi_valid + 42) >> 3; /* number of header bytes */
/* maximum stored block length that will fit in pending: */
have = MIN(s->pending_buf_size - have, MAX_STORED);
min_block = MIN(have, s->w_size);
left = s->strstart - s->block_start;
if (left >= min_block ||
((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
s->strm->avail_in == 0 && left <= have)) {
len = MIN(left, have);
last = flush == Z_FINISH && s->strm->avail_in == 0 &&
len == left ? 1 : 0;
_tr_stored_block(s, (charf *)s->window + s->block_start, len, last);
s->block_start += len;
flush_pending(s->strm);
}
/* We've done all we can with the available input and output. */
return last ? finish_started : need_more;
}
/* ===========================================================================
* Compress as much as possible from the input stream, return the current
* block state.
* This function does not perform lazy evaluation of matches and inserts
* new strings in the dictionary only for unmatched strings or for short
* matches. It is used only for the fast compression options.
*/
local block_state deflate_fast(s, flush)
deflate_state *s;
int flush;
{
IPos hash_head; /* head of the hash chain */
int bflush; /* set if current block must be flushed */
for (;;) {
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
* for the next match, plus MIN_MATCH bytes to insert the
* string following the next match.
*/
if (s->lookahead < MIN_LOOKAHEAD) {
fill_window(s);
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */
}
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
hash_head = NIL;
if (s->lookahead >= MIN_MATCH) {
INSERT_STRING(s, s->strstart, hash_head);
}
/* Find the longest match, discarding those <= prev_length.
* At this point we have always match_length < MIN_MATCH
*/
if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
/* To simplify the code, we prevent matches with the string
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
s->match_length = longest_match (s, hash_head);
/* longest_match() sets match_start */
}
if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length);
_tr_tally_dist(s, s->strstart - s->match_start,
s->match_length - MIN_MATCH, bflush);
s->lookahead -= s->match_length;
/* Insert new strings in the hash table only if the match length
* is not too large. This saves time but degrades compression.
*/
#ifndef FASTEST
if (s->match_length <= s->max_insert_length &&
s->lookahead >= MIN_MATCH) {
s->match_length--; /* string at strstart already in table */
do {
s->strstart++;
INSERT_STRING(s, s->strstart, hash_head);
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
* always MIN_MATCH bytes ahead.
*/
} while (--s->match_length != 0);
s->strstart++;
} else
#endif
{
s->strstart += s->match_length;
s->match_length = 0;
s->ins_h = s->window[s->strstart];
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
#if MIN_MATCH != 3
Call UPDATE_HASH() MIN_MATCH-3 more times
#endif
/* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
* matter since it will be recomputed at next deflate call.
*/
}
} else {
/* No match, output a literal byte */
Tracevv((stderr,"%c", s->window[s->strstart]));
_tr_tally_lit (s, s->window[s->strstart], bflush);
s->lookahead--;
s->strstart++;
}
if (bflush) FLUSH_BLOCK(s, 0);
}
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
if (flush == Z_FINISH) {
FLUSH_BLOCK(s, 1);
return finish_done;
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);
return block_done;
}
#ifndef FASTEST
/* ===========================================================================
* Same as above, but achieves better compression. We use a lazy
* evaluation for matches: a match is finally adopted only if there is
* no better match at the next window position.
*/
local block_state deflate_slow(s, flush)
deflate_state *s;
int flush;
{
IPos hash_head; /* head of hash chain */
int bflush; /* set if current block must be flushed */
/* Process the input block. */
for (;;) {
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
* for the next match, plus MIN_MATCH bytes to insert the
* string following the next match.
*/
if (s->lookahead < MIN_LOOKAHEAD) {
fill_window(s);
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */
}
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
hash_head = NIL;
if (s->lookahead >= MIN_MATCH) {
INSERT_STRING(s, s->strstart, hash_head);
}
/* Find the longest match, discarding those <= prev_length.
*/
s->prev_length = s->match_length, s->prev_match = s->match_start;
s->match_length = MIN_MATCH-1;
if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
s->strstart - hash_head <= MAX_DIST(s)) {
/* To simplify the code, we prevent matches with the string
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
s->match_length = longest_match (s, hash_head);
/* longest_match() sets match_start */
if (s->match_length <= 5 && (s->strategy == Z_FILTERED
#if TOO_FAR <= 32767
|| (s->match_length == MIN_MATCH &&
s->strstart - s->match_start > TOO_FAR)
#endif
)) {
/* If prev_match is also MIN_MATCH, match_start is garbage
* but we will ignore the current match anyway.
*/
s->match_length = MIN_MATCH-1;
}
}
/* If there was a match at the previous step and the current
* match is not better, output the previous match:
*/
if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
/* Do not insert strings in hash table beyond this. */
check_match(s, s->strstart-1, s->prev_match, s->prev_length);
_tr_tally_dist(s, s->strstart -1 - s->prev_match,
s->prev_length - MIN_MATCH, bflush);
/* Insert in hash table all strings up to the end of the match.
* strstart-1 and strstart are already inserted. If there is not
* enough lookahead, the last two strings are not inserted in
* the hash table.
*/
s->lookahead -= s->prev_length-1;
s->prev_length -= 2;
do {
if (++s->strstart <= max_insert) {
INSERT_STRING(s, s->strstart, hash_head);
}
} while (--s->prev_length != 0);
s->match_available = 0;
s->match_length = MIN_MATCH-1;
s->strstart++;
if (bflush) FLUSH_BLOCK(s, 0);
} else if (s->match_available) {
/* If there was no match at the previous position, output a
* single literal. If there was a match but the current match
* is longer, truncate the previous match to a single literal.
*/
Tracevv((stderr,"%c", s->window[s->strstart-1]));
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
if (bflush) {
FLUSH_BLOCK_ONLY(s, 0);
}
s->strstart++;
s->lookahead--;
if (s->strm->avail_out == 0) return need_more;
} else {
/* There is no previous match to compare with, wait for
* the next step to decide.
*/
s->match_available = 1;
s->strstart++;
s->lookahead--;
}
}
Assert (flush != Z_NO_FLUSH, "no flush?");
if (s->match_available) {
Tracevv((stderr,"%c", s->window[s->strstart-1]));
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
s->match_available = 0;
}
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
if (flush == Z_FINISH) {
FLUSH_BLOCK(s, 1);
return finish_done;
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);
return block_done;
}
#endif /* FASTEST */
/* ===========================================================================
* For Z_RLE, simply look for runs of bytes, generate matches only of distance
* one. Do not maintain a hash table. (It will be regenerated if this run of
* deflate switches away from Z_RLE.)
*/
local block_state deflate_rle(s, flush)
deflate_state *s;
int flush;
{
int bflush; /* set if current block must be flushed */
uInt prev; /* byte at distance one to match */
Bytef *scan, *strend; /* scan goes up to strend for length of run */
for (;;) {
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
* for the longest run, plus one for the unrolled loop.
*/
if (s->lookahead <= MAX_MATCH) {
fill_window(s);
if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */
}
/* See how many times the previous byte repeats */
s->match_length = 0;
if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
scan = s->window + s->strstart - 1;
prev = *scan;
if (prev == *++scan && prev == *++scan && prev == *++scan) {
strend = s->window + s->strstart + MAX_MATCH;
do {
} while (prev == *++scan && prev == *++scan &&
prev == *++scan && prev == *++scan &&
prev == *++scan && prev == *++scan &&
prev == *++scan && prev == *++scan &&
scan < strend);
s->match_length = MAX_MATCH - (uInt)(strend - scan);
if (s->match_length > s->lookahead)
s->match_length = s->lookahead;
}
Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
}
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->strstart - 1, s->match_length);
_tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
s->lookahead -= s->match_length;
s->strstart += s->match_length;
s->match_length = 0;
} else {
/* No match, output a literal byte */
Tracevv((stderr,"%c", s->window[s->strstart]));
_tr_tally_lit (s, s->window[s->strstart], bflush);
s->lookahead--;
s->strstart++;
}
if (bflush) FLUSH_BLOCK(s, 0);
}
s->insert = 0;
if (flush == Z_FINISH) {
FLUSH_BLOCK(s, 1);
return finish_done;
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);
return block_done;
}
/* ===========================================================================
* For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
* (It will be regenerated if this run of deflate switches away from Huffman.)
*/
local block_state deflate_huff(s, flush)
deflate_state *s;
int flush;
{
int bflush; /* set if current block must be flushed */
for (;;) {
/* Make sure that we have a literal to write. */
if (s->lookahead == 0) {
fill_window(s);
if (s->lookahead == 0) {
if (flush == Z_NO_FLUSH)
return need_more;
break; /* flush the current block */
}
}
/* Output a literal byte */
s->match_length = 0;
Tracevv((stderr,"%c", s->window[s->strstart]));
_tr_tally_lit (s, s->window[s->strstart], bflush);
s->lookahead--;
s->strstart++;
if (bflush) FLUSH_BLOCK(s, 0);
}
s->insert = 0;
if (flush == Z_FINISH) {
FLUSH_BLOCK(s, 1);
return finish_done;
}
- if (s->last_lit)
+ if (s->sym_next)
FLUSH_BLOCK(s, 0);
return block_done;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/deflate.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/deflate.h
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/deflate.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/deflate.h
index 23ecdd31..17c22611 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/deflate.h
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/deflate.h
@@ -1,349 +1,346 @@
/* deflate.h -- internal compression state
- * Copyright (C) 1995-2016 Jean-loup Gailly
+ * Copyright (C) 1995-2018 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef DEFLATE_H
#define DEFLATE_H
#include "zutil.h"
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip encoding
should be left enabled. */
#ifndef NO_GZIP
# define GZIP
#endif
/* ===========================================================================
* Internal compression state.
*/
#define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */
#define LITERALS 256
/* number of literal bytes 0..255 */
#define L_CODES (LITERALS+1+LENGTH_CODES)
/* number of Literal or Length codes, including the END_BLOCK code */
#define D_CODES 30
/* number of distance codes */
#define BL_CODES 19
/* number of codes used to transfer the bit lengths */
#define HEAP_SIZE (2*L_CODES+1)
/* maximum heap size */
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
#define Buf_size 16
/* size of bit buffer in bi_buf */
#define INIT_STATE 42 /* zlib header -> BUSY_STATE */
#ifdef GZIP
# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */
#endif
#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */
#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */
#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */
#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */
#define BUSY_STATE 113 /* deflate -> FINISH_STATE */
#define FINISH_STATE 666 /* stream complete */
/* Stream status */
/* Data structure describing a single value and its code string. */
typedef struct ct_data_s {
union {
ush freq; /* frequency count */
ush code; /* bit string */
} fc;
union {
ush dad; /* father node in Huffman tree */
ush len; /* length of bit string */
} dl;
} FAR ct_data;
#define Freq fc.freq
#define Code fc.code
#define Dad dl.dad
#define Len dl.len
typedef struct static_tree_desc_s static_tree_desc;
typedef struct tree_desc_s {
ct_data *dyn_tree; /* the dynamic tree */
int max_code; /* largest code with non zero frequency */
const static_tree_desc *stat_desc; /* the corresponding static tree */
} FAR tree_desc;
typedef ush Pos;
typedef Pos FAR Posf;
typedef unsigned IPos;
/* A Pos is an index in the character window. We use short instead of int to
* save space in the various tables. IPos is used only for parameter passing.
*/
typedef struct internal_state {
z_streamp strm; /* pointer back to this zlib stream */
int status; /* as the name implies */
Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */
ulg pending; /* nb of bytes in the pending buffer */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
gz_headerp gzhead; /* gzip header information to write */
ulg gzindex; /* where in extra, name, or comment */
Byte method; /* can only be DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */
uInt w_size; /* LZ77 window size (32K by default) */
uInt w_bits; /* log2(w_size) (8..16) */
uInt w_mask; /* w_size - 1 */
Bytef *window;
/* Sliding window. Input bytes are read into the second half of the window,
* and move to the first half later to keep a dictionary of at least wSize
* bytes. With this organization, matches are limited to a distance of
* wSize-MAX_MATCH bytes, but this ensures that IO is always
* performed with a length multiple of the block size. Also, it limits
* the window size to 64K, which is quite useful on MSDOS.
* To do: use the user input buffer as sliding window.
*/
ulg window_size;
/* Actual size of window: 2*wSize, except when the user input buffer
* is directly used as sliding window.
*/
Posf *prev;
/* Link to older string with same hash index. To limit the size of this
* array to 64K, this link is maintained only for the last 32K strings.
* An index in this array is thus a window index modulo 32K.
*/
Posf *head; /* Heads of the hash chains or NIL. */
uInt ins_h; /* hash index of string to be inserted */
uInt hash_size; /* number of elements in hash table */
uInt hash_bits; /* log2(hash_size) */
uInt hash_mask; /* hash_size-1 */
uInt hash_shift;
/* Number of bits by which ins_h must be shifted at each input
* step. It must be such that after MIN_MATCH steps, the oldest
* byte no longer takes part in the hash key, that is:
* hash_shift * MIN_MATCH >= hash_bits
*/
long block_start;
/* Window position at the beginning of the current output block. Gets
* negative when the window is moved backwards.
*/
uInt match_length; /* length of best match */
IPos prev_match; /* previous match */
int match_available; /* set if previous match exists */
uInt strstart; /* start of string to insert */
uInt match_start; /* start of matching string */
uInt lookahead; /* number of valid bytes ahead in window */
uInt prev_length;
/* Length of the best match at previous step. Matches not greater than this
* are discarded. This is used in the lazy match evaluation.
*/
uInt max_chain_length;
/* To speed up deflation, hash chains are never searched beyond this
* length. A higher limit improves compression ratio but degrades the
* speed.
*/
uInt max_lazy_match;
/* Attempt to find a better match only when the current match is strictly
* smaller than this value. This mechanism is used only for compression
* levels >= 4.
*/
# define max_insert_length max_lazy_match
/* Insert new strings in the hash table only if the match length is not
* greater than this length. This saves time but degrades compression.
* max_insert_length is used only for compression levels <= 3.
*/
int level; /* compression level (1..9) */
int strategy; /* favor or force Huffman coding*/
uInt good_match;
/* Use a faster search when the previous match is longer than this */
int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */
/* Didn't use ct_data typedef below to suppress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
struct tree_desc_s l_desc; /* desc. for literal tree */
struct tree_desc_s d_desc; /* desc. for distance tree */
struct tree_desc_s bl_desc; /* desc. for bit length tree */
ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
int heap_len; /* number of elements in the heap */
int heap_max; /* element of largest frequency */
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
* The same heap array is used to build all trees.
*/
uch depth[2*L_CODES+1];
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
- uchf *l_buf; /* buffer for literals or lengths */
+ uchf *sym_buf; /* buffer for distances and literals/lengths */
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
* limiting lit_bufsize to 64K:
* - frequencies can be kept in 16 bit counters
* - if compression is not successful for the first block, all input
* data is still in the window so we can still emit a stored block even
* when input comes from standard input. (This can also be done for
* all blocks if lit_bufsize is not greater than 32K.)
* - if compression is not successful for a file smaller than 64K, we can
* even emit a stored file instead of a stored block (saving 5 bytes).
* This is applicable only for zip (not gzip or zlib).
* - creating new Huffman trees less frequently may not provide fast
* adaptation to changes in the input data statistics. (Take for
* example a binary file with poorly compressible code followed by
* a highly compressible string table.) Smaller buffer sizes give
* fast adaptation but have of course the overhead of transmitting
* trees more frequently.
* - I can't count above 4
*/
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
+ uInt sym_next; /* running index in sym_buf */
+ uInt sym_end; /* symbol table full when sym_next reaches this */
ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */
uInt insert; /* bytes at end of window left to insert */
#ifdef ZLIB_DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
#endif
ush bi_buf;
/* Output buffer. bits are inserted starting at the bottom (least
* significant bits).
*/
int bi_valid;
/* Number of valid bits in bi_buf. All bits above the last valid bit
* are always zero.
*/
ulg high_water;
/* High water mark offset in window for initialized bytes -- bytes above
* this are set to zero in order to avoid memory check warnings when
* longest match routines access bytes past the input. This is then
* updated to the new high water mark.
*/
} FAR deflate_state;
/* Output a byte on the stream.
* IN assertion: there is enough room in pending_buf.
*/
#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);}
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
/* Minimum amount of lookahead, except at the end of the input file.
* See deflate.c for comments about the MIN_MATCH+1.
*/
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
/* In order to simplify the code, particularly on 16 bit machines, match
* distances are limited to MAX_DIST instead of WSIZE.
*/
#define WIN_INIT MAX_MATCH
/* Number of bytes after end of data in window to initialize in order to avoid
memory checker errors from longest match routines */
/* in trees.c */
void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
ulg stored_len, int last));
void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
ulg stored_len, int last));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. _dist_code[256] and _dist_code[257] are never
* used.
*/
#ifndef ZLIB_DEBUG
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
extern uch ZLIB_INTERNAL _length_code[];
extern uch ZLIB_INTERNAL _dist_code[];
#else
extern const uch ZLIB_INTERNAL _length_code[];
extern const uch ZLIB_INTERNAL _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
+ s->sym_buf[s->sym_next++] = 0; \
+ s->sym_buf[s->sym_next++] = 0; \
+ s->sym_buf[s->sym_next++] = cc; \
s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
+ flush = (s->sym_next == s->sym_end); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (uch)(length); \
ush dist = (ush)(distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
+ s->sym_buf[s->sym_next++] = dist; \
+ s->sym_buf[s->sym_next++] = dist >> 8; \
+ s->sym_buf[s->sym_next++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
+ flush = (s->sym_next == s->sym_end); \
}
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
flush = _tr_tally(s, distance, length)
#endif
#endif /* DEFLATE_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzclose.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzclose.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzclose.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzclose.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzguts.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzguts.h
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzguts.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzguts.h
index 990a4d25..57faf371 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzguts.h
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzguts.h
@@ -1,218 +1,219 @@
/* gzguts.h -- zlib internal header definitions for gz* operations
- * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * Copyright (C) 2004-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#ifdef _LARGEFILE64_SOURCE
# ifndef _LARGEFILE_SOURCE
# define _LARGEFILE_SOURCE 1
# endif
# ifdef _FILE_OFFSET_BITS
# undef _FILE_OFFSET_BITS
# endif
#endif
#ifdef HAVE_HIDDEN
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#else
# define ZLIB_INTERNAL
#endif
#include <stdio.h>
#include "zlib.h"
#ifdef STDC
# include <string.h>
# include <stdlib.h>
# include <limits.h>
#endif
#ifndef _POSIX_SOURCE
# define _POSIX_SOURCE
#endif
#include <fcntl.h>
#ifdef _WIN32
# include <stddef.h>
#endif
#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
# include <io.h>
#endif
-#if defined(_WIN32) || defined(__CYGWIN__)
+#if defined(_WIN32)
# define WIDECHAR
#endif
#ifdef WINAPI_FAMILY
# define open _open
# define read _read
# define write _write
# define close _close
#endif
#ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS
#endif
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#if defined(__CYGWIN__)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#ifndef HAVE_VSNPRINTF
# ifdef MSDOS
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
but for now we just assume it doesn't. */
# define NO_vsnprintf
# endif
# ifdef __TURBOC__
# define NO_vsnprintf
# endif
# ifdef WIN32
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
# define vsnprintf _vsnprintf
# endif
# endif
# endif
# ifdef __SASC
# define NO_vsnprintf
# endif
# ifdef VMS
# define NO_vsnprintf
# endif
# ifdef __OS400__
# define NO_vsnprintf
# endif
# ifdef __MVS__
# define NO_vsnprintf
# endif
#endif
/* unlike snprintf (which is required in C99), _snprintf does not guarantee
null termination of the result -- however this is only used in gzlib.c where
the result is assured to fit in the space provided */
#if defined(_MSC_VER) && _MSC_VER < 1900
# define snprintf _snprintf
#endif
#ifndef local
# define local static
#endif
/* since "static" is used to mean two completely different things in C, we
define "local" for the non-static meaning of "static", for readability
(compile with -Dlocal if your debugger can't find static symbols) */
/* gz* functions always use library allocation functions */
#ifndef STDC
extern voidp malloc OF((uInt size));
extern void free OF((voidpf ptr));
#endif
/* get errno and strerror definition */
#if defined UNDER_CE
# include <windows.h>
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
#else
# ifndef NO_STRERROR
# include <errno.h>
# define zstrerror() strerror(errno)
# else
# define zstrerror() "stdio error (consult errno)"
# endif
#endif
/* provide prototypes for these when building zlib without LFS */
#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
#endif
/* default memLevel */
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
/* default i/o buffer size -- double this for output when reading (this and
twice this must be able to fit in an unsigned type) */
#define GZBUFSIZE 8192
/* gzip modes, also provide a little integrity check on the passed structure */
#define GZ_NONE 0
#define GZ_READ 7247
#define GZ_WRITE 31153
#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
/* values for gz_state how */
#define LOOK 0 /* look for a gzip header */
#define COPY 1 /* copy input directly */
#define GZIP 2 /* decompress a gzip stream */
/* internal gzip file state data structure */
typedef struct {
/* exposed contents for gzgetc() macro */
struct gzFile_s x; /* "x" for exposed */
/* x.have: number of bytes available at x.next */
/* x.next: next output data to deliver or write */
/* x.pos: current position in uncompressed data */
/* used for both reading and writing */
int mode; /* see gzip modes above */
int fd; /* file descriptor */
char *path; /* path or fd for error messages */
unsigned size; /* buffer size, zero if not allocated yet */
unsigned want; /* requested buffer size, default is GZBUFSIZE */
unsigned char *in; /* input buffer (double-sized when writing) */
unsigned char *out; /* output buffer (double-sized when reading) */
int direct; /* 0 if processing gzip, 1 if transparent */
/* just for reading */
int how; /* 0: get header, 1: copy, 2: decompress */
z_off64_t start; /* where the gzip data started, for rewinding */
int eof; /* true if end of input file reached */
int past; /* true if read requested past end */
/* just for writing */
int level; /* compression level */
int strategy; /* compression strategy */
+ int reset; /* true if a reset is pending after a Z_FINISH */
/* seek request */
z_off64_t skip; /* amount to skip (already rewound if backwards) */
int seek; /* true if seek request pending */
/* error information */
int err; /* error code */
char *msg; /* error message */
/* zlib inflate or deflate stream */
z_stream strm; /* stream structure in-place (not a pointer) */
} gz_state;
typedef gz_state FAR *gz_statep;
/* shared functions */
void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
#if defined UNDER_CE
char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
#endif
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
value -- needed when comparing unsigned to z_off64_t, which is signed
(possible z_off64_t types off_t, off64_t, and long are all signed) */
#ifdef INT_MAX
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
#else
unsigned ZLIB_INTERNAL gz_intmax OF((void));
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzlib.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzlib.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzlib.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzlib.c
index 4105e6af..dddaf268 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzlib.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzlib.c
@@ -1,637 +1,639 @@
/* gzlib.c -- zlib functions common to reading and writing gzip files
- * Copyright (C) 2004-2017 Mark Adler
+ * Copyright (C) 2004-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "gzguts.h"
-#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
+#if defined(_WIN32) && !defined(__BORLANDC__)
# define LSEEK _lseeki64
#else
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
# define LSEEK lseek64
#else
# define LSEEK lseek
#endif
#endif
/* Local functions */
local void gz_reset OF((gz_statep));
local gzFile gz_open OF((const void *, int, const char *));
#if defined UNDER_CE
/* Map the Windows error number in ERROR to a locale-dependent error message
string and return a pointer to it. Typically, the values for ERROR come
from GetLastError.
The string pointed to shall not be modified by the application, but may be
overwritten by a subsequent call to gz_strwinerror
The gz_strwinerror function does not change the current setting of
GetLastError. */
char ZLIB_INTERNAL *gz_strwinerror (error)
DWORD error;
{
static char buf[1024];
wchar_t *msgbuf;
DWORD lasterr = GetLastError();
DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
error,
0, /* Default language */
(LPVOID)&msgbuf,
0,
NULL);
if (chars != 0) {
/* If there is an \r\n appended, zap it. */
if (chars >= 2
&& msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
chars -= 2;
msgbuf[chars] = 0;
}
if (chars > sizeof (buf) - 1) {
chars = sizeof (buf) - 1;
msgbuf[chars] = 0;
}
wcstombs(buf, msgbuf, chars + 1);
LocalFree(msgbuf);
}
else {
sprintf(buf, "unknown win32 error (%ld)", error);
}
SetLastError(lasterr);
return buf;
}
#endif /* UNDER_CE */
/* Reset gzip file state */
local void gz_reset(state)
gz_statep state;
{
state->x.have = 0; /* no output data available */
if (state->mode == GZ_READ) { /* for reading ... */
state->eof = 0; /* not at end of file */
state->past = 0; /* have not read past end yet */
state->how = LOOK; /* look for gzip header */
}
+ else /* for writing ... */
+ state->reset = 0; /* no deflateReset pending */
state->seek = 0; /* no seek request pending */
gz_error(state, Z_OK, NULL); /* clear error */
state->x.pos = 0; /* no uncompressed data yet */
state->strm.avail_in = 0; /* no input data yet */
}
/* Open a gzip file either by name or file descriptor. */
local gzFile gz_open(path, fd, mode)
const void *path;
int fd;
const char *mode;
{
gz_statep state;
z_size_t len;
int oflag;
#ifdef O_CLOEXEC
int cloexec = 0;
#endif
#ifdef O_EXCL
int exclusive = 0;
#endif
/* check input */
if (path == NULL)
return NULL;
/* allocate gzFile structure to return */
state = (gz_statep)malloc(sizeof(gz_state));
if (state == NULL)
return NULL;
state->size = 0; /* no buffers allocated yet */
state->want = GZBUFSIZE; /* requested buffer size */
state->msg = NULL; /* no error message yet */
/* interpret mode */
state->mode = GZ_NONE;
state->level = Z_DEFAULT_COMPRESSION;
state->strategy = Z_DEFAULT_STRATEGY;
state->direct = 0;
while (*mode) {
if (*mode >= '0' && *mode <= '9')
state->level = *mode - '0';
else
switch (*mode) {
case 'r':
state->mode = GZ_READ;
break;
#ifndef NO_GZCOMPRESS
case 'w':
state->mode = GZ_WRITE;
break;
case 'a':
state->mode = GZ_APPEND;
break;
#endif
case '+': /* can't read and write at the same time */
free(state);
return NULL;
case 'b': /* ignore -- will request binary anyway */
break;
#ifdef O_CLOEXEC
case 'e':
cloexec = 1;
break;
#endif
#ifdef O_EXCL
case 'x':
exclusive = 1;
break;
#endif
case 'f':
state->strategy = Z_FILTERED;
break;
case 'h':
state->strategy = Z_HUFFMAN_ONLY;
break;
case 'R':
state->strategy = Z_RLE;
break;
case 'F':
state->strategy = Z_FIXED;
break;
case 'T':
state->direct = 1;
break;
default: /* could consider as an error, but just ignore */
;
}
mode++;
}
/* must provide an "r", "w", or "a" */
if (state->mode == GZ_NONE) {
free(state);
return NULL;
}
/* can't force transparent read */
if (state->mode == GZ_READ) {
if (state->direct) {
free(state);
return NULL;
}
state->direct = 1; /* for empty file */
}
/* save the path name for error messages */
#ifdef WIDECHAR
if (fd == -2) {
len = wcstombs(NULL, path, 0);
if (len == (z_size_t)-1)
len = 0;
}
else
#endif
len = strlen((const char *)path);
state->path = (char *)malloc(len + 1);
if (state->path == NULL) {
free(state);
return NULL;
}
#ifdef WIDECHAR
if (fd == -2)
if (len)
wcstombs(state->path, path, len + 1);
else
*(state->path) = 0;
else
#endif
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
(void)snprintf(state->path, len + 1, "%s", (const char *)path);
#else
strcpy(state->path, path);
#endif
/* compute the flags for open() */
oflag =
#ifdef O_LARGEFILE
O_LARGEFILE |
#endif
#ifdef O_BINARY
O_BINARY |
#endif
#ifdef O_CLOEXEC
(cloexec ? O_CLOEXEC : 0) |
#endif
(state->mode == GZ_READ ?
O_RDONLY :
(O_WRONLY | O_CREAT |
#ifdef O_EXCL
(exclusive ? O_EXCL : 0) |
#endif
(state->mode == GZ_WRITE ?
O_TRUNC :
O_APPEND)));
/* open the file with the appropriate flags (or just use fd) */
state->fd = fd > -1 ? fd : (
#ifdef WIDECHAR
fd == -2 ? _wopen(path, oflag, 0666) :
#endif
open((const char *)path, oflag, 0666));
if (state->fd == -1) {
free(state->path);
free(state);
return NULL;
}
if (state->mode == GZ_APPEND) {
LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
state->mode = GZ_WRITE; /* simplify later checks */
}
/* save the current position for rewinding (only if reading) */
if (state->mode == GZ_READ) {
state->start = LSEEK(state->fd, 0, SEEK_CUR);
if (state->start == -1) state->start = 0;
}
/* initialize stream */
gz_reset(state);
/* return stream */
return (gzFile)state;
}
/* -- see zlib.h -- */
gzFile ZEXPORT gzopen(path, mode)
const char *path;
const char *mode;
{
return gz_open(path, -1, mode);
}
/* -- see zlib.h -- */
gzFile ZEXPORT gzopen64(path, mode)
const char *path;
const char *mode;
{
return gz_open(path, -1, mode);
}
/* -- see zlib.h -- */
gzFile ZEXPORT gzdopen(fd, mode)
int fd;
const char *mode;
{
char *path; /* identifier for error messages */
gzFile gz;
if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
return NULL;
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
(void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
#else
sprintf(path, "<fd:%d>", fd); /* for debugging */
#endif
gz = gz_open(path, fd, mode);
free(path);
return gz;
}
/* -- see zlib.h -- */
#ifdef WIDECHAR
gzFile ZEXPORT gzopen_w(path, mode)
const wchar_t *path;
const char *mode;
{
return gz_open(path, -2, mode);
}
#endif
/* -- see zlib.h -- */
int ZEXPORT gzbuffer(file, size)
gzFile file;
unsigned size;
{
gz_statep state;
/* get internal structure and check integrity */
if (file == NULL)
return -1;
state = (gz_statep)file;
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
return -1;
/* make sure we haven't already allocated memory */
if (state->size != 0)
return -1;
/* check and set requested size */
if ((size << 1) < size)
return -1; /* need to be able to double it */
if (size < 2)
size = 2; /* need two bytes to check magic header */
state->want = size;
return 0;
}
/* -- see zlib.h -- */
int ZEXPORT gzrewind(file)
gzFile file;
{
gz_statep state;
/* get internal structure */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* check that we're reading and that there's no error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* back up and start over */
if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
return -1;
gz_reset(state);
return 0;
}
/* -- see zlib.h -- */
z_off64_t ZEXPORT gzseek64(file, offset, whence)
gzFile file;
z_off64_t offset;
int whence;
{
unsigned n;
z_off64_t ret;
gz_statep state;
/* get internal structure and check integrity */
if (file == NULL)
return -1;
state = (gz_statep)file;
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
return -1;
/* check that there's no error */
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
return -1;
/* can only seek from start or relative to current position */
if (whence != SEEK_SET && whence != SEEK_CUR)
return -1;
/* normalize offset to a SEEK_CUR specification */
if (whence == SEEK_SET)
offset -= state->x.pos;
else if (state->seek)
offset += state->skip;
state->seek = 0;
/* if within raw area while reading, just go there */
if (state->mode == GZ_READ && state->how == COPY &&
state->x.pos + offset >= 0) {
- ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
+ ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);
if (ret == -1)
return -1;
state->x.have = 0;
state->eof = 0;
state->past = 0;
state->seek = 0;
gz_error(state, Z_OK, NULL);
state->strm.avail_in = 0;
state->x.pos += offset;
return state->x.pos;
}
/* calculate skip amount, rewinding if needed for back seek when reading */
if (offset < 0) {
if (state->mode != GZ_READ) /* writing -- can't go backwards */
return -1;
offset += state->x.pos;
if (offset < 0) /* before start of file! */
return -1;
if (gzrewind(file) == -1) /* rewind, then skip to offset */
return -1;
}
/* if reading, skip what's in output buffer (one less gzgetc() check) */
if (state->mode == GZ_READ) {
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
(unsigned)offset : state->x.have;
state->x.have -= n;
state->x.next += n;
state->x.pos += n;
offset -= n;
}
/* request skip (if not zero) */
if (offset) {
state->seek = 1;
state->skip = offset;
}
return state->x.pos + offset;
}
/* -- see zlib.h -- */
z_off_t ZEXPORT gzseek(file, offset, whence)
gzFile file;
z_off_t offset;
int whence;
{
z_off64_t ret;
ret = gzseek64(file, (z_off64_t)offset, whence);
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
}
/* -- see zlib.h -- */
z_off64_t ZEXPORT gztell64(file)
gzFile file;
{
gz_statep state;
/* get internal structure and check integrity */
if (file == NULL)
return -1;
state = (gz_statep)file;
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
return -1;
/* return position */
return state->x.pos + (state->seek ? state->skip : 0);
}
/* -- see zlib.h -- */
z_off_t ZEXPORT gztell(file)
gzFile file;
{
z_off64_t ret;
ret = gztell64(file);
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
}
/* -- see zlib.h -- */
z_off64_t ZEXPORT gzoffset64(file)
gzFile file;
{
z_off64_t offset;
gz_statep state;
/* get internal structure and check integrity */
if (file == NULL)
return -1;
state = (gz_statep)file;
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
return -1;
/* compute and return effective offset in file */
offset = LSEEK(state->fd, 0, SEEK_CUR);
if (offset == -1)
return -1;
if (state->mode == GZ_READ) /* reading */
offset -= state->strm.avail_in; /* don't count buffered input */
return offset;
}
/* -- see zlib.h -- */
z_off_t ZEXPORT gzoffset(file)
gzFile file;
{
z_off64_t ret;
ret = gzoffset64(file);
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
}
/* -- see zlib.h -- */
int ZEXPORT gzeof(file)
gzFile file;
{
gz_statep state;
/* get internal structure and check integrity */
if (file == NULL)
return 0;
state = (gz_statep)file;
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
return 0;
/* return end-of-file state */
return state->mode == GZ_READ ? state->past : 0;
}
/* -- see zlib.h -- */
const char * ZEXPORT gzerror(file, errnum)
gzFile file;
int *errnum;
{
gz_statep state;
/* get internal structure and check integrity */
if (file == NULL)
return NULL;
state = (gz_statep)file;
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
return NULL;
/* return error information */
if (errnum != NULL)
*errnum = state->err;
return state->err == Z_MEM_ERROR ? "out of memory" :
(state->msg == NULL ? "" : state->msg);
}
/* -- see zlib.h -- */
void ZEXPORT gzclearerr(file)
gzFile file;
{
gz_statep state;
/* get internal structure and check integrity */
if (file == NULL)
return;
state = (gz_statep)file;
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
return;
/* clear error and end-of-file */
if (state->mode == GZ_READ) {
state->eof = 0;
state->past = 0;
}
gz_error(state, Z_OK, NULL);
}
/* Create an error message in allocated memory and set state->err and
state->msg accordingly. Free any previous error message already there. Do
not try to free or allocate space if the error is Z_MEM_ERROR (out of
memory). Simply save the error message as a static string. If there is an
allocation failure constructing the error message, then convert the error to
out of memory. */
void ZLIB_INTERNAL gz_error(state, err, msg)
gz_statep state;
int err;
const char *msg;
{
/* free previously allocated message and clear */
if (state->msg != NULL) {
if (state->err != Z_MEM_ERROR)
free(state->msg);
state->msg = NULL;
}
/* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
if (err != Z_OK && err != Z_BUF_ERROR)
state->x.have = 0;
/* set error code, and if no message, then done */
state->err = err;
if (msg == NULL)
return;
/* for an out of memory error, return literal string when requested */
if (err == Z_MEM_ERROR)
return;
/* construct error message with path */
if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
NULL) {
state->err = Z_MEM_ERROR;
return;
}
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
(void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
"%s%s%s", state->path, ": ", msg);
#else
strcpy(state->msg, state->path);
strcat(state->msg, ": ");
strcat(state->msg, msg);
#endif
}
#ifndef INT_MAX
/* portably return maximum value for an int (when limits.h presumed not
available) -- we need to do this to cover cases where 2's complement not
used, since C standard permits 1's complement and sign-bit representations,
otherwise we could just use ((unsigned)-1) >> 1 */
unsigned ZLIB_INTERNAL gz_intmax()
{
unsigned p, q;
p = 1;
do {
q = p;
p <<= 1;
p++;
} while (p > q);
return q >> 1;
}
#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzread.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzread.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzread.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzread.c
index 08aa0de5..884c9bfe 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzread.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzread.c
@@ -1,656 +1,652 @@
/* gzread.c -- zlib functions for reading gzip files
- * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * Copyright (C) 2004-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "gzguts.h"
-#ifndef __clang_analyzer__
/* Local functions */
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
local int gz_avail OF((gz_statep));
local int gz_look OF((gz_statep));
local int gz_decomp OF((gz_statep));
local int gz_fetch OF((gz_statep));
local int gz_skip OF((gz_statep, z_off64_t));
local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
state->fd, and update state->eof, state->err, and state->msg as appropriate.
This function needs to loop on read(), since read() is not guaranteed to
read the number of bytes requested, depending on the type of descriptor. */
local int gz_load(state, buf, len, have)
gz_statep state;
unsigned char *buf;
unsigned len;
unsigned *have;
{
int ret;
unsigned get, max = ((unsigned)-1 >> 2) + 1;
*have = 0;
do {
get = len - *have;
if (get > max)
get = max;
ret = read(state->fd, buf + *have, get);
if (ret <= 0)
break;
*have += (unsigned)ret;
} while (*have < len);
if (ret < 0) {
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
if (ret == 0)
state->eof = 1;
return 0;
}
/* Load up input buffer and set eof flag if last data loaded -- return -1 on
error, 0 otherwise. Note that the eof flag is set when the end of the input
file is reached, even though there may be unused data in the buffer. Once
that data has been used, no more attempts will be made to read the file.
If strm->avail_in != 0, then the current data is moved to the beginning of
the input buffer, and then the remainder of the buffer is loaded with the
available data from the input file. */
local int gz_avail(state)
gz_statep state;
{
unsigned got;
z_streamp strm = &(state->strm);
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
return -1;
if (state->eof == 0) {
if (strm->avail_in) { /* copy what's there to the start */
unsigned char *p = state->in;
unsigned const char *q = strm->next_in;
unsigned n = strm->avail_in;
do {
*p++ = *q++;
} while (--n);
}
if (gz_load(state, state->in + strm->avail_in,
state->size - strm->avail_in, &got) == -1)
return -1;
strm->avail_in += got;
strm->next_in = state->in;
}
return 0;
}
/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
If this is the first time in, allocate required memory. state->how will be
left unchanged if there is no more input data available, will be set to COPY
if there is no gzip header and direct copying will be performed, or it will
be set to GZIP for decompression. If direct copying, then leftover input
data from the input buffer will be copied to the output buffer. In that
case, all further file reads will be directly to either the output buffer or
a user buffer. If decompressing, the inflate state will be initialized.
gz_look() will return 0 on success or -1 on failure. */
local int gz_look(state)
gz_statep state;
{
z_streamp strm = &(state->strm);
/* allocate read buffers and inflate memory */
if (state->size == 0) {
/* allocate buffers */
state->in = (unsigned char *)malloc(state->want);
state->out = (unsigned char *)malloc(state->want << 1);
if (state->in == NULL || state->out == NULL) {
free(state->out);
free(state->in);
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
}
state->size = state->want;
/* allocate inflate memory */
state->strm.zalloc = Z_NULL;
state->strm.zfree = Z_NULL;
state->strm.opaque = Z_NULL;
state->strm.avail_in = 0;
state->strm.next_in = Z_NULL;
if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
free(state->out);
free(state->in);
state->size = 0;
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
}
}
/* get at least the magic bytes in the input buffer */
if (strm->avail_in < 2) {
if (gz_avail(state) == -1)
return -1;
if (strm->avail_in == 0)
return 0;
}
/* look for gzip magic bytes -- if there, do gzip decoding (note: there is
a logical dilemma here when considering the case of a partially written
gzip file, to wit, if a single 31 byte is written, then we cannot tell
whether this is a single-byte file, or just a partially written gzip
file -- for here we assume that if a gzip file is being written, then
the header will be written in a single operation, so that reading a
single byte is sufficient indication that it is not a gzip file) */
if (strm->avail_in > 1 &&
strm->next_in[0] == 31 && strm->next_in[1] == 139) {
inflateReset(strm);
state->how = GZIP;
state->direct = 0;
return 0;
}
/* no gzip header -- if we were decoding gzip before, then this is trailing
garbage. Ignore the trailing garbage and finish. */
if (state->direct == 0) {
strm->avail_in = 0;
state->eof = 1;
state->x.have = 0;
return 0;
}
/* doing raw i/o, copy any leftover input to output -- this assumes that
the output buffer is larger than the input buffer, which also assures
space for gzungetc() */
state->x.next = state->out;
if (strm->avail_in) {
memcpy(state->x.next, strm->next_in, strm->avail_in);
state->x.have = strm->avail_in;
strm->avail_in = 0;
}
state->how = COPY;
state->direct = 1;
return 0;
}
/* Decompress from input to the provided next_out and avail_out in the state.
On return, state->x.have and state->x.next point to the just decompressed
data. If the gzip stream completes, state->how is reset to LOOK to look for
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
on success, -1 on failure. */
local int gz_decomp(state)
gz_statep state;
{
int ret = Z_OK;
unsigned had;
z_streamp strm = &(state->strm);
/* fill output buffer up to end of deflate stream */
had = strm->avail_out;
do {
/* get more input for inflate() */
if (strm->avail_in == 0 && gz_avail(state) == -1)
return -1;
if (strm->avail_in == 0) {
gz_error(state, Z_BUF_ERROR, "unexpected end of file");
break;
}
/* decompress and handle errors */
ret = inflate(strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
gz_error(state, Z_STREAM_ERROR,
"internal error: inflate stream corrupt");
return -1;
}
if (ret == Z_MEM_ERROR) {
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
}
if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
gz_error(state, Z_DATA_ERROR,
strm->msg == NULL ? "compressed data error" : strm->msg);
return -1;
}
} while (strm->avail_out && ret != Z_STREAM_END);
/* update available output */
state->x.have = had - strm->avail_out;
state->x.next = strm->next_out - state->x.have;
/* if the gzip stream completed successfully, look for another */
if (ret == Z_STREAM_END)
state->how = LOOK;
/* good decompression */
return 0;
}
/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
Data is either copied from the input file or decompressed from the input
file depending on state->how. If state->how is LOOK, then a gzip header is
looked for to determine whether to copy or decompress. Returns -1 on error,
otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
end of the input file has been reached and all data has been processed. */
local int gz_fetch(state)
gz_statep state;
{
z_streamp strm = &(state->strm);
do {
switch(state->how) {
case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
if (gz_look(state) == -1)
return -1;
if (state->how == LOOK)
return 0;
break;
case COPY: /* -> COPY */
if (gz_load(state, state->out, state->size << 1, &(state->x.have))
== -1)
return -1;
state->x.next = state->out;
return 0;
case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
strm->avail_out = state->size << 1;
strm->next_out = state->out;
if (gz_decomp(state) == -1)
return -1;
}
} while (state->x.have == 0 && (!state->eof || strm->avail_in));
return 0;
}
/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
local int gz_skip(state, len)
gz_statep state;
z_off64_t len;
{
unsigned n;
/* skip over len bytes or reach end-of-file, whichever comes first */
while (len)
/* skip over whatever is in output buffer */
if (state->x.have) {
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
(unsigned)len : state->x.have;
state->x.have -= n;
state->x.next += n;
state->x.pos += n;
len -= n;
}
/* output buffer empty -- return if we're at the end of the input */
else if (state->eof && state->strm.avail_in == 0)
break;
/* need more data to skip -- load up output buffer */
else {
/* get more output, looking for header if required */
if (gz_fetch(state) == -1)
return -1;
}
return 0;
}
/* Read len bytes into buf from file, or less than len up to the end of the
input. Return the number of bytes read. If zero is returned, either the
end of file was reached, or there was an error. state->err must be
consulted in that case to determine which. */
local z_size_t gz_read(state, buf, len)
gz_statep state;
voidp buf;
z_size_t len;
{
z_size_t got;
unsigned n;
/* if len is zero, avoid unnecessary operations */
if (len == 0)
return 0;
/* process a skip request */
if (state->seek) {
state->seek = 0;
if (gz_skip(state, state->skip) == -1)
return 0;
}
/* get len bytes to buf, or less than len if at the end */
got = 0;
do {
/* set n to the maximum amount of len that fits in an unsigned int */
- n = -1;
+ n = (unsigned)-1;
if (n > len)
- n = len;
+ n = (unsigned)len;
/* first just try copying data from the output buffer */
if (state->x.have) {
if (state->x.have < n)
n = state->x.have;
memcpy(buf, state->x.next, n);
state->x.next += n;
state->x.have -= n;
}
/* output buffer empty -- return if we're at the end of the input */
else if (state->eof && state->strm.avail_in == 0) {
state->past = 1; /* tried to read past end */
break;
}
/* need output data -- for small len or new stream load up our output
buffer */
else if (state->how == LOOK || n < (state->size << 1)) {
/* get more output, looking for header if required */
if (gz_fetch(state) == -1)
return 0;
continue; /* no progress yet -- go back to copy above */
/* the copy above assures that we will leave with space in the
output buffer, allowing at least one gzungetc() to succeed */
}
/* large len -- read directly into user buffer */
else if (state->how == COPY) { /* read directly */
if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
return 0;
}
/* large len -- decompress directly into user buffer */
else { /* state->how == GZIP */
state->strm.avail_out = n;
state->strm.next_out = (unsigned char *)buf;
if (gz_decomp(state) == -1)
return 0;
n = state->x.have;
state->x.have = 0;
}
/* update progress */
len -= n;
buf = (char *)buf + n;
got += n;
state->x.pos += n;
} while (len);
/* return number of bytes read into user buffer */
return got;
}
/* -- see zlib.h -- */
int ZEXPORT gzread(file, buf, len)
gzFile file;
voidp buf;
unsigned len;
{
gz_statep state;
/* get internal structure */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* since an int is returned, make sure len fits in one, otherwise return
with an error (this avoids a flaw in the interface) */
if ((int)len < 0) {
gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
return -1;
}
/* read len or fewer bytes to buf */
- len = gz_read(state, buf, len);
+ len = (unsigned)gz_read(state, buf, len);
/* check for an error */
if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
return -1;
/* return the number of bytes read (this is assured to fit in an int) */
return (int)len;
}
/* -- see zlib.h -- */
z_size_t ZEXPORT gzfread(buf, size, nitems, file)
voidp buf;
z_size_t size;
z_size_t nitems;
gzFile file;
{
z_size_t len;
gz_statep state;
/* get internal structure */
if (file == NULL)
return 0;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
return 0;
/* compute bytes to read -- error on overflow */
len = nitems * size;
if (size && len / size != nitems) {
gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
return 0;
}
/* read len or fewer bytes to buf, return the number of full items read */
return len ? gz_read(state, buf, len) / size : 0;
}
/* -- see zlib.h -- */
#ifdef Z_PREFIX_SET
# undef z_gzgetc
#else
# undef gzgetc
#endif
int ZEXPORT gzgetc(file)
gzFile file;
{
- int ret;
unsigned char buf[1];
gz_statep state;
/* get internal structure */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* try output buffer (no need to check for skip request) */
if (state->x.have) {
state->x.have--;
state->x.pos++;
return *(state->x.next)++;
}
/* nothing there -- try gz_read() */
- ret = gz_read(state, buf, 1);
- return ret < 1 ? -1 : buf[0];
+ return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
}
int ZEXPORT gzgetc_(file)
gzFile file;
{
return gzgetc(file);
}
/* -- see zlib.h -- */
int ZEXPORT gzungetc(c, file)
int c;
gzFile file;
{
gz_statep state;
/* get internal structure */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
return -1;
/* process a skip request */
if (state->seek) {
state->seek = 0;
if (gz_skip(state, state->skip) == -1)
return -1;
}
/* can't push EOF */
if (c < 0)
return -1;
/* if output buffer empty, put byte at end (allows more pushing) */
if (state->x.have == 0) {
state->x.have = 1;
state->x.next = state->out + (state->size << 1) - 1;
state->x.next[0] = (unsigned char)c;
state->x.pos--;
state->past = 0;
return c;
}
/* if no room, give up (must have already done a gzungetc()) */
if (state->x.have == (state->size << 1)) {
gz_error(state, Z_DATA_ERROR, "out of room to push characters");
return -1;
}
/* slide output data if needed and insert byte before existing data */
if (state->x.next == state->out) {
unsigned char *src = state->out + state->x.have;
unsigned char *dest = state->out + (state->size << 1);
while (src > state->out)
*--dest = *--src;
state->x.next = dest;
}
state->x.have++;
state->x.next--;
state->x.next[0] = (unsigned char)c;
state->x.pos--;
state->past = 0;
return c;
}
/* -- see zlib.h -- */
char * ZEXPORT gzgets(file, buf, len)
gzFile file;
char *buf;
int len;
{
unsigned left, n;
char *str;
unsigned char *eol;
gz_statep state;
/* check parameters and get internal structure */
if (file == NULL || buf == NULL || len < 1)
return NULL;
state = (gz_statep)file;
/* check that we're reading and that there's no (serious) error */
if (state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
return NULL;
/* process a skip request */
if (state->seek) {
state->seek = 0;
if (gz_skip(state, state->skip) == -1)
return NULL;
}
/* copy output bytes up to new line or len - 1, whichever comes first --
append a terminating zero to the string (we don't check for a zero in
the contents, let the user worry about that) */
str = buf;
left = (unsigned)len - 1;
if (left) do {
/* assure that something is in the output buffer */
if (state->x.have == 0 && gz_fetch(state) == -1)
return NULL; /* error */
if (state->x.have == 0) { /* end of file */
state->past = 1; /* read past end */
break; /* return what we have */
}
/* look for end-of-line in current output buffer */
n = state->x.have > left ? left : state->x.have;
eol = (unsigned char *)memchr(state->x.next, '\n', n);
if (eol != NULL)
n = (unsigned)(eol - state->x.next) + 1;
/* copy through end-of-line, or remainder if not found */
memcpy(buf, state->x.next, n);
state->x.have -= n;
state->x.next += n;
state->x.pos += n;
left -= n;
buf += n;
} while (left && eol == NULL);
/* return terminated string, or if nothing, end of file */
if (buf == str)
return NULL;
buf[0] = 0;
return str;
}
/* -- see zlib.h -- */
int ZEXPORT gzdirect(file)
gzFile file;
{
gz_statep state;
/* get internal structure */
if (file == NULL)
return 0;
state = (gz_statep)file;
/* if the state is not known, but we can find out, then do so (this is
mainly for right after a gzopen() or gzdopen()) */
if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
(void)gz_look(state);
/* return 1 if transparent, 0 if processing a gzip stream */
return state->direct;
}
/* -- see zlib.h -- */
int ZEXPORT gzclose_r(file)
gzFile file;
{
int ret, err;
gz_statep state;
/* get internal structure */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
/* check that we're reading */
if (state->mode != GZ_READ)
return Z_STREAM_ERROR;
/* free memory and close file */
if (state->size) {
inflateEnd(&(state->strm));
free(state->out);
free(state->in);
}
err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
gz_error(state, Z_OK, NULL);
free(state->path);
ret = close(state->fd);
free(state);
return ret ? Z_ERRNO : err;
}
-#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzwrite.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzwrite.c
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzwrite.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzwrite.c
index 3be0dd0c..a8ffc8f5 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/gzwrite.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/gzwrite.c
@@ -1,667 +1,677 @@
/* gzwrite.c -- zlib functions for writing gzip files
- * Copyright (C) 2004-2017 Mark Adler
+ * Copyright (C) 2004-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "gzguts.h"
-#ifndef __clang_analyzer__
/* Local functions */
local int gz_init OF((gz_statep));
local int gz_comp OF((gz_statep, int));
local int gz_zero OF((gz_statep, z_off64_t));
local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
/* Initialize state for writing a gzip file. Mark initialization by setting
state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
success. */
local int gz_init(state)
gz_statep state;
{
int ret;
z_streamp strm = &(state->strm);
/* allocate input buffer (double size for gzprintf) */
state->in = (unsigned char *)malloc(state->want << 1);
if (state->in == NULL) {
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
}
/* only need output buffer and deflate state if compressing */
if (!state->direct) {
/* allocate output buffer */
state->out = (unsigned char *)malloc(state->want);
if (state->out == NULL) {
free(state->in);
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
}
/* allocate deflate memory, set up for gzip compression */
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
ret = deflateInit2(strm, state->level, Z_DEFLATED,
MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
if (ret != Z_OK) {
free(state->out);
free(state->in);
gz_error(state, Z_MEM_ERROR, "out of memory");
return -1;
}
strm->next_in = NULL;
}
/* mark state as initialized */
state->size = state->want;
/* initialize write buffer if compressing */
if (!state->direct) {
strm->avail_out = state->size;
strm->next_out = state->out;
state->x.next = strm->next_out;
}
return 0;
}
/* Compress whatever is at avail_in and next_in and write to the output file.
Return -1 if there is an error writing to the output file or if gz_init()
fails to allocate memory, otherwise 0. flush is assumed to be a valid
deflate() flush value. If flush is Z_FINISH, then the deflate() state is
reset to start a new gzip stream. If gz->direct is true, then simply write
to the output file without compressing, and ignore flush. */
local int gz_comp(state, flush)
gz_statep state;
int flush;
{
int ret, writ;
unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
z_streamp strm = &(state->strm);
/* allocate memory if this is the first time through */
if (state->size == 0 && gz_init(state) == -1)
return -1;
/* write directly if requested */
if (state->direct) {
while (strm->avail_in) {
put = strm->avail_in > max ? max : strm->avail_in;
writ = write(state->fd, strm->next_in, put);
if (writ < 0) {
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
strm->avail_in -= (unsigned)writ;
strm->next_in += writ;
}
return 0;
}
+ /* check for a pending reset */
+ if (state->reset) {
+ /* don't start a new gzip member unless there is data to write */
+ if (strm->avail_in == 0)
+ return 0;
+ deflateReset(strm);
+ state->reset = 0;
+ }
+
/* run deflate() on provided input until it produces no more output */
ret = Z_OK;
do {
/* write out current buffer contents if full, or if flushing, but if
doing Z_FINISH then don't write until we get to Z_STREAM_END */
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
(flush != Z_FINISH || ret == Z_STREAM_END))) {
while (strm->next_out > state->x.next) {
put = strm->next_out - state->x.next > (int)max ? max :
(unsigned)(strm->next_out - state->x.next);
writ = write(state->fd, state->x.next, put);
if (writ < 0) {
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
state->x.next += writ;
}
if (strm->avail_out == 0) {
strm->avail_out = state->size;
strm->next_out = state->out;
state->x.next = state->out;
}
}
/* compress */
have = strm->avail_out;
ret = deflate(strm, flush);
if (ret == Z_STREAM_ERROR) {
gz_error(state, Z_STREAM_ERROR,
"internal error: deflate stream corrupt");
return -1;
}
have -= strm->avail_out;
} while (have);
/* if that completed a deflate stream, allow another to start */
if (flush == Z_FINISH)
- deflateReset(strm);
+ state->reset = 1;
/* all done, no errors */
return 0;
}
/* Compress len zeros to output. Return -1 on a write error or memory
allocation failure by gz_comp(), or 0 on success. */
local int gz_zero(state, len)
gz_statep state;
z_off64_t len;
{
int first;
unsigned n;
z_streamp strm = &(state->strm);
/* consume whatever's left in the input buffer */
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
return -1;
/* compress len zeros (len guaranteed > 0) */
first = 1;
while (len) {
n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
(unsigned)len : state->size;
if (first) {
memset(state->in, 0, n);
first = 0;
}
strm->avail_in = n;
strm->next_in = state->in;
state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return -1;
len -= n;
}
return 0;
}
/* Write len bytes from buf to file. Return the number of bytes written. If
the returned value is less than len, then there was an error. */
local z_size_t gz_write(state, buf, len)
gz_statep state;
voidpc buf;
z_size_t len;
{
z_size_t put = len;
/* if len is zero, avoid unnecessary operations */
if (len == 0)
return 0;
/* allocate memory if this is the first time through */
if (state->size == 0 && gz_init(state) == -1)
return 0;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return 0;
}
/* for small len, copy to input buffer, otherwise compress directly */
if (len < state->size) {
/* copy to input buffer, compress when full */
do {
unsigned have, copy;
if (state->strm.avail_in == 0)
state->strm.next_in = state->in;
have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
state->in);
copy = state->size - have;
if (copy > len)
- copy = len;
+ copy = (unsigned)len;
memcpy(state->in + have, buf, copy);
state->strm.avail_in += copy;
state->x.pos += copy;
buf = (const char *)buf + copy;
len -= copy;
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
} while (len);
}
else {
/* consume whatever's left in the input buffer */
if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
/* directly compress user buffer to file */
state->strm.next_in = (z_const Bytef *)buf;
do {
unsigned n = (unsigned)-1;
if (n > len)
- n = len;
+ n = (unsigned)len;
state->strm.avail_in = n;
state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
len -= n;
} while (len);
}
/* input was all buffered or compressed */
return put;
}
/* -- see zlib.h -- */
int ZEXPORT gzwrite(file, buf, len)
gzFile file;
voidpc buf;
unsigned len;
{
gz_statep state;
/* get internal structure */
if (file == NULL)
return 0;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return 0;
/* since an int is returned, make sure len fits in one, otherwise return
with an error (this avoids a flaw in the interface) */
if ((int)len < 0) {
gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
return 0;
}
/* write len bytes from buf (the return value will fit in an int) */
return (int)gz_write(state, buf, len);
}
/* -- see zlib.h -- */
z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
voidpc buf;
z_size_t size;
z_size_t nitems;
gzFile file;
{
z_size_t len;
gz_statep state;
/* get internal structure */
if (file == NULL)
return 0;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return 0;
/* compute bytes to read -- error on overflow */
len = nitems * size;
if (size && len / size != nitems) {
gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
return 0;
}
/* write len bytes to buf, return the number of full items written */
return len ? gz_write(state, buf, len) / size : 0;
}
/* -- see zlib.h -- */
int ZEXPORT gzputc(file, c)
gzFile file;
int c;
{
unsigned have;
unsigned char buf[1];
gz_statep state;
z_streamp strm;
/* get internal structure */
if (file == NULL)
return -1;
state = (gz_statep)file;
strm = &(state->strm);
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return -1;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return -1;
}
/* try writing to input buffer for speed (state->size == 0 if buffer not
initialized) */
if (state->size) {
if (strm->avail_in == 0)
strm->next_in = state->in;
have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
if (have < state->size) {
state->in[have] = (unsigned char)c;
strm->avail_in++;
state->x.pos++;
return c & 0xff;
}
}
/* no room in buffer or not initialized, use gz_write() */
buf[0] = (unsigned char)c;
if (gz_write(state, buf, 1) != 1)
return -1;
return c & 0xff;
}
/* -- see zlib.h -- */
-int ZEXPORT gzputs(file, str)
+int ZEXPORT gzputs(file, s)
gzFile file;
- const char *str;
+ const char *s;
{
- int ret;
- z_size_t len;
+ z_size_t len, put;
gz_statep state;
/* get internal structure */
if (file == NULL)
return -1;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return -1;
/* write string */
- len = strlen(str);
- ret = gz_write(state, str, len);
- return ret == 0 && len != 0 ? -1 : ret;
+ len = strlen(s);
+ if ((int)len < 0 || (unsigned)len != len) {
+ gz_error(state, Z_STREAM_ERROR, "string length does not fit in int");
+ return -1;
+ }
+ put = gz_write(state, s, len);
+ return put < len ? -1 : (int)len;
}
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
#include <stdarg.h>
/* -- see zlib.h -- */
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
{
int len;
unsigned left;
char *next;
gz_statep state;
z_streamp strm;
/* get internal structure */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
strm = &(state->strm);
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return Z_STREAM_ERROR;
/* make sure we have some buffer space */
if (state->size == 0 && gz_init(state) == -1)
return state->err;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->err;
}
/* do the printf() into the input buffer, put length in len -- the input
buffer is double-sized just for this function, so there is guaranteed to
be state->size bytes available after the current contents */
if (strm->avail_in == 0)
strm->next_in = state->in;
next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
next[state->size - 1] = 0;
#ifdef NO_vsnprintf
# ifdef HAS_vsprintf_void
(void)vsprintf(next, format, va);
for (len = 0; len < state->size; len++)
if (next[len] == 0) break;
# else
len = vsprintf(next, format, va);
# endif
#else
# ifdef HAS_vsnprintf_void
(void)vsnprintf(next, state->size, format, va);
len = strlen(next);
# else
len = vsnprintf(next, state->size, format, va);
# endif
#endif
/* check that printf() results fit in buffer */
if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
return 0;
/* update buffer and position, compress first half if past that */
strm->avail_in += (unsigned)len;
state->x.pos += len;
if (strm->avail_in >= state->size) {
left = strm->avail_in - state->size;
strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err;
- memcpy(state->in, state->in + state->size, left);
+ memmove(state->in, state->in + state->size, left);
strm->next_in = state->in;
strm->avail_in = left;
}
return len;
}
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
{
va_list va;
int ret;
va_start(va, format);
ret = gzvprintf(file, format, va);
va_end(va);
return ret;
}
#else /* !STDC && !Z_HAVE_STDARG_H */
/* -- see zlib.h -- */
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
gzFile file;
const char *format;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
{
unsigned len, left;
char *next;
gz_statep state;
z_streamp strm;
/* get internal structure */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
strm = &(state->strm);
/* check that can really pass pointer in ints */
if (sizeof(int) != sizeof(void *))
return Z_STREAM_ERROR;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return Z_STREAM_ERROR;
/* make sure we have some buffer space */
if (state->size == 0 && gz_init(state) == -1)
return state->error;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->error;
}
/* do the printf() into the input buffer, put length in len -- the input
buffer is double-sized just for this function, so there is guaranteed to
be state->size bytes available after the current contents */
if (strm->avail_in == 0)
strm->next_in = state->in;
next = (char *)(strm->next_in + strm->avail_in);
next[state->size - 1] = 0;
#ifdef NO_snprintf
# ifdef HAS_sprintf_void
sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
a13, a14, a15, a16, a17, a18, a19, a20);
for (len = 0; len < size; len++)
if (next[len] == 0)
break;
# else
len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#else
# ifdef HAS_snprintf_void
snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
len = strlen(next);
# else
len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#endif
/* check that printf() results fit in buffer */
if (len == 0 || len >= state->size || next[state->size - 1] != 0)
return 0;
/* update buffer and position, compress first half if past that */
strm->avail_in += len;
state->x.pos += len;
if (strm->avail_in >= state->size) {
left = strm->avail_in - state->size;
strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err;
- memcpy(state->in, state->in + state->size, left);
+ memmove(state->in, state->in + state->size, left);
strm->next_in = state->in;
strm->avail_in = left;
}
return (int)len;
}
#endif
/* -- see zlib.h -- */
int ZEXPORT gzflush(file, flush)
gzFile file;
int flush;
{
gz_statep state;
/* get internal structure */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return Z_STREAM_ERROR;
/* check flush parameter */
if (flush < 0 || flush > Z_FINISH)
return Z_STREAM_ERROR;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->err;
}
/* compress remaining data with requested flush */
(void)gz_comp(state, flush);
return state->err;
}
/* -- see zlib.h -- */
int ZEXPORT gzsetparams(file, level, strategy)
gzFile file;
int level;
int strategy;
{
gz_statep state;
z_streamp strm;
/* get internal structure */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
strm = &(state->strm);
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return Z_STREAM_ERROR;
/* if no change is requested, then do nothing */
if (level == state->level && strategy == state->strategy)
return Z_OK;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->err;
}
/* change compression parameters for subsequent input */
if (state->size) {
/* flush previous input with previous parameters before changing */
if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
return state->err;
deflateParams(strm, level, strategy);
}
state->level = level;
state->strategy = strategy;
return Z_OK;
}
/* -- see zlib.h -- */
int ZEXPORT gzclose_w(file)
gzFile file;
{
int ret = Z_OK;
gz_statep state;
/* get internal structure */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
/* check that we're writing */
if (state->mode != GZ_WRITE)
return Z_STREAM_ERROR;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
ret = state->err;
}
/* flush, free memory, and close file */
if (gz_comp(state, Z_FINISH) == -1)
ret = state->err;
if (state->size) {
if (!state->direct) {
(void)deflateEnd(&(state->strm));
free(state->out);
}
free(state->in);
}
gz_error(state, Z_OK, NULL);
free(state->path);
if (close(state->fd) == -1)
ret = Z_ERRNO;
free(state);
return ret;
}
-#endif
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/infback.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/infback.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/infback.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/infback.c
index 59679ecb..a390c58e 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/infback.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/infback.c
@@ -1,640 +1,641 @@
/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2016 Mark Adler
+ * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
This code is largely copied from inflate.c. Normally either infback.o or
inflate.o would be linked into an application--not both. The interface
with inffast.c is retained so that optimized assembler-coded versions of
inflate_fast() can be used with either inflate.c or infback.c.
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
/* function prototypes */
local void fixedtables OF((struct inflate_state FAR *state));
/*
strm provides memory allocation functions in zalloc and zfree, or
Z_NULL to use the library memory allocation functions.
windowBits is in the range 8..15, and window is a user-supplied
window and output buffer that is 2**windowBits bytes.
*/
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
z_streamp strm;
int windowBits;
unsigned char FAR *window;
const char *version;
int stream_size;
{
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != (int)(sizeof(z_stream)))
return Z_VERSION_ERROR;
if (strm == Z_NULL || window == Z_NULL ||
windowBits < 8 || windowBits > 15)
return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
#ifdef Z_SOLO
return Z_STREAM_ERROR;
#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
#endif
}
if (strm->zfree == (free_func)0)
#ifdef Z_SOLO
return Z_STREAM_ERROR;
#else
strm->zfree = zcfree;
#endif
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
state->dmax = 32768U;
state->wbits = (uInt)windowBits;
state->wsize = 1U << windowBits;
state->window = window;
state->wnext = 0;
state->whave = 0;
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(state)
struct inflate_state FAR *state;
{
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
/* Macros for inflateBack(): */
/* Load returned state from inflate_fast() */
#define LOAD() \
do { \
put = strm->next_out; \
left = strm->avail_out; \
next = strm->next_in; \
have = strm->avail_in; \
hold = state->hold; \
bits = state->bits; \
} while (0)
/* Set state from registers for inflate_fast() */
#define RESTORE() \
do { \
strm->next_out = put; \
strm->avail_out = left; \
strm->next_in = next; \
strm->avail_in = have; \
state->hold = hold; \
state->bits = bits; \
} while (0)
/* Clear the input bit accumulator */
#define INITBITS() \
do { \
hold = 0; \
bits = 0; \
} while (0)
/* Assure that some input is available. If input is requested, but denied,
then return a Z_BUF_ERROR from inflateBack(). */
#define PULL() \
do { \
if (have == 0) { \
have = in(in_desc, &next); \
if (have == 0) { \
next = Z_NULL; \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/* Get a byte of input into the bit accumulator, or return from inflateBack()
with an error if there is no input available. */
#define PULLBYTE() \
do { \
PULL(); \
have--; \
hold += (unsigned long)(*next++) << bits; \
bits += 8; \
} while (0)
/* Assure that there are at least n bits in the bit accumulator. If there is
not enough available input to do that, then return from inflateBack() with
an error. */
#define NEEDBITS(n) \
do { \
while (bits < (unsigned)(n)) \
PULLBYTE(); \
} while (0)
/* Return the low n bits of the bit accumulator (n < 16) */
#define BITS(n) \
((unsigned)hold & ((1U << (n)) - 1))
/* Remove n bits from the bit accumulator */
#define DROPBITS(n) \
do { \
hold >>= (n); \
bits -= (unsigned)(n); \
} while (0)
/* Remove zero to seven bits as needed to go to a byte boundary */
#define BYTEBITS() \
do { \
hold >>= bits & 7; \
bits -= bits & 7; \
} while (0)
/* Assure that some output space is available, by writing out the window
if it's full. If the write fails, return from inflateBack() with a
Z_BUF_ERROR. */
#define ROOM() \
do { \
if (left == 0) { \
put = state->window; \
left = state->wsize; \
state->whave = left; \
if (out(out_desc, put, left)) { \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/*
strm provides the memory allocation functions and window buffer on input,
and provides information on the unused input on return. For Z_DATA_ERROR
returns, strm will also provide an error message.
in() and out() are the call-back input and output functions. When
inflateBack() needs more input, it calls in(). When inflateBack() has
filled the window with output, or when it completes with data in the
window, it calls out() to write out the data. The application must not
change the provided input until in() is called again or inflateBack()
returns. The application must not change the window/output buffer until
inflateBack() returns.
in() and out() are called with a descriptor parameter provided in the
inflateBack() call. This parameter can be a structure that provides the
information required to do the read or write, as well as accumulated
information on the input and output such as totals and check values.
in() should return zero on failure. out() should return non-zero on
failure. If either in() or out() fails, than inflateBack() returns a
Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
was in() or out() that caused in the error. Otherwise, inflateBack()
returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
error, or Z_MEM_ERROR if it could not allocate memory for the state.
inflateBack() can also return Z_STREAM_ERROR if the input parameters
are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
z_streamp strm;
in_func in;
void FAR *in_desc;
out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
code here; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* Check that the strm exists and that the state was initialized */
if (strm == Z_NULL || strm->state == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* Reset the state */
strm->msg = Z_NULL;
state->mode = TYPE;
state->last = 0;
state->whave = 0;
next = strm->next_in;
have = next != Z_NULL ? strm->avail_in : 0;
hold = 0;
bits = 0;
put = state->window;
left = state->wsize;
/* Inflate until end of block marked as last */
for (;;)
switch (state->mode) {
case TYPE:
/* determine and dispatch block type */
if (state->last) {
BYTEBITS();
state->mode = DONE;
break;
}
NEEDBITS(3);
state->last = BITS(1);
DROPBITS(1);
switch (BITS(2)) {
case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n",
state->last ? " (last)" : ""));
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN; /* decode codes */
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
break;
case STORED:
/* get and verify stored block length */
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
/* copy stored block from input to output */
while (state->length != 0) {
copy = state->length;
PULL();
ROOM();
if (copy > have) copy = have;
if (copy > left) copy = left;
zmemcpy(put, next, copy);
have -= copy;
next += copy;
left -= copy;
put += copy;
state->length -= copy;
}
Tracev((stderr, "inflate: stored end\n"));
state->mode = TYPE;
break;
case TABLE:
/* get dynamic table entries descriptor */
NEEDBITS(14);
state->nlen = BITS(5) + 257;
DROPBITS(5);
state->ndist = BITS(5) + 1;
DROPBITS(5);
state->ncode = BITS(4) + 4;
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
state->mode = BAD;
break;
}
#endif
Tracev((stderr, "inflate: table sizes ok\n"));
/* get code length code lengths (not a typo) */
state->have = 0;
while (state->have < state->ncode) {
NEEDBITS(3);
state->lens[order[state->have++]] = (unsigned short)BITS(3);
DROPBITS(3);
}
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: code lengths ok\n"));
/* get length and distance code code lengths */
state->have = 0;
while (state->have < state->nlen + state->ndist) {
for (;;) {
here = state->lencode[BITS(state->lenbits)];
if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
if (here.val < 16) {
DROPBITS(here.bits);
state->lens[state->have++] = here.val;
}
else {
if (here.val == 16) {
NEEDBITS(here.bits + 2);
DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
len = (unsigned)(state->lens[state->have - 1]);
copy = 3 + BITS(2);
DROPBITS(2);
}
else if (here.val == 17) {
NEEDBITS(here.bits + 3);
DROPBITS(here.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
NEEDBITS(here.bits + 7);
DROPBITS(here.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
while (copy--)
state->lens[state->have++] = (unsigned short)len;
}
}
/* handle error breaks in while */
if (state->mode == BAD) break;
/* check for end-of-block code (better have one) */
if (state->lens[256] == 0) {
strm->msg = (char *)"invalid code -- missing end-of-block";
state->mode = BAD;
break;
}
/* build code tables -- note: do not change the lenbits or distbits
values here (9 and 6) without reading the comments in inftrees.h
concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
state->distcode = (code const FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN;
+ /* fallthrough */
case LEN:
/* use inflate_fast() if we have enough input and output */
if (have >= 6 && left >= 258) {
RESTORE();
if (state->whave < state->wsize)
state->whave = state->wsize - left;
inflate_fast(strm, state->wsize);
LOAD();
break;
}
/* get a literal, length, or end-of-block code */
for (;;) {
here = state->lencode[BITS(state->lenbits)];
if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
if (here.op && (here.op & 0xf0) == 0) {
last = here;
for (;;) {
here = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(here.bits);
state->length = (unsigned)here.val;
/* process literal */
if (here.op == 0) {
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", here.val));
ROOM();
*put++ = (unsigned char)(state->length);
left--;
state->mode = LEN;
break;
}
/* process end of block */
if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
/* invalid code */
if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
/* length code -- get extra bits, if any */
state->extra = (unsigned)(here.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
}
Tracevv((stderr, "inflate: length %u\n", state->length));
/* get distance code */
for (;;) {
here = state->distcode[BITS(state->distbits)];
if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
if ((here.op & 0xf0) == 0) {
last = here;
for (;;) {
here = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(here.bits);
if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
state->offset = (unsigned)here.val;
/* get distance extra bits, if any */
state->extra = (unsigned)(here.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
}
if (state->offset > state->wsize - (state->whave < state->wsize ?
left : 0)) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
Tracevv((stderr, "inflate: distance %u\n", state->offset));
/* copy match from window to output */
do {
ROOM();
copy = state->wsize - state->offset;
if (copy < left) {
from = put + copy;
copy = left - copy;
}
else {
from = put - state->offset;
copy = left;
}
if (copy > state->length) copy = state->length;
state->length -= copy;
left -= copy;
do {
*put++ = *from++;
} while (--copy);
} while (state->length != 0);
break;
case DONE:
/* inflate stream terminated properly -- write leftover output */
ret = Z_STREAM_END;
if (left < state->wsize) {
if (out(out_desc, state->window, state->wsize - left))
ret = Z_BUF_ERROR;
}
goto inf_leave;
case BAD:
ret = Z_DATA_ERROR;
goto inf_leave;
default: /* can't happen, but makes compilers happy */
ret = Z_STREAM_ERROR;
goto inf_leave;
}
/* Return unused input */
inf_leave:
strm->next_in = next;
strm->avail_in = have;
return ret;
}
int ZEXPORT inflateBackEnd(strm)
z_streamp strm;
{
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
ZFREE(strm, strm->state);
strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inffast.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inffast.c
similarity index 94%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inffast.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inffast.c
index 0dbd1dbc..1fec7f36 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inffast.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inffast.c
@@ -1,323 +1,323 @@
/* inffast.c -- fast decoding
* Copyright (C) 1995-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
#ifdef ASMINF
# pragma message("Assembler code may have bugs -- use at your own risk")
#else
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
Entry assumptions:
state->mode == LEN
strm->avail_in >= 6
strm->avail_out >= 258
start >= strm->avail_out
state->bits < 8
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void ZLIB_INTERNAL inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
z_const unsigned char FAR *in; /* local strm->next_in */
z_const unsigned char FAR *last; /* have enough input while in < last */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
#ifdef INFLATE_STRICT
unsigned dmax; /* maximum distance from zlib header */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
- code here; /* retrieved table entry */
+ code const *here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
unsigned dist; /* match distance */
unsigned char FAR *from; /* where to copy match from */
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
in = strm->next_in;
last = in + (strm->avail_in - 5);
out = strm->next_out;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize;
whave = state->whave;
wnext = state->wnext;
window = state->window;
hold = state->hold;
bits = state->bits;
lcode = state->lencode;
dcode = state->distcode;
lmask = (1U << state->lenbits) - 1;
dmask = (1U << state->distbits) - 1;
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
if (bits < 15) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
- here = lcode[hold & lmask];
+ here = lcode + (hold & lmask);
dolen:
- op = (unsigned)(here.bits);
+ op = (unsigned)(here->bits);
hold >>= op;
bits -= op;
- op = (unsigned)(here.op);
+ op = (unsigned)(here->op);
if (op == 0) { /* literal */
- Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", here.val));
- *out++ = (unsigned char)(here.val);
+ "inflate: literal 0x%02x\n", here->val));
+ *out++ = (unsigned char)(here->val);
}
else if (op & 16) { /* length base */
- len = (unsigned)(here.val);
+ len = (unsigned)(here->val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
- here = dcode[hold & dmask];
+ here = dcode + (hold & dmask);
dodist:
- op = (unsigned)(here.bits);
+ op = (unsigned)(here->bits);
hold >>= op;
bits -= op;
- op = (unsigned)(here.op);
+ op = (unsigned)(here->op);
if (op & 16) { /* distance base */
- dist = (unsigned)(here.val);
+ dist = (unsigned)(here->val);
op &= 15; /* number of extra bits */
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
}
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
op = (unsigned)(out - beg); /* max distance in output */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
if (state->sane) {
strm->msg =
(char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (len <= op - whave) {
do {
*out++ = 0;
} while (--len);
continue;
}
len -= op - whave;
do {
*out++ = 0;
} while (--op > whave);
if (op == 0) {
from = out - dist;
do {
*out++ = *from++;
} while (--len);
continue;
}
#endif
}
from = window;
if (wnext == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
else if (wnext < op) { /* wrap around window */
from += wsize + wnext - op;
op -= wnext;
if (op < len) { /* some from end of window */
len -= op;
do {
*out++ = *from++;
} while (--op);
from = window;
if (wnext < len) { /* some from start of window */
op = wnext;
len -= op;
do {
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
from += wnext - op;
if (op < len) { /* some from window */
len -= op;
do {
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
*out++ = *from++;
*out++ = *from++;
*out++ = *from++;
len -= 3;
}
if (len) {
*out++ = *from++;
if (len > 1)
*out++ = *from++;
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
*out++ = *from++;
*out++ = *from++;
*out++ = *from++;
len -= 3;
} while (len > 2);
if (len) {
*out++ = *from++;
if (len > 1)
*out++ = *from++;
}
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
- here = dcode[here.val + (hold & ((1U << op) - 1))];
+ here = dcode + here->val + (hold & ((1U << op) - 1));
goto dodist;
}
else {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
- here = lcode[here.val + (hold & ((1U << op) - 1))];
+ here = lcode + here->val + (hold & ((1U << op) - 1));
goto dolen;
}
else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
else {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
} while (in < last && out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
/* update state and return */
strm->next_in = in;
strm->next_out = out;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
state->hold = hold;
state->bits = bits;
return;
}
/*
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and wnext == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
- Swapping literal/length else
- Swapping window/direct else
- Larger unrolled copy loops (three is about right)
- Moving len -= 3 statement into middle of loop
*/
#endif /* !ASMINF */
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inffast.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inffast.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inffast.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inffast.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inffixed.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inffixed.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inffixed.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inffixed.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inflate.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inflate.c
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inflate.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inflate.c
index ac333e8c..7be8c636 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inflate.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inflate.c
@@ -1,1561 +1,1592 @@
/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2016 Mark Adler
+ * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
* Change history:
*
* 1.2.beta0 24 Nov 2002
* - First version -- complete rewrite of inflate to simplify code, avoid
* creation of window when not needed, minimize use of window when it is
* needed, make inffast.c even faster, implement gzip decoding, and to
* improve code readability and style over the previous zlib inflate code
*
* 1.2.beta1 25 Nov 2002
* - Use pointers for available input and output checking in inffast.c
* - Remove input and output counters in inffast.c
* - Change inffast.c entry and loop from avail_in >= 7 to >= 6
* - Remove unnecessary second byte pull from length extra in inffast.c
* - Unroll direct copy to three copies per loop in inffast.c
*
* 1.2.beta2 4 Dec 2002
* - Change external routine names to reduce potential conflicts
* - Correct filename to inffixed.h for fixed tables in inflate.c
* - Make hbuf[] unsigned char to match parameter type in inflate.c
* - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
* to avoid negation problem on Alphas (64 bit) in inflate.c
*
* 1.2.beta3 22 Dec 2002
* - Add comments on state->bits assertion in inffast.c
* - Add comments on op field in inftrees.h
* - Fix bug in reuse of allocated window after inflateReset()
* - Remove bit fields--back to byte structure for speed
* - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
* - Change post-increments to pre-increments in inflate_fast(), PPC biased?
* - Add compile time option, POSTINC, to use post-increments instead (Intel?)
* - Make MATCH copy in inflate() much faster for when inflate_fast() not used
* - Use local copies of stream next and avail values, as well as local bit
* buffer and bit count in inflate()--for speed when inflate_fast() not used
*
* 1.2.beta4 1 Jan 2003
* - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
* - Move a comment on output buffer sizes from inffast.c to inflate.c
* - Add comments in inffast.c to introduce the inflate_fast() routine
* - Rearrange window copies in inflate_fast() for speed and simplification
* - Unroll last copy for window match in inflate_fast()
* - Use local copies of window variables in inflate_fast() for speed
* - Pull out common wnext == 0 case for speed in inflate_fast()
* - Make op and len in inflate_fast() unsigned for consistency
* - Add FAR to lcode and dcode declarations in inflate_fast()
* - Simplified bad distance check in inflate_fast()
* - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
* source file infback.c to provide a call-back interface to inflate for
* programs like gzip and unzip -- uses window as output buffer to avoid
* window copying
*
* 1.2.beta5 1 Jan 2003
* - Improved inflateBack() interface to allow the caller to provide initial
* input in strm.
* - Fixed stored blocks bug in inflateBack()
*
* 1.2.beta6 4 Jan 2003
* - Added comments in inffast.c on effectiveness of POSTINC
* - Typecasting all around to reduce compiler warnings
* - Changed loops from while (1) or do {} while (1) to for (;;), again to
* make compilers happy
* - Changed type of window in inflateBackInit() to unsigned char *
*
* 1.2.beta7 27 Jan 2003
* - Changed many types to unsigned or unsigned short to avoid warnings
* - Added inflateCopy() function
*
* 1.2.0 9 Mar 2003
* - Changed inflateBack() interface to provide separate opaque descriptors
* for the in() and out() functions
* - Changed inflateBack() argument and in_func typedef to swap the length
* and buffer address return values for the input function
* - Check next_in and next_out for Z_NULL on entry to inflate()
*
* The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
#ifdef MAKEFIXED
# ifndef BUILDFIXED
# define BUILDFIXED
# endif
#endif
/* function prototypes */
local int inflateStateCheck OF((z_streamp strm));
local void fixedtables OF((struct inflate_state FAR *state));
local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
unsigned copy));
#ifdef BUILDFIXED
void makefixed OF((void));
#endif
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
unsigned len));
local int inflateStateCheck(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
if (strm == Z_NULL ||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
return 1;
state = (struct inflate_state FAR *)strm->state;
if (state == Z_NULL || state->strm != strm ||
state->mode < HEAD || state->mode > SYNC)
return 1;
return 0;
}
int ZEXPORT inflateResetKeep(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
strm->total_in = strm->total_out = state->total = 0;
strm->msg = Z_NULL;
if (state->wrap) /* to support ill-conceived Java test suite */
strm->adler = state->wrap & 1;
state->mode = HEAD;
state->last = 0;
state->havedict = 0;
+ state->flags = -1;
state->dmax = 32768U;
state->head = Z_NULL;
state->hold = 0;
state->bits = 0;
state->lencode = state->distcode = state->next = state->codes;
state->sane = 1;
state->back = -1;
Tracev((stderr, "inflate: reset\n"));
return Z_OK;
}
int ZEXPORT inflateReset(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
state->wsize = 0;
state->whave = 0;
state->wnext = 0;
return inflateResetKeep(strm);
}
int ZEXPORT inflateReset2(strm, windowBits)
z_streamp strm;
int windowBits;
{
int wrap;
struct inflate_state FAR *state;
/* get the state */
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* extract wrap request from windowBits parameter */
if (windowBits < 0) {
wrap = 0;
windowBits = -windowBits;
}
else {
wrap = (windowBits >> 4) + 5;
#ifdef GUNZIP
if (windowBits < 48)
windowBits &= 15;
#endif
}
/* set number of window bits, free window if different */
if (windowBits && (windowBits < 8 || windowBits > 15))
return Z_STREAM_ERROR;
if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
ZFREE(strm, state->window);
state->window = Z_NULL;
}
/* update state and reset the rest of it */
state->wrap = wrap;
state->wbits = (unsigned)windowBits;
return inflateReset(strm);
}
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
z_streamp strm;
int windowBits;
const char *version;
int stream_size;
{
int ret;
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != (int)(sizeof(z_stream)))
return Z_VERSION_ERROR;
if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
#ifdef Z_SOLO
return Z_STREAM_ERROR;
#else
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
#endif
}
if (strm->zfree == (free_func)0)
#ifdef Z_SOLO
return Z_STREAM_ERROR;
#else
strm->zfree = zcfree;
#endif
state = (struct inflate_state FAR *)
ZALLOC(strm, 1, sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
state->strm = strm;
state->window = Z_NULL;
state->mode = HEAD; /* to pass state test in inflateReset2() */
ret = inflateReset2(strm, windowBits);
if (ret != Z_OK) {
ZFREE(strm, state);
strm->state = Z_NULL;
}
return ret;
}
int ZEXPORT inflateInit_(strm, version, stream_size)
z_streamp strm;
const char *version;
int stream_size;
{
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
}
int ZEXPORT inflatePrime(strm, bits, value)
z_streamp strm;
int bits;
int value;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (bits < 0) {
state->hold = 0;
state->bits = 0;
return Z_OK;
}
if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
value &= (1L << bits) - 1;
state->hold += (unsigned)value << state->bits;
state->bits += (uInt)bits;
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(state)
struct inflate_state FAR *state;
{
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
#ifdef MAKEFIXED
#include <stdio.h>
/*
Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
those tables to stdout, which would be piped to inffixed.h. A small program
can simply call makefixed to do this:
void makefixed(void);
int main(void)
{
makefixed();
return 0;
}
Then that can be linked with zlib built with MAKEFIXED defined and run:
a.out > inffixed.h
*/
void makefixed()
{
unsigned low, size;
struct inflate_state state;
fixedtables(&state);
puts(" /* inffixed.h -- table for decoding fixed codes");
puts(" * Generated automatically by makefixed().");
puts(" */");
puts("");
puts(" /* WARNING: this file should *not* be used by applications.");
puts(" It is part of the implementation of this library and is");
puts(" subject to change. Applications should only use zlib.h.");
puts(" */");
puts("");
size = 1U << 9;
printf(" static const code lenfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 7) == 0) printf("\n ");
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
state.lencode[low].bits, state.lencode[low].val);
if (++low == size) break;
putchar(',');
}
puts("\n };");
size = 1U << 5;
printf("\n static const code distfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 6) == 0) printf("\n ");
printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
state.distcode[low].val);
if (++low == size) break;
putchar(',');
}
puts("\n };");
}
#endif /* MAKEFIXED */
/*
Update the window with the last wsize (normally 32K) bytes written before
returning. If window does not exist yet, create it. This is only called
when a window is already in use, or when output has been written during this
inflate call, but the end of the deflate stream has not been reached yet.
It is also called to create a window for dictionary data when a dictionary
is loaded.
Providing output buffers larger than 32K to inflate() should provide a speed
advantage, since only the last 32K of output is copied to the sliding window
upon return from inflate(), and since all distances after the first 32K of
output will fall in the output data, making match copies simpler and faster.
The advantage may be dependent on the size of the processor's data caches.
*/
local int updatewindow(strm, end, copy)
z_streamp strm;
const Bytef *end;
unsigned copy;
{
struct inflate_state FAR *state;
unsigned dist;
state = (struct inflate_state FAR *)strm->state;
/* if it hasn't been done already, allocate space for the window */
if (state->window == Z_NULL) {
state->window = (unsigned char FAR *)
ZALLOC(strm, 1U << state->wbits,
sizeof(unsigned char));
if (state->window == Z_NULL) return 1;
}
/* if window not in use yet, initialize */
if (state->wsize == 0) {
state->wsize = 1U << state->wbits;
state->wnext = 0;
state->whave = 0;
}
/* copy state->wsize or less output bytes into the circular window */
if (copy >= state->wsize) {
zmemcpy(state->window, end - state->wsize, state->wsize);
state->wnext = 0;
state->whave = state->wsize;
}
else {
dist = state->wsize - state->wnext;
if (dist > copy) dist = copy;
zmemcpy(state->window + state->wnext, end - copy, dist);
copy -= dist;
if (copy) {
zmemcpy(state->window, end - copy, copy);
state->wnext = copy;
state->whave = state->wsize;
}
else {
state->wnext += dist;
if (state->wnext == state->wsize) state->wnext = 0;
if (state->whave < state->wsize) state->whave += dist;
}
}
return 0;
}
/* Macros for inflate(): */
/* check function to use adler32() for zlib or crc32() for gzip */
#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
+# define UPDATE_CHECK(check, buf, len) \
(state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
#else
-# define UPDATE(check, buf, len) adler32(check, buf, len)
+# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
#endif
/* check macros for header crc */
#ifdef GUNZIP
# define CRC2(check, word) \
do { \
hbuf[0] = (unsigned char)(word); \
hbuf[1] = (unsigned char)((word) >> 8); \
check = crc32(check, hbuf, 2); \
} while (0)
# define CRC4(check, word) \
do { \
hbuf[0] = (unsigned char)(word); \
hbuf[1] = (unsigned char)((word) >> 8); \
hbuf[2] = (unsigned char)((word) >> 16); \
hbuf[3] = (unsigned char)((word) >> 24); \
check = crc32(check, hbuf, 4); \
} while (0)
#endif
/* Load registers with state in inflate() for speed */
#define LOAD() \
do { \
put = strm->next_out; \
left = strm->avail_out; \
next = strm->next_in; \
have = strm->avail_in; \
hold = state->hold; \
bits = state->bits; \
} while (0)
/* Restore state from registers in inflate() */
#define RESTORE() \
do { \
strm->next_out = put; \
strm->avail_out = left; \
strm->next_in = next; \
strm->avail_in = have; \
state->hold = hold; \
state->bits = bits; \
} while (0)
/* Clear the input bit accumulator */
#define INITBITS() \
do { \
hold = 0; \
bits = 0; \
} while (0)
/* Get a byte of input into the bit accumulator, or return from inflate()
if there is no input available. */
#define PULLBYTE() \
do { \
if (have == 0) goto inf_leave; \
have--; \
hold += (unsigned long)(*next++) << bits; \
bits += 8; \
} while (0)
/* Assure that there are at least n bits in the bit accumulator. If there is
not enough available input to do that, then return from inflate(). */
#define NEEDBITS(n) \
do { \
while (bits < (unsigned)(n)) \
PULLBYTE(); \
} while (0)
/* Return the low n bits of the bit accumulator (n < 16) */
#define BITS(n) \
((unsigned)hold & ((1U << (n)) - 1))
/* Remove n bits from the bit accumulator */
#define DROPBITS(n) \
do { \
hold >>= (n); \
bits -= (unsigned)(n); \
} while (0)
/* Remove zero to seven bits as needed to go to a byte boundary */
#define BYTEBITS() \
do { \
hold >>= bits & 7; \
bits -= bits & 7; \
} while (0)
/*
inflate() uses a state machine to process as much input data and generate as
much output data as possible before returning. The state machine is
structured roughly as follows:
for (;;) switch (state) {
...
case STATEn:
if (not enough input data or output space to make progress)
return;
... make progress ...
state = STATEm;
break;
...
}
so when inflate() is called again, the same case is attempted again, and
if the appropriate resources are provided, the machine proceeds to the
next state. The NEEDBITS() macro is usually the way the state evaluates
whether it can proceed or should return. NEEDBITS() does the return if
the requested bits are not available. The typical use of the BITS macros
is:
NEEDBITS(n);
... do something with BITS(n) ...
DROPBITS(n);
where NEEDBITS(n) either returns from inflate() if there isn't enough
input left to load n bits into the accumulator, or it continues. BITS(n)
gives the low n bits in the accumulator. When done, DROPBITS(n) drops
the low n bits off the accumulator. INITBITS() clears the accumulator
and sets the number of available bits to zero. BYTEBITS() discards just
enough bits to put the accumulator on a byte boundary. After BYTEBITS()
and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
if there is no input available. The decoding of variable length codes uses
PULLBYTE() directly in order to pull just enough bytes to decode the next
code, and no more.
Some states loop until they get enough input, making sure that enough
state information is maintained to continue the loop where it left off
if NEEDBITS() returns in the loop. For example, want, need, and keep
would all have to actually be part of the saved state in case NEEDBITS()
returns:
case STATEw:
while (want < need) {
NEEDBITS(n);
keep[want++] = BITS(n);
DROPBITS(n);
}
state = STATEx;
case STATEx:
As shown above, if the next state is also the next case, then the break
is omitted.
A state may also return if there is not enough output space available to
complete that state. Those states are copying stored data, writing a
literal byte, and copying a matching string.
When returning, a "goto inf_leave" is used to update the total counters,
update the check value, and determine whether any progress has been made
during that inflate() call in order to return the proper return code.
Progress is defined as a change in either strm->avail_in or strm->avail_out.
When there is a window, goto inf_leave will update the window with the last
output written. If a goto inf_leave occurs in the middle of decompression
and there is no window currently, goto inf_leave will create one and copy
output to the window for the next call of inflate().
In this implementation, the flush parameter of inflate() only affects the
return code (per zlib.h). inflate() always writes as much as possible to
strm->next_out, given the space available and the provided input--the effect
documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
the allocation of and copying into a sliding window until necessary, which
provides the effect documented in zlib.h for Z_FINISH when the entire input
stream available. So the only thing the flush parameter actually does is:
when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
will return Z_BUF_ERROR if it has not reached the end of the stream.
*/
int ZEXPORT inflate(strm, flush)
z_streamp strm;
int flush;
{
struct inflate_state FAR *state;
z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
unsigned in, out; /* save starting available input and output */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
code here; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
#ifdef GUNZIP
unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
#endif
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
(strm->next_in == Z_NULL && strm->avail_in != 0))
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
LOAD();
in = have;
out = left;
ret = Z_OK;
for (;;)
switch (state->mode) {
case HEAD:
if (state->wrap == 0) {
state->mode = TYPEDO;
break;
}
NEEDBITS(16);
#ifdef GUNZIP
if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
if (state->wbits == 0)
state->wbits = 15;
state->check = crc32(0L, Z_NULL, 0);
CRC2(state->check, hold);
INITBITS();
state->mode = FLAGS;
break;
}
- state->flags = 0; /* expect zlib header */
if (state->head != Z_NULL)
state->head->done = -1;
if (!(state->wrap & 1) || /* check if zlib header allowed */
#else
if (
#endif
((BITS(8) << 8) + (hold >> 8)) % 31) {
strm->msg = (char *)"incorrect header check";
state->mode = BAD;
break;
}
if (BITS(4) != Z_DEFLATED) {
strm->msg = (char *)"unknown compression method";
state->mode = BAD;
break;
}
DROPBITS(4);
len = BITS(4) + 8;
if (state->wbits == 0)
state->wbits = len;
if (len > 15 || len > state->wbits) {
strm->msg = (char *)"invalid window size";
state->mode = BAD;
break;
}
state->dmax = 1U << len;
+ state->flags = 0; /* indicate zlib header */
Tracev((stderr, "inflate: zlib header ok\n"));
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE;
INITBITS();
break;
#ifdef GUNZIP
case FLAGS:
NEEDBITS(16);
state->flags = (int)(hold);
if ((state->flags & 0xff) != Z_DEFLATED) {
strm->msg = (char *)"unknown compression method";
state->mode = BAD;
break;
}
if (state->flags & 0xe000) {
strm->msg = (char *)"unknown header flags set";
state->mode = BAD;
break;
}
if (state->head != Z_NULL)
state->head->text = (int)((hold >> 8) & 1);
if ((state->flags & 0x0200) && (state->wrap & 4))
CRC2(state->check, hold);
INITBITS();
state->mode = TIME;
+ /* fallthrough */
case TIME:
NEEDBITS(32);
if (state->head != Z_NULL)
state->head->time = hold;
if ((state->flags & 0x0200) && (state->wrap & 4))
CRC4(state->check, hold);
INITBITS();
state->mode = OS;
+ /* fallthrough */
case OS:
NEEDBITS(16);
if (state->head != Z_NULL) {
state->head->xflags = (int)(hold & 0xff);
state->head->os = (int)(hold >> 8);
}
if ((state->flags & 0x0200) && (state->wrap & 4))
CRC2(state->check, hold);
INITBITS();
state->mode = EXLEN;
+ /* fallthrough */
case EXLEN:
if (state->flags & 0x0400) {
NEEDBITS(16);
state->length = (unsigned)(hold);
if (state->head != Z_NULL)
state->head->extra_len = (unsigned)hold;
if ((state->flags & 0x0200) && (state->wrap & 4))
CRC2(state->check, hold);
INITBITS();
}
else if (state->head != Z_NULL)
state->head->extra = Z_NULL;
state->mode = EXTRA;
+ /* fallthrough */
case EXTRA:
if (state->flags & 0x0400) {
copy = state->length;
if (copy > have) copy = have;
if (copy) {
if (state->head != Z_NULL &&
state->head->extra != Z_NULL) {
len = state->head->extra_len - state->length;
zmemcpy(state->head->extra + len, next,
len + copy > state->head->extra_max ?
state->head->extra_max - len : copy);
}
if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
state->length -= copy;
}
if (state->length) goto inf_leave;
}
state->length = 0;
state->mode = NAME;
+ /* fallthrough */
case NAME:
if (state->flags & 0x0800) {
if (have == 0) goto inf_leave;
copy = 0;
do {
len = (unsigned)(next[copy++]);
if (state->head != Z_NULL &&
state->head->name != Z_NULL &&
state->length < state->head->name_max)
state->head->name[state->length++] = (Bytef)len;
} while (len && copy < have);
if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
if (len) goto inf_leave;
}
else if (state->head != Z_NULL)
state->head->name = Z_NULL;
state->length = 0;
state->mode = COMMENT;
+ /* fallthrough */
case COMMENT:
if (state->flags & 0x1000) {
if (have == 0) goto inf_leave;
copy = 0;
do {
len = (unsigned)(next[copy++]);
if (state->head != Z_NULL &&
state->head->comment != Z_NULL &&
state->length < state->head->comm_max)
state->head->comment[state->length++] = (Bytef)len;
} while (len && copy < have);
if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
if (len) goto inf_leave;
}
else if (state->head != Z_NULL)
state->head->comment = Z_NULL;
state->mode = HCRC;
+ /* fallthrough */
case HCRC:
if (state->flags & 0x0200) {
NEEDBITS(16);
if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
strm->msg = (char *)"header crc mismatch";
state->mode = BAD;
break;
}
INITBITS();
}
if (state->head != Z_NULL) {
state->head->hcrc = (int)((state->flags >> 9) & 1);
state->head->done = 1;
}
strm->adler = state->check = crc32(0L, Z_NULL, 0);
state->mode = TYPE;
break;
#endif
case DICTID:
NEEDBITS(32);
strm->adler = state->check = ZSWAP32(hold);
INITBITS();
state->mode = DICT;
+ /* fallthrough */
case DICT:
if (state->havedict == 0) {
RESTORE();
return Z_NEED_DICT;
}
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = TYPE;
+ /* fallthrough */
case TYPE:
if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+ /* fallthrough */
case TYPEDO:
if (state->last) {
BYTEBITS();
state->mode = CHECK;
break;
}
NEEDBITS(3);
state->last = BITS(1);
DROPBITS(1);
switch (BITS(2)) {
case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n",
state->last ? " (last)" : ""));
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN_; /* decode codes */
if (flush == Z_TREES) {
DROPBITS(2);
goto inf_leave;
}
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
break;
case STORED:
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
state->mode = COPY_;
if (flush == Z_TREES) goto inf_leave;
+ /* fallthrough */
case COPY_:
state->mode = COPY;
+ /* fallthrough */
case COPY:
copy = state->length;
if (copy) {
if (copy > have) copy = have;
if (copy > left) copy = left;
if (copy == 0) goto inf_leave;
zmemcpy(put, next, copy);
have -= copy;
next += copy;
left -= copy;
put += copy;
state->length -= copy;
break;
}
Tracev((stderr, "inflate: stored end\n"));
state->mode = TYPE;
break;
case TABLE:
NEEDBITS(14);
state->nlen = BITS(5) + 257;
DROPBITS(5);
state->ndist = BITS(5) + 1;
DROPBITS(5);
state->ncode = BITS(4) + 4;
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
state->mode = BAD;
break;
}
#endif
Tracev((stderr, "inflate: table sizes ok\n"));
state->have = 0;
state->mode = LENLENS;
+ /* fallthrough */
case LENLENS:
while (state->have < state->ncode) {
NEEDBITS(3);
state->lens[order[state->have++]] = (unsigned short)BITS(3);
DROPBITS(3);
}
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
state->lencode = (const code FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: code lengths ok\n"));
state->have = 0;
state->mode = CODELENS;
+ /* fallthrough */
case CODELENS:
while (state->have < state->nlen + state->ndist) {
for (;;) {
here = state->lencode[BITS(state->lenbits)];
if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
if (here.val < 16) {
DROPBITS(here.bits);
state->lens[state->have++] = here.val;
}
else {
if (here.val == 16) {
NEEDBITS(here.bits + 2);
DROPBITS(here.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
len = state->lens[state->have - 1];
copy = 3 + BITS(2);
DROPBITS(2);
}
else if (here.val == 17) {
NEEDBITS(here.bits + 3);
DROPBITS(here.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
NEEDBITS(here.bits + 7);
DROPBITS(here.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
while (copy--)
state->lens[state->have++] = (unsigned short)len;
}
}
/* handle error breaks in while */
if (state->mode == BAD) break;
/* check for end-of-block code (better have one) */
if (state->lens[256] == 0) {
strm->msg = (char *)"invalid code -- missing end-of-block";
state->mode = BAD;
break;
}
/* build code tables -- note: do not change the lenbits or distbits
values here (9 and 6) without reading the comments in inftrees.h
concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
state->lencode = (const code FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
state->distcode = (const code FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN_;
if (flush == Z_TREES) goto inf_leave;
+ /* fallthrough */
case LEN_:
state->mode = LEN;
+ /* fallthrough */
case LEN:
if (have >= 6 && left >= 258) {
RESTORE();
inflate_fast(strm, out);
LOAD();
if (state->mode == TYPE)
state->back = -1;
break;
}
state->back = 0;
for (;;) {
here = state->lencode[BITS(state->lenbits)];
if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
if (here.op && (here.op & 0xf0) == 0) {
last = here;
for (;;) {
here = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
state->back += last.bits;
}
DROPBITS(here.bits);
state->back += here.bits;
state->length = (unsigned)here.val;
if ((int)(here.op) == 0) {
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", here.val));
state->mode = LIT;
break;
}
if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->back = -1;
state->mode = TYPE;
break;
}
if (here.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
state->extra = (unsigned)(here.op) & 15;
state->mode = LENEXT;
+ /* fallthrough */
case LENEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
state->back += state->extra;
}
Tracevv((stderr, "inflate: length %u\n", state->length));
state->was = state->length;
state->mode = DIST;
+ /* fallthrough */
case DIST:
for (;;) {
here = state->distcode[BITS(state->distbits)];
if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
}
if ((here.op & 0xf0) == 0) {
last = here;
for (;;) {
here = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
state->back += last.bits;
}
DROPBITS(here.bits);
state->back += here.bits;
if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
state->offset = (unsigned)here.val;
state->extra = (unsigned)(here.op) & 15;
state->mode = DISTEXT;
+ /* fallthrough */
case DISTEXT:
if (state->extra) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
state->back += state->extra;
}
#ifdef INFLATE_STRICT
if (state->offset > state->dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
Tracevv((stderr, "inflate: distance %u\n", state->offset));
state->mode = MATCH;
+ /* fallthrough */
case MATCH:
if (left == 0) goto inf_leave;
copy = out - left;
if (state->offset > copy) { /* copy from window */
copy = state->offset - copy;
if (copy > state->whave) {
if (state->sane) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
Trace((stderr, "inflate.c too far\n"));
copy -= state->whave;
if (copy > state->length) copy = state->length;
if (copy > left) copy = left;
left -= copy;
state->length -= copy;
do {
*put++ = 0;
} while (--copy);
if (state->length == 0) state->mode = LEN;
break;
#endif
}
if (copy > state->wnext) {
copy -= state->wnext;
from = state->window + (state->wsize - copy);
}
else
from = state->window + (state->wnext - copy);
if (copy > state->length) copy = state->length;
}
else { /* copy from output */
from = put - state->offset;
copy = state->length;
}
if (copy > left) copy = left;
left -= copy;
state->length -= copy;
do {
*put++ = *from++;
} while (--copy);
if (state->length == 0) state->mode = LEN;
break;
case LIT:
if (left == 0) goto inf_leave;
*put++ = (unsigned char)(state->length);
left--;
state->mode = LEN;
break;
case CHECK:
if (state->wrap) {
NEEDBITS(32);
out -= left;
strm->total_out += out;
state->total += out;
if ((state->wrap & 4) && out)
strm->adler = state->check =
- UPDATE(state->check, put - out, out);
+ UPDATE_CHECK(state->check, put - out, out);
out = left;
if ((state->wrap & 4) && (
#ifdef GUNZIP
state->flags ? hold :
#endif
ZSWAP32(hold)) != state->check) {
strm->msg = (char *)"incorrect data check";
state->mode = BAD;
break;
}
INITBITS();
Tracev((stderr, "inflate: check matches trailer\n"));
}
#ifdef GUNZIP
state->mode = LENGTH;
+ /* fallthrough */
case LENGTH:
if (state->wrap && state->flags) {
NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
+ if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
strm->msg = (char *)"incorrect length check";
state->mode = BAD;
break;
}
INITBITS();
Tracev((stderr, "inflate: length matches trailer\n"));
}
#endif
state->mode = DONE;
+ /* fallthrough */
case DONE:
ret = Z_STREAM_END;
goto inf_leave;
case BAD:
ret = Z_DATA_ERROR;
goto inf_leave;
case MEM:
return Z_MEM_ERROR;
case SYNC:
+ /* fallthrough */
default:
return Z_STREAM_ERROR;
}
/*
Return from inflate(), updating the total counts and the check value.
If there was no progress during the inflate() call, return a buffer
error. Call updatewindow() to create and/or update the window state.
Note: a memory error from inflate() is non-recoverable.
*/
inf_leave:
RESTORE();
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
(state->mode < CHECK || flush != Z_FINISH)))
if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
state->mode = MEM;
return Z_MEM_ERROR;
}
in -= strm->avail_in;
out -= strm->avail_out;
strm->total_in += in;
strm->total_out += out;
state->total += out;
if ((state->wrap & 4) && out)
strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
+ UPDATE_CHECK(state->check, strm->next_out - out, out);
strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
(state->mode == TYPE ? 128 : 0) +
(state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
ret = Z_BUF_ERROR;
return ret;
}
int ZEXPORT inflateEnd(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm))
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (state->window != Z_NULL) ZFREE(strm, state->window);
ZFREE(strm, strm->state);
strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}
int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
z_streamp strm;
Bytef *dictionary;
uInt *dictLength;
{
struct inflate_state FAR *state;
/* check state */
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* copy dictionary */
if (state->whave && dictionary != Z_NULL) {
zmemcpy(dictionary, state->window + state->wnext,
state->whave - state->wnext);
zmemcpy(dictionary + state->whave - state->wnext,
state->window, state->wnext);
}
if (dictLength != Z_NULL)
*dictLength = state->whave;
return Z_OK;
}
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
struct inflate_state FAR *state;
unsigned long dictid;
int ret;
/* check state */
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (state->wrap != 0 && state->mode != DICT)
return Z_STREAM_ERROR;
/* check for correct dictionary identifier */
if (state->mode == DICT) {
dictid = adler32(0L, Z_NULL, 0);
dictid = adler32(dictid, dictionary, dictLength);
if (dictid != state->check)
return Z_DATA_ERROR;
}
/* copy dictionary to window using updatewindow(), which will amend the
existing dictionary if appropriate */
ret = updatewindow(strm, dictionary + dictLength, dictLength);
if (ret) {
state->mode = MEM;
return Z_MEM_ERROR;
}
state->havedict = 1;
Tracev((stderr, "inflate: dictionary set\n"));
return Z_OK;
}
int ZEXPORT inflateGetHeader(strm, head)
z_streamp strm;
gz_headerp head;
{
struct inflate_state FAR *state;
/* check state */
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
/* save header structure */
state->head = head;
head->done = 0;
return Z_OK;
}
/*
Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
or when out of input. When called, *have is the number of pattern bytes
found in order so far, in 0..3. On return *have is updated to the new
state. If on return *have equals four, then the pattern was found and the
return value is how many bytes were read including the last byte of the
pattern. If *have is less than four, then the pattern has not been found
yet and the return value is len. In the latter case, syncsearch() can be
called again with more data and the *have state. *have is initialized to
zero for the first call.
*/
local unsigned syncsearch(have, buf, len)
unsigned FAR *have;
const unsigned char FAR *buf;
unsigned len;
{
unsigned got;
unsigned next;
got = *have;
next = 0;
while (next < len && got < 4) {
if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
got++;
else if (buf[next])
got = 0;
else
got = 4 - got;
next++;
}
*have = got;
return next;
}
int ZEXPORT inflateSync(strm)
z_streamp strm;
{
unsigned len; /* number of bytes to look at or looked at */
+ int flags; /* temporary to save header status */
unsigned long in, out; /* temporary to save total_in and total_out */
unsigned char buf[4]; /* to restore bit buffer to byte string */
struct inflate_state FAR *state;
/* check parameters */
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
/* if first time, start search in bit buffer */
if (state->mode != SYNC) {
state->mode = SYNC;
state->hold <<= state->bits & 7;
state->bits -= state->bits & 7;
len = 0;
while (state->bits >= 8) {
buf[len++] = (unsigned char)(state->hold);
state->hold >>= 8;
state->bits -= 8;
}
state->have = 0;
syncsearch(&(state->have), buf, len);
}
/* search available input */
len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
strm->avail_in -= len;
strm->next_in += len;
strm->total_in += len;
/* return no joy or set up to restart inflate() on a new block */
if (state->have != 4) return Z_DATA_ERROR;
+ if (state->flags == -1)
+ state->wrap = 0; /* if no header yet, treat as raw */
+ else
+ state->wrap &= ~4; /* no point in computing a check value now */
+ flags = state->flags;
in = strm->total_in; out = strm->total_out;
inflateReset(strm);
strm->total_in = in; strm->total_out = out;
+ state->flags = flags;
state->mode = TYPE;
return Z_OK;
}
/*
Returns true if inflate is currently at the end of a block generated by
Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
implementation to provide an additional safety check. PPP uses
Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
block. When decompressing, PPP checks that at the end of input packet,
inflate is waiting for these length bytes.
*/
int ZEXPORT inflateSyncPoint(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
return state->mode == STORED && state->bits == 0;
}
int ZEXPORT inflateCopy(dest, source)
z_streamp dest;
z_streamp source;
{
struct inflate_state FAR *state;
struct inflate_state FAR *copy;
unsigned char FAR *window;
unsigned wsize;
/* check input */
if (inflateStateCheck(source) || dest == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)source->state;
/* allocate space */
copy = (struct inflate_state FAR *)
ZALLOC(source, 1, sizeof(struct inflate_state));
if (copy == Z_NULL) return Z_MEM_ERROR;
window = Z_NULL;
if (state->window != Z_NULL) {
window = (unsigned char FAR *)
ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
if (window == Z_NULL) {
ZFREE(source, copy);
return Z_MEM_ERROR;
}
}
/* copy state */
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
copy->strm = dest;
if (state->lencode >= state->codes &&
state->lencode <= state->codes + ENOUGH - 1) {
copy->lencode = copy->codes + (state->lencode - state->codes);
copy->distcode = copy->codes + (state->distcode - state->codes);
}
copy->next = copy->codes + (state->next - state->codes);
if (window != Z_NULL) {
wsize = 1U << state->wbits;
zmemcpy(window, state->window, wsize);
}
copy->window = window;
dest->state = (struct internal_state FAR *)copy;
return Z_OK;
}
int ZEXPORT inflateUndermine(strm, subvert)
z_streamp strm;
int subvert;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
state->sane = !subvert;
return Z_OK;
#else
(void)subvert;
state->sane = 1;
return Z_DATA_ERROR;
#endif
}
int ZEXPORT inflateValidate(strm, check)
z_streamp strm;
int check;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
- if (check)
+ if (check && state->wrap)
state->wrap |= 4;
else
state->wrap &= ~4;
return Z_OK;
}
long ZEXPORT inflateMark(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm))
return -(1L << 16);
state = (struct inflate_state FAR *)strm->state;
return (long)(((unsigned long)((long)state->back)) << 16) +
(state->mode == COPY ? state->length :
(state->mode == MATCH ? state->was - state->length : 0));
}
unsigned long ZEXPORT inflateCodesUsed(strm)
z_streamp strm;
{
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return (unsigned long)-1;
state = (struct inflate_state FAR *)strm->state;
return (unsigned long)(state->next - state->codes);
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inflate.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inflate.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inflate.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inflate.h
index a46cce6b..f127b6b1 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inflate.h
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inflate.h
@@ -1,125 +1,126 @@
/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2016 Mark Adler
+ * Copyright (C) 1995-2019 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
# define GUNZIP
#endif
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD = 16180, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY_, /* i/o: same as COPY below, but only first time in */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN_, /* i: same as LEN below, but only first time in */
LEN, /* i: waiting for length/lit/eob code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
State transitions between above modes -
(most modes can go to BAD or MEM on error -- not shown for clarity)
Process header:
HEAD -> (gzip) or (zlib) or (raw)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
(raw) -> TYPEDO
Read deflate blocks:
TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
STORED -> COPY_ -> COPY -> TYPE
TABLE -> LENLENS -> CODELENS -> LEN_
LEN_ -> LEN
Read deflate codes in fixed or dynamic block:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
Process trailer:
CHECK -> LENGTH -> DONE
*/
/* State maintained between inflate() calls -- approximately 7K bytes, not
including the allocated sliding window, which is up to 32K bytes. */
struct inflate_state {
z_streamp strm; /* pointer back to this zlib stream */
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
bit 2 true to validate check value */
int havedict; /* true if dictionary provided */
- int flags; /* gzip header method and flags (0 if zlib) */
+ int flags; /* gzip header method and flags, 0 if zlib, or
+ -1 if raw or no header yet */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
int sane; /* if false, allow invalid distance too far */
int back; /* bits back of last unprocessed length/lit */
unsigned was; /* initial length of match */
};
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inftrees.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inftrees.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inftrees.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inftrees.c
index 2ea08fc1..09462a74 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inftrees.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inftrees.c
@@ -1,304 +1,304 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2017 Mark Adler
+ * Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#define MAXBITS 15
const char inflate_copyright[] =
- " inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
+ " inflate 1.2.12 Copyright 1995-2022 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
/*
Build a set of tables to decode the provided canonical Huffman code.
The code lengths are lens[0..codes-1]. The result starts at *table,
whose indices are 0..2^bits-1. work is a writable array of at least
lens shorts, which is used as a work area. type is the type of code
to be generated, CODES, LENS, or DISTS. On return, zero is success,
-1 is an invalid code, and +1 means that ENOUGH isn't enough. table
on return points to the next available entry's address. bits is the
requested root table index bits, and on return it is the actual root
table index bits. It will differ if the request is greater than the
longest code or if it is less than the shortest code.
*/
int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
codetype type;
unsigned short FAR *lens;
unsigned codes;
code FAR * FAR *table;
unsigned FAR *bits;
unsigned short FAR *work;
{
unsigned len; /* a code's length in bits */
unsigned sym; /* index of code symbols */
unsigned min, max; /* minimum and maximum code lengths */
unsigned root; /* number of index bits for root table */
unsigned curr; /* number of index bits for current table */
unsigned drop; /* code bits to drop for sub-table */
int left; /* number of prefix codes available */
unsigned used; /* code entries in table used */
unsigned huff; /* Huffman code */
unsigned incr; /* for incrementing code, index */
unsigned fill; /* index for replicating entries */
unsigned low; /* low bits for current root entry */
unsigned mask; /* mask for low root bits */
code here; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
unsigned match; /* use base and extra for symbol >= match */
unsigned short count[MAXBITS+1]; /* number of codes of each length */
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 202};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577, 0, 0};
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
28, 28, 29, 29, 64, 64};
/*
Process a set of code lengths to create a canonical Huffman code. The
code lengths are lens[0..codes-1]. Each length corresponds to the
symbols 0..codes-1. The Huffman code is generated by first sorting the
symbols by length from short to long, and retaining the symbol order
for codes with equal lengths. Then the code starts with all zero bits
for the first code of the shortest length, and the codes are integer
increments for the same length, and zeros are appended as the length
increases. For the deflate format, these bits are stored backwards
from their more natural integer increment ordering, and so when the
decoding tables are built in the large loop below, the integer codes
are incremented backwards.
This routine assumes, but does not check, that all of the entries in
lens[] are in the range 0..MAXBITS. The caller must assure this.
1..MAXBITS is interpreted as that code length. zero means that that
symbol does not occur in this code.
The codes are sorted by computing a count of codes for each length,
creating from that a table of starting indices for each length in the
sorted table, and then entering the symbols in order in the sorted
table. The sorted table is work[], with that space being provided by
the caller.
The length counts are used for other purposes as well, i.e. finding
the minimum and maximum length codes, determining if there are any
codes at all, checking for a valid set of lengths, and looking ahead
at length counts to determine sub-table sizes when building the
decoding tables.
*/
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
for (len = 0; len <= MAXBITS; len++)
count[len] = 0;
for (sym = 0; sym < codes; sym++)
count[lens[sym]]++;
/* bound code lengths, force root to be within code lengths */
root = *bits;
for (max = MAXBITS; max >= 1; max--)
if (count[max] != 0) break;
if (root > max) root = max;
if (max == 0) { /* no symbols to code at all */
here.op = (unsigned char)64; /* invalid code marker */
here.bits = (unsigned char)1;
here.val = (unsigned short)0;
*(*table)++ = here; /* make a table to force an error */
*(*table)++ = here;
*bits = 1;
return 0; /* no symbols, but wait for decoding to report error */
}
for (min = 1; min < max; min++)
if (count[min] != 0) break;
if (root < min) root = min;
/* check for an over-subscribed or incomplete set of lengths */
left = 1;
for (len = 1; len <= MAXBITS; len++) {
left <<= 1;
left -= count[len];
if (left < 0) return -1; /* over-subscribed */
}
if (left > 0 && (type == CODES || max != 1))
return -1; /* incomplete set */
/* generate offsets into symbol table for each length for sorting */
offs[1] = 0;
for (len = 1; len < MAXBITS; len++)
offs[len + 1] = offs[len] + count[len];
/* sort symbols by length, by symbol order within each length */
for (sym = 0; sym < codes; sym++)
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
/*
Create and fill in decoding tables. In this loop, the table being
filled is at next and has curr index bits. The code being used is huff
with length len. That code is converted to an index by dropping drop
bits off of the bottom. For codes where len is less than drop + curr,
those top drop + curr - len bits are incremented through all values to
fill the table with replicated entries.
root is the number of index bits for the root table. When len exceeds
root, sub-tables are created pointed to by the root entry with an index
of the low root bits of huff. This is saved in low to check for when a
new sub-table should be started. drop is zero when the root table is
being filled, and drop is root when sub-tables are being filled.
When a new sub-table is needed, it is necessary to look ahead in the
code lengths to determine what size sub-table is needed. The length
counts are used for this, and so count[] is decremented as codes are
entered in the tables.
used keeps track of how many table entries have been allocated from the
provided *table space. It is checked for LENS and DIST tables against
the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
the initial root table size constants. See the comments in inftrees.h
for more information.
sym increments through all symbols, and the loop terminates when
all codes of length max, i.e. all codes, have been processed. This
routine permits incomplete codes, so another loop after this one fills
in the rest of the decoding tables with invalid code markers.
*/
/* set up for code type */
switch (type) {
case CODES:
base = extra = work; /* dummy value--not used */
match = 20;
break;
case LENS:
base = lbase;
extra = lext;
match = 257;
break;
default: /* DISTS */
base = dbase;
extra = dext;
match = 0;
}
/* initialize state for loop */
huff = 0; /* starting code */
sym = 0; /* starting code symbol */
len = min; /* starting code length */
next = *table; /* current table to fill in */
curr = root; /* current table index bits */
drop = 0; /* current bits to drop from code for index */
low = (unsigned)(-1); /* trigger new sub-table when len > root */
used = 1U << root; /* use root table entries */
mask = used - 1; /* mask for comparing low */
/* check available table space */
if ((type == LENS && used > ENOUGH_LENS) ||
(type == DISTS && used > ENOUGH_DISTS))
return 1;
/* process all codes and make table entries */
for (;;) {
/* create table entry */
here.bits = (unsigned char)(len - drop);
if (work[sym] + 1U < match) {
here.op = (unsigned char)0;
here.val = work[sym];
}
else if (work[sym] >= match) {
here.op = (unsigned char)(extra[work[sym] - match]);
here.val = base[work[sym] - match];
}
else {
here.op = (unsigned char)(32 + 64); /* end of block */
here.val = 0;
}
/* replicate for those indices with low len bits equal to huff */
incr = 1U << (len - drop);
fill = 1U << curr;
min = fill; /* save offset to next table */
do {
fill -= incr;
next[(huff >> drop) + fill] = here;
} while (fill != 0);
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
while (huff & incr)
incr >>= 1;
if (incr != 0) {
huff &= incr - 1;
huff += incr;
}
else
huff = 0;
/* go to next symbol, update count, len */
sym++;
if (--(count[len]) == 0) {
if (len == max) break;
len = lens[work[sym]];
}
/* create new sub-table if needed */
if (len > root && (huff & mask) != low) {
/* if first time, transition to sub-tables */
if (drop == 0)
drop = root;
/* increment past last table */
next += min; /* here min is 1 << curr */
/* determine length of next table */
curr = len - drop;
left = (int)(1 << curr);
while (curr + drop < max) {
left -= count[curr + drop];
if (left <= 0) break;
curr++;
left <<= 1;
}
/* check for enough space */
used += 1U << curr;
if ((type == LENS && used > ENOUGH_LENS) ||
(type == DISTS && used > ENOUGH_DISTS))
return 1;
/* point entry in root table to sub-table */
low = huff & mask;
(*table)[low].op = (unsigned char)curr;
(*table)[low].bits = (unsigned char)root;
(*table)[low].val = (unsigned short)(next - *table);
}
}
/* fill in remaining table entry if code is incomplete (guaranteed to have
at most one remaining entry, since if the code is incomplete, the
maximum code length that was allowed to get this far is one bit) */
if (huff != 0) {
here.op = (unsigned char)64; /* invalid code marker */
here.bits = (unsigned char)(len - drop);
here.val = (unsigned short)0;
next[huff] = here;
}
/* set return parameters */
*table += used;
*bits = root;
return 0;
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inftrees.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inftrees.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/inftrees.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/inftrees.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/trees.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/trees.c
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/trees.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/trees.c
index 50cf4b45..f73fd99c 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/trees.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/trees.c
@@ -1,1203 +1,1182 @@
/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2017 Jean-loup Gailly
+ * Copyright (C) 1995-2021 Jean-loup Gailly
* detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
* ALGORITHM
*
* The "deflation" process uses several Huffman trees. The more
* common source values are represented by shorter bit sequences.
*
* Each code tree is stored in a compressed form which is itself
* a Huffman encoding of the lengths of all the code strings (in
* ascending order by source values). The actual code strings are
* reconstructed from the lengths in the inflate process, as described
* in the deflate specification.
*
* REFERENCES
*
* Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
* Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
*
* Storer, James A.
* Data Compression: Methods and Theory, pp. 49-50.
* Computer Science Press, 1988. ISBN 0-7167-8156-5.
*
* Sedgewick, R.
* Algorithms, p290.
* Addison-Wesley, 1983. ISBN 0-201-06672-6.
*/
/* @(#) $Id$ */
/* #define GEN_TREES_H */
#include "deflate.h"
#ifdef ZLIB_DEBUG
# include <ctype.h>
#endif
/* ===========================================================================
* Constants
*/
#define MAX_BL_BITS 7
/* Bit length codes must not exceed MAX_BL_BITS bits */
#define END_BLOCK 256
/* end of block literal code */
#define REP_3_6 16
/* repeat previous bit length 3-6 times (2 bits of repeat count) */
#define REPZ_3_10 17
/* repeat a zero length 3-10 times (3 bits of repeat count) */
#define REPZ_11_138 18
/* repeat a zero length 11-138 times (7 bits of repeat count) */
local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
= {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
local const int extra_dbits[D_CODES] /* extra bits for each distance code */
= {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
local const uch bl_order[BL_CODES]
= {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
/* The lengths of the bit length codes are sent in order of decreasing
* probability, to avoid transmitting the lengths for unused bit length codes.
*/
/* ===========================================================================
* Local data. These are initialized only once.
*/
#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
#if defined(GEN_TREES_H) || !defined(STDC)
/* non ANSI compilers may not accept trees.h */
local ct_data static_ltree[L_CODES+2];
/* The static literal tree. Since the bit lengths are imposed, there is no
* need for the L_CODES extra codes used during heap construction. However
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init
* below).
*/
local ct_data static_dtree[D_CODES];
/* The static distance tree. (Actually a trivial tree since all codes use
* 5 bits.)
*/
uch _dist_code[DIST_CODE_LEN];
/* Distance codes. The first 256 values correspond to the distances
* 3 .. 258, the last 256 values correspond to the top 8 bits of
* the 15 bit distances.
*/
uch _length_code[MAX_MATCH-MIN_MATCH+1];
/* length code for each normalized match length (0 == MIN_MATCH) */
local int base_length[LENGTH_CODES];
/* First normalized length for each code (0 = MIN_MATCH) */
local int base_dist[D_CODES];
/* First normalized distance for each code (0 = distance of 1) */
#else
# include "trees.h"
#endif /* GEN_TREES_H */
struct static_tree_desc_s {
const ct_data *static_tree; /* static tree or NULL */
const intf *extra_bits; /* extra bits for each code or NULL */
int extra_base; /* base index for extra_bits */
int elems; /* max number of elements in the tree */
int max_length; /* max bit length for the codes */
};
local const static_tree_desc static_l_desc =
{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
local const static_tree_desc static_d_desc =
{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
local const static_tree_desc static_bl_desc =
{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
/* ===========================================================================
* Local (static) routines in this file.
*/
local void tr_static_init OF((void));
local void init_block OF((deflate_state *s));
local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
local void build_tree OF((deflate_state *s, tree_desc *desc));
local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
local int build_bl_tree OF((deflate_state *s));
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
int blcodes));
local void compress_block OF((deflate_state *s, const ct_data *ltree,
const ct_data *dtree));
local int detect_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
+local unsigned bi_reverse OF((unsigned code, int len));
local void bi_windup OF((deflate_state *s));
local void bi_flush OF((deflate_state *s));
#ifdef GEN_TREES_H
local void gen_trees_header OF((void));
#endif
#ifndef ZLIB_DEBUG
# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
/* Send a code of the given tree. c and tree must not have side effects */
#else /* !ZLIB_DEBUG */
# define send_code(s, c, tree) \
{ if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
send_bits(s, tree[c].Code, tree[c].Len); }
#endif
/* ===========================================================================
* Output a short LSB first on the stream.
* IN assertion: there is enough room in pendingBuf.
*/
#define put_short(s, w) { \
put_byte(s, (uch)((w) & 0xff)); \
put_byte(s, (uch)((ush)(w) >> 8)); \
}
/* ===========================================================================
* Send a value on a given number of bits.
* IN assertion: length <= 16 and value fits in length bits.
*/
#ifdef ZLIB_DEBUG
local void send_bits OF((deflate_state *s, int value, int length));
local void send_bits(s, value, length)
deflate_state *s;
int value; /* value to send */
int length; /* number of bits */
{
Tracevv((stderr," l %2d v %4x ", length, value));
Assert(length > 0 && length <= 15, "invalid length");
s->bits_sent += (ulg)length;
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
* (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
* unused bits in value.
*/
if (s->bi_valid > (int)Buf_size - length) {
s->bi_buf |= (ush)value << s->bi_valid;
put_short(s, s->bi_buf);
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
s->bi_valid += length - Buf_size;
} else {
s->bi_buf |= (ush)value << s->bi_valid;
s->bi_valid += length;
}
}
#else /* !ZLIB_DEBUG */
#define send_bits(s, value, length) \
{ int len = length;\
if (s->bi_valid > (int)Buf_size - len) {\
int val = (int)value;\
s->bi_buf |= (ush)val << s->bi_valid;\
put_short(s, s->bi_buf);\
s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
s->bi_valid += len - Buf_size;\
} else {\
s->bi_buf |= (ush)(value) << s->bi_valid;\
s->bi_valid += len;\
}\
}
#endif /* ZLIB_DEBUG */
/* the arguments must not have side effects */
/* ===========================================================================
* Initialize the various 'constant' tables.
*/
local void tr_static_init()
{
#if defined(GEN_TREES_H) || !defined(STDC)
static int static_init_done = 0;
int n; /* iterates over tree elements */
int bits; /* bit counter */
int length; /* length value */
int code; /* code value */
int dist; /* distance index */
ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */
if (static_init_done) return;
/* For some embedded targets, global variables are not initialized: */
#ifdef NO_INIT_GLOBAL_POINTERS
static_l_desc.static_tree = static_ltree;
static_l_desc.extra_bits = extra_lbits;
static_d_desc.static_tree = static_dtree;
static_d_desc.extra_bits = extra_dbits;
static_bl_desc.extra_bits = extra_blbits;
#endif
/* Initialize the mapping length (0..255) -> length code (0..28) */
length = 0;
for (code = 0; code < LENGTH_CODES-1; code++) {
base_length[code] = length;
for (n = 0; n < (1<<extra_lbits[code]); n++) {
_length_code[length++] = (uch)code;
}
}
Assert (length == 256, "tr_static_init: length != 256");
/* Note that the length 255 (match length 258) can be represented
* in two different ways: code 284 + 5 bits or code 285, so we
* overwrite length_code[255] to use the best encoding:
*/
_length_code[length-1] = (uch)code;
/* Initialize the mapping dist (0..32K) -> dist code (0..29) */
dist = 0;
for (code = 0 ; code < 16; code++) {
base_dist[code] = dist;
for (n = 0; n < (1<<extra_dbits[code]); n++) {
_dist_code[dist++] = (uch)code;
}
}
Assert (dist == 256, "tr_static_init: dist != 256");
dist >>= 7; /* from now on, all distances are divided by 128 */
for ( ; code < D_CODES; code++) {
base_dist[code] = dist << 7;
for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
_dist_code[256 + dist++] = (uch)code;
}
}
Assert (dist == 256, "tr_static_init: 256+dist != 512");
/* Construct the codes of the static literal tree */
for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
n = 0;
while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
/* Codes 286 and 287 do not exist, but we must include them in the
* tree construction to get a canonical Huffman tree (longest code
* all ones)
*/
gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
/* The static distance tree is trivial: */
for (n = 0; n < D_CODES; n++) {
static_dtree[n].Len = 5;
static_dtree[n].Code = bi_reverse((unsigned)n, 5);
}
static_init_done = 1;
# ifdef GEN_TREES_H
gen_trees_header();
# endif
#endif /* defined(GEN_TREES_H) || !defined(STDC) */
}
/* ===========================================================================
* Genererate the file trees.h describing the static trees.
*/
#ifdef GEN_TREES_H
# ifndef ZLIB_DEBUG
# include <stdio.h>
# endif
# define SEPARATOR(i, last, width) \
((i) == (last)? "\n};\n\n" : \
((i) % (width) == (width)-1 ? ",\n" : ", "))
void gen_trees_header()
{
FILE *header = fopen("trees.h", "w");
int i;
Assert (header != NULL, "Can't open trees.h");
fprintf(header,
"/* header created automatically with -DGEN_TREES_H */\n\n");
fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
for (i = 0; i < L_CODES+2; i++) {
fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
}
fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
for (i = 0; i < D_CODES; i++) {
fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
}
fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
for (i = 0; i < DIST_CODE_LEN; i++) {
fprintf(header, "%2u%s", _dist_code[i],
SEPARATOR(i, DIST_CODE_LEN-1, 20));
}
fprintf(header,
"const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
fprintf(header, "%2u%s", _length_code[i],
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
}
fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
for (i = 0; i < LENGTH_CODES; i++) {
fprintf(header, "%1u%s", base_length[i],
SEPARATOR(i, LENGTH_CODES-1, 20));
}
fprintf(header, "local const int base_dist[D_CODES] = {\n");
for (i = 0; i < D_CODES; i++) {
fprintf(header, "%5u%s", base_dist[i],
SEPARATOR(i, D_CODES-1, 10));
}
fclose(header);
}
#endif /* GEN_TREES_H */
/* ===========================================================================
* Initialize the tree data structures for a new zlib stream.
*/
void ZLIB_INTERNAL _tr_init(s)
deflate_state *s;
{
tr_static_init();
s->l_desc.dyn_tree = s->dyn_ltree;
s->l_desc.stat_desc = &static_l_desc;
s->d_desc.dyn_tree = s->dyn_dtree;
s->d_desc.stat_desc = &static_d_desc;
s->bl_desc.dyn_tree = s->bl_tree;
s->bl_desc.stat_desc = &static_bl_desc;
s->bi_buf = 0;
s->bi_valid = 0;
#ifdef ZLIB_DEBUG
s->compressed_len = 0L;
s->bits_sent = 0L;
#endif
/* Initialize the first block of the first file: */
init_block(s);
}
/* ===========================================================================
* Initialize a new block.
*/
local void init_block(s)
deflate_state *s;
{
int n; /* iterates over tree elements */
/* Initialize the trees. */
for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
s->dyn_ltree[END_BLOCK].Freq = 1;
s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
+ s->sym_next = s->matches = 0;
}
#define SMALLEST 1
/* Index within the heap array of least frequent node in the Huffman tree */
/* ===========================================================================
* Remove the smallest element from the heap and recreate the heap with
* one less element. Updates heap and heap_len.
*/
#define pqremove(s, tree, top) \
{\
top = s->heap[SMALLEST]; \
s->heap[SMALLEST] = s->heap[s->heap_len--]; \
pqdownheap(s, tree, SMALLEST); \
}
/* ===========================================================================
* Compares to subtrees, using the tree depth as tie breaker when
* the subtrees have equal frequency. This minimizes the worst case length.
*/
#define smaller(tree, n, m, depth) \
(tree[n].Freq < tree[m].Freq || \
(tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
/* ===========================================================================
* Restore the heap property by moving down the tree starting at node k,
* exchanging a node with the smallest of its two sons if necessary, stopping
* when the heap property is re-established (each father smaller than its
* two sons).
*/
local void pqdownheap(s, tree, k)
deflate_state *s;
ct_data *tree; /* the tree to restore */
int k; /* node to move down */
{
int v = s->heap[k];
int j = k << 1; /* left son of k */
while (j <= s->heap_len) {
/* Set j to the smallest of the two sons: */
if (j < s->heap_len &&
smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
j++;
}
/* Exit if v is smaller than both sons */
if (smaller(tree, v, s->heap[j], s->depth)) break;
/* Exchange v with the smallest son */
s->heap[k] = s->heap[j]; k = j;
/* And continue down the tree, setting j to the left son of k */
j <<= 1;
}
s->heap[k] = v;
}
/* ===========================================================================
* Compute the optimal bit lengths for a tree and update the total bit length
* for the current block.
* IN assertion: the fields freq and dad are set, heap[heap_max] and
* above are the tree nodes sorted by increasing frequency.
* OUT assertions: the field len is set to the optimal bit length, the
* array bl_count contains the frequencies for each bit length.
* The length opt_len is updated; static_len is also updated if stree is
* not null.
*/
local void gen_bitlen(s, desc)
deflate_state *s;
tree_desc *desc; /* the tree descriptor */
{
ct_data *tree = desc->dyn_tree;
int max_code = desc->max_code;
const ct_data *stree = desc->stat_desc->static_tree;
const intf *extra = desc->stat_desc->extra_bits;
int base = desc->stat_desc->extra_base;
int max_length = desc->stat_desc->max_length;
int h; /* heap index */
int n, m; /* iterate over the tree elements */
int bits; /* bit length */
int xbits; /* extra bits */
ush f; /* frequency */
int overflow = 0; /* number of elements with bit length too large */
for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
/* In a first pass, compute the optimal bit lengths (which may
* overflow in the case of the bit length tree).
*/
tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
n = s->heap[h];
bits = tree[tree[n].Dad].Len + 1;
if (bits > max_length) bits = max_length, overflow++;
tree[n].Len = (ush)bits;
/* We overwrite tree[n].Dad which is no longer needed */
if (n > max_code) continue; /* not a leaf node */
s->bl_count[bits]++;
xbits = 0;
if (n >= base) xbits = extra[n-base];
f = tree[n].Freq;
s->opt_len += (ulg)f * (unsigned)(bits + xbits);
if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
}
if (overflow == 0) return;
Tracev((stderr,"\nbit length overflow\n"));
/* This happens for example on obj2 and pic of the Calgary corpus */
/* Find the first bit length which could increase: */
do {
bits = max_length-1;
while (s->bl_count[bits] == 0) bits--;
s->bl_count[bits]--; /* move one leaf down the tree */
s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
s->bl_count[max_length]--;
/* The brother of the overflow item also moves one step up,
* but this does not affect bl_count[max_length]
*/
overflow -= 2;
} while (overflow > 0);
/* Now recompute all bit lengths, scanning in increasing frequency.
* h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
* lengths instead of fixing only the wrong ones. This idea is taken
* from 'ar' written by Haruhiko Okumura.)
*/
for (bits = max_length; bits != 0; bits--) {
n = s->bl_count[bits];
while (n != 0) {
m = s->heap[--h];
if (m > max_code) continue;
if ((unsigned) tree[m].Len != (unsigned) bits) {
Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;
tree[m].Len = (ush)bits;
}
n--;
}
}
}
/* ===========================================================================
* Generate the codes for a given tree and bit counts (which need not be
* optimal).
* IN assertion: the array bl_count contains the bit length statistics for
* the given tree and the field len is set for all tree elements.
* OUT assertion: the field code is set for all tree elements of non
* zero code length.
*/
local void gen_codes (tree, max_code, bl_count)
ct_data *tree; /* the tree to decorate */
int max_code; /* largest code with non zero frequency */
ushf *bl_count; /* number of codes at each bit length */
{
ush next_code[MAX_BITS+1]; /* next code value for each bit length */
unsigned code = 0; /* running code value */
int bits; /* bit index */
int n; /* code index */
/* The distribution counts are first used to generate the code values
* without bit reversal.
*/
for (bits = 1; bits <= MAX_BITS; bits++) {
code = (code + bl_count[bits-1]) << 1;
next_code[bits] = (ush)code;
}
/* Check that the bit counts in bl_count are consistent. The last code
* must be all ones.
*/
Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
"inconsistent bit counts");
Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
for (n = 0; n <= max_code; n++) {
int len = tree[n].Len;
if (len == 0) continue;
/* Now reverse the bits */
tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
}
}
/* ===========================================================================
* Construct one Huffman tree and assigns the code bit strings and lengths.
* Update the total bit length for the current block.
* IN assertion: the field freq is set for all tree elements.
* OUT assertions: the fields len and code are set to the optimal bit length
* and corresponding code. The length opt_len is updated; static_len is
* also updated if stree is not null. The field max_code is set.
*/
local void build_tree(s, desc)
deflate_state *s;
tree_desc *desc; /* the tree descriptor */
{
ct_data *tree = desc->dyn_tree;
const ct_data *stree = desc->stat_desc->static_tree;
int elems = desc->stat_desc->elems;
int n, m; /* iterate over heap elements */
int max_code = -1; /* largest code with non zero frequency */
int node; /* new node being created */
/* Construct the initial heap, with least frequent element in
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
* heap[0] is not used.
*/
s->heap_len = 0, s->heap_max = HEAP_SIZE;
for (n = 0; n < elems; n++) {
if (tree[n].Freq != 0) {
s->heap[++(s->heap_len)] = max_code = n;
s->depth[n] = 0;
} else {
tree[n].Len = 0;
}
}
/* The pkzip format requires that at least one distance code exists,
* and that at least one bit should be sent even if there is only one
* possible code. So to avoid special checks later on we force at least
* two codes of non zero frequency.
*/
while (s->heap_len < 2) {
node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
tree[node].Freq = 1;
s->depth[node] = 0;
s->opt_len--; if (stree) s->static_len -= stree[node].Len;
/* node is 0 or 1 so it does not have extra bits */
}
desc->max_code = max_code;
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
* establish sub-heaps of increasing lengths:
*/
for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
/* Construct the Huffman tree by repeatedly combining the least two
* frequent nodes.
*/
node = elems; /* next internal node of the tree */
do {
pqremove(s, tree, n); /* n = node of least frequency */
m = s->heap[SMALLEST]; /* m = node of next least frequency */
s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
s->heap[--(s->heap_max)] = m;
/* Create a new node father of n and m */
tree[node].Freq = tree[n].Freq + tree[m].Freq;
s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
s->depth[n] : s->depth[m]) + 1);
tree[n].Dad = tree[m].Dad = (ush)node;
#ifdef DUMP_BL_TREE
if (tree == s->bl_tree) {
fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
}
#endif
/* and insert the new node in the heap */
s->heap[SMALLEST] = node++;
pqdownheap(s, tree, SMALLEST);
} while (s->heap_len >= 2);
s->heap[--(s->heap_max)] = s->heap[SMALLEST];
/* At this point, the fields freq and dad are set. We can now
* generate the bit lengths.
*/
gen_bitlen(s, (tree_desc *)desc);
/* The field len is now set, we can generate the bit codes */
gen_codes ((ct_data *)tree, max_code, s->bl_count);
}
/* ===========================================================================
* Scan a literal or distance tree to determine the frequencies of the codes
* in the bit length tree.
*/
local void scan_tree (s, tree, max_code)
deflate_state *s;
ct_data *tree; /* the tree to be scanned */
int max_code; /* and its largest code of non zero frequency */
{
int n; /* iterates over all tree elements */
int prevlen = -1; /* last emitted length */
int curlen; /* length of current code */
int nextlen = tree[0].Len; /* length of next code */
int count = 0; /* repeat count of the current code */
int max_count = 7; /* max repeat count */
int min_count = 4; /* min repeat count */
if (nextlen == 0) max_count = 138, min_count = 3;
tree[max_code+1].Len = (ush)0xffff; /* guard */
for (n = 0; n <= max_code; n++) {
curlen = nextlen; nextlen = tree[n+1].Len;
if (++count < max_count && curlen == nextlen) {
continue;
} else if (count < min_count) {
s->bl_tree[curlen].Freq += count;
} else if (curlen != 0) {
if (curlen != prevlen) s->bl_tree[curlen].Freq++;
s->bl_tree[REP_3_6].Freq++;
} else if (count <= 10) {
s->bl_tree[REPZ_3_10].Freq++;
} else {
s->bl_tree[REPZ_11_138].Freq++;
}
count = 0; prevlen = curlen;
if (nextlen == 0) {
max_count = 138, min_count = 3;
} else if (curlen == nextlen) {
max_count = 6, min_count = 3;
} else {
max_count = 7, min_count = 4;
}
}
}
/* ===========================================================================
* Send a literal or distance tree in compressed form, using the codes in
* bl_tree.
*/
local void send_tree (s, tree, max_code)
deflate_state *s;
ct_data *tree; /* the tree to be scanned */
int max_code; /* and its largest code of non zero frequency */
{
int n; /* iterates over all tree elements */
int prevlen = -1; /* last emitted length */
int curlen; /* length of current code */
int nextlen = tree[0].Len; /* length of next code */
int count = 0; /* repeat count of the current code */
int max_count = 7; /* max repeat count */
int min_count = 4; /* min repeat count */
/* tree[max_code+1].Len = -1; */ /* guard already set */
if (nextlen == 0) max_count = 138, min_count = 3;
for (n = 0; n <= max_code; n++) {
curlen = nextlen; nextlen = tree[n+1].Len;
if (++count < max_count && curlen == nextlen) {
continue;
} else if (count < min_count) {
do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
} else if (curlen != 0) {
if (curlen != prevlen) {
send_code(s, curlen, s->bl_tree); count--;
}
Assert(count >= 3 && count <= 6, " 3_6?");
send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
} else if (count <= 10) {
send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
} else {
send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
}
count = 0; prevlen = curlen;
if (nextlen == 0) {
max_count = 138, min_count = 3;
} else if (curlen == nextlen) {
max_count = 6, min_count = 3;
} else {
max_count = 7, min_count = 4;
}
}
}
/* ===========================================================================
* Construct the Huffman tree for the bit lengths and return the index in
* bl_order of the last bit length code to send.
*/
local int build_bl_tree(s)
deflate_state *s;
{
int max_blindex; /* index of last bit length code of non zero freq */
/* Determine the bit length frequencies for literal and distance trees */
scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
/* Build the bit length tree: */
build_tree(s, (tree_desc *)(&(s->bl_desc)));
/* opt_len now includes the length of the tree representations, except
* the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
*/
/* Determine the number of bit length codes to send. The pkzip format
* requires that at least 4 bit length codes be sent. (appnote.txt says
* 3 but the actual value used is 4.)
*/
for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
}
/* Update opt_len to include the bit length tree and counts */
s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
s->opt_len, s->static_len));
return max_blindex;
}
/* ===========================================================================
* Send the header for a block using dynamic Huffman trees: the counts, the
* lengths of the bit length codes, the literal tree and the distance tree.
* IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
*/
local void send_all_trees(s, lcodes, dcodes, blcodes)
deflate_state *s;
int lcodes, dcodes, blcodes; /* number of codes for each tree */
{
int rank; /* index in bl_order */
Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
"too many codes");
Tracev((stderr, "\nbl counts: "));
send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
send_bits(s, dcodes-1, 5);
send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
for (rank = 0; rank < blcodes; rank++) {
Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
}
Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
}
/* ===========================================================================
* Send a stored block
*/
void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
deflate_state *s;
charf *buf; /* input block */
ulg stored_len; /* length of input block */
int last; /* one if this is the last block for a file */
{
send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
bi_windup(s); /* align on byte boundary */
put_short(s, (ush)stored_len);
put_short(s, (ush)~stored_len);
- zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
+ if (stored_len)
+ zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
s->pending += stored_len;
#ifdef ZLIB_DEBUG
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
s->compressed_len += (stored_len + 4) << 3;
s->bits_sent += 2*16;
s->bits_sent += stored_len<<3;
#endif
}
/* ===========================================================================
* Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
*/
void ZLIB_INTERNAL _tr_flush_bits(s)
deflate_state *s;
{
bi_flush(s);
}
/* ===========================================================================
* Send one empty static block to give enough lookahead for inflate.
* This takes 10 bits, of which 7 may remain in the bit buffer.
*/
void ZLIB_INTERNAL _tr_align(s)
deflate_state *s;
{
send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree);
#ifdef ZLIB_DEBUG
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
#endif
bi_flush(s);
}
/* ===========================================================================
* Determine the best encoding for the current block: dynamic trees, static
* trees or store, and write out the encoded block.
*/
void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
deflate_state *s;
charf *buf; /* input block, or NULL if too old */
ulg stored_len; /* length of input block */
int last; /* one if this is the last block for a file */
{
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
int max_blindex = 0; /* index of last bit length code of non zero freq */
/* Build the Huffman trees unless a stored block is forced */
if (s->level > 0) {
/* Check if the file is binary or text */
if (s->strm->data_type == Z_UNKNOWN)
s->strm->data_type = detect_data_type(s);
/* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc)));
Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
s->static_len));
build_tree(s, (tree_desc *)(&(s->d_desc)));
Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
s->static_len));
/* At this point, opt_len and static_len are the total bit lengths of
* the compressed block data, excluding the tree representations.
*/
/* Build the bit length tree for the above two trees, and get the index
* in bl_order of the last bit length code to send.
*/
max_blindex = build_bl_tree(s);
/* Determine the best encoding. Compute the block lengths in bytes. */
opt_lenb = (s->opt_len+3+7)>>3;
static_lenb = (s->static_len+3+7)>>3;
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
+ s->sym_next / 3));
if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
} else {
Assert(buf != (char*)0, "lost buf");
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
}
#ifdef FORCE_STORED
if (buf != (char*)0) { /* force stored block */
#else
if (stored_len+4 <= opt_lenb && buf != (char*)0) {
/* 4: two words for the lengths */
#endif
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
* Otherwise we can't have processed more than WSIZE input bytes since
* the last block flush, because compression would have been
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
* transform a block into a stored block.
*/
_tr_stored_block(s, buf, stored_len, last);
#ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */
#else
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif
send_bits(s, (STATIC_TREES<<1)+last, 3);
compress_block(s, (const ct_data *)static_ltree,
(const ct_data *)static_dtree);
#ifdef ZLIB_DEBUG
s->compressed_len += 3 + s->static_len;
#endif
} else {
send_bits(s, (DYN_TREES<<1)+last, 3);
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
max_blindex+1);
compress_block(s, (const ct_data *)s->dyn_ltree,
(const ct_data *)s->dyn_dtree);
#ifdef ZLIB_DEBUG
s->compressed_len += 3 + s->opt_len;
#endif
}
Assert (s->compressed_len == s->bits_sent, "bad compressed size");
/* The above check is made mod 2^32, for files larger than 512 MB
* and uLong implemented on 32 bits.
*/
init_block(s);
if (last) {
bi_windup(s);
#ifdef ZLIB_DEBUG
s->compressed_len += 7; /* align on byte boundary */
#endif
}
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
s->compressed_len-7*last));
}
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
*/
int ZLIB_INTERNAL _tr_tally (s, dist, lc)
deflate_state *s;
unsigned dist; /* distance of matched string */
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
+ s->sym_buf[s->sym_next++] = dist;
+ s->sym_buf[s->sym_next++] = dist >> 8;
+ s->sym_buf[s->sym_next++] = lc;
if (dist == 0) {
/* lc is the unmatched char */
s->dyn_ltree[lc].Freq++;
} else {
s->matches++;
/* Here, lc is the match length - MIN_MATCH */
dist--; /* dist = match distance - 1 */
Assert((ush)dist < (ush)MAX_DIST(s) &&
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
(ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
s->dyn_dtree[d_code(dist)].Freq++;
}
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
+ return (s->sym_next == s->sym_end);
}
/* ===========================================================================
* Send the block data compressed using the given Huffman trees
*/
local void compress_block(s, ltree, dtree)
deflate_state *s;
const ct_data *ltree; /* literal tree */
const ct_data *dtree; /* distance tree */
{
unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
+ unsigned sx = 0; /* running index in sym_buf */
unsigned code; /* the code to send */
int extra; /* number of extra bits to send */
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
+ if (s->sym_next != 0) do {
+ dist = s->sym_buf[sx++] & 0xff;
+ dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
+ lc = s->sym_buf[sx++];
if (dist == 0) {
send_code(s, lc, ltree); /* send a literal byte */
Tracecv(isgraph(lc), (stderr," '%c' ", lc));
} else {
/* Here, lc is the match length - MIN_MATCH */
code = _length_code[lc];
send_code(s, code+LITERALS+1, ltree); /* send the length code */
extra = extra_lbits[code];
if (extra != 0) {
lc -= base_length[code];
send_bits(s, lc, extra); /* send the extra length bits */
}
dist--; /* dist is now the match distance - 1 */
code = d_code(dist);
Assert (code < D_CODES, "bad d_code");
send_code(s, code, dtree); /* send the distance code */
extra = extra_dbits[code];
if (extra != 0) {
dist -= (unsigned)base_dist[code];
send_bits(s, dist, extra); /* send the extra distance bits */
}
} /* literal or match pair ? */
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
- "pendingBuf overflow");
+ /* Check that the overlay between pending_buf and sym_buf is ok: */
+ Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
- } while (lx < s->last_lit);
+ } while (sx < s->sym_next);
send_code(s, END_BLOCK, ltree);
}
/* ===========================================================================
* Check if the data type is TEXT or BINARY, using the following algorithm:
* - TEXT if the two conditions below are satisfied:
* a) There are no non-portable control characters belonging to the
- * "black list" (0..6, 14..25, 28..31).
+ * "block list" (0..6, 14..25, 28..31).
* b) There is at least one printable character belonging to the
- * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
* - BINARY otherwise.
* - The following partially-portable control characters form a
* "gray list" that is ignored in this detection algorithm:
* (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
* IN assertion: the fields Freq of dyn_ltree are set.
*/
local int detect_data_type(s)
deflate_state *s;
{
- /* black_mask is the bit mask of black-listed bytes
+ /* block_mask is the bit mask of block-listed bytes
* set bits 0..6, 14..25, and 28..31
* 0xf3ffc07f = binary 11110011111111111100000001111111
*/
- unsigned long black_mask = 0xf3ffc07fUL;
+ unsigned long block_mask = 0xf3ffc07fUL;
int n;
- /* Check for non-textual ("black-listed") bytes. */
- for (n = 0; n <= 31; n++, black_mask >>= 1)
- if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+ /* Check for non-textual ("block-listed") bytes. */
+ for (n = 0; n <= 31; n++, block_mask >>= 1)
+ if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
return Z_BINARY;
- /* Check for textual ("white-listed") bytes. */
+ /* Check for textual ("allow-listed") bytes. */
if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
|| s->dyn_ltree[13].Freq != 0)
return Z_TEXT;
for (n = 32; n < LITERALS; n++)
if (s->dyn_ltree[n].Freq != 0)
return Z_TEXT;
- /* There are no "black-listed" or "white-listed" bytes:
+ /* There are no "block-listed" or "allow-listed" bytes:
* this stream either is empty or has tolerated ("gray-listed") bytes only.
*/
return Z_BINARY;
}
/* ===========================================================================
* Reverse the first len bits of a code, using straightforward code (a faster
* method would use a table)
* IN assertion: 1 <= len <= 15
*/
local unsigned bi_reverse(code, len)
unsigned code; /* the value to invert */
int len; /* its bit length */
{
register unsigned res = 0;
do {
res |= code & 1;
code >>= 1, res <<= 1;
} while (--len > 0);
return res >> 1;
}
/* ===========================================================================
* Flush the bit buffer, keeping at most 7 bits in it.
*/
local void bi_flush(s)
deflate_state *s;
{
if (s->bi_valid == 16) {
put_short(s, s->bi_buf);
s->bi_buf = 0;
s->bi_valid = 0;
} else if (s->bi_valid >= 8) {
put_byte(s, (Byte)s->bi_buf);
s->bi_buf >>= 8;
s->bi_valid -= 8;
}
}
/* ===========================================================================
* Flush the bit buffer and align the output on a byte boundary
*/
local void bi_windup(s)
deflate_state *s;
{
if (s->bi_valid > 8) {
put_short(s, s->bi_buf);
} else if (s->bi_valid > 0) {
put_byte(s, (Byte)s->bi_buf);
}
s->bi_buf = 0;
s->bi_valid = 0;
#ifdef ZLIB_DEBUG
s->bits_sent = (s->bits_sent+7) & ~7;
#endif
}
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/trees.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/trees.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/trees.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/trees.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/uncompr.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/uncompr.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/uncompr.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/uncompr.c
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zconf.h.in b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zconf.h.in
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zconf.h.in
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zconf.h.in
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zlib.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zlib.h
similarity index 91%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zlib.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zlib.h
index f09cdaf1..4a98e38b 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zlib.h
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zlib.h
@@ -1,1912 +1,1935 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.11, January 15th, 2017
+ version 1.2.12, March 11th, 2022
- Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef ZLIB_H
#define ZLIB_H
#include "zconf.h"
#ifdef __cplusplus
extern "C" {
#endif
-#define ZLIB_VERSION "1.2.11"
-#define ZLIB_VERNUM 0x12b0
+#define ZLIB_VERSION "1.2.12"
+#define ZLIB_VERNUM 0x12c0
#define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 11
+#define ZLIB_VER_REVISION 12
#define ZLIB_VER_SUBREVISION 0
/*
The 'zlib' compression library provides in-memory compression and
decompression functions, including integrity checks of the uncompressed data.
This version of the library supports only one compression method (deflation)
but other algorithms will be added later and will have the same stream
interface.
Compression can be done in a single step if the buffers are large enough,
or can be done by repeated calls of the compression function. In the latter
case, the application must provide more input and/or consume the output
(providing more output space) before each call.
The compressed data format used by default by the in-memory functions is
the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
around a deflate stream, which is itself documented in RFC 1951.
The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio using the functions that start
with "gz". The gzip format is different from the zlib format. gzip is a
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
This library can optionally read and write gzip and raw deflate streams in
memory as well.
The zlib format was designed to be compact and fast for use in memory
and on communications channels. The gzip format was designed for single-
file compression on file systems, has a larger header than zlib to maintain
directory information, and uses a different, slower check method than zlib.
The library does not install any signal handler. The decoder checks
the consistency of the compressed data, so the library should never crash
even in the case of corrupted input.
*/
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
typedef void (*free_func) OF((voidpf opaque, voidpf address));
struct internal_state;
typedef struct z_stream_s {
z_const Bytef *next_in; /* next input byte */
uInt avail_in; /* number of bytes available at next_in */
uLong total_in; /* total number of input bytes read so far */
Bytef *next_out; /* next output byte will go here */
uInt avail_out; /* remaining free space at next_out */
uLong total_out; /* total number of bytes output so far */
z_const char *msg; /* last error message, NULL if no error */
struct internal_state FAR *state; /* not visible by applications */
alloc_func zalloc; /* used to allocate the internal state */
free_func zfree; /* used to free the internal state */
voidpf opaque; /* private data object passed to zalloc and zfree */
int data_type; /* best guess about the data type: binary or text
for deflate, or the decoding state for inflate */
uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */
uLong reserved; /* reserved for future use */
} z_stream;
typedef z_stream FAR *z_streamp;
/*
gzip header information passed to and from zlib routines. See RFC 1952
for more details on the meanings of these fields.
*/
typedef struct gz_header_s {
int text; /* true if compressed data believed to be text */
uLong time; /* modification time */
int xflags; /* extra flags (not used when writing a gzip file) */
int os; /* operating system */
Bytef *extra; /* pointer to extra field or Z_NULL if none */
uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
uInt extra_max; /* space at extra (only when reading header) */
Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
uInt name_max; /* space at name (only when reading header) */
Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
uInt comm_max; /* space at comment (only when reading header) */
int hcrc; /* true if there was or will be a header crc */
int done; /* true when done reading gzip header (not used
when writing a gzip file) */
} gz_header;
typedef gz_header FAR *gz_headerp;
/*
The application must update next_in and avail_in when avail_in has dropped
to zero. It must update next_out and avail_out when avail_out has dropped
to zero. The application must initialize zalloc, zfree and opaque before
calling the init function. All other fields are set by the compression
library and must not be updated by the application.
The opaque value provided by the application will be passed as the first
parameter for calls of zalloc and zfree. This can be useful for custom
memory management. The compression library attaches no meaning to the
opaque value.
zalloc must return Z_NULL if there is not enough memory for the object.
If zlib is used in a multi-threaded application, zalloc and zfree must be
thread safe. In that case, zlib is thread-safe. When zalloc and zfree are
Z_NULL on entry to the initialization function, they are set to internal
routines that use the standard library functions malloc() and free().
On 16-bit systems, the functions zalloc and zfree must be able to allocate
exactly 65536 bytes, but will not be required to allocate more than this if
the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
returned by zalloc for objects of exactly 65536 bytes *must* have their
offset normalized to zero. The default allocation function provided by this
library ensures this (see zutil.c). To reduce memory requirements and avoid
any allocation of 64K objects, at the expense of compression ratio, compile
the library with -DMAX_WBITS=14 (see zconf.h).
The fields total_in and total_out can be used for statistics or progress
reports. After compression, total_in holds the total size of the
uncompressed data and may be saved for use by the decompressor (particularly
if the decompressor wants to decompress everything in a single step).
*/
/* constants */
#define Z_NO_FLUSH 0
#define Z_PARTIAL_FLUSH 1
#define Z_SYNC_FLUSH 2
#define Z_FULL_FLUSH 3
#define Z_FINISH 4
#define Z_BLOCK 5
#define Z_TREES 6
/* Allowed flush values; see deflate() and inflate() below for details */
#define Z_OK 0
#define Z_STREAM_END 1
#define Z_NEED_DICT 2
#define Z_ERRNO (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR (-3)
#define Z_MEM_ERROR (-4)
#define Z_BUF_ERROR (-5)
#define Z_VERSION_ERROR (-6)
/* Return codes for the compression/decompression functions. Negative values
* are errors, positive values are used for special but normal events.
*/
#define Z_NO_COMPRESSION 0
#define Z_BEST_SPEED 1
#define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_COMPRESSION (-1)
/* compression levels */
#define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
#define Z_FIXED 4
#define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */
#define Z_BINARY 0
#define Z_TEXT 1
#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
#define Z_UNKNOWN 2
/* Possible values of the data_type field for deflate() */
#define Z_DEFLATED 8
/* The deflate compression method (the only one supported in this version) */
#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
#define zlib_version zlibVersion()
/* for compatibility with versions < 1.0.2 */
/* basic functions */
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
If the first character differs, the library code actually used is not
compatible with the zlib.h header file used by the application. This check
is automatically made by deflateInit and inflateInit.
*/
/*
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
Initializes the internal stream state for compression. The fields
zalloc, zfree and opaque must be initialized before by the caller. If
zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
allocation functions.
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
1 gives best speed, 9 gives best compression, 0 gives no compression at all
(the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
requests a default compromise between speed and compression (currently
equivalent to level 6).
deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if level is not a valid compression level, or
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
with the version assumed by the caller (ZLIB_VERSION). msg is set to null
if there is no error message. deflateInit does not perform any compression:
this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
/*
deflate compresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may introduce
some output latency (reading input without producing any output) except when
forced to flush.
The detailed semantics are as follows. deflate performs one or both of the
following actions:
- Compress more input starting at next_in and update next_in and avail_in
accordingly. If not all input can be processed (because there is not
enough room in the output buffer), next_in and avail_in are updated and
processing will resume at this point for the next call of deflate().
- Generate more output starting at next_out and update next_out and avail_out
accordingly. This action is forced if the parameter flush is non zero.
Forcing flush frequently degrades the compression ratio, so this parameter
should be set only when necessary. Some output may be provided even if
flush is zero.
Before the call of deflate(), the application should ensure that at least
one of the actions is possible, by providing more input and/or consuming more
output, and updating avail_in or avail_out accordingly; avail_out should
never be zero before the call. The application can consume the compressed
output when it wants, for example when the output buffer is full (avail_out
== 0), or after each call of deflate(). If deflate returns Z_OK and with
zero avail_out, it must be called again after making room in the output
buffer because there might be more output pending. See deflatePending(),
which can be used if desired to determine whether or not there is more ouput
in that case.
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
decide how much data to accumulate before producing output, in order to
maximize compression.
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
flushed to the output buffer and the output is aligned on a byte boundary, so
that the decompressor can get all input data available so far. (In
particular avail_in is zero after the call if enough output space has been
provided before the call.) Flushing may degrade compression for some
compression algorithms and so it should be used only when necessary. This
completes the current deflate block and follows it with an empty stored block
that is three bits plus filler bits to the next byte, followed by four bytes
(00 00 ff ff).
If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
output buffer, but the output is not aligned to a byte boundary. All of the
input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
This completes the current deflate block and follows it with an empty fixed
codes block that is 10 bits long. This assures that enough bytes are output
in order for the decompressor to finish the block before the empty fixed
codes block.
If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
seven bits of the current block are held to be written as the next byte after
the next deflate block is completed. In this case, the decompressor may not
be provided enough bits at this point in order to complete decompression of
the data provided so far to the compressor. It may need to wait for the next
block to be emitted. This is for advanced applications that need to control
the emission of deflate blocks.
If flush is set to Z_FULL_FLUSH, all output is flushed as with
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
compression.
If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated
avail_out), until the flush is complete (deflate returns with non-zero
avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
avail_out is greater than six to avoid repeated flush markers due to
avail_out == 0 on return.
If the parameter flush is set to Z_FINISH, pending input is processed,
pending output is flushed and deflate returns with Z_STREAM_END if there was
enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this
function must be called again with Z_FINISH and more output space (updated
avail_out) but no more input data, until it returns with Z_STREAM_END or an
error. After deflate has returned Z_STREAM_END, the only possible operations
on the stream are deflateReset or deflateEnd.
Z_FINISH can be used in the first deflate call after deflateInit if all the
compression is to be done in a single step. In order to complete in one
call, avail_out must be at least the value returned by deflateBound (see
below). Then deflate is guaranteed to return Z_STREAM_END. If not enough
output space is provided, deflate will not return Z_STREAM_END, and it must
be called again as described above.
deflate() sets strm->adler to the Adler-32 checksum of all input read
so far (that is, total_in bytes). If a gzip stream is being generated, then
strm->adler will be the CRC-32 checksum of the input read so far. (See
deflateInit2 below.)
deflate() may update strm->data_type if it can make a good guess about
the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is
considered binary. This field is only for information purposes and does not
affect the compression algorithm in any manner.
deflate() returns Z_OK if some progress has been made (more input
processed or more output produced), Z_STREAM_END if all input has been
consumed and all output has been produced (only when flush is set to
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
if next_in or next_out was Z_NULL or the state was inadvertently written over
by the application), or Z_BUF_ERROR if no progress is possible (for example
avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and
deflate() can be called again with more input and more output space to
continue compressing.
*/
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any pending
output.
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
stream state was inconsistent, Z_DATA_ERROR if the stream was freed
prematurely (some input or output was discarded). In the error case, msg
may be set but then points to a static string (which must not be
deallocated).
*/
/*
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
Initializes the internal stream state for decompression. The fields
next_in, avail_in, zalloc, zfree and opaque must be initialized before by
the caller. In the current version of inflate, the provided input is not
read or consumed. The allocation of a sliding window will be deferred to
the first call of inflate (if the decompression does not complete on the
first call). If zalloc and zfree are set to Z_NULL, inflateInit updates
them to use default allocation functions.
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
version assumed by the caller, or Z_STREAM_ERROR if the parameters are
invalid, such as a null pointer to the structure. msg is set to null if
there is no error message. inflateInit does not perform any decompression.
Actual decompression will be done by inflate(). So next_in, and avail_in,
next_out, and avail_out are unused and unchanged. The current
implementation of inflateInit() does not process any header information --
that is deferred until inflate() is called.
*/
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
/*
inflate decompresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may introduce
some output latency (reading input without producing any output) except when
forced to flush.
The detailed semantics are as follows. inflate performs one or both of the
following actions:
- Decompress more input starting at next_in and update next_in and avail_in
accordingly. If not all input can be processed (because there is not
enough room in the output buffer), then next_in and avail_in are updated
accordingly, and processing will resume at this point for the next call of
inflate().
- Generate more output starting at next_out and update next_out and avail_out
accordingly. inflate() provides as much output as possible, until there is
no more input data or no more space in the output buffer (see below about
the flush parameter).
Before the call of inflate(), the application should ensure that at least
one of the actions is possible, by providing more input and/or consuming more
output, and updating the next_* and avail_* values accordingly. If the
caller of inflate() does not provide both available input and available
output space, it is possible that there will be no progress made. The
application can consume the uncompressed output when it wants, for example
when the output buffer is full (avail_out == 0), or after each call of
inflate(). If inflate returns Z_OK and with zero avail_out, it must be
called again after making room in the output buffer because there might be
more output pending.
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
output as possible to the output buffer. Z_BLOCK requests that inflate()
stop if and when it gets to the next deflate block boundary. When decoding
the zlib or gzip format, this will cause inflate() to return immediately
after the header and before the first block. When doing a raw inflate,
inflate() will go ahead and process the first block, and will return when it
gets to the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams.
To assist in this, on return inflate() always sets strm->data_type to the
number of unused bits in the last byte taken from strm->next_in, plus 64 if
inflate() is currently decoding the last block in the deflate stream, plus
128 if inflate() returned immediately after decoding an end-of-block code or
decoding the complete header up to just before the first byte of the deflate
stream. The end-of-block will not be indicated until all of the uncompressed
data from that block has been written to strm->next_out. The number of
unused bits may in general be greater than seven, except when bit 7 of
data_type is set, in which case the number of unused bits will be less than
eight. data_type is set as noted here every time inflate() returns for all
flush options, and so can be used to determine the amount of currently
consumed input in bits.
The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
end of each deflate block header is reached, before any actual data in that
block is decoded. This allows the caller to determine the length of the
deflate block header for later use in random access within a deflate block.
256 is added to the value of strm->data_type when inflate() returns
immediately after reaching the end of the deflate block header.
inflate() should normally be called until it returns Z_STREAM_END or an
error. However if all decompression is to be performed in a single step (a
single call of inflate), the parameter flush should be set to Z_FINISH. In
this case all pending input is processed and all pending output is flushed;
avail_out must be large enough to hold all of the uncompressed data for the
operation to complete. (The size of the uncompressed data may have been
saved by the compressor for this purpose.) The use of Z_FINISH is not
required to perform an inflation in one step. However it may be used to
inform inflate that a faster approach can be used for the single inflate()
call. Z_FINISH also informs inflate to not maintain a sliding window if the
stream completes, which reduces inflate's memory footprint. If the stream
does not complete, either because not all of the stream is provided or not
enough output space is provided, then a sliding window will be allocated and
inflate() can be called again to continue the operation as if Z_NO_FLUSH had
been used.
In this implementation, inflate() always flushes as much output as
possible to the output buffer, and always uses the faster approach on the
first call. So the effects of the flush parameter in this implementation are
on the return value of inflate() as noted below, when inflate() returns early
when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
memory for a sliding window when Z_FINISH is used.
If a preset dictionary is needed after this call (see inflateSetDictionary
below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
strm->adler to the Adler-32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
below. At the end of the stream, inflate() checks that its computed Adler-32
checksum is equal to that saved by the compressor and returns Z_STREAM_END
only if the checksum is correct.
inflate() can decompress and check either zlib-wrapped or gzip-wrapped
deflate data. The header type is detected automatically, if requested when
initializing with inflateInit2(). Any information contained in the gzip
header is not retained unless inflateGetHeader() is used. When processing
gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
produced so far. The CRC-32 is checked against the gzip trailer, as is the
uncompressed length, modulo 2^32.
inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has
been reached and all uncompressed output has been produced, Z_NEED_DICT if a
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
corrupted (input stream not conforming to the zlib format or incorrect check
value, in which case strm->msg points to a string with a more specific
error), Z_STREAM_ERROR if the stream structure was inconsistent (for example
next_in or next_out was Z_NULL, or the state was inadvertently written over
by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR
if no progress was possible or if there was not enough room in the output
buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
inflate() can be called again with more input and more output space to
continue decompressing. If Z_DATA_ERROR is returned, the application may
then call inflateSync() to look for a good compression block if a partial
recovery of the data is to be attempted.
*/
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any pending
output.
inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state
was inconsistent.
*/
/* Advanced functions */
/*
The following functions are needed only in some special applications.
*/
/*
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
int level,
int method,
int windowBits,
int memLevel,
int strategy));
This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by the
- caller.
+ fields zalloc, zfree and opaque must be initialized before by the caller.
The method parameter is the compression method. It must be Z_DEFLATED in
this version of the library.
The windowBits parameter is the base two logarithm of the window size
(the size of the history buffer). It should be in the range 8..15 for this
version of the library. Larger values of this parameter result in better
compression at the expense of memory usage. The default value is 15 if
deflateInit is used instead.
For the current implementation of deflate(), a windowBits value of 8 (a
window size of 256 bytes) is not supported. As a result, a request for 8
will result in 9 (a 512-byte window). In that case, providing 8 to
inflateInit2() will result in an error when the zlib header with 9 is
checked against the initialization of inflate(). The remedy is to not use 8
with deflateInit2() with this initialization, or at least in that case use 9
with inflateInit2().
windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
determines the window size. deflate() will then generate raw deflate data
with no zlib header or trailer, and will not compute a check value.
windowBits can also be greater than 15 for optional gzip encoding. Add
16 to windowBits to write a simple gzip header and trailer around the
compressed data instead of a zlib wrapper. The gzip header will have no
file name, no extra data, no comment, no modification time (set to zero), no
header crc, and the operating system will be set to the appropriate value,
if the operating system was determined at compile time. If a gzip stream is
being written, strm->adler is a CRC-32 instead of an Adler-32.
For raw deflate or gzip encoding, a request for a 256-byte window is
rejected as invalid, since only the zlib header provides a means of
transmitting the window size to the decompressor.
The memLevel parameter specifies how much memory should be allocated
for the internal compression state. memLevel=1 uses minimum memory but is
slow and reduces compression ratio; memLevel=9 uses maximum memory for
optimal speed. The default value is 8. See zconf.h for total memory usage
as a function of windowBits and memLevel.
The strategy parameter is used to tune the compression algorithm. Use the
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
string match), or Z_RLE to limit match distances to one (run-length
encoding). Filtered data consists mostly of small values with a somewhat
random distribution. In this case, the compression algorithm is tuned to
compress them better. The effect of Z_FILTERED is to force more Huffman
coding and less string matching; it is somewhat intermediate between
Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
strategy parameter only affects the compression ratio but not the
correctness of the compressed output even if it is not set appropriately.
Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
decoder for special applications.
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
set to null if there is no error message. deflateInit2 does not perform any
compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dictLength));
/*
Initializes the compression dictionary from the given byte sequence
without producing any compressed output. When using the zlib format, this
function must be called immediately after deflateInit, deflateInit2 or
deflateReset, and before any call of deflate. When doing raw deflate, this
function must be called either before any call of deflate, or immediately
after the completion of a deflate block, i.e. after all input has been
consumed and all output has been delivered when using any of the flush
options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
compressor and decompressor must use exactly the same dictionary (see
inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely
to be encountered later in the data to be compressed, with the most commonly
used strings preferably put towards the end of the dictionary. Using a
dictionary is most useful when the data to be compressed is short and can be
predicted with good accuracy; the data can then be compressed better than
with the default empty dictionary.
Depending on the size of the compression data structures selected by
deflateInit or deflateInit2, a part of the dictionary may in effect be
discarded, for example if the dictionary is larger than the window size
provided in deflateInit or deflateInit2. Thus the strings most likely to be
useful should be put at the end of the dictionary, not at the front. In
addition, the current implementation of deflate will use at most the window
size minus 262 bytes of the provided dictionary.
Upon return of this function, strm->adler is set to the Adler-32 value
of the dictionary; the decompressor may later use this value to determine
which dictionary has been used by the compressor. (The Adler-32 value
applies to the whole dictionary even if only a subset of the dictionary is
actually used by the compressor.) If a raw deflate was requested, then the
Adler-32 value is not computed and strm->adler is not set.
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent (for example if deflate has already been called for this stream
or if not at a block boundary for raw deflate). deflateSetDictionary does
not perform any compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
Bytef *dictionary,
uInt *dictLength));
/*
Returns the sliding dictionary being maintained by deflate. dictLength is
set to the number of bytes in the dictionary, and that many bytes are copied
to dictionary. dictionary must have enough space, where 32768 bytes is
always enough. If deflateGetDictionary() is called with dictionary equal to
Z_NULL, then only the dictionary length is returned, and nothing is copied.
Similary, if dictLength is Z_NULL, then it is not set.
deflateGetDictionary() may return a length less than the window size, even
when more than the window size in input has been provided. It may return up
to 258 bytes less in that case, due to how zlib's implementation of deflate
manages the sliding window and lookahead for matches, where matches can be
up to 258 bytes long. If the application needs the last window-size bytes of
input, then that would need to be saved by the application outside of zlib.
deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
stream state is inconsistent.
*/
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
z_streamp source));
/*
Sets the destination stream as a complete copy of the source stream.
This function can be useful when several compression strategies will be
tried, for example when there are several ways of pre-processing the input
data with a filter. The streams that will be discarded should then be freed
by calling deflateEnd. Note that deflateCopy duplicates the internal
compression state which can be quite large, so this strategy is slow and can
consume lots of memory.
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
(such as zalloc being Z_NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
/*
This function is equivalent to deflateEnd followed by deflateInit, but
does not free and reallocate the internal compression state. The stream
will leave the compression level and any other attributes that may have been
set unchanged.
deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent (such as zalloc or state being Z_NULL).
*/
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
int level,
int strategy));
/*
Dynamically update the compression level and compression strategy. The
interpretation of level and strategy is as in deflateInit2(). This can be
used to switch between compression and straight copy of the input data, or
to switch to a different kind of input data requiring a different strategy.
If the compression approach (which is a function of the level) or the
- strategy is changed, and if any input has been consumed in a previous
- deflate() call, then the input available so far is compressed with the old
- level and strategy using deflate(strm, Z_BLOCK). There are three approaches
- for the compression levels 0, 1..3, and 4..9 respectively. The new level
- and strategy will take effect at the next call of deflate().
+ strategy is changed, and if there have been any deflate() calls since the
+ state was initialized or reset, then the input available so far is
+ compressed with the old level and strategy using deflate(strm, Z_BLOCK).
+ There are three approaches for the compression levels 0, 1..3, and 4..9
+ respectively. The new level and strategy will take effect at the next call
+ of deflate().
If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
not have enough output space to complete, then the parameter change will not
take effect. In this case, deflateParams() can be called again with the
same parameters and more output space to try again.
In order to assure a change in the parameters on the first try, the
deflate stream should be flushed using deflate() with Z_BLOCK or other flush
request until strm.avail_out is not zero, before calling deflateParams().
Then no more input data should be provided before the deflateParams() call.
If this is done, the old level and strategy will be applied to the data
compressed before deflateParams(), and the new level and strategy will be
applied to the the data compressed after deflateParams().
deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
there was not enough output space to complete the compression of the
available input data before a change in the strategy or approach. Note that
in the case of a Z_BUF_ERROR, the parameters are not changed. A return
value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be
retried with more output space.
*/
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
int good_length,
int max_lazy,
int nice_length,
int max_chain));
/*
Fine tune deflate's internal compression parameters. This should only be
used by someone who understands the algorithm used by zlib's deflate for
searching for the best matching string, and even then only by the most
fanatic optimizer trying to squeeze out the last compressed bit for their
specific input data. Read the deflate.c source code for the meaning of the
max_lazy, good_length, nice_length, and max_chain parameters.
deflateTune() can be called after deflateInit() or deflateInit2(), and
returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
*/
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen));
/*
deflateBound() returns an upper bound on the compressed size after
deflation of sourceLen bytes. It must be called after deflateInit() or
deflateInit2(), and after deflateSetHeader(), if used. This would be used
to allocate an output buffer for deflation in a single pass, and so would be
called before deflate(). If that first deflate() call is provided the
sourceLen input bytes, an output buffer allocated to the size returned by
deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
to return Z_STREAM_END. Note that it is possible for the compressed size to
be larger than the value returned by deflateBound() if flush options other
than Z_FINISH or Z_NO_FLUSH are used.
*/
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
unsigned *pending,
int *bits));
/*
deflatePending() returns the number of bytes and bits of output that have
been generated, but not yet provided in the available output. The bytes not
provided would be due to the available output space having being consumed.
The number of bits of output not provided are between 0 and 7, where they
await more bits to join them in order to fill out a full byte. If pending
or bits are Z_NULL, then those values are not set.
deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits,
int value));
/*
deflatePrime() inserts bits in the deflate output stream. The intent
is that this function is used to start off the deflate output with the bits
leftover from a previous deflate stream when appending to it. As such, this
function can only be used for raw deflate, and must be used before the first
deflate() call after a deflateInit2() or deflateReset(). bits must be less
than or equal to 16, and that many of the least significant bits of value
will be inserted in the output.
deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
source stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
gz_headerp head));
/*
deflateSetHeader() provides gzip header information for when a gzip
stream is requested by deflateInit2(). deflateSetHeader() may be called
after deflateInit2() or deflateReset() and before the first call of
deflate(). The text, time, os, extra field, name, and comment information
in the provided gz_header structure are written to the gzip header (xflag is
ignored -- the extra flags are set according to the compression level). The
caller must assure that, if not Z_NULL, name and comment are terminated with
a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
available there. If hcrc is true, a gzip header crc is included. Note that
the current versions of the command-line version of gzip (up through version
1.3.x) do not support header crc's, and will report that it is a "multi-part
gzip file" and give up.
If deflateSetHeader is not used, the default gzip header has text false,
the time set to zero, and os set to 255, with no extra, name, or comment
fields. The gzip header is returned to the default state by deflateReset().
deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
/*
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
int windowBits));
This is another version of inflateInit with an extra parameter. The
fields next_in, avail_in, zalloc, zfree and opaque must be initialized
before by the caller.
The windowBits parameter is the base two logarithm of the maximum window
size (the size of the history buffer). It should be in the range 8..15 for
this version of the library. The default value is 15 if inflateInit is used
instead. windowBits must be greater than or equal to the windowBits value
provided to deflateInit2() while compressing, or it must be equal to 15 if
deflateInit2() was not used. If a compressed stream with a larger window
size is given as input, inflate() will return with the error code
Z_DATA_ERROR instead of trying to allocate a larger window.
windowBits can also be zero to request that inflate use the window size in
the zlib header of the compressed stream.
windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
determines the window size. inflate() will then process raw deflate data,
not looking for a zlib or gzip header, not generating a check value, and not
looking for any check values for comparison at the end of the stream. This
is for use with other formats that use the deflate compressed data format
such as zip. Those formats provide their own check values. If a custom
format is developed using the raw deflate format for compressed data, it is
recommended that a check value such as an Adler-32 or a CRC-32 be applied to
the uncompressed data as is done in the zlib, gzip, and zip formats. For
most applications, the zlib format should be used as is. Note that comments
above on the use in deflateInit2() applies to the magnitude of windowBits.
windowBits can also be greater than 15 for optional gzip decoding. Add
32 to windowBits to enable zlib and gzip decoding with automatic header
detection, or add 16 to decode only the gzip format (the zlib format will
return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see
- below), inflate() will not automatically decode concatenated gzip streams.
- inflate() will return Z_STREAM_END at the end of the gzip stream. The state
- would need to be reset to continue decoding a subsequent gzip stream.
+ below), inflate() will *not* automatically decode concatenated gzip members.
+ inflate() will return Z_STREAM_END at the end of the gzip member. The state
+ would need to be reset to continue decoding a subsequent gzip member. This
+ *must* be done if there is more data after a gzip member, in order for the
+ decompression to be compliant with the gzip standard (RFC 1952).
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
version assumed by the caller, or Z_STREAM_ERROR if the parameters are
invalid, such as a null pointer to the structure. msg is set to null if
there is no error message. inflateInit2 does not perform any decompression
apart from possibly reading the zlib header if present: actual decompression
will be done by inflate(). (So next_in and avail_in may be modified, but
next_out and avail_out are unused and unchanged.) The current implementation
of inflateInit2() does not process any header information -- that is
deferred until inflate() is called.
*/
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dictLength));
/*
Initializes the decompression dictionary from the given uncompressed byte
sequence. This function must be called immediately after a call of inflate,
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the Adler-32 value returned by that call of inflate.
The compressor and decompressor must use exactly the same dictionary (see
deflateSetDictionary). For raw inflate, this function can be called at any
time to set the dictionary. If the provided dictionary is smaller than the
window and there is already data in the window, then the provided dictionary
will amend what's there. The application must insure that the dictionary
that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
expected one (incorrect Adler-32 value). inflateSetDictionary does not
perform any decompression: this will be done by subsequent calls of
inflate().
*/
ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
Bytef *dictionary,
uInt *dictLength));
/*
Returns the sliding dictionary being maintained by inflate. dictLength is
set to the number of bytes in the dictionary, and that many bytes are copied
to dictionary. dictionary must have enough space, where 32768 bytes is
always enough. If inflateGetDictionary() is called with dictionary equal to
Z_NULL, then only the dictionary length is returned, and nothing is copied.
Similary, if dictLength is Z_NULL, then it is not set.
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
stream state is inconsistent.
*/
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
/*
Skips invalid compressed data until a possible full flush point (see above
for the description of deflate with Z_FULL_FLUSH) can be found, or until all
available input is skipped. No output is provided.
inflateSync searches for a 00 00 FF FF pattern in the compressed data.
All full flush points have this pattern, but not all occurrences of this
pattern are full flush points.
inflateSync returns Z_OK if a possible full flush point has been found,
Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
In the success case, the application may save the current current value of
total_in which indicates where valid compressed data was found. In the
error case, the application may repeatedly call inflateSync, providing more
input each time, until success or end of the input data.
*/
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
z_streamp source));
/*
Sets the destination stream as a complete copy of the source stream.
This function can be useful when randomly accessing a large stream. The
first pass through the stream can periodically record the inflate state,
allowing restarting inflate at those points when randomly accessing the
stream.
inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
(such as zalloc being Z_NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
/*
This function is equivalent to inflateEnd followed by inflateInit,
but does not free and reallocate the internal decompression state. The
stream will keep attributes that may have been set by inflateInit2.
inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent (such as zalloc or state being Z_NULL).
*/
ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
int windowBits));
/*
This function is the same as inflateReset, but it also permits changing
the wrap and window size requests. The windowBits parameter is interpreted
the same as it is for inflateInit2. If the window size is changed, then the
memory allocated for the window is freed, and the window will be reallocated
by inflate() if needed.
inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent (such as zalloc or state being Z_NULL), or if
the windowBits parameter is invalid.
*/
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
int bits,
int value));
/*
This function inserts bits in the inflate input stream. The intent is
that this function is used to start inflating at a bit position in the
middle of a byte. The provided bits will be used before any bytes are used
from next_in. This function should only be used with raw inflate, and
should be used before the first inflate() call after inflateInit2() or
inflateReset(). bits must be less than or equal to 16, and that many of the
least significant bits of value will be inserted in the input.
If bits is negative, then the input stream bit buffer is emptied. Then
inflatePrime() can be called again to put bits in the buffer. This is used
to clear out bits leftover after feeding inflate a block description prior
to feeding inflate codes.
inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
/*
This function returns two values, one in the lower 16 bits of the return
value, and the other in the remaining upper bits, obtained by shifting the
return value down 16 bits. If the upper value is -1 and the lower value is
zero, then inflate() is currently decoding information outside of a block.
If the upper value is -1 and the lower value is non-zero, then inflate is in
the middle of a stored block, with the lower value equaling the number of
bytes from the input remaining to copy. If the upper value is not -1, then
it is the number of bits back from the current bit position in the input of
the code (literal or length/distance pair) currently being processed. In
that case the lower value is the number of bytes already emitted for that
code.
A code is being processed if inflate is waiting for more input to complete
decoding of the code, or if it has completed decoding but is waiting for
more output space to write the literal or match data.
inflateMark() is used to mark locations in the input data for random
access, which may be at bit positions, and to note those cases where the
output of a code may span boundaries of random access blocks. The current
location in the input stream can be determined from avail_in and data_type
as noted in the description for the Z_BLOCK flush parameter for inflate.
inflateMark returns the value noted above, or -65536 if the provided
source stream state was inconsistent.
*/
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
gz_headerp head));
/*
inflateGetHeader() requests that gzip header information be stored in the
provided gz_header structure. inflateGetHeader() may be called after
inflateInit2() or inflateReset(), and before the first call of inflate().
As inflate() processes the gzip stream, head->done is zero until the header
is completed, at which time head->done is set to one. If a zlib stream is
being decoded, then head->done is set to -1 to indicate that there will be
no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
used to force inflate() to return immediately after header processing is
complete and before any actual data is decompressed.
The text, time, xflags, and os fields are filled in with the gzip header
contents. hcrc is set to true if there is a header CRC. (The header CRC
was valid if done is set to one.) If extra is not Z_NULL, then extra_max
contains the maximum number of bytes to write to extra. Once done is true,
extra_len contains the actual extra field length, and extra contains the
extra field, or that field truncated if extra_max is less than extra_len.
If name is not Z_NULL, then up to name_max characters are written there,
terminated with a zero unless the length is greater than name_max. If
comment is not Z_NULL, then up to comm_max characters are written there,
terminated with a zero unless the length is greater than comm_max. When any
of extra, name, or comment are not Z_NULL and the respective field is not
present in the header, then that field is set to Z_NULL to signal its
absence. This allows the use of deflateSetHeader() with the returned
structure to duplicate the header. However if those fields are set to
allocated memory, then the application will need to save those pointers
elsewhere so that they can be eventually freed.
If inflateGetHeader is not used, then the header information is simply
discarded. The header is always checked for validity, including the header
CRC if present. inflateReset() will reset the process to discard the header
information. The application would need to call inflateGetHeader() again to
retrieve the header from the next gzip stream.
inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
/*
ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
unsigned char FAR *window));
Initialize the internal stream state for decompression using inflateBack()
calls. The fields zalloc, zfree and opaque in strm must be initialized
before the call. If zalloc and zfree are Z_NULL, then the default library-
derived memory allocation routines are used. windowBits is the base two
logarithm of the window size, in the range 8..15. window is a caller
supplied buffer of that size. Except for special applications where it is
assured that deflate was used with small window sizes, windowBits must be 15
and a 32K byte window must be supplied to be able to decompress general
deflate streams.
See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
the parameters are invalid, Z_MEM_ERROR if the internal state could not be
allocated, or Z_VERSION_ERROR if the version of the library does not match
the version of the header file.
*/
typedef unsigned (*in_func) OF((void FAR *,
z_const unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
in_func in, void FAR *in_desc,
out_func out, void FAR *out_desc));
/*
inflateBack() does a raw inflate with a single call using a call-back
interface for input and output. This is potentially more efficient than
inflate() for file i/o applications, in that it avoids copying between the
output and the sliding window by simply making the window itself the output
buffer. inflate() can be faster on modern CPUs when used with large
buffers. inflateBack() trusts the application to not change the output
buffer passed by the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer.
inflateBack() may then be used multiple times to inflate a complete, raw
deflate stream with each call. inflateBackEnd() is then called to free the
allocated state.
A raw deflate stream is one with no zlib or gzip header or trailer.
This routine would normally be used in a utility that reads zip or gzip
files and writes out uncompressed files. The utility would decode the
header and process the trailer on its own, hence this routine expects only
the raw deflate stream to decompress. This is different from the default
behavior of inflate(), which expects a zlib header and trailer around the
deflate stream.
inflateBack() uses two subroutines supplied by the caller that are then
called by inflateBack() for input and output. inflateBack() calls those
routines until it reads a complete deflate stream and writes out all of the
uncompressed data, or until it encounters an error. The function's
parameters and return types are defined above in the in_func and out_func
typedefs. inflateBack() will call in(in_desc, &buf) which should return the
number of bytes of provided input, and a pointer to that input in buf. If
there is no input available, in() must return zero -- buf is ignored in that
case -- and inflateBack() will return a buffer error. inflateBack() will
call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].
out() should return zero on success, or non-zero on failure. If out()
returns non-zero, inflateBack() will return with an error. Neither in() nor
out() are permitted to change the contents of the window provided to
inflateBackInit(), which is also the buffer that out() uses to write from.
The length written by out() will be at most the window size. Any non-zero
amount of input may be provided by in().
For convenience, inflateBack() can be provided input on the first call by
setting strm->next_in and strm->avail_in. If that input is exhausted, then
in() will be called. Therefore strm->next_in must be initialized before
calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
must also be initialized, and then if strm->avail_in is not zero, input will
initially be taken from strm->next_in[0 .. strm->avail_in - 1].
The in_desc and out_desc parameters of inflateBack() is passed as the
first parameter of in() and out() respectively when they are called. These
descriptors can be optionally used to pass any information that the caller-
supplied in() and out() functions need to do their job.
On return, inflateBack() will set strm->next_in and strm->avail_in to
pass back any unused input that was provided by the last in() call. The
return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
if in() or out() returned an error, Z_DATA_ERROR if there was a format error
in the deflate stream (in which case strm->msg is set to indicate the nature
of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
In the case of Z_BUF_ERROR, an input or output error can be distinguished
using strm->next_in which will be Z_NULL only if in() returned an error. If
strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
non-zero. (in() will always be called before out(), so strm->next_in is
assured to be defined if out() returns non-zero.) Note that inflateBack()
cannot return Z_OK.
*/
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
/*
All memory allocated by inflateBackInit() is freed.
inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
state was inconsistent.
*/
ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
/* Return flags indicating compile-time options.
Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
1.0: size of uInt
3.2: size of uLong
5.4: size of voidpf (pointer)
7.6: size of z_off_t
Compiler, assembler, and debug options:
8: ZLIB_DEBUG
9: ASMV or ASMINF -- use ASM code
10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
11: 0 (reserved)
One-time table building (smaller code, but not thread-safe if true):
12: BUILDFIXED -- build static block decoding tables when needed
13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
14,15: 0 (reserved)
Library content (indicates missing functionality):
16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
deflate code when not needed)
17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
and decode gzip streams (to avoid linking crc code)
18-19: 0 (reserved)
Operation variations (changes in library functionality):
20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
21: FASTEST -- deflate algorithm with only one, lowest compression level
22,23: 0 (reserved)
The sprintf variant used by gzprintf (zero is best):
24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
26: 0 = returns value, 1 = void -- 1 means inferred string length returned
Remainder:
27-31: 0 (reserved)
*/
#ifndef Z_SOLO
/* utility functions */
/*
The following utility functions are implemented on top of the basic
stream-oriented functions. To simplify the interface, some default options
are assumed (compression level and memory usage, standard memory allocation
functions). The source code of these utility functions can be modified if
you need special options.
*/
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Compresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total size
of the destination buffer, which must be at least the value returned by
compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed data. compress() is equivalent to compress2() with a level
parameter of Z_DEFAULT_COMPRESSION.
compress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer.
*/
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
/*
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least the value returned by
compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed data.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
/*
compressBound() returns an upper bound on the compressed size after
compress() or compress2() on sourceLen bytes. It would be used before a
compress() or compress2() call to allocate the destination buffer.
*/
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total size
of the destination buffer, which must be large enough to hold the entire
uncompressed data. (The size of the uncompressed data must have been saved
previously by the compressor and transmitted to the decompressor by some
mechanism outside the scope of this compression library.) Upon exit, destLen
is the actual size of the uncompressed data.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
the case where there is not enough room, uncompress() will fill the output
buffer with the uncompressed data up to that point.
*/
ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong *sourceLen));
/*
Same as uncompress, except that sourceLen is a pointer, where the
length of the source is *sourceLen. On return, *sourceLen is the number of
source bytes consumed.
*/
/* gzip file access functions */
/*
This library supports reading and writing files in gzip (.gz) format with
an interface similar to that of stdio, using the functions that start with
"gz". The gzip format is different from the zlib format. gzip is a gzip
wrapper, documented in RFC 1952, wrapped around a deflate stream.
*/
typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
/*
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
- Opens a gzip (.gz) file for reading or writing. The mode parameter is as
- in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
- a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
- compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
- for fixed code compression as in "wb9F". (See the description of
- deflateInit2 for more information about the strategy parameter.) 'T' will
- request transparent writing or appending with no compression and not using
- the gzip format.
+ Open the gzip (.gz) file at path for reading and decompressing, or
+ compressing and writing. The mode parameter is as in fopen ("rb" or "wb")
+ but can also include a compression level ("wb9") or a strategy: 'f' for
+ filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h",
+ 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression
+ as in "wb9F". (See the description of deflateInit2 for more information
+ about the strategy parameter.) 'T' will request transparent writing or
+ appending with no compression and not using the gzip format.
"a" can be used instead of "w" to request that the gzip stream that will
be written be appended to the file. "+" will result in an error, since
reading and writing to the same gzip file is not supported. The addition of
"x" when writing will create the file exclusively, which fails if the file
already exists. On systems that support it, the addition of "e" when
reading or writing will set the flag to close the file on an execve() call.
These functions, as well as gzip, will read and decode a sequence of gzip
streams in a file. The append function of gzopen() can be used to create
such a file. (Also see gzflush() for another way to do this.) When
appending, gzopen does not test whether the file begins with a gzip stream,
nor does it look for the end of the gzip streams to begin appending. gzopen
will simply append a gzip stream to the existing file.
gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression. When
reading, this will be detected automatically by looking for the magic two-
byte gzip header.
gzopen returns NULL if the file could not be opened, if there was
insufficient memory to allocate the gzFile state, or if an invalid mode was
specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
errno can be checked to determine if the reason gzopen failed was that the
file could not be opened.
*/
ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
/*
- gzdopen associates a gzFile with the file descriptor fd. File descriptors
- are obtained from calls like open, dup, creat, pipe or fileno (if the file
- has been previously opened with fopen). The mode parameter is as in gzopen.
+ Associate a gzFile with the file descriptor fd. File descriptors are
+ obtained from calls like open, dup, creat, pipe or fileno (if the file has
+ been previously opened with fopen). The mode parameter is as in gzopen.
The next call of gzclose on the returned gzFile will also close the file
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
mode);. The duplicated descriptor should be saved to avoid a leak, since
gzdopen does not close fd if it fails. If you are using fileno() to get the
file descriptor from a FILE *, then you will have to use dup() to avoid
double-close()ing the file descriptor. Both gzclose() and fclose() will
close the associated file descriptor, so they need to have different file
descriptors.
gzdopen returns NULL if there was insufficient memory to allocate the
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
provided, or '+' was provided), or if fd is -1. The file descriptor is not
used until the next gz* read, write, seek, or close operation, so gzdopen
will not detect if fd is invalid (unless fd is -1).
*/
ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
/*
- Set the internal buffer size used by this library's functions. The
- default buffer size is 8192 bytes. This function must be called after
- gzopen() or gzdopen(), and before any other calls that read or write the
- file. The buffer memory allocation is always deferred to the first read or
- write. Three times that size in buffer space is allocated. A larger buffer
- size of, for example, 64K or 128K bytes will noticeably increase the speed
- of decompression (reading).
+ Set the internal buffer size used by this library's functions for file to
+ size. The default buffer size is 8192 bytes. This function must be called
+ after gzopen() or gzdopen(), and before any other calls that read or write
+ the file. The buffer memory allocation is always deferred to the first read
+ or write. Three times that size in buffer space is allocated. A larger
+ buffer size of, for example, 64K or 128K bytes will noticeably increase the
+ speed of decompression (reading).
The new buffer size also affects the maximum length for gzprintf().
gzbuffer() returns 0 on success, or -1 on failure, such as being called
too late.
*/
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters. Previously provided
- data is flushed before the parameter change.
+ Dynamically update the compression level and strategy for file. See the
+ description of deflateInit2 for the meaning of these parameters. Previously
+ provided data is flushed before applying the parameter changes.
gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
opened for writing, Z_ERRNO if there is an error writing the flushed data,
or Z_MEM_ERROR if there is a memory allocation error.
*/
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/*
- Reads the given number of uncompressed bytes from the compressed file. If
+ Read and decompress up to len uncompressed bytes from file into buf. If
the input file is not in gzip format, gzread copies the given number of
bytes into the buffer directly from the file.
After reaching the end of a gzip stream in the input, gzread will continue
to read, looking for another gzip stream. Any number of gzip streams may be
concatenated in the input file, and will all be decompressed by gzread().
If something other than a gzip stream is encountered after a gzip stream,
that remaining trailing garbage is ignored (and no error is returned).
gzread can be used to read a gzip file that is being concurrently written.
Upon reaching the end of the input, gzread will return with the available
data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
gzclearerr can be used to clear the end of file indicator in order to permit
gzread to be tried again. Z_OK indicates that a gzip stream was completed
on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
middle of a gzip stream. Note that gzread does not return -1 in the event
of an incomplete gzip stream. This error is deferred until gzclose(), which
will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
stream. Alternatively, gzerror can be used before gzclose to detect this
case.
gzread returns the number of uncompressed bytes actually read, less than
len for end of file, or -1 for error. If len is too large to fit in an int,
then nothing is read, -1 is returned, and the error state is set to
Z_STREAM_ERROR.
*/
ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
gzFile file));
/*
- Read up to nitems items of size size from file to buf, otherwise operating
- as gzread() does. This duplicates the interface of stdio's fread(), with
- size_t request and return types. If the library defines size_t, then
- z_size_t is identical to size_t. If not, then z_size_t is an unsigned
- integer type that can contain a pointer.
+ Read and decompress up to nitems items of size size from file into buf,
+ otherwise operating as gzread() does. This duplicates the interface of
+ stdio's fread(), with size_t request and return types. If the library
+ defines size_t, then z_size_t is identical to size_t. If not, then z_size_t
+ is an unsigned integer type that can contain a pointer.
gzfread() returns the number of full items read of size size, or zero if
the end of the file was reached and a full item could not be read, or if
there was an error. gzerror() must be consulted if zero is returned in
order to determine if there was an error. If the multiplication of size and
nitems overflows, i.e. the product does not fit in a z_size_t, then nothing
is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
In the event that the end of file is reached and only a partial item is
available at the end, i.e. the remaining uncompressed data length is not a
multiple of size, then the final partial item is nevetheless read into buf
and the end-of-file flag is set. The length of the partial item read is not
provided, but could be inferred from the result of gztell(). This behavior
is the same as the behavior of fread() implementations in common libraries,
but it prevents the direct use of gzfread() to read a concurrently written
file, reseting and retrying on end-of-file, when size is not 1.
*/
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes written or 0 in case of
- error.
+ Compress and write the len uncompressed bytes at buf to file. gzwrite
+ returns the number of uncompressed bytes written or 0 in case of error.
*/
ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
z_size_t nitems, gzFile file));
/*
- gzfwrite() writes nitems items of size size from buf to file, duplicating
+ Compress and write nitems items of size size from buf to file, duplicating
the interface of stdio's fwrite(), with size_t request and return types. If
the library defines size_t, then z_size_t is identical to size_t. If not,
then z_size_t is an unsigned integer type that can contain a pointer.
gzfwrite() returns the number of full items written of size size, or zero
if there was an error. If the multiplication of size and nitems overflows,
i.e. the product does not fit in a z_size_t, then nothing is written, zero
is returned, and the error state is set to Z_STREAM_ERROR.
*/
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
/*
- Converts, formats, and writes the arguments to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
+ Convert, format, compress, and write the arguments (...) to file under
+ control of the string format, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written, or a negative zlib error code in case
of error. The number of uncompressed bytes written is limited to 8191, or
one less than the buffer size given to gzbuffer(). The caller should assure
that this limit is not exceeded. If it is exceeded, then gzprintf() will
return an error (0) with nothing written. In this case, there may also be a
buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
+ zlib was compiled with the insecure functions sprintf() or vsprintf(),
because the secure snprintf() or vsnprintf() functions were not available.
This can be determined using zlibCompileFlags().
*/
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
/*
- Writes the given null-terminated string to the compressed file, excluding
+ Compress and write the given null-terminated string s to file, excluding
the terminating null character.
gzputs returns the number of characters written, or -1 in case of error.
*/
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
/*
- Reads bytes from the compressed file until len-1 characters are read, or a
- newline character is read and transferred to buf, or an end-of-file
- condition is encountered. If any characters are read or if len == 1, the
- string is terminated with a null character. If no characters are read due
- to an end-of-file or len < 1, then the buffer is left untouched.
+ Read and decompress bytes from file into buf, until len-1 characters are
+ read, or until a newline character is read and transferred to buf, or an
+ end-of-file condition is encountered. If any characters are read or if len
+ is one, the string is terminated with a null character. If no characters
+ are read due to an end-of-file or len is less than one, then the buffer is
+ left untouched.
gzgets returns buf which is a null-terminated string, or it returns NULL
for end-of-file or in case of error. If there was an error, the contents at
buf are indeterminate.
*/
ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
/*
- Writes c, converted to an unsigned char, into the compressed file. gzputc
+ Compress and write c, converted to an unsigned char, into file. gzputc
returns the value that was written, or -1 in case of error.
*/
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/*
- Reads one byte from the compressed file. gzgetc returns this byte or -1
+ Read and decompress one byte from file. gzgetc returns this byte or -1
in case of end of file or error. This is implemented as a macro for speed.
As such, it does not do all of the checking the other functions do. I.e.
it does not check to see if file is NULL, nor whether the structure file
points to has been clobbered or not.
*/
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
/*
- Push one character back onto the stream to be read as the first character
- on the next read. At least one character of push-back is allowed.
+ Push c back onto the stream for file to be read as the first character on
+ the next read. At least one character of push-back is always allowed.
gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
fail if c is -1, and may fail if a character has been pushed but not read
yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
output buffer size of pushed characters is allowed. (See gzbuffer above.)
The pushed character will be discarded if the stream is repositioned with
gzseek() or gzrewind().
*/
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
/*
- Flushes all pending output into the compressed file. The parameter flush
- is as in the deflate() function. The return value is the zlib error number
- (see function gzerror below). gzflush is only permitted when writing.
+ Flush all pending output to file. The parameter flush is as in the
+ deflate() function. The return value is the zlib error number (see function
+ gzerror below). gzflush is only permitted when writing.
If the flush parameter is Z_FINISH, the remaining data is written and the
gzip stream is completed in the output. If gzwrite() is called again, a new
gzip stream will be started in the output. gzread() is able to read such
concatenated gzip streams.
gzflush should be called only when strictly necessary because it will
degrade compression if called too often.
*/
/*
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
z_off_t offset, int whence));
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
+ Set the starting position to offset relative to whence for the next gzread
+ or gzwrite on file. The offset represents a number of bytes in the
uncompressed data stream. The whence parameter is defined as in lseek(2);
the value SEEK_END is not supported.
If the file is opened for reading, this function is emulated but can be
extremely slow. If the file is opened for writing, only forward seeks are
supported; gzseek then compresses a sequence of zeroes up to the new
starting position.
gzseek returns the resulting offset location as measured in bytes from
the beginning of the uncompressed stream, or -1 in case of error, in
particular if the file is opened for writing and the new starting position
would be before the current position.
*/
ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
/*
- Rewinds the given file. This function is supported only for reading.
+ Rewind file. This function is supported only for reading.
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET).
*/
/*
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
- Returns the starting position for the next gzread or gzwrite on the given
- compressed file. This position represents a number of bytes in the
- uncompressed data stream, and is zero when starting, even if appending or
- reading a gzip stream from the middle of a file using gzdopen().
+ Return the starting position for the next gzread or gzwrite on file.
+ This position represents a number of bytes in the uncompressed data stream,
+ and is zero when starting, even if appending or reading a gzip stream from
+ the middle of a file using gzdopen().
gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
*/
/*
ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
- Returns the current offset in the file being read or written. This offset
- includes the count of bytes that precede the gzip stream, for example when
- appending or when using gzdopen() for reading. When reading, the offset
- does not include as yet unused buffered input. This information can be used
- for a progress indicator. On error, gzoffset() returns -1.
+ Return the current compressed (actual) read or write offset of file. This
+ offset includes the count of bytes that precede the gzip stream, for example
+ when appending or when using gzdopen() for reading. When reading, the
+ offset does not include as yet unused buffered input. This information can
+ be used for a progress indicator. On error, gzoffset() returns -1.
*/
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
/*
- Returns true (1) if the end-of-file indicator has been set while reading,
- false (0) otherwise. Note that the end-of-file indicator is set only if the
- read tried to go past the end of the input, but came up short. Therefore,
- just like feof(), gzeof() may return false even if there is no more data to
- read, in the event that the last read request was for the exact number of
- bytes remaining in the input file. This will happen if the input file size
- is an exact multiple of the buffer size.
+ Return true (1) if the end-of-file indicator for file has been set while
+ reading, false (0) otherwise. Note that the end-of-file indicator is set
+ only if the read tried to go past the end of the input, but came up short.
+ Therefore, just like feof(), gzeof() may return false even if there is no
+ more data to read, in the event that the last read request was for the exact
+ number of bytes remaining in the input file. This will happen if the input
+ file size is an exact multiple of the buffer size.
If gzeof() returns true, then the read functions will return no more data,
unless the end-of-file indicator is reset by gzclearerr() and the input file
has grown since the previous end of file was detected.
*/
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
- Returns true (1) if file is being copied directly while reading, or false
+ Return true (1) if file is being copied directly while reading, or false
(0) if file is a gzip stream being decompressed.
If the input file is empty, gzdirect() will return true, since the input
does not contain a gzip stream.
If gzdirect() is used immediately after gzopen() or gzdopen() it will
cause buffers to be allocated to allow reading the file to determine if it
is a gzip file. Therefore if gzbuffer() is used, it should be called before
gzdirect().
When writing, gzdirect() returns true (1) if transparent writing was
requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
gzdirect() is not needed when writing. Transparent writing must be
explicitly requested, so the application already knows the answer. When
linking statically, using gzdirect() will include all of the zlib code for
gzip file reading and decompression, which may not be desired.)
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
/*
- Flushes all pending output if necessary, closes the compressed file and
- deallocates the (de)compression state. Note that once file is closed, you
+ Flush all pending output for file, if necessary, close file and
+ deallocate the (de)compression state. Note that once file is closed, you
cannot call gzerror with file, since its structures have been deallocated.
gzclose must not be called more than once on the same file, just as free
must not be called more than once on the same allocation.
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
last read ended in the middle of a gzip stream, or Z_OK on success.
*/
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
/*
Same as gzclose(), but gzclose_r() is only for use when reading, and
gzclose_w() is only for use when writing or appending. The advantage to
using these instead of gzclose() is that they avoid linking in zlib
compression or decompression code that is not used when only reading or only
writing respectively. If gzclose() is used, then both compression and
decompression code will be included the application when linking to a static
zlib library.
*/
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
/*
- Returns the error message for the last error which occurred on the given
- compressed file. errnum is set to zlib error number. If an error occurred
- in the file system and not in the compression library, errnum is set to
- Z_ERRNO and the application may consult errno to get the exact error code.
+ Return the error message for the last error which occurred on file.
+ errnum is set to zlib error number. If an error occurred in the file system
+ and not in the compression library, errnum is set to Z_ERRNO and the
+ application may consult errno to get the exact error code.
The application must not modify the returned string. Future calls to
this function may invalidate the previously returned string. If file is
closed, then the string previously returned by gzerror will no longer be
available.
gzerror() should be used to distinguish errors from end-of-file for those
functions above that do not distinguish those cases in their return values.
*/
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
/*
- Clears the error and end-of-file flags for file. This is analogous to the
+ Clear the error and end-of-file flags for file. This is analogous to the
clearerr() function in stdio. This is useful for continuing to read a gzip
file that is being written concurrently.
*/
#endif /* !Z_SOLO */
/* checksum functions */
/*
These functions are not related to compression but are exported
anyway because they might be useful in applications using the compression
library.
*/
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is Z_NULL, this function returns the
- required initial value for the checksum.
+ return the updated checksum. An Adler-32 value is in the range of a 32-bit
+ unsigned integer. If buf is Z_NULL, this function returns the required
+ initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
much faster.
Usage example:
uLong adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();
*/
ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
z_size_t len));
/*
Same as adler32(), but with a size_t length.
*/
/*
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
z_off_t len2));
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
that the z_off_t type (like off_t) is a signed integer. If len2 is
negative, the result has no meaning or utility.
*/
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/*
Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is Z_NULL, this function returns the required
- initial value for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
+ updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer.
+ If buf is Z_NULL, this function returns the required initial value for the
+ crc. Pre- and post-conditioning (one's complement) is performed within this
+ function so it shouldn't be done by the application.
Usage example:
uLong crc = crc32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
crc = crc32(crc, buffer, length);
}
if (crc != original_crc) error();
*/
-ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf,
+ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf,
z_size_t len));
/*
Same as crc32(), but with a size_t length.
*/
/*
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
Combine two CRC-32 check values into one. For two sequences of bytes,
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
len2.
*/
+/*
+ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
+
+ Return the operator corresponding to length len2, to be used with
+ crc32_combine_op().
+*/
+
+ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
+/*
+ Give the same result as crc32_combine(), using op in place of len2. op is
+ is generated from len2 by crc32_combine_gen(). This will be faster than
+ crc32_combine() if the generated op is used more than once.
+*/
+
/* various hacks, don't look :) */
/* deflateInit and inflateInit are macros to allow checking the zlib version
* and the compiler's view of z_stream:
*/
ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
const char *version, int stream_size));
ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
const char *version, int stream_size));
ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int windowBits, int memLevel,
int strategy, const char *version,
int stream_size));
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size));
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
unsigned char FAR *window,
const char *version,
int stream_size));
#ifdef Z_PREFIX_SET
# define z_deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
# define z_inflateInit(strm) \
inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
(strategy), ZLIB_VERSION, (int)sizeof(z_stream))
# define z_inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
(int)sizeof(z_stream))
# define z_inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \
ZLIB_VERSION, (int)sizeof(z_stream))
#else
# define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
# define inflateInit(strm) \
inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
(strategy), ZLIB_VERSION, (int)sizeof(z_stream))
# define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
(int)sizeof(z_stream))
# define inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \
ZLIB_VERSION, (int)sizeof(z_stream))
#endif
#ifndef Z_SOLO
/* gzgetc() macro and its supporting function and exposed data structure. Note
* that the real internal state is much larger than the exposed structure.
* This abbreviated structure exposes just enough for the gzgetc() macro. The
* user should not mess with these exposed elements, since their names or
* behavior could change in the future, perhaps even capriciously. They can
* only be used by the gzgetc() macro. You have been warned.
*/
struct gzFile_s {
unsigned have;
unsigned char *next;
z_off64_t pos;
};
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
#ifdef Z_PREFIX_SET
# undef z_gzgetc
# define z_gzgetc(g) \
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
#else
# define gzgetc(g) \
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
#endif
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
* both are true, the application gets the *64 functions, and the regular
* functions are changed to 64 bits) -- in case these are set on systems
* without large file support, _LFS64_LARGEFILE must also be true
*/
#ifdef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t));
#endif
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
# ifdef Z_PREFIX_SET
# define z_gzopen z_gzopen64
# define z_gzseek z_gzseek64
# define z_gztell z_gztell64
# define z_gzoffset z_gzoffset64
# define z_adler32_combine z_adler32_combine64
# define z_crc32_combine z_crc32_combine64
+# define z_crc32_combine_gen z_crc32_combine_gen64
# else
# define gzopen gzopen64
# define gzseek gzseek64
# define gztell gztell64
# define gzoffset gzoffset64
# define adler32_combine adler32_combine64
# define crc32_combine crc32_combine64
+# define crc32_combine_gen crc32_combine_gen64
# endif
# ifndef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
# endif
#else
ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
#endif
#else /* Z_SOLO */
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
#endif /* !Z_SOLO */
/* undocumented functions */
ZEXTERN const char * ZEXPORT zError OF((int));
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int));
ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp));
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
-#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO)
+#if defined(_WIN32) && !defined(Z_SOLO)
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
const char *mode));
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
const char *format,
va_list va));
# endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* ZLIB_H */
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zutil.c b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zutil.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zutil.c
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zutil.c
index a76c6b0c..dcab28a0 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zutil.c
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zutil.c
@@ -1,325 +1,325 @@
/* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-2017 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zutil.h"
#ifndef Z_SOLO
# include "gzguts.h"
#endif
z_const char * const z_errmsg[10] = {
(z_const char *)"need dictionary", /* Z_NEED_DICT 2 */
(z_const char *)"stream end", /* Z_STREAM_END 1 */
(z_const char *)"", /* Z_OK 0 */
(z_const char *)"file error", /* Z_ERRNO (-1) */
(z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */
(z_const char *)"data error", /* Z_DATA_ERROR (-3) */
(z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */
(z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */
(z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
(z_const char *)""
};
const char * ZEXPORT zlibVersion()
{
return ZLIB_VERSION;
}
uLong ZEXPORT zlibCompileFlags()
{
uLong flags;
flags = 0;
switch ((int)(sizeof(uInt))) {
case 2: break;
case 4: flags += 1; break;
case 8: flags += 2; break;
default: flags += 3;
}
switch ((int)(sizeof(uLong))) {
case 2: break;
case 4: flags += 1 << 2; break;
case 8: flags += 2 << 2; break;
default: flags += 3 << 2;
}
switch ((int)(sizeof(voidpf))) {
case 2: break;
case 4: flags += 1 << 4; break;
case 8: flags += 2 << 4; break;
default: flags += 3 << 4;
}
switch ((int)(sizeof(z_off_t))) {
case 2: break;
case 4: flags += 1 << 6; break;
case 8: flags += 2 << 6; break;
default: flags += 3 << 6;
}
#ifdef ZLIB_DEBUG
flags += 1 << 8;
#endif
#if defined(ASMV) || defined(ASMINF)
flags += 1 << 9;
#endif
#ifdef ZLIB_WINAPI
flags += 1 << 10;
#endif
#ifdef BUILDFIXED
flags += 1 << 12;
#endif
#ifdef DYNAMIC_CRC_TABLE
flags += 1 << 13;
#endif
#ifdef NO_GZCOMPRESS
flags += 1L << 16;
#endif
#ifdef NO_GZIP
flags += 1L << 17;
#endif
#ifdef PKZIP_BUG_WORKAROUND
flags += 1L << 20;
#endif
#ifdef FASTEST
flags += 1L << 21;
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifdef NO_vsnprintf
flags += 1L << 25;
# ifdef HAS_vsprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
flags += 1L << 26;
# endif
# endif
#else
flags += 1L << 24;
# ifdef NO_snprintf
flags += 1L << 25;
# ifdef HAS_sprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
flags += 1L << 26;
# endif
# endif
#endif
return flags;
}
#ifdef ZLIB_DEBUG
#include <stdlib.h>
# ifndef verbose
# define verbose 0
# endif
int ZLIB_INTERNAL z_verbose = verbose;
void ZLIB_INTERNAL z_error (m)
char *m;
{
fprintf(stderr, "%s\n", m);
exit(1);
}
#endif
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char * ZEXPORT zError(err)
int err;
{
return ERR_MSG(err);
}
-#if defined(_WIN32_WCE)
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
+#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
+ /* The older Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used.
*/
int errno = 0;
#endif
#ifndef HAVE_MEMCPY
void ZLIB_INTERNAL zmemcpy(dest, source, len)
Bytef* dest;
const Bytef* source;
uInt len;
{
if (len == 0) return;
do {
*dest++ = *source++; /* ??? to be unrolled */
} while (--len != 0);
}
int ZLIB_INTERNAL zmemcmp(s1, s2, len)
const Bytef* s1;
const Bytef* s2;
uInt len;
{
uInt j;
for (j = 0; j < len; j++) {
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
}
return 0;
}
void ZLIB_INTERNAL zmemzero(dest, len)
Bytef* dest;
uInt len;
{
if (len == 0) return;
do {
*dest++ = 0; /* ??? to be unrolled */
} while (--len != 0);
}
#endif
#ifndef Z_SOLO
#ifdef SYS16BIT
#ifdef __TURBOC__
/* Turbo C in 16-bit mode */
# define MY_ZCALLOC
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
* and farmalloc(64K) returns a pointer with an offset of 8, so we
* must fix the pointer. Warning: the pointer must be put back to its
* original form in order to free it, use zcfree().
*/
#define MAX_PTR 10
/* 10*64K = 640K */
local int next_ptr = 0;
typedef struct ptr_table_s {
voidpf org_ptr;
voidpf new_ptr;
} ptr_table;
local ptr_table table[MAX_PTR];
/* This table is used to remember the original form of pointers
* to large buffers (64K). Such pointers are normalized with a zero offset.
* Since MSDOS is not a preemptive multitasking OS, this table is not
* protected from concurrent access. This hack doesn't work anyway on
* a protected system like OS/2. Use Microsoft C instead.
*/
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
{
voidpf buf;
ulg bsize = (ulg)items*size;
(void)opaque;
/* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
if (bsize < 65520L) {
buf = farmalloc(bsize);
if (*(ush*)&buf != 0) return buf;
} else {
buf = farmalloc(bsize + 16L);
}
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
table[next_ptr].org_ptr = buf;
/* Normalize the pointer to seg:0 */
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
*(ush*)&buf = 0;
table[next_ptr++].new_ptr = buf;
return buf;
}
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
int n;
(void)opaque;
if (*(ush*)&ptr != 0) { /* object < 64K */
farfree(ptr);
return;
}
/* Find the original pointer */
for (n = 0; n < next_ptr; n++) {
if (ptr != table[n].new_ptr) continue;
farfree(table[n].org_ptr);
while (++n < next_ptr) {
table[n-1] = table[n];
}
next_ptr--;
return;
}
Assert(0, "zcfree: ptr not found");
}
#endif /* __TURBOC__ */
#ifdef M_I86
/* Microsoft C in 16-bit mode */
# define MY_ZCALLOC
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
# define _halloc halloc
# define _hfree hfree
#endif
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
{
(void)opaque;
return _halloc((long)items, size);
}
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
(void)opaque;
_hfree(ptr);
}
#endif /* M_I86 */
#endif /* SYS16BIT */
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef STDC
extern voidp malloc OF((uInt size));
extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
(void)opaque;
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
(voidpf)calloc(items, size);
}
void ZLIB_INTERNAL zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
(void)opaque;
free(ptr);
}
#endif /* MY_ZCALLOC */
#endif /* !Z_SOLO */
diff --git a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zutil.h b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zutil.h
similarity index 95%
rename from mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zutil.h
rename to mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zutil.h
index b079ea6a..d9a20ae1 100644
--- a/mongodb-1.13.0/src/libmongoc/src/zlib-1.2.11/zutil.h
+++ b/mongodb-1.14.0/src/libmongoc/src/zlib-1.2.12/zutil.h
@@ -1,271 +1,274 @@
/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef ZUTIL_H
#define ZUTIL_H
#ifdef HAVE_HIDDEN
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#else
# define ZLIB_INTERNAL
#endif
#include "zlib.h"
#if defined(STDC) && !defined(Z_SOLO)
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include <stddef.h>
# endif
# include <string.h>
# include <stdlib.h>
#endif
-#ifdef Z_SOLO
- typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
-#endif
-
#ifndef local
# define local static
#endif
/* since "static" is used to mean two completely different things in C, we
define "local" for the non-static meaning of "static", for readability
(compile with -Dlocal if your debugger can't find static symbols) */
typedef unsigned char uch;
typedef uch FAR uchf;
typedef unsigned short ush;
typedef ush FAR ushf;
typedef unsigned long ulg;
+#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (ULONG_MAX == 0xffffffffffffffff)
+# define Z_U8 unsigned long
+# elif (ULLONG_MAX == 0xffffffffffffffff)
+# define Z_U8 unsigned long long
+# elif (UINT_MAX == 0xffffffffffffffff)
+# define Z_U8 unsigned
+# endif
+#endif
+
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
return (strm->msg = ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */
/* common constants */
#ifndef DEF_WBITS
# define DEF_WBITS MAX_WBITS
#endif
/* default windowBits for decompression. MAX_WBITS is for compression only */
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
/* default memLevel */
#define STORED_BLOCK 0
#define STATIC_TREES 1
#define DYN_TREES 2
/* The three kinds of block type */
#define MIN_MATCH 3
#define MAX_MATCH 258
/* The minimum and maximum match lengths */
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
/* target dependencies */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00
# ifndef Z_SOLO
# if defined(__TURBOC__) || defined(__BORLANDC__)
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
/* Allow compilation with ANSI keywords only enabled */
void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes );
# else
# include <alloc.h>
# endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif
# endif
#endif
#ifdef AMIGA
# define OS_CODE 1
#endif
#if defined(VAXC) || defined(VMS)
# define OS_CODE 2
# define F_OPEN(name, mode) \
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif
#ifdef __370__
# if __TARGET_LIB__ < 0x20000000
# define OS_CODE 4
# elif __TARGET_LIB__ < 0x40000000
# define OS_CODE 11
# else
# define OS_CODE 8
# endif
#endif
#if defined(ATARI) || defined(atarist)
# define OS_CODE 5
#endif
#ifdef OS2
# define OS_CODE 6
# if defined(M_I86) && !defined(Z_SOLO)
# include <malloc.h>
# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 7
# ifndef Z_SOLO
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# include <unix.h> /* for fdopen */
# else
# ifndef fdopen
# define fdopen(fd,mode) NULL /* No fdopen() */
# endif
# endif
# endif
#endif
#ifdef __acorn
# define OS_CODE 13
#endif
#if defined(WIN32) && !defined(__CYGWIN__)
# define OS_CODE 10
#endif
#ifdef _BEOS_
# define OS_CODE 16
#endif
#ifdef __TOS_OS400__
# define OS_CODE 18
#endif
#ifdef __APPLE__
# define OS_CODE 19
#endif
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
# if defined(_WIN32_WCE)
# define fdopen(fd,mode) NULL /* No fdopen() */
-# ifndef _PTRDIFF_T_DEFINED
- typedef int ptrdiff_t;
-# define _PTRDIFF_T_DEFINED
-# endif
# else
# define fdopen(fd,type) _fdopen(fd,type)
# endif
#endif
#if defined(__BORLANDC__) && !defined(MSDOS)
#pragma warn -8004
#pragma warn -8008
#pragma warn -8066
#endif
/* provide prototypes for these when building zlib without LFS */
#if !defined(_WIN32) && \
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
#endif
/* common defaults */
#ifndef OS_CODE
# define OS_CODE 3 /* assume Unix */
#endif
#ifndef F_OPEN
# define F_OPEN(name, mode) fopen((name), (mode))
#endif
/* functions */
#if defined(pyr) || defined(Z_SOLO)
# define NO_MEMCPY
#endif
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
/* Use our own functions for small and medium model with MSC <= 5.0.
* You may have to use the same strategy for Borland C (untested).
* The __SC__ check is for Symantec.
*/
# define NO_MEMCPY
#endif
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
# define HAVE_MEMCPY
#endif
#ifdef HAVE_MEMCPY
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
# define zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
# define zmemzero(dest, len) _fmemset(dest, 0, len)
# else
# define zmemcpy memcpy
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len)
# endif
#else
void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
#endif
/* Diagnostic functions */
#ifdef ZLIB_DEBUG
# include <stdio.h>
extern int ZLIB_INTERNAL z_verbose;
extern void ZLIB_INTERNAL z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
#ifndef Z_SOLO
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
unsigned size));
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
#endif
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
/* Reverse the bytes in a 32-bit value */
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
#endif /* ZUTIL_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt-compat/mongocrypt-export.h b/mongodb-1.14.0/src/libmongocrypt-compat/mongocrypt-export.h
new file mode 100644
index 00000000..7891d7b6
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt-compat/mongocrypt-export.h
@@ -0,0 +1,16 @@
+#ifndef MONGOCRYPT_EXPORT_H
+#define MONGOCRYPT_EXPORT_H
+
+/* This file would typically be generated by libmongocrypt's CMake build process
+ * so it must exist when building libmongocrypt as a submodule via Autotools. We
+ * need only ensure this file exists and expected constants are defined, since
+ * libmongocrypt APIs will not actually be exported.
+ *
+ * See: https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html */
+#define MONGOCRYPT_EXPORT
+#define MONGOCRYPT_NO_EXPORT
+#define MONGOCRYPT_DEPRECATED
+#define MONGOCRYPT_DEPRECATED_EXPORT
+#define MONGOCRYPT_DEPRECATED_NO_EXPORT
+
+#endif /* MONGOCRYPT_EXPORT_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt-compat/mongocrypt/mongocrypt.h b/mongodb-1.14.0/src/libmongocrypt-compat/mongocrypt/mongocrypt.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt-compat/mongocrypt/mongocrypt.h
rename to mongodb-1.14.0/src/libmongocrypt-compat/mongocrypt/mongocrypt.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/hexlify.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/hexlify.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/hexlify.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/hexlify.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/hexlify.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/hexlify.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/hexlify.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/hexlify.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_azure_request.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_azure_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_azure_request.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_azure_request.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_b64.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_b64.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_b64.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_b64.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_caller_identity_request.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_apple.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_apple.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_apple.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_apple.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_none.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_none.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_none.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_none.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_windows.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_windows.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_crypto_windows.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_crypto_windows.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_decrypt_request.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_decrypt_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_decrypt_request.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_decrypt_request.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_encrypt_request.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_encrypt_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_encrypt_request.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_encrypt_request.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_endian_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_endian_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_endian_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_endian_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_gcp_request.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_gcp_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_gcp_request.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_gcp_request.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_item_type_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_item_type_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_item_type_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_item_type_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_request.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_request.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_request.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_request.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_response.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_response.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_response.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_response.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_response_parser_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_result_reason_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_result_reason_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_result_reason_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_result_reason_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_result_status_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_result_status_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_result_status_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_result_status_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kv_list.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kv_list.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kv_list.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kv_list.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kv_list.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kv_list.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_kv_list.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_kv_list.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_azure_request.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_azure_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_azure_request.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_azure_request.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_b64.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_gcp_request.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_gcp_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_gcp_request.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_gcp_request.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response_parser.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response_parser.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response_parser.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response_parser.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_message.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_message.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_message.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_message.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_request.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_request.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_request.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_request.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_response.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_response.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_response.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_response.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_message_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_message_private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_port.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_port.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_port.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_port.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_port.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_port.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_port.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_port.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request.c
index a51f09cb..37fe1191 100644
--- a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request.c
+++ b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request.c
@@ -1,915 +1,915 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"){}
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "kms_crypto.h"
#include "kms_message/kms_message.h"
#include "kms_message_private.h"
#include "kms_request_opt_private.h"
#include "kms_port.h"
static kms_kv_list_t *
parse_query_params (kms_request_str_t *q)
{
kms_kv_list_t *lst = kms_kv_list_new ();
char *p = q->str;
char *end = q->str + q->len;
char *amp, *equals;
kms_request_str_t *k, *v;
do {
equals = strchr ((const char *) p, '=');
if (!equals) {
kms_kv_list_destroy (lst);
return NULL;
}
amp = strchr ((const char *) equals, '&');
if (!amp) {
amp = end;
}
k = kms_request_str_new_from_chars (p, equals - p);
v = kms_request_str_new_from_chars (equals + 1, amp - equals - 1);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
p = amp + 1;
} while (p < end);
return lst;
}
static bool
check_and_prohibit_kmip (kms_request_t *req)
{
if (req->provider == KMS_REQUEST_PROVIDER_KMIP) {
KMS_ERROR (req, "Function not applicable to KMIP");
return false;
}
return true;
}
kms_request_t *
kms_request_new (const char *method,
const char *path_and_query,
const kms_request_opt_t *opt)
{
kms_request_t *request = calloc (1, sizeof (kms_request_t));
const char *question_mark;
KMS_ASSERT (request);
if (opt && opt->provider) {
request->provider = opt->provider;
} else {
request->provider = KMS_REQUEST_PROVIDER_AWS;
}
if (!check_and_prohibit_kmip (request)) {
return request;
}
/* parsing may set failed to true */
request->failed = false;
request->finalized = false;
request->region = kms_request_str_new ();
request->service = kms_request_str_new ();
request->access_key_id = kms_request_str_new ();
request->secret_key = kms_request_str_new ();
question_mark = strchr (path_and_query, '?');
if (question_mark) {
request->path = kms_request_str_new_from_chars (
path_and_query, question_mark - path_and_query);
request->query = kms_request_str_new_from_chars (question_mark + 1, -1);
request->query_params = parse_query_params (request->query);
if (!request->query_params) {
KMS_ERROR (request, "Cannot parse query: %s", request->query->str);
}
} else {
request->path = kms_request_str_new_from_chars (path_and_query, -1);
request->query = kms_request_str_new ();
request->query_params = kms_kv_list_new ();
}
request->payload = kms_request_str_new ();
request->date = kms_request_str_new ();
request->datetime = kms_request_str_new ();
request->method = kms_request_str_new_from_chars (method, -1);
request->header_fields = kms_kv_list_new ();
request->auto_content_length = true;
/* For AWS KMS requests, add a X-Amz-Date header. */
if (request->provider == KMS_REQUEST_PROVIDER_AWS &&
!kms_request_set_date (request, NULL)) {
return request;
}
if (opt && opt->connection_close) {
if (!kms_request_add_header_field (request, "Connection", "close")) {
return request;
}
}
if (opt && opt->crypto.sha256) {
memcpy (&request->crypto, &opt->crypto, sizeof (opt->crypto));
} else {
request->crypto.sha256 = kms_sha256;
request->crypto.sha256_hmac = kms_sha256_hmac;
}
return request;
}
void
kms_request_destroy (kms_request_t *request)
{
kms_request_str_destroy (request->region);
kms_request_str_destroy (request->service);
kms_request_str_destroy (request->access_key_id);
kms_request_str_destroy (request->secret_key);
kms_request_str_destroy (request->method);
kms_request_str_destroy (request->path);
kms_request_str_destroy (request->query);
kms_request_str_destroy (request->payload);
kms_request_str_destroy (request->datetime);
kms_request_str_destroy (request->date);
kms_kv_list_destroy (request->query_params);
kms_kv_list_destroy (request->header_fields);
kms_request_str_destroy (request->to_string);
free (request->kmip.data);
free (request);
}
const char *
kms_request_get_error (kms_request_t *request)
{
return request->failed ? request->error : NULL;
}
#define AMZ_DT_FORMAT "YYYYmmDDTHHMMSSZ"
bool
kms_request_set_date (kms_request_t *request, const struct tm *tm)
{
char buf[sizeof AMZ_DT_FORMAT];
struct tm tmp_tm;
if (request->failed) {
return false;
}
if (!check_and_prohibit_kmip (request)) {
return false;
}
if (!tm) {
/* use current time */
time_t t;
time (&t);
#ifdef _WIN32
gmtime_s (&tmp_tm, &t);
#else
gmtime_r (&t, &tmp_tm);
#endif
tm = &tmp_tm;
}
if (0 == strftime (buf, sizeof AMZ_DT_FORMAT, "%Y%m%dT%H%M%SZ", tm)) {
KMS_ERROR (request, "Invalid tm struct");
return false;
}
kms_request_str_set_chars (request->date, buf, sizeof "YYYYmmDD" - 1);
kms_request_str_set_chars (request->datetime, buf, sizeof AMZ_DT_FORMAT - 1);
kms_kv_list_del (request->header_fields, "X-Amz-Date");
if (!kms_request_add_header_field (request, "X-Amz-Date", buf)) {
return false;
}
return true;
}
#undef AMZ_DT_FORMAT
bool
kms_request_set_region (kms_request_t *request, const char *region)
{
if (!check_and_prohibit_kmip (request)) {
return false;
}
kms_request_str_set_chars (request->region, region, -1);
return true;
}
bool
kms_request_set_service (kms_request_t *request, const char *service)
{
if (!check_and_prohibit_kmip (request)) {
return false;
}
kms_request_str_set_chars (request->service, service, -1);
return true;
}
bool
kms_request_set_access_key_id (kms_request_t *request, const char *akid)
{
if (!check_and_prohibit_kmip (request)) {
return false;
}
kms_request_str_set_chars (request->access_key_id, akid, -1);
return true;
}
bool
kms_request_set_secret_key (kms_request_t *request, const char *key)
{
if (!check_and_prohibit_kmip (request)) {
return false;
}
kms_request_str_set_chars (request->secret_key, key, -1);
return true;
}
bool
kms_request_add_header_field (kms_request_t *request,
const char *field_name,
const char *value)
{
kms_request_str_t *k, *v;
CHECK_FAILED;
if (!check_and_prohibit_kmip (request)) {
return false;
}
k = kms_request_str_new_from_chars (field_name, -1);
v = kms_request_str_new_from_chars (value, -1);
kms_kv_list_add (request->header_fields, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
return true;
}
bool
kms_request_append_header_field_value (kms_request_t *request,
const char *value,
size_t len)
{
kms_request_str_t *v;
CHECK_FAILED;
if (!check_and_prohibit_kmip (request)) {
return false;
}
if (request->header_fields->len == 0) {
KMS_ERROR (
request,
"Ensure the request has at least one header field before calling %s",
- __FUNCTION__);
+ __func__);
}
v = request->header_fields->kvs[request->header_fields->len - 1].value;
kms_request_str_append_chars (v, value, len);
return true;
}
bool
kms_request_append_payload (kms_request_t *request,
const char *payload,
size_t len)
{
CHECK_FAILED;
if (!check_and_prohibit_kmip (request)) {
return false;
}
kms_request_str_append_chars (request->payload, payload, len);
return true;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
*
* "Sort the parameter names by character code point in ascending order. For
* example, a parameter name that begins with the uppercase letter F precedes a
* parameter name that begins with a lowercase letter b."
*/
static int
cmp_query_params (const void *a, const void *b)
{
int r = strcmp (((kms_kv_t *) a)->key->str, ((kms_kv_t *) b)->key->str);
if (r != 0) {
return r;
}
/* not in docs, but tested in get-vanilla-query-order-key: sort by value */
return strcmp (((kms_kv_t *) a)->value->str, ((kms_kv_t *) b)->value->str);
}
static void
append_canonical_query (kms_request_t *request, kms_request_str_t *str)
{
size_t i;
kms_kv_list_t *lst;
if (!request->query_params->len) {
return;
}
lst = kms_kv_list_dup (request->query_params);
kms_kv_list_sort (lst, cmp_query_params);
for (i = 0; i < lst->len; i++) {
kms_request_str_append_escaped (str, lst->kvs[i].key, true);
kms_request_str_append_char (str, '=');
kms_request_str_append_escaped (str, lst->kvs[i].value, true);
if (i < lst->len - 1) {
kms_request_str_append_char (str, '&');
}
}
kms_kv_list_destroy (lst);
}
/* "lst" is a sorted list of headers */
static void
append_canonical_headers (kms_kv_list_t *lst, kms_request_str_t *str)
{
size_t i;
kms_kv_t *kv;
const kms_request_str_t *previous_key = NULL;
/* aws docs: "To create the canonical headers list, convert all header names
* to lowercase and remove leading spaces and trailing spaces. Convert
* sequential spaces in the header value to a single space." "Do not sort the
* values in headers that have multiple values." */
for (i = 0; i < lst->len; i++) {
kv = &lst->kvs[i];
if (previous_key &&
0 == kms_strcasecmp (previous_key->str, kv->key->str)) {
/* duplicate header */
kms_request_str_append_char (str, ',');
kms_request_str_append_stripped (str, kv->value);
continue;
}
if (i > 0) {
kms_request_str_append_newline (str);
}
kms_request_str_append_lowercase (str, kv->key);
kms_request_str_append_char (str, ':');
kms_request_str_append_stripped (str, kv->value);
previous_key = kv->key;
}
kms_request_str_append_newline (str);
}
static void
append_signed_headers (kms_kv_list_t *lst, kms_request_str_t *str)
{
size_t i;
kms_kv_t *kv;
const kms_request_str_t *previous_key = NULL;
for (i = 0; i < lst->len; i++) {
kv = &lst->kvs[i];
if (previous_key &&
0 == kms_strcasecmp (previous_key->str, kv->key->str)) {
/* duplicate header */
continue;
}
if (0 == kms_strcasecmp (kv->key->str, "connection")) {
continue;
}
kms_request_str_append_lowercase (str, kv->key);
if (i < lst->len - 1) {
kms_request_str_append_char (str, ';');
}
previous_key = kv->key;
}
}
static bool
finalize (kms_request_t *request)
{
kms_kv_list_t *lst;
kms_request_str_t *k;
kms_request_str_t *v;
if (request->failed) {
return false;
}
if (request->finalized) {
return true;
}
request->finalized = true;
lst = request->header_fields;
if (!kms_kv_list_find (lst, "Host")) {
if (request->provider != KMS_REQUEST_PROVIDER_AWS) {
KMS_ERROR (request, "Required Host header not set");
return false;
}
/* For AWS requests, derive a default Host header from region + service.
* E.g. "kms.us-east-1.amazonaws.com" */
k = kms_request_str_new_from_chars ("Host", -1);
v = kms_request_str_dup (request->service);
kms_request_str_append_char (v, '.');
kms_request_str_append (v, request->region);
kms_request_str_append_chars (v, ".amazonaws.com", -1);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
}
if (!kms_kv_list_find (lst, "Content-Length") && request->payload->len &&
request->auto_content_length) {
k = kms_request_str_new_from_chars ("Content-Length", -1);
v = kms_request_str_new ();
kms_request_str_appendf (v, "%zu", request->payload->len);
kms_kv_list_add (lst, k, v);
kms_request_str_destroy (k);
kms_request_str_destroy (v);
}
return true;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
*
* "Build the canonical headers list by sorting the (lowercase) headers by
* character code... Do not sort the values in headers that have multiple
* values."
*/
static int
cmp_header_field_names (const void *a, const void *b)
{
return kms_strcasecmp (((kms_kv_t *) a)->key->str,
((kms_kv_t *) b)->key->str);
}
static kms_kv_list_t *
canonical_headers (const kms_request_t *request)
{
kms_kv_list_t *lst;
KMS_ASSERT (request->finalized);
lst = kms_kv_list_dup (request->header_fields);
kms_kv_list_sort (lst, cmp_header_field_names);
kms_kv_list_del (lst, "Connection");
return lst;
}
char *
kms_request_get_canonical (kms_request_t *request)
{
kms_request_str_t *canonical;
kms_request_str_t *normalized;
kms_kv_list_t *lst;
if (request->failed) {
return NULL;
}
if (!check_and_prohibit_kmip (request)) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
canonical = kms_request_str_new ();
kms_request_str_append (canonical, request->method);
kms_request_str_append_newline (canonical);
normalized = kms_request_str_path_normalized (request->path);
kms_request_str_append_escaped (canonical, normalized, false);
kms_request_str_destroy (normalized);
kms_request_str_append_newline (canonical);
append_canonical_query (request, canonical);
kms_request_str_append_newline (canonical);
lst = canonical_headers (request);
append_canonical_headers (lst, canonical);
kms_request_str_append_newline (canonical);
append_signed_headers (lst, canonical);
kms_kv_list_destroy (lst);
kms_request_str_append_newline (canonical);
if (!kms_request_str_append_hashed (
&request->crypto, canonical, request->payload)) {
KMS_ERROR (request, "could not generate hash");
kms_request_str_destroy (canonical);
return NULL;
}
return kms_request_str_detach (canonical);
}
const char *
kms_request_get_canonical_header (kms_request_t *request, const char *header)
{
const kms_kv_t *value;
if (request->failed) {
return NULL;
}
if (!check_and_prohibit_kmip (request)) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
value = kms_kv_list_find (request->header_fields, header);
if (!value) {
return NULL;
}
return value->value->str;
}
char *
kms_request_get_string_to_sign (kms_request_t *request)
{
bool success = false;
kms_request_str_t *sts;
kms_request_str_t *creq = NULL; /* canonical request */
if (request->failed) {
return NULL;
}
if (!check_and_prohibit_kmip (request)) {
return NULL;
}
if (!finalize (request)) {
return NULL;
}
sts = kms_request_str_new ();
kms_request_str_append_chars (sts, "AWS4-HMAC-SHA256\n", -1);
kms_request_str_append (sts, request->datetime);
kms_request_str_append_newline (sts);
/* credential scope, like "20150830/us-east-1/service/aws4_request" */
kms_request_str_append (sts, request->date);
kms_request_str_append_char (sts, '/');
kms_request_str_append (sts, request->region);
kms_request_str_append_char (sts, '/');
kms_request_str_append (sts, request->service);
kms_request_str_append_chars (sts, "/aws4_request\n", -1);
creq = kms_request_str_wrap (kms_request_get_canonical (request), -1);
if (!creq) {
goto done;
}
if (!kms_request_str_append_hashed (&request->crypto, sts, creq)) {
goto done;
}
success = true;
done:
kms_request_str_destroy (creq);
if (!success) {
kms_request_str_destroy (sts);
sts = NULL;
}
return kms_request_str_detach (sts);
}
static bool
kms_request_hmac (_kms_crypto_t *crypto,
unsigned char *out,
kms_request_str_t *key,
kms_request_str_t *data)
{
return crypto->sha256_hmac (
crypto->ctx, key->str, (int) key->len, data->str, data->len, out);
}
static bool
kms_request_hmac_again (_kms_crypto_t *crypto,
unsigned char *out,
unsigned char *in,
kms_request_str_t *data)
{
return crypto->sha256_hmac (
crypto->ctx, (const char *) in, 32, data->str, data->len, out);
}
bool
kms_request_get_signing_key (kms_request_t *request, unsigned char *key)
{
bool success = false;
kms_request_str_t *aws4_plus_secret = NULL;
kms_request_str_t *aws4_request = NULL;
unsigned char k_date[32];
unsigned char k_region[32];
unsigned char k_service[32];
if (request->failed) {
return false;
}
if (!check_and_prohibit_kmip (request)) {
return false;
}
/* docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
* Pseudocode for deriving a signing key
*
* kSecret = your secret access key
* kDate = HMAC("AWS4" + kSecret, Date)
* kRegion = HMAC(kDate, Region)
* kService = HMAC(kRegion, Service)
* kSigning = HMAC(kService, "aws4_request")
*/
aws4_plus_secret = kms_request_str_new_from_chars ("AWS4", -1);
kms_request_str_append (aws4_plus_secret, request->secret_key);
aws4_request = kms_request_str_new_from_chars ("aws4_request", -1);
if (!(kms_request_hmac (
&request->crypto, k_date, aws4_plus_secret, request->date) &&
kms_request_hmac_again (
&request->crypto, k_region, k_date, request->region) &&
kms_request_hmac_again (
&request->crypto, k_service, k_region, request->service) &&
kms_request_hmac_again (
&request->crypto, key, k_service, aws4_request))) {
goto done;
}
success = true;
done:
kms_request_str_destroy (aws4_plus_secret);
kms_request_str_destroy (aws4_request);
return success;
}
char *
kms_request_get_signature (kms_request_t *request)
{
bool success = false;
kms_kv_list_t *lst = NULL;
kms_request_str_t *sig = NULL;
kms_request_str_t *sts = NULL;
unsigned char signing_key[32];
unsigned char signature[32];
if (request->failed) {
return NULL;
}
if (!check_and_prohibit_kmip (request)) {
return NULL;
}
sts = kms_request_str_wrap (kms_request_get_string_to_sign (request), -1);
if (!sts) {
goto done;
}
sig = kms_request_str_new ();
kms_request_str_append_chars (sig, "AWS4-HMAC-SHA256 Credential=", -1);
kms_request_str_append (sig, request->access_key_id);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->date);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->region);
kms_request_str_append_char (sig, '/');
kms_request_str_append (sig, request->service);
kms_request_str_append_chars (sig, "/aws4_request, SignedHeaders=", -1);
lst = canonical_headers (request);
append_signed_headers (lst, sig);
kms_request_str_append_chars (sig, ", Signature=", -1);
if (!(kms_request_get_signing_key (request, signing_key) &&
kms_request_hmac_again (
&request->crypto, signature, signing_key, sts))) {
goto done;
}
kms_request_str_append_hex (sig, signature, sizeof (signature));
success = true;
done:
kms_kv_list_destroy (lst);
kms_request_str_destroy (sts);
if (!success) {
kms_request_str_destroy (sig);
sig = NULL;
}
return kms_request_str_detach (sig);
}
void
kms_request_validate (kms_request_t *request)
{
if (!check_and_prohibit_kmip (request)) {
return;
}
if (0 == request->region->len) {
KMS_ERROR (request, "Region not set");
} else if (0 == request->service->len) {
KMS_ERROR (request, "Service not set");
} else if (0 == request->access_key_id->len) {
KMS_ERROR (request, "Access key ID not set");
} else if (0 == request->method->len) {
KMS_ERROR (request, "Method not set");
} else if (0 == request->path->len) {
KMS_ERROR (request, "Path not set");
} else if (0 == request->date->len) {
KMS_ERROR (request, "Date not set");
} else if (0 == request->secret_key->len) {
KMS_ERROR (request, "Secret key not set");
}
}
char *
kms_request_get_signed (kms_request_t *request)
{
bool success = false;
kms_kv_list_t *lst = NULL;
char *signature = NULL;
kms_request_str_t *sreq = NULL;
size_t i;
kms_request_validate (request);
if (request->failed) {
return NULL;
}
if (!check_and_prohibit_kmip (request)) {
return false;
}
if (!finalize (request)) {
return NULL;
}
sreq = kms_request_str_new ();
/* like "POST / HTTP/1.1" */
kms_request_str_append (sreq, request->method);
kms_request_str_append_char (sreq, ' ');
kms_request_str_append (sreq, request->path);
if (request->query->len) {
kms_request_str_append_char (sreq, '?');
kms_request_str_append (sreq, request->query);
}
kms_request_str_append_chars (sreq, " HTTP/1.1", -1);
kms_request_str_append_newline (sreq);
/* headers */
lst = kms_kv_list_dup (request->header_fields);
kms_kv_list_sort (lst, cmp_header_field_names);
for (i = 0; i < lst->len; i++) {
kms_request_str_append (sreq, lst->kvs[i].key);
kms_request_str_append_char (sreq, ':');
kms_request_str_append (sreq, lst->kvs[i].value);
kms_request_str_append_newline (sreq);
}
/* authorization header */
signature = kms_request_get_signature (request);
if (!signature) {
goto done;
}
/* note space after ':', to match test .sreq files */
kms_request_str_append_chars (sreq, "Authorization: ", -1);
kms_request_str_append_chars (sreq, signature, -1);
/* body */
if (request->payload->len) {
kms_request_str_append_newline (sreq);
kms_request_str_append_newline (sreq);
kms_request_str_append (sreq, request->payload);
}
success = true;
done:
free (signature);
kms_kv_list_destroy (lst);
if (!success) {
kms_request_str_destroy (sreq);
sreq = NULL;
}
return kms_request_str_detach (sreq);
}
char *
kms_request_to_string (kms_request_t *request)
{
kms_kv_list_t *lst = NULL;
kms_request_str_t *sreq = NULL;
size_t i;
if (!finalize (request)) {
return false;
}
if (!check_and_prohibit_kmip (request)) {
return false;
}
if (request->to_string) {
return kms_request_str_detach (kms_request_str_dup (request->to_string));
}
sreq = kms_request_str_new ();
/* like "POST / HTTP/1.1" */
kms_request_str_append (sreq, request->method);
kms_request_str_append_char (sreq, ' ');
kms_request_str_append (sreq, request->path);
if (request->query->len) {
kms_request_str_append_char (sreq, '?');
kms_request_str_append (sreq, request->query);
}
kms_request_str_append_chars (sreq, " HTTP/1.1", -1);
kms_request_str_append_newline (sreq);
/* headers */
lst = kms_kv_list_dup (request->header_fields);
kms_kv_list_sort (lst, cmp_header_field_names);
for (i = 0; i < lst->len; i++) {
kms_request_str_append (sreq, lst->kvs[i].key);
kms_request_str_append_char (sreq, ':');
kms_request_str_append (sreq, lst->kvs[i].value);
kms_request_str_append_newline (sreq);
}
kms_request_str_append_newline (sreq);
/* body */
if (request->payload->len) {
kms_request_str_append (sreq, request->payload);
}
kms_kv_list_destroy (lst);
request->to_string = kms_request_str_dup (sreq);
return kms_request_str_detach (sreq);
}
void
kms_request_free_string (char *ptr)
{
free (ptr);
}
const uint8_t *
kms_request_to_bytes (kms_request_t *request, size_t *len)
{
if (request->provider == KMS_REQUEST_PROVIDER_KMIP) {
*len = request->kmip.len;
return request->kmip.data;
}
if (!request->to_string && !kms_request_to_string (request)) {
return NULL;
}
KMS_ASSERT (request->to_string);
*len = request->to_string->len;
return (const uint8_t*) request->to_string->str;
}
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_opt.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_opt.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_opt.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_opt.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_opt_private.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_opt_private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_opt_private.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_opt_private.h
diff --git a/mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_str.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_str.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongoc/src/kms-message/src/kms_request_str.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_str.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_str.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_str.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_request_str.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_request_str.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_response.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_response.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_response.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_response.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_response_parser.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_response_parser.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_response_parser.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_response_parser.c
index a8a5a65f..3a6fdbd1 100644
--- a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/kms_response_parser.c
+++ b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/kms_response_parser.c
@@ -1,402 +1,406 @@
#include "kms_message/kms_response_parser.h"
#include "kms_message_private.h"
#include "kms_kmip_response_parser_private.h"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include "hexlify.h"
/* destroys the members of parser, but not the parser itself. */
static void
_parser_destroy (kms_response_parser_t *parser)
{
kms_request_str_destroy (parser->raw_response);
parser->raw_response = NULL;
parser->content_length = -1;
kms_response_destroy (parser->response);
parser->response = NULL;
kms_kmip_response_parser_destroy (parser->kmip);
}
/* initializes the members of parser. */
static void
_parser_init (kms_response_parser_t *parser)
{
parser->raw_response = kms_request_str_new ();
parser->content_length = -1;
parser->response = calloc (1, sizeof (kms_response_t));
KMS_ASSERT (parser->response);
parser->response->headers = kms_kv_list_new ();
parser->state = PARSING_STATUS_LINE;
parser->start = 0;
parser->failed = false;
parser->chunk_size = 0;
parser->transfer_encoding_chunked = false;
parser->kmip = NULL;
}
kms_response_parser_t *
kms_response_parser_new (void)
{
kms_response_parser_t *parser = malloc (sizeof (kms_response_parser_t));
KMS_ASSERT (parser);
_parser_init (parser);
return parser;
}
int
kms_response_parser_wants_bytes (kms_response_parser_t *parser, int32_t max)
{
if (parser->kmip) {
return kms_kmip_response_parser_wants_bytes (parser->kmip, max);
}
switch (parser->state) {
case PARSING_DONE:
return 0;
case PARSING_STATUS_LINE:
case PARSING_HEADER:
return max;
case PARSING_CHUNK_LENGTH:
return max;
case PARSING_CHUNK:
/* add 2 for trailing \r\n */
return (parser->chunk_size + 2) -
((int) parser->raw_response->len - parser->start);
case PARSING_BODY:
KMS_ASSERT (parser->content_length != -1);
return parser->content_length -
((int) parser->raw_response->len - parser->start);
+ default:
+ KMS_ASSERT (false && "Invalid kms_response_parser HTTP state");
}
return -1;
}
static bool
_parse_int (const char *str, int *result)
{
char *endptr = NULL;
int64_t long_result;
errno = 0;
long_result = strtol (str, &endptr, 10);
if (endptr == str) {
/* No digits were parsed. Consider this an error */
return false;
}
if (endptr != NULL && *endptr != '\0') {
/* endptr points to the first invalid character. */
return false;
}
if (errno == EINVAL || errno == ERANGE) {
return false;
}
if (long_result > INT32_MAX || long_result < INT32_MIN) {
return false;
}
*result = (int) long_result;
return true;
}
/* parse an int from a substring inside of a string. */
static bool
_parse_int_from_view (const char *str, int start, int end, int *result)
{
char *num_str = malloc (end - start + 1);
KMS_ASSERT (num_str);
bool ret;
strncpy (num_str, str + start, end - start);
num_str[end - start] = '\0';
ret = _parse_int (num_str, result);
free (num_str);
return ret;
}
static bool
_parse_hex_from_view (const char *str, int len, int *result)
{
*result = unhexlify (str, len);
if (*result < 0) {
return false;
}
return true;
}
/* returns true if char is "linear white space". This *ignores* the folding case
* of CRLF followed by WSP. See https://stackoverflow.com/a/21072806/774658 */
static bool
_is_lwsp (char c)
{
return c == ' ' || c == 0x09 /* HTAB */;
}
/* parse a header line or status line. */
static kms_response_parser_state_t
_parse_line (kms_response_parser_t *parser, int end)
{
int i = parser->start;
const char *raw = parser->raw_response->str;
kms_response_t *response = parser->response;
if (parser->state == PARSING_STATUS_LINE) {
/* Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
int j;
int status;
if (strncmp (raw + i, "HTTP/1.1 ", 9) != 0) {
KMS_ERROR (parser, "Could not parse HTTP-Version.");
return PARSING_DONE;
}
i += 9;
for (j = i; j < end; j++) {
if (raw[j] == ' ')
break;
}
if (!_parse_int_from_view (raw, i, j, &status)) {
KMS_ERROR (parser, "Could not parse Status-Code.");
return PARSING_DONE;
}
response->status = status;
/* ignore the Reason-Phrase. */
return PARSING_HEADER;
} else if (parser->state == PARSING_HEADER) {
/* Treating a header as:
* message-header = field-name ":" [ field-value ] CRLF
* This is not completely correct, and does not take folding into acct.
* See https://tools.ietf.org/html/rfc822#section-3.1
*/
int j;
kms_request_str_t *key;
kms_request_str_t *val;
if (i == end) {
/* empty line, this signals the start of the body. */
if (parser->transfer_encoding_chunked) {
return PARSING_CHUNK_LENGTH;
}
return PARSING_BODY;
}
for (j = i; j < end; j++) {
if (raw[j] == ':')
break;
}
if (j == end) {
KMS_ERROR (parser, "Could not parse header, no colon found.");
return PARSING_DONE;
}
key = kms_request_str_new_from_chars (raw + i, j - i);
i = j + 1;
/* remove leading and trailing whitespace from the value. */
for (j = i; j < end; j++) {
if (!_is_lwsp (raw[j]))
break;
}
i = j;
/* find the end of the header by backtracking. */
for (j = end; j > i; j--) {
if (!_is_lwsp (raw[j]))
break;
}
if (i == j) {
val = kms_request_str_new ();
} else {
val = kms_request_str_new_from_chars (raw + i, j - i);
}
kms_kv_list_add (response->headers, key, val);
/* if we have *not* read the Content-Length yet, check. */
if (parser->content_length == -1 &&
strcmp (key->str, "Content-Length") == 0) {
if (!_parse_int (val->str, &parser->content_length)) {
KMS_ERROR (parser, "Could not parse Content-Length header.");
kms_request_str_destroy (key);
kms_request_str_destroy (val);
return PARSING_DONE;
}
}
if (0 == strcmp (key->str, "Transfer-Encoding")) {
if (0 == strcmp (val->str, "chunked")) {
parser->transfer_encoding_chunked = true;
} else {
KMS_ERROR (parser, "Unsupported Transfer-Encoding: %s", val->str);
kms_request_str_destroy (key);
kms_request_str_destroy (val);
return PARSING_DONE;
}
}
kms_request_str_destroy (key);
kms_request_str_destroy (val);
return PARSING_HEADER;
} else if (parser->state == PARSING_CHUNK_LENGTH) {
int result = 0;
if (!_parse_hex_from_view (raw + i, end - i, &result)) {
KMS_ERROR (parser, "Failed to parse hex chunk length.");
return PARSING_DONE;
}
parser->chunk_size = result;
return PARSING_CHUNK;
}
return PARSING_DONE;
}
bool
kms_response_parser_feed (kms_response_parser_t *parser,
uint8_t *buf,
uint32_t len)
{
kms_request_str_t *raw = parser->raw_response;
int curr, body_read, chunk_read;
if (parser->kmip) {
return kms_kmip_response_parser_feed (parser->kmip, buf, len);
}
curr = (int) raw->len;
kms_request_str_append_chars (raw, (char *) buf, len);
/* process the new data appended. */
while (curr < (int) raw->len) {
switch (parser->state) {
case PARSING_STATUS_LINE:
case PARSING_HEADER:
case PARSING_CHUNK_LENGTH:
/* find the next \r\n. */
if (curr && strncmp (raw->str + (curr - 1), "\r\n", 2) == 0) {
parser->state = _parse_line (parser, curr - 1);
parser->start = curr + 1;
}
curr++;
if (parser->state == PARSING_BODY && parser->content_length <= 0) {
/* Ok, no Content-Length header, or explicitly 0, so empty body */
parser->response->body = kms_request_str_new ();
parser->state = PARSING_DONE;
}
break;
case PARSING_BODY:
body_read = (int) raw->len - parser->start;
if (parser->content_length == -1 ||
body_read > parser->content_length) {
KMS_ERROR (parser, "Unexpected: exceeded content length");
return false;
}
/* check if we have the entire body. */
if (body_read == parser->content_length) {
parser->response->body = kms_request_str_new_from_chars (
raw->str + parser->start, parser->content_length);
parser->state = PARSING_DONE;
}
curr = (int) raw->len;
break;
case PARSING_CHUNK:
chunk_read = (int) raw->len - parser->start;
/* check if we've read the full chunk and the trailing \r\n */
if (chunk_read >= parser->chunk_size + 2) {
if (!parser->response->body) {
parser->response->body = kms_request_str_new ();
}
kms_request_str_append_chars (parser->response->body,
raw->str + parser->start,
parser->chunk_size);
curr = parser->start + parser->chunk_size + 2;
parser->start = curr;
if (parser->chunk_size == 0) {
/* last chunk. */
parser->state = PARSING_DONE;
} else {
parser->state = PARSING_CHUNK_LENGTH;
}
} else {
curr = (int) raw->len;
}
break;
case PARSING_DONE:
KMS_ERROR (parser, "Unexpected extra HTTP content");
return false;
+ default:
+ KMS_ASSERT (false && "Invalid kms_response_parser HTTP state");
}
}
if (parser->failed) {
return false;
}
return true;
}
/* steals the response from the parser. */
kms_response_t *
kms_response_parser_get_response (kms_response_parser_t *parser)
{
kms_response_t *response;
if (parser->kmip) {
return kms_kmip_response_parser_get_response (parser->kmip);
}
-
+
response = parser->response;
parser->response = NULL;
/* reset the parser. */
_parser_destroy (parser);
_parser_init (parser);
return response;
}
int
kms_response_parser_status (kms_response_parser_t *parser)
{
if (!parser) {
return 0;
}
-
+
if (parser->kmip) {
KMS_ERROR (parser, "kms_response_parser_status not applicable to KMIP");
return 0;
}
-
+
if (!parser->response) {
return 0;
}
return parser->response->status;
}
const char *
kms_response_parser_error (kms_response_parser_t *parser)
{
if (!parser) {
return NULL;
}
if (parser->kmip) {
return kms_kmip_response_parser_error (parser->kmip);
}
return parser->error;
}
void
kms_response_parser_destroy (kms_response_parser_t *parser)
{
_parser_destroy (parser);
free (parser);
}
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/sort.c b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/sort.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/sort.c
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/sort.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/kms-message/src/sort.h b/mongodb-1.14.0/src/libmongocrypt/kms-message/src/sort.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/kms-message/src/sort.h
rename to mongodb-1.14.0/src/libmongocrypt/kms-message/src/sort.h
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/crypto/cng.c b/mongodb-1.14.0/src/libmongocrypt/src/crypto/cng.c
new file mode 100644
index 00000000..f7b83f9b
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/crypto/cng.c
@@ -0,0 +1,610 @@
+/*
+ * Copyright 2019-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../mongocrypt-crypto-private.h"
+#include "../mongocrypt-private.h"
+#include <stdint.h>
+
+#ifdef MONGOCRYPT_ENABLE_CRYPTO_CNG
+
+#include <bcrypt.h>
+
+static BCRYPT_ALG_HANDLE _algo_sha512_hmac = 0;
+static BCRYPT_ALG_HANDLE _algo_sha256_hmac = 0;
+static BCRYPT_ALG_HANDLE _algo_aes256_cbc = 0;
+static BCRYPT_ALG_HANDLE _algo_aes256_ecb = 0;
+static DWORD _aes256_key_blob_length;
+static DWORD _aes256_block_length;
+
+static BCRYPT_ALG_HANDLE _random;
+
+#define STATUS_SUCCESS 0
+
+bool _native_crypto_initialized = false;
+
+void
+_native_crypto_init ()
+{
+ DWORD cbOutput;
+ NTSTATUS nt_status;
+
+ /* Note, there is no mechanism for libmongocrypt to close these providers,
+ * If we ever add such a mechanism, call BCryptCloseAlgorithmProvider.
+ */
+ nt_status = BCryptOpenAlgorithmProvider (&_algo_sha512_hmac,
+ BCRYPT_SHA512_ALGORITHM,
+ MS_PRIMITIVE_PROVIDER,
+ BCRYPT_ALG_HANDLE_HMAC_FLAG);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ nt_status = BCryptOpenAlgorithmProvider (&_algo_sha256_hmac,
+ BCRYPT_SHA256_ALGORITHM,
+ MS_PRIMITIVE_PROVIDER,
+ BCRYPT_ALG_HANDLE_HMAC_FLAG);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ nt_status = BCryptOpenAlgorithmProvider (
+ &_algo_aes256_cbc, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ nt_status = BCryptSetProperty (
+ _algo_aes256_cbc,
+ BCRYPT_CHAINING_MODE,
+ (PUCHAR) (BCRYPT_CHAIN_MODE_CBC),
+ (ULONG) (sizeof (wchar_t) * wcslen (BCRYPT_CHAIN_MODE_CBC)),
+ 0);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ nt_status = BCryptOpenAlgorithmProvider (
+ &_algo_aes256_ecb, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ nt_status = BCryptSetProperty (
+ _algo_aes256_ecb,
+ BCRYPT_CHAINING_MODE,
+ (PUCHAR) (BCRYPT_CHAIN_MODE_ECB),
+ (ULONG) (sizeof (wchar_t) * wcslen (BCRYPT_CHAIN_MODE_ECB)),
+ 0);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ cbOutput = sizeof (_aes256_key_blob_length);
+ nt_status = BCryptGetProperty (_algo_aes256_cbc,
+ BCRYPT_OBJECT_LENGTH,
+ (PUCHAR) (&_aes256_key_blob_length),
+ cbOutput,
+ &cbOutput,
+ 0);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ cbOutput = sizeof (_aes256_block_length);
+ nt_status = BCryptGetProperty (_algo_aes256_cbc,
+ BCRYPT_BLOCK_LENGTH,
+ (PUCHAR) (&_aes256_block_length),
+ cbOutput,
+ &cbOutput,
+ 0);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ nt_status = BCryptOpenAlgorithmProvider (
+ &_random, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
+ if (nt_status != STATUS_SUCCESS) {
+ return;
+ }
+
+ _native_crypto_initialized = true;
+}
+
+typedef struct {
+ unsigned char *key_object;
+ uint32_t key_object_length;
+
+ BCRYPT_KEY_HANDLE key_handle;
+
+ unsigned char *iv;
+ uint32_t iv_len;
+} cng_encrypt_state;
+
+static void
+_crypto_state_destroy (cng_encrypt_state *state);
+
+static cng_encrypt_state *
+_crypto_state_init (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *iv,
+ mongocrypt_status_t *status)
+{
+ cng_encrypt_state *state;
+ uint32_t keyBlobLength;
+ unsigned char *keyBlob;
+ BCRYPT_KEY_DATA_BLOB_HEADER blobHeader;
+ NTSTATUS nt_status;
+
+ keyBlob = NULL;
+
+ state = bson_malloc0 (sizeof (*state));
+ BSON_ASSERT (state);
+
+ state->key_handle = INVALID_HANDLE_VALUE;
+
+ /* Initialize key storage buffer */
+ state->key_object = bson_malloc0 (_aes256_key_blob_length);
+ BSON_ASSERT (state->key_object);
+
+ state->key_object_length = _aes256_key_blob_length;
+
+ /* Allocate temporary buffer for key import */
+ keyBlobLength = sizeof (BCRYPT_KEY_DATA_BLOB_HEADER) + key->len;
+ keyBlob = bson_malloc0 (keyBlobLength);
+ BSON_ASSERT (keyBlob);
+
+
+ blobHeader.dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
+ blobHeader.dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
+ blobHeader.cbKeyData = key->len;
+
+ memcpy (keyBlob, &blobHeader, sizeof (BCRYPT_KEY_DATA_BLOB_HEADER));
+
+ memcpy (keyBlob + sizeof (BCRYPT_KEY_DATA_BLOB_HEADER), key->data, key->len);
+
+ nt_status = BCryptImportKey (_algo_aes256_cbc,
+ NULL,
+ BCRYPT_KEY_DATA_BLOB,
+ &(state->key_handle),
+ state->key_object,
+ state->key_object_length,
+ keyBlob,
+ keyBlobLength,
+ 0);
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("Import Key Failed: 0x%x", (int) nt_status);
+ goto fail;
+ }
+
+ bson_free (keyBlob);
+
+ state->iv = bson_malloc0 (iv->len);
+ BSON_ASSERT (state->iv);
+
+ state->iv_len = iv->len;
+ memcpy (state->iv, iv->data, iv->len);
+
+ return state;
+fail:
+ _crypto_state_destroy (state);
+ bson_free (keyBlob);
+
+ return NULL;
+}
+
+
+static void
+_crypto_state_destroy (cng_encrypt_state *state)
+{
+ if (state) {
+ /* Free the key handle before the key_object that contains it */
+ if (state->key_handle != INVALID_HANDLE_VALUE) {
+ BCryptDestroyKey (state->key_handle);
+ }
+
+ bson_free (state->key_object);
+ bson_free (state->iv);
+ bson_free (state);
+ }
+}
+
+
+bool
+_native_crypto_aes_256_cbc_encrypt (aes_256_args_t args)
+{
+ bool ret = false;
+ mongocrypt_status_t *status = args.status;
+ cng_encrypt_state *state = _crypto_state_init (args.key, args.iv, status);
+
+ NTSTATUS nt_status;
+
+ nt_status = BCryptEncrypt (state->key_handle,
+ (PUCHAR) (args.in->data),
+ args.in->len,
+ NULL,
+ state->iv,
+ state->iv_len,
+ args.out->data,
+ args.out->len,
+ args.bytes_written,
+ 0);
+
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("error initializing cipher: 0x%x", (int) nt_status);
+ goto done;
+ }
+
+ ret = true;
+done:
+ _crypto_state_destroy (state);
+ return ret;
+}
+
+
+bool
+_native_crypto_aes_256_cbc_decrypt (aes_256_args_t args)
+{
+ bool ret = false;
+ mongocrypt_status_t *status = args.status;
+ cng_encrypt_state *state = _crypto_state_init (args.key, args.iv, status);
+
+ NTSTATUS nt_status;
+
+ nt_status = BCryptDecrypt (state->key_handle,
+ (PUCHAR) (args.in->data),
+ args.in->len,
+ NULL,
+ state->iv,
+ state->iv_len,
+ args.out->data,
+ args.out->len,
+ args.bytes_written,
+ 0);
+
+
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("error initializing cipher: 0x%x", (int) nt_status);
+ goto done;
+ }
+
+ ret = true;
+done:
+ _crypto_state_destroy (state);
+ return ret;
+}
+
+/* _hmac_with_algorithm computes an HMAC of @in with the algorithm specified by
+ * @hAlgorithm.
+ * @key is the input key.
+ * @out is the output. @out must be allocated by the caller with
+ * the expected length @expect_out_len for the output.
+ * Returns false and sets @status on error. @status is required. */
+bool
+_hmac_with_algorithm (BCRYPT_ALG_HANDLE hAlgorithm,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ uint32_t expect_out_len,
+ mongocrypt_status_t *status)
+{
+ bool ret = false;
+ BCRYPT_HASH_HANDLE hHash;
+ NTSTATUS nt_status;
+
+ if (out->len != expect_out_len) {
+ CLIENT_ERR ("out does not contain " PRIu32 " bytes", expect_out_len);
+ return false;
+ }
+
+ nt_status = BCryptCreateHash (
+ hAlgorithm, &hHash, NULL, 0, (PUCHAR) key->data, (ULONG) key->len, 0);
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("error initializing hmac: 0x%x", (int) nt_status);
+ /* Only call BCryptDestroyHash if BCryptCreateHash succeeded. */
+ return false;
+ }
+
+ nt_status = BCryptHashData (hHash, (PUCHAR) in->data, (ULONG) in->len, 0);
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("error hashing data: 0x%x", (int) nt_status);
+ goto done;
+ }
+
+ nt_status = BCryptFinishHash (hHash, out->data, out->len, 0);
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("error finishing hmac: 0x%x", (int) nt_status);
+ goto done;
+ }
+
+ ret = true;
+done:
+ (void) BCryptDestroyHash (hHash);
+ return ret;
+}
+
+bool
+_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ return _hmac_with_algorithm (
+ _algo_sha512_hmac, key, in, out, MONGOCRYPT_HMAC_SHA512_LEN, status);
+}
+
+
+bool
+_native_crypto_random (_mongocrypt_buffer_t *out,
+ uint32_t count,
+ mongocrypt_status_t *status)
+{
+ NTSTATUS nt_status = BCryptGenRandom (_random, out->data, count, 0);
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("BCryptGenRandom Failed: 0x%x", (int) nt_status);
+ return false;
+ }
+
+ return true;
+}
+
+typedef struct {
+ BCRYPT_KEY_HANDLE key_handle;
+
+ unsigned char *input_block;
+ uint32_t input_block_len;
+
+ unsigned char *output_block;
+ uint32_t output_block_len;
+ uint32_t output_block_ptr;
+} cng_ctr_encrypt_state;
+
+static bool
+_cng_ctr_crypto_generate (cng_ctr_encrypt_state *state,
+ mongocrypt_status_t *status)
+{
+ BSON_ASSERT (state);
+ BSON_ASSERT (status);
+
+ uint32_t bytesEncrypted = 0;
+ NTSTATUS nt_status = BCryptEncrypt (state->key_handle,
+ state->input_block,
+ state->input_block_len,
+ NULL,
+ NULL,
+ 0,
+ state->output_block,
+ state->output_block_len,
+ &bytesEncrypted,
+ 0);
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("error encrypting: 0x%x", (int) nt_status);
+ return false;
+ }
+ BSON_ASSERT (bytesEncrypted);
+ state->output_block_ptr = 0;
+ return true;
+}
+
+static void
+_cng_ctr_crypto_advance (cng_ctr_encrypt_state *state)
+{
+ BSON_ASSERT (state);
+
+ uint32_t carry = 1;
+ for (int i = state->input_block_len - 1; i >= 0 && carry != 0; --i) {
+ uint32_t bpp = (uint32_t) (state->input_block[i]) + carry;
+ carry = bpp >> 8;
+ state->input_block[i] = bpp & 0xFF;
+ }
+}
+
+static bool
+_cng_ctr_crypto_next (cng_ctr_encrypt_state *state,
+ mongocrypt_status_t *status,
+ unsigned char *mask)
+{
+ BSON_ASSERT (state);
+ BSON_ASSERT (status);
+ BSON_ASSERT (mask);
+
+ if (state->output_block_ptr >= state->output_block_len) {
+ _cng_ctr_crypto_advance (state);
+ if (!_cng_ctr_crypto_generate (state, status)) {
+ return false;
+ };
+ }
+
+ *mask = state->output_block[state->output_block_ptr];
+ ++state->output_block_ptr;
+
+ return true;
+}
+
+static void
+_cng_ctr_crypto_state_destroy (cng_ctr_encrypt_state *state);
+
+static cng_ctr_encrypt_state *
+_cng_ctr_crypto_state_init (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *iv,
+ mongocrypt_status_t *status)
+{
+ cng_ctr_encrypt_state *state;
+ uint32_t keyBlobLength;
+ unsigned char *keyBlob;
+ BCRYPT_KEY_DATA_BLOB_HEADER blobHeader;
+ NTSTATUS nt_status;
+
+ keyBlob = NULL;
+
+ state = bson_malloc0 (sizeof (*state));
+ BSON_ASSERT (state);
+
+ state->key_handle = INVALID_HANDLE_VALUE;
+
+ /* Initialize input storage buffer */
+ state->input_block = bson_malloc0 (_aes256_block_length);
+ BSON_ASSERT (state->input_block);
+ state->input_block_len = _aes256_block_length;
+ BSON_ASSERT (iv->len == _aes256_block_length);
+ memcpy (state->input_block, iv->data, iv->len);
+
+ /* Initialize output storage buffer */
+ state->output_block = bson_malloc0 (_aes256_block_length);
+ BSON_ASSERT (state->output_block);
+ state->output_block_len = _aes256_block_length;
+ state->output_block_ptr = 0;
+
+ /* Allocate temporary buffer for key import */
+ keyBlobLength = sizeof (BCRYPT_KEY_DATA_BLOB_HEADER) + key->len;
+ keyBlob = bson_malloc0 (keyBlobLength);
+ BSON_ASSERT (keyBlob);
+
+ blobHeader.dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC;
+ blobHeader.dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1;
+ blobHeader.cbKeyData = key->len;
+
+ memcpy (keyBlob, &blobHeader, sizeof (BCRYPT_KEY_DATA_BLOB_HEADER));
+
+ memcpy (keyBlob + sizeof (BCRYPT_KEY_DATA_BLOB_HEADER), key->data, key->len);
+
+ nt_status = BCryptImportKey (_algo_aes256_ecb,
+ NULL,
+ BCRYPT_KEY_DATA_BLOB,
+ &(state->key_handle),
+ NULL,
+ 0,
+ keyBlob,
+ keyBlobLength,
+ 0);
+ if (nt_status != STATUS_SUCCESS) {
+ CLIENT_ERR ("Import Key Failed: 0x%x", (int) nt_status);
+ goto fail;
+ }
+
+ bson_free (keyBlob);
+
+ if (!_cng_ctr_crypto_generate (state, status)) {
+ goto fail;
+ }
+
+ return state;
+fail:
+ _cng_ctr_crypto_state_destroy (state);
+ bson_free (keyBlob);
+
+ return NULL;
+}
+
+static void
+_cng_ctr_crypto_state_destroy (cng_ctr_encrypt_state *state)
+{
+ if (state) {
+ if (state->key_handle != INVALID_HANDLE_VALUE) {
+ BCryptDestroyKey (state->key_handle);
+ }
+
+ bson_free (state->input_block);
+ bson_free (state->output_block);
+ bson_free (state);
+ }
+}
+
+bool
+_native_crypto_aes_256_ctr_encrypt (aes_256_args_t args)
+{
+ bool ret = false;
+ cng_ctr_encrypt_state *state = NULL;
+ mongocrypt_status_t *status = args.status;
+
+ BSON_ASSERT (args.in && args.in->data);
+ BSON_ASSERT (args.out && args.out->data);
+ if (args.out->len < args.in->len) {
+ CLIENT_ERR ("Output buffer is too small");
+ goto fail;
+ }
+
+ state = _cng_ctr_crypto_state_init (args.key, args.iv, status);
+ if (!state) {
+ goto fail;
+ }
+
+ for (uint32_t i = 0; i < args.in->len; ++i) {
+ unsigned char mask;
+ if (!_cng_ctr_crypto_next (state, status, &mask)) {
+ goto fail;
+ }
+ args.out->data[i] = args.in->data[i] ^ mask;
+ }
+
+ if (args.bytes_written) {
+ *args.bytes_written = args.in->len;
+ }
+
+ ret = true;
+
+fail:
+ _cng_ctr_crypto_state_destroy (state);
+ return ret;
+}
+
+bool
+_native_crypto_aes_256_ctr_decrypt (aes_256_args_t args)
+{
+ bool ret = false;
+ cng_ctr_encrypt_state *state = NULL;
+ mongocrypt_status_t *status = args.status;
+
+ BSON_ASSERT (args.in && args.in->data);
+ BSON_ASSERT (args.out && args.out->data);
+ if (args.out->len < args.in->len) {
+ CLIENT_ERR ("Output buffer is too small");
+ goto fail;
+ }
+
+ state = _cng_ctr_crypto_state_init (args.key, args.iv, status);
+ if (!state) {
+ goto fail;
+ }
+
+ for (uint32_t i = 0; i < args.in->len; ++i) {
+ unsigned char mask;
+ if (!_cng_ctr_crypto_next (state, status, &mask)) {
+ goto fail;
+ }
+ args.out->data[i] = args.in->data[i] ^ mask;
+ }
+
+ if (args.bytes_written) {
+ *args.bytes_written = args.in->len;
+ }
+
+ ret = true;
+
+fail:
+ _cng_ctr_crypto_state_destroy (state);
+ return ret;
+}
+
+bool
+_native_crypto_hmac_sha_256 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ return _hmac_with_algorithm (
+ _algo_sha256_hmac, key, in, out, MONGOCRYPT_HMAC_SHA256_LEN, status);
+}
+
+#endif /* MONGOCRYPT_ENABLE_CRYPTO_CNG */
\ No newline at end of file
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/crypto/commoncrypto.c b/mongodb-1.14.0/src/libmongocrypt/src/crypto/commoncrypto.c
new file mode 100644
index 00000000..5786685f
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/crypto/commoncrypto.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2019-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../mongocrypt-crypto-private.h"
+#include "../mongocrypt-private.h"
+
+#ifdef MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO
+
+#include <CommonCrypto/CommonCryptor.h>
+#include <CommonCrypto/CommonHMAC.h>
+#include <CommonCrypto/CommonRandom.h>
+
+static const char *
+CCCryptorStatus_to_string (CCCryptorStatus status)
+{
+ switch (status) {
+ case kCCSuccess:
+ return "Success";
+ case kCCParamError:
+ return "ParamError";
+ case kCCBufferTooSmall:
+ return "BufferTooSmall";
+ case kCCMemoryFailure:
+ return "MemoryFailure";
+ case kCCAlignmentError:
+ return "AlignmentError";
+ case kCCDecodeError:
+ return "DecodeError";
+ case kCCUnimplemented:
+ return "Unimplemented";
+ case kCCOverflow:
+ return "Overflow";
+ case kCCRNGFailure:
+ return "RNGFailure";
+ case kCCUnspecifiedError:
+ return "UnspecifiedError";
+ case kCCCallSequenceError:
+ return "CallSequenceError";
+ case kCCKeySizeError:
+ return "KeySizeError";
+ case kCCInvalidKey:
+ return "InvalidKey";
+ default:
+ return "Unknown";
+ }
+}
+
+bool _native_crypto_initialized = false;
+
+void
+_native_crypto_init ()
+{
+ _native_crypto_initialized = true;
+}
+
+
+bool
+_native_crypto_aes_256_cbc_encrypt_with_mode (aes_256_args_t args, CCMode mode)
+{
+ bool ret = false;
+ CCCryptorRef ctx = NULL;
+ CCCryptorStatus cc_status;
+ size_t intermediate_bytes_written;
+ mongocrypt_status_t *status = args.status;
+
+ cc_status = CCCryptorCreateWithMode (kCCEncrypt,
+ mode,
+ kCCAlgorithmAES,
+ 0 /* defaults to CBC w/ no padding */,
+ args.iv->data,
+ args.key->data,
+ kCCKeySizeAES256,
+ NULL,
+ 0,
+ 0,
+ 0,
+ &ctx);
+
+ if (cc_status != kCCSuccess) {
+ if (cc_status == kCCUnimplemented && mode == kCCModeCTR) {
+ CLIENT_ERR ("error initializing cipher: %s (%d). CTR mode is only "
+ "supported on macOS 10.15+",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ } else {
+ CLIENT_ERR ("error initializing cipher: %s (%d)",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ }
+ goto done;
+ }
+
+ *args.bytes_written = 0;
+
+ cc_status = CCCryptorUpdate (ctx,
+ args.in->data,
+ args.in->len,
+ args.out->data,
+ args.out->len,
+ &intermediate_bytes_written);
+ if (cc_status != kCCSuccess) {
+ CLIENT_ERR ("error encrypting: %s (%d)",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ goto done;
+ }
+ *args.bytes_written = intermediate_bytes_written;
+
+
+ cc_status = CCCryptorFinal (ctx,
+ args.out->data + *args.bytes_written,
+ args.out->len - *args.bytes_written,
+ &intermediate_bytes_written);
+ *args.bytes_written += intermediate_bytes_written;
+
+ if (cc_status != kCCSuccess) {
+ CLIENT_ERR ("error finalizing: %s (%d)",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ goto done;
+ }
+
+ ret = true;
+done:
+ CCCryptorRelease (ctx);
+ return ret;
+}
+
+bool
+_native_crypto_aes_256_cbc_encrypt (aes_256_args_t args)
+{
+ return _native_crypto_aes_256_cbc_encrypt_with_mode (args, kCCModeCBC);
+}
+
+bool
+_native_crypto_aes_256_ctr_encrypt (aes_256_args_t args)
+{
+ return _native_crypto_aes_256_cbc_encrypt_with_mode (args, kCCModeCTR);
+}
+
+/* Note, the decrypt function is almost exactly the same as the encrypt
+ * functions except for the kCCDecrypt and the error message. */
+bool
+_native_crypto_aes_256_cbc_decrypt_with_mode (aes_256_args_t args, CCMode mode)
+{
+ bool ret = false;
+ CCCryptorRef ctx = NULL;
+ CCCryptorStatus cc_status;
+ size_t intermediate_bytes_written;
+ mongocrypt_status_t *status = args.status;
+
+ cc_status = CCCryptorCreateWithMode (kCCDecrypt,
+ mode,
+ kCCAlgorithmAES,
+ 0 /* defaults to CBC w/ no padding */,
+ args.iv->data,
+ args.key->data,
+ kCCKeySizeAES256,
+ NULL,
+ 0,
+ 0,
+ 0,
+ &ctx);
+
+ if (cc_status != kCCSuccess) {
+ if (cc_status == kCCUnimplemented && mode == kCCModeCTR) {
+ CLIENT_ERR ("error initializing cipher: %s (%d). CTR mode is only "
+ "supported on macOS 10.15+",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ } else {
+ CLIENT_ERR ("error initializing cipher: %s (%d)",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ }
+ goto done;
+ }
+
+ *args.bytes_written = 0;
+ cc_status = CCCryptorUpdate (ctx,
+ args.in->data,
+ args.in->len,
+ args.out->data,
+ args.out->len,
+ &intermediate_bytes_written);
+ if (cc_status != kCCSuccess) {
+ CLIENT_ERR ("error decrypting: %s (%d)",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ goto done;
+ }
+ *args.bytes_written = intermediate_bytes_written;
+
+ cc_status = CCCryptorFinal (ctx,
+ args.out->data + *args.bytes_written,
+ args.out->len - *args.bytes_written,
+ &intermediate_bytes_written);
+ *args.bytes_written += intermediate_bytes_written;
+
+ if (cc_status != kCCSuccess) {
+ CLIENT_ERR ("error finalizing: %s (%d)",
+ CCCryptorStatus_to_string (cc_status),
+ (int) cc_status);
+ goto done;
+ }
+
+ ret = true;
+done:
+ CCCryptorRelease (ctx);
+ return ret;
+}
+
+bool
+_native_crypto_aes_256_cbc_decrypt (aes_256_args_t args)
+{
+ return _native_crypto_aes_256_cbc_decrypt_with_mode (args, kCCModeCBC);
+}
+
+bool
+_native_crypto_aes_256_ctr_decrypt (aes_256_args_t args)
+{
+ return _native_crypto_aes_256_cbc_decrypt_with_mode (args, kCCModeCTR);
+}
+
+
+/* _hmac_with_algorithm computes an HMAC of @in with the algorithm specified by
+ * @algorithm.
+ * @key is the input key.
+ * @out is the output. @out must be allocated by the caller with
+ * the expected length @expect_out_len for the output.
+ * Returns false and sets @status on error. @status is required. */
+bool
+_hmac_with_algorithm (CCHmacAlgorithm algorithm,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ uint32_t expect_out_len,
+ mongocrypt_status_t *status)
+{
+ CCHmacContext *ctx;
+
+ if (out->len != expect_out_len) {
+ CLIENT_ERR ("out does not contain %" PRIu32 " bytes", expect_out_len);
+ return false;
+ }
+
+ ctx = bson_malloc0 (sizeof (*ctx));
+ BSON_ASSERT (ctx);
+
+
+ CCHmacInit (ctx, algorithm, key->data, key->len);
+ CCHmacUpdate (ctx, in->data, in->len);
+ CCHmacFinal (ctx, out->data);
+ bson_free (ctx);
+ return true;
+}
+
+bool
+_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ return _hmac_with_algorithm (
+ kCCHmacAlgSHA512, key, in, out, MONGOCRYPT_HMAC_SHA512_LEN, status);
+}
+
+
+bool
+_native_crypto_random (_mongocrypt_buffer_t *out,
+ uint32_t count,
+ mongocrypt_status_t *status)
+{
+ CCRNGStatus ret = CCRandomGenerateBytes (out->data, (size_t) count);
+ if (ret != kCCSuccess) {
+ CLIENT_ERR ("failed to generate random iv: %d", (int) ret);
+ return false;
+ }
+ return true;
+}
+
+bool
+_native_crypto_hmac_sha_256 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ return _hmac_with_algorithm (
+ kCCHmacAlgSHA256, key, in, out, MONGOCRYPT_HMAC_SHA256_LEN, status);
+}
+
+#endif /* MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/crypto/libcrypto.c b/mongodb-1.14.0/src/libmongocrypt/src/crypto/libcrypto.c
similarity index 82%
rename from mongodb-1.13.0/src/libmongocrypt/src/crypto/libcrypto.c
rename to mongodb-1.14.0/src/libmongocrypt/src/crypto/libcrypto.c
index 86fe3925..b7b58326 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/crypto/libcrypto.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/crypto/libcrypto.c
@@ -1,288 +1,317 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Comments in this implementation refer to:
* [MCGREW] https://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-05
*/
#include "../mongocrypt-crypto-private.h"
#include "../mongocrypt-private.h"
#include "../mongocrypt-log-private.h"
#ifdef MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO
#include <bson/bson.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
static HMAC_CTX *
HMAC_CTX_new (void)
{
return bson_malloc0 (sizeof (HMAC_CTX));
}
static void
HMAC_CTX_free (HMAC_CTX *ctx)
{
HMAC_CTX_cleanup (ctx);
bson_free (ctx);
}
#endif
bool _native_crypto_initialized = false;
void
_native_crypto_init ()
{
_native_crypto_initialized = true;
}
/* _encrypt_with_cipher encrypts @in with the OpenSSL cipher specified by
* @cipher.
* @key is the input key. @iv is the input IV.
* @out is the output ciphertext. @out must be allocated by the caller with
* enough room for the ciphertext.
* @bytes_written is the number of bytes that were written to @out.
* Returns false and sets @status on error. @status is required. */
static bool
_encrypt_with_cipher (const EVP_CIPHER *cipher, aes_256_args_t args)
{
EVP_CIPHER_CTX *ctx;
bool ret = false;
int intermediate_bytes_written;
mongocrypt_status_t *status = args.status;
ctx = EVP_CIPHER_CTX_new ();
BSON_ASSERT (ctx);
BSON_ASSERT (cipher);
- BSON_ASSERT (EVP_CIPHER_iv_length (cipher) == args.iv->len);
+ BSON_ASSERT (NULL == args.iv ||
+ EVP_CIPHER_iv_length (cipher) == args.iv->len);
BSON_ASSERT (EVP_CIPHER_key_length (cipher) == args.key->len);
- if (!EVP_EncryptInit_ex (
- ctx, cipher, NULL /* engine */, args.key->data, args.iv->data)) {
+ if (!EVP_EncryptInit_ex (ctx,
+ cipher,
+ NULL /* engine */,
+ args.key->data,
+ NULL == args.iv ? NULL : args.iv->data)) {
CLIENT_ERR ("error in EVP_EncryptInit_ex: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
/* Disable the default OpenSSL padding. */
EVP_CIPHER_CTX_set_padding (ctx, 0);
*args.bytes_written = 0;
if (!EVP_EncryptUpdate (ctx,
args.out->data,
&intermediate_bytes_written,
args.in->data,
args.in->len)) {
CLIENT_ERR ("error in EVP_EncryptUpdate: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
*args.bytes_written = (uint32_t) intermediate_bytes_written;
if (!EVP_EncryptFinal_ex (
ctx, args.out->data, &intermediate_bytes_written)) {
CLIENT_ERR ("error in EVP_EncryptFinal_ex: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
*args.bytes_written += (uint32_t) intermediate_bytes_written;
ret = true;
done:
EVP_CIPHER_CTX_free (ctx);
return ret;
}
/* _decrypt_with_cipher decrypts @in with the OpenSSL cipher specified by
* @cipher.
* @key is the input key. @iv is the input IV.
* @out is the output plaintext. @out must be allocated by the caller with
* enough room for the plaintext.
* @bytes_written is the number of bytes that were written to @out.
* Returns false and sets @status on error. @status is required. */
static bool
_decrypt_with_cipher (const EVP_CIPHER *cipher, aes_256_args_t args)
{
EVP_CIPHER_CTX *ctx;
bool ret = false;
int intermediate_bytes_written;
mongocrypt_status_t *status = args.status;
ctx = EVP_CIPHER_CTX_new ();
BSON_ASSERT (EVP_CIPHER_iv_length (cipher) == args.iv->len);
BSON_ASSERT (EVP_CIPHER_key_length (cipher) == args.key->len);
if (!EVP_DecryptInit_ex (
ctx, cipher, NULL /* engine */, args.key->data, args.iv->data)) {
CLIENT_ERR ("error in EVP_DecryptInit_ex: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
/* Disable padding. */
EVP_CIPHER_CTX_set_padding (ctx, 0);
*args.bytes_written = 0;
if (!EVP_DecryptUpdate (ctx,
args.out->data,
&intermediate_bytes_written,
args.in->data,
args.in->len)) {
CLIENT_ERR ("error in EVP_DecryptUpdate: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
*args.bytes_written = intermediate_bytes_written;
if (!EVP_DecryptFinal_ex (
ctx, args.out->data, &intermediate_bytes_written)) {
CLIENT_ERR ("error in EVP_DecryptFinal_ex: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
*args.bytes_written += intermediate_bytes_written;
ret = true;
done:
EVP_CIPHER_CTX_free (ctx);
return ret;
}
bool
_native_crypto_aes_256_cbc_encrypt (aes_256_args_t args)
{
return _encrypt_with_cipher (EVP_aes_256_cbc (), args);
}
bool
_native_crypto_aes_256_cbc_decrypt (aes_256_args_t args)
{
return _decrypt_with_cipher (EVP_aes_256_cbc (), args);
}
-
bool
-_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
- const _mongocrypt_buffer_t *in,
- _mongocrypt_buffer_t *out,
- mongocrypt_status_t *status)
+_native_crypto_aes_256_ecb_encrypt (aes_256_args_t args)
{
- const EVP_MD *algo;
+ return _encrypt_with_cipher (EVP_aes_256_ecb (), args);
+}
- algo = EVP_sha512 ();
- BSON_ASSERT (EVP_MD_block_size (algo) == 128);
- BSON_ASSERT (EVP_MD_size (algo) == MONGOCRYPT_HMAC_SHA512_LEN);
+/* _hmac_with_hash computes an HMAC of @in with the OpenSSL hash specified by
+ * @hash.
+ * @key is the input key.
+ * @out is the output. @out must be allocated by the caller with
+ * the exact length for the output. E.g. for HMAC 256, @out->len must be 32.
+ * Returns false and sets @status on error. @status is required. */
+bool
+_hmac_with_hash (const EVP_MD *hash,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
- if (!HMAC (algo,
+ if (!HMAC (hash,
key->data,
key->len,
in->data,
in->len,
out->data,
NULL /* unused out len */)) {
CLIENT_ERR ("error initializing HMAC: %s",
ERR_error_string (ERR_get_error (), NULL));
return false;
}
return true;
#else
HMAC_CTX *ctx;
bool ret = false;
ctx = HMAC_CTX_new ();
- if (out->len != MONGOCRYPT_HMAC_SHA512_LEN) {
- CLIENT_ERR ("out does not contain %d bytes", MONGOCRYPT_HMAC_SHA512_LEN);
+ if (out->len != EVP_MD_size (hash)) {
+ CLIENT_ERR ("out does not contain %d bytes", EVP_MD_size (hash));
return false;
}
- if (!HMAC_Init_ex (ctx, key->data, key->len, algo, NULL /* engine */)) {
+ if (!HMAC_Init_ex (ctx, key->data, key->len, hash, NULL /* engine */)) {
CLIENT_ERR ("error initializing HMAC: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
if (!HMAC_Update (ctx, in->data, in->len)) {
CLIENT_ERR ("error updating HMAC: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
if (!HMAC_Final (ctx, out->data, NULL /* unused out len */)) {
CLIENT_ERR ("error finalizing: %s",
ERR_error_string (ERR_get_error (), NULL));
goto done;
}
ret = true;
done:
HMAC_CTX_free (ctx);
return ret;
#endif
}
+bool
+_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ return _hmac_with_hash (EVP_sha512 (), key, in, out, status);
+}
+
bool
_native_crypto_random (_mongocrypt_buffer_t *out,
uint32_t count,
mongocrypt_status_t *status)
{
int ret = RAND_bytes (out->data, count);
/* From man page: "RAND_bytes() and RAND_priv_bytes() return 1 on success, -1
* if not supported by the current RAND method, or 0 on other failure. The
* error code can be obtained by ERR_get_error(3)" */
if (ret == -1) {
CLIENT_ERR ("secure random IV not supported: %s",
ERR_error_string (ERR_get_error (), NULL));
return false;
} else if (ret == 0) {
CLIENT_ERR ("failed to generate random IV: %s",
ERR_error_string (ERR_get_error (), NULL));
return false;
}
return true;
}
bool
_native_crypto_aes_256_ctr_encrypt (aes_256_args_t args)
{
return _encrypt_with_cipher (EVP_aes_256_ctr (), args);
}
bool
_native_crypto_aes_256_ctr_decrypt (aes_256_args_t args)
{
return _decrypt_with_cipher (EVP_aes_256_ctr (), args);
}
+bool
+_native_crypto_hmac_sha_256 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ return _hmac_with_hash (EVP_sha256 (), key, in, out, status);
+}
+
#endif /* MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/crypto/none.c b/mongodb-1.14.0/src/libmongocrypt/src/crypto/none.c
similarity index 87%
rename from mongodb-1.13.0/src/libmongocrypt/src/crypto/none.c
rename to mongodb-1.14.0/src/libmongocrypt/src/crypto/none.c
index 831cf2b3..aa87f68f 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/crypto/none.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/crypto/none.c
@@ -1,87 +1,96 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* everything is a no-op */
#include "../mongocrypt-crypto-private.h"
#include "../mongocrypt-private.h"
#ifndef MONGOCRYPT_ENABLE_CRYPTO
bool _native_crypto_initialized = false;
void
_native_crypto_init ()
{
_native_crypto_initialized = true;
}
bool
_native_crypto_aes_256_cbc_encrypt (aes_256_args_t args)
{
mongocrypt_status_t *status = args.status;
CLIENT_ERR ("hook not set for aes_256_cbc_encrypt");
return false;
}
bool
_native_crypto_aes_256_cbc_decrypt (aes_256_args_t args)
{
mongocrypt_status_t *status = args.status;
CLIENT_ERR ("hook not set for aes_256_cbc_decrypt");
return false;
}
bool
_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *in,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status)
{
CLIENT_ERR ("hook not set for hmac_sha_512");
return false;
}
bool
_native_crypto_random (_mongocrypt_buffer_t *out,
uint32_t count,
mongocrypt_status_t *status)
{
CLIENT_ERR ("hook not set for random");
return false;
}
bool
_native_crypto_aes_256_ctr_encrypt (aes_256_args_t args)
{
mongocrypt_status_t *status = args.status;
CLIENT_ERR ("hook not set for _native_crypto_aes_256_ctr_encrypt");
return false;
}
bool
_native_crypto_aes_256_ctr_decrypt (aes_256_args_t args)
{
mongocrypt_status_t *status = args.status;
CLIENT_ERR ("hook not set for _native_crypto_aes_256_ctr_decrypt");
return false;
}
+bool
+_native_crypto_hmac_sha_256 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status) {
+ CLIENT_ERR ("hook not set for _native_crypto_hmac_sha_256");
+ return false;
+}
+
#endif /* MONGOCRYPT_ENABLE_CRYPTO */
\ No newline at end of file
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-efc-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-efc-private.h
new file mode 100644
index 00000000..4b8c9efb
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-efc-private.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MC_EFC_PRIVATE_H
+#define MC_EFC_PRIVATE_H
+
+#include "mongocrypt-buffer-private.h"
+#include <bson/bson.h>
+
+typedef struct _mc_EncryptedField_t {
+ bool has_queries;
+ _mongocrypt_buffer_t keyId;
+ const char *path;
+ struct _mc_EncryptedField_t *next;
+} mc_EncryptedField_t;
+
+/* See
+ * https://github.com/mongodb/mongo/blob/591f49a64e96cea68bf3501320de31c51c31f412/src/mongo/crypto/encryption_fields.idl#L48-L112
+ * for the server IDL definition of EncryptedFieldConfig. */
+typedef struct {
+ mc_EncryptedField_t *fields;
+} mc_EncryptedFieldConfig_t;
+
+/* mc_EncryptedFieldConfig_parse parses a subset of the fields from @efc_bson
+ * into @efc. Fields are copied from @efc_bson. It is OK to free efc_bson after
+ * this call. Fields are appended in reverse order to @efc->fields. Extra
+ * unrecognized fields are not considered an error for forward compatibility. */
+bool
+mc_EncryptedFieldConfig_parse (mc_EncryptedFieldConfig_t *efc,
+ const bson_t *efc_bson,
+ mongocrypt_status_t *status);
+
+void
+mc_EncryptedFieldConfig_cleanup (mc_EncryptedFieldConfig_t *efc);
+
+#endif /* MC_EFC_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-efc.c b/mongodb-1.14.0/src/libmongocrypt/src/mc-efc.c
new file mode 100644
index 00000000..8a492b31
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-efc.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "mc-efc-private.h"
+
+#include "mongocrypt-private.h"
+
+/* _parse_field parses and prepends one field document to efc->fields. */
+static bool
+_parse_field (mc_EncryptedFieldConfig_t *efc,
+ bson_t *field,
+ mongocrypt_status_t *status)
+{
+ bool has_queries = false;
+ bson_iter_t field_iter;
+ if (!bson_iter_init_find (&field_iter, field, "keyId")) {
+ CLIENT_ERR ("unable to find 'keyId' in 'field' document");
+ return false;
+ }
+ if (!BSON_ITER_HOLDS_BINARY (&field_iter)) {
+ CLIENT_ERR ("expected 'fields.keyId' to be type binary, got: %d",
+ bson_iter_type (&field_iter));
+ return false;
+ }
+ _mongocrypt_buffer_t field_keyid;
+ if (!_mongocrypt_buffer_from_uuid_iter (&field_keyid, &field_iter)) {
+ CLIENT_ERR ("unable to parse uuid key from 'fields.keyId'");
+ return false;
+ }
+
+ const char *field_path;
+ if (!bson_iter_init_find (&field_iter, field, "path")) {
+ CLIENT_ERR ("unable to find 'path' in 'field' document");
+ return false;
+ }
+ if (!BSON_ITER_HOLDS_UTF8 (&field_iter)) {
+ CLIENT_ERR ("expected 'fields.path' to be type UTF-8, got: %d",
+ bson_iter_type (&field_iter));
+ return false;
+ }
+ field_path = bson_iter_utf8 (&field_iter, NULL /* length */);
+
+ if (bson_iter_init_find (&field_iter, field, "queries")) {
+ has_queries = true;
+ }
+
+ /* Prepend a new mc_EncryptedField_t */
+ mc_EncryptedField_t *ef = bson_malloc0 (sizeof (mc_EncryptedField_t));
+ _mongocrypt_buffer_copy_to (&field_keyid, &ef->keyId);
+ ef->path = bson_strdup (field_path);
+ ef->next = efc->fields;
+ ef->has_queries = has_queries;
+ efc->fields = ef;
+
+ return true;
+}
+
+bool
+mc_EncryptedFieldConfig_parse (mc_EncryptedFieldConfig_t *efc,
+ const bson_t *efc_bson,
+ mongocrypt_status_t *status)
+{
+ memset (efc, 0, sizeof (*efc));
+ bson_iter_t iter;
+ if (!bson_iter_init_find (&iter, efc_bson, "fields")) {
+ CLIENT_ERR ("unable to find 'fields' in encrypted_field_config");
+ return false;
+ }
+ if (!BSON_ITER_HOLDS_ARRAY (&iter)) {
+ CLIENT_ERR ("expected 'fields' to be type array, got: %d",
+ bson_iter_type (&iter));
+ return false;
+ }
+ if (!bson_iter_recurse (&iter, &iter)) {
+ CLIENT_ERR ("unable to recurse into encrypted_field_config 'fields'");
+ return false;
+ }
+ while (bson_iter_next (&iter)) {
+ if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ CLIENT_ERR ("expected 'fields' to be type document, got: %d",
+ bson_iter_type (&iter));
+ return false;
+ }
+ bson_t field;
+ const uint8_t *field_data;
+ uint32_t field_len;
+ bson_iter_document (&iter, &field_len, &field_data);
+ if (!bson_init_static (&field, field_data, field_len)) {
+ CLIENT_ERR ("unable to initialize 'fields' value as document");
+ return false;
+ }
+ if (!_parse_field (efc, &field, status)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void
+mc_EncryptedFieldConfig_cleanup (mc_EncryptedFieldConfig_t *efc)
+{
+ if (!efc) {
+ return;
+ }
+ mc_EncryptedField_t *ptr = efc->fields;
+ while (ptr != NULL) {
+ mc_EncryptedField_t *ptr_next = ptr->next;
+ _mongocrypt_buffer_cleanup (&ptr->keyId);
+ bson_free ((char *) ptr->path);
+ bson_free (ptr);
+ ptr = ptr_next;
+ }
+}
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle-blob-subtype-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle-blob-subtype-private.h
new file mode 100644
index 00000000..3314eb62
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle-blob-subtype-private.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MC_FLE_BLOB_SUBTYPE_PRIVATE_H
+#define MC_FLE_BLOB_SUBTYPE_PRIVATE_H
+
+/* FLE Blob Subtype is the first byte of a BSON Binary Subtype 6.
+ * FLE1 Blob Subtypes are defined in:
+ * https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/subtype6.rst
+ * FLE2 Blob Subtypes are currently defined in:
+ * https://github.com/markbenvenuto/mongo-enterprise-modules/blob/fle2/fle_protocol.md#reference-bindata-6-subtypes.
+ */
+
+typedef enum {
+ MC_SUBTYPE_FLE1EncryptionPlaceholder = 0,
+ MC_SUBTYPE_FLE1DeterministicEncryptedValue = 1,
+ MC_SUBTYPE_FLE1RandomEncryptedValue = 2,
+ MC_SUBTYPE_FLE2EncryptionPlaceholder = 3,
+ MC_SUBTYPE_FLE2InsertUpdatePayload = 4,
+ MC_SUBTYPE_FLE2FindEqualityPayload = 5,
+ MC_SUBTYPE_FLE2UnindexedEncryptedValue = 6,
+ MC_SUBTYPE_FLE2IndexedEqualityEncryptedValue = 7
+} mc_fle_blob_subtype_t;
+
+#endif /* MC_FLE_BLOB_SUBTYPE_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h
new file mode 100644
index 00000000..36943d28
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MC_FLE2_ENCRYPTION_PLACEHOLDER_PRIVATE_H
+#define MC_FLE2_ENCRYPTION_PLACEHOLDER_PRIVATE_H
+
+#include <bson/bson.h>
+
+#include "mongocrypt.h"
+#include "mongocrypt-private.h"
+
+typedef struct {
+ mongocrypt_fle2_placeholder_type_t type;
+ mongocrypt_fle2_encryption_algorithm_t algorithm;
+ bson_iter_t v_iter;
+ _mongocrypt_buffer_t index_key_id;
+ _mongocrypt_buffer_t user_key_id;
+ int64_t maxContentionCounter;
+} mc_FLE2EncryptionPlaceholder_t;
+
+void
+mc_FLE2EncryptionPlaceholder_init (mc_FLE2EncryptionPlaceholder_t *placeholder);
+
+bool
+mc_FLE2EncryptionPlaceholder_parse (mc_FLE2EncryptionPlaceholder_t *out,
+ const bson_t *in,
+ mongocrypt_status_t *status);
+
+void
+mc_FLE2EncryptionPlaceholder_cleanup (
+ mc_FLE2EncryptionPlaceholder_t *placeholder);
+
+/* mc_validate_contention is used to check that contention is a valid
+ * value. contention may come from the 'cm' field in FLE2EncryptionPlaceholder
+ * or from mongocrypt_ctx_setopt_contention_factor. */
+bool
+mc_validate_contention (int64_t contention, mongocrypt_status_t *status);
+
+#endif /* MC_FLE2_ENCRYPTION_PLACEHOLDER_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-encryption-placeholder.c b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-encryption-placeholder.c
new file mode 100644
index 00000000..c081344a
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-encryption-placeholder.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bson/bson.h>
+
+#include "mc-fle2-encryption-placeholder-private.h"
+#include "mongocrypt.h"
+#include "mongocrypt-buffer-private.h"
+
+// Common logic for testing field name, tracking duplication, and presence.
+#define IF_FIELD(Name) \
+ if (0 == strcmp (field, #Name)) { \
+ if (has_##Name) { \
+ CLIENT_ERR ("Duplicate field '" #Name "' in placeholder bson"); \
+ goto fail; \
+ } \
+ has_##Name = true;
+
+#define END_IF_FIELD \
+ continue; \
+ }
+
+#define CHECK_HAS(Name) \
+ if (!has_##Name) { \
+ CLIENT_ERR ("Missing field '" #Name "' in placeholder"); \
+ goto fail; \
+ }
+
+void
+mc_FLE2EncryptionPlaceholder_init (mc_FLE2EncryptionPlaceholder_t *placeholder)
+{
+ memset (placeholder, 0, sizeof (mc_FLE2EncryptionPlaceholder_t));
+}
+
+bool
+mc_FLE2EncryptionPlaceholder_parse (mc_FLE2EncryptionPlaceholder_t *out,
+ const bson_t *in,
+ mongocrypt_status_t *status)
+{
+ bson_iter_t iter;
+ bool has_t = false, has_a = false, has_v = false, has_cm = false;
+ bool has_ki = false, has_ku = false;
+
+ mc_FLE2EncryptionPlaceholder_init (out);
+ if (!bson_validate (in, BSON_VALIDATE_NONE, NULL) ||
+ !bson_iter_init (&iter, in)) {
+ CLIENT_ERR ("invalid BSON");
+ return false;
+ }
+
+ while (bson_iter_next (&iter)) {
+ const char *field = bson_iter_key (&iter);
+ BSON_ASSERT (field);
+
+ IF_FIELD (t)
+ {
+ int32_t type;
+ if (!BSON_ITER_HOLDS_INT32 (&iter)) {
+ CLIENT_ERR ("invalid marking, 't' must be an int32");
+ goto fail;
+ }
+ type = bson_iter_int32 (&iter);
+ if ((type != MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT) &&
+ (type != MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND)) {
+ CLIENT_ERR ("invalid placeholder type value: %d", type);
+ goto fail;
+ }
+ out->type = (mongocrypt_fle2_placeholder_type_t) type;
+ }
+ END_IF_FIELD
+
+ IF_FIELD (a)
+ {
+ int32_t algorithm;
+ if (!BSON_ITER_HOLDS_INT32 (&iter)) {
+ CLIENT_ERR ("invalid marking, 'a' must be an int32");
+ goto fail;
+ }
+ algorithm = bson_iter_int32 (&iter);
+ if (algorithm != MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED &&
+ algorithm != MONGOCRYPT_FLE2_ALGORITHM_EQUALITY) {
+ CLIENT_ERR ("invalid algorithm value: %d", algorithm);
+ goto fail;
+ }
+ out->algorithm = (mongocrypt_fle2_encryption_algorithm_t) algorithm;
+ }
+ END_IF_FIELD
+
+ IF_FIELD (ki)
+ {
+ if (!_mongocrypt_buffer_from_uuid_iter (&out->index_key_id, &iter)) {
+ CLIENT_ERR ("index key id must be a UUID");
+ goto fail;
+ }
+ }
+ END_IF_FIELD
+
+ IF_FIELD (ku)
+ {
+ if (!_mongocrypt_buffer_from_uuid_iter (&out->user_key_id, &iter)) {
+ CLIENT_ERR ("user key id must be a UUID");
+ goto fail;
+ }
+ }
+ END_IF_FIELD
+
+ IF_FIELD (v)
+ {
+ memcpy (&out->v_iter, &iter, sizeof (bson_iter_t));
+ }
+ END_IF_FIELD
+
+ IF_FIELD (cm)
+ {
+ if (!BSON_ITER_HOLDS_INT64 (&iter)) {
+ CLIENT_ERR ("invalid maeking, 'cm' must be an int64");
+ goto fail;
+ }
+ out->maxContentionCounter = bson_iter_int64 (&iter);
+ if (!mc_validate_contention (out->maxContentionCounter, status)) {
+ goto fail;
+ }
+ }
+ END_IF_FIELD
+ }
+
+ CHECK_HAS (t)
+ CHECK_HAS (a)
+ CHECK_HAS (ki)
+ CHECK_HAS (ku)
+ CHECK_HAS (v)
+ CHECK_HAS (cm)
+
+ return true;
+
+fail:
+ mc_FLE2EncryptionPlaceholder_cleanup (out);
+ return false;
+}
+
+void
+mc_FLE2EncryptionPlaceholder_cleanup (
+ mc_FLE2EncryptionPlaceholder_t *placeholder)
+{
+ _mongocrypt_buffer_cleanup (&placeholder->index_key_id);
+ _mongocrypt_buffer_cleanup (&placeholder->user_key_id);
+ mc_FLE2EncryptionPlaceholder_init (placeholder);
+}
+
+bool
+mc_validate_contention (int64_t contention, mongocrypt_status_t *status)
+{
+ if (contention < 0) {
+ CLIENT_ERR ("contention must be non-negative, got: %" PRId64, contention);
+ return false;
+ }
+ if (contention == INT64_MAX) {
+ CLIENT_ERR ("contention must be < INT64_MAX, got: %" PRId64, contention);
+ return false;
+ }
+ return true;
+}
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-find-equality-payload-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-find-equality-payload-private.h
new file mode 100644
index 00000000..7884ea4e
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-find-equality-payload-private.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MC_FLE2_FIND_EQUALITY_PAYLOAD_PRIVATE_H
+#define MC_FLE2_FIND_EQUALITY_PAYLOAD_PRIVATE_H
+
+#include "mongocrypt.h"
+#include "mongocrypt-private.h"
+#include "mongocrypt-buffer-private.h"
+
+typedef struct {
+ _mongocrypt_buffer_t edcDerivedToken; // d
+ _mongocrypt_buffer_t escDerivedToken; // s
+ _mongocrypt_buffer_t eccDerivedToken; // c
+ _mongocrypt_buffer_t serverEncryptionToken; // e
+ int64_t maxContentionCounter; // cm
+} mc_FLE2FindEqualityPayload_t;
+
+void
+mc_FLE2FindEqualityPayload_init (mc_FLE2FindEqualityPayload_t *payload);
+
+bool
+mc_FLE2FindEqualityPayload_parse (mc_FLE2FindEqualityPayload_t *out,
+ const bson_t *in,
+ mongocrypt_status_t *status);
+
+bool
+mc_FLE2FindEqualityPayload_serialize (
+ bson_t *out, const mc_FLE2FindEqualityPayload_t *payload);
+
+void
+mc_FLE2FindEqualityPayload_cleanup (mc_FLE2FindEqualityPayload_t *payload);
+
+#endif /* MC_FLE2_FIND_EQUALITY_PAYLOAD_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-find-equality-payload.c b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-find-equality-payload.c
new file mode 100644
index 00000000..3b1393b5
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-find-equality-payload.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bson/bson.h>
+
+#include "mc-fle2-find-equality-payload-private.h"
+#include "mongocrypt.h"
+#include "mongocrypt-buffer-private.h"
+
+void
+mc_FLE2FindEqualityPayload_init (mc_FLE2FindEqualityPayload_t *payload)
+{
+ memset (payload, 0, sizeof (mc_FLE2FindEqualityPayload_t));
+}
+
+void
+mc_FLE2FindEqualityPayload_cleanup (mc_FLE2FindEqualityPayload_t *payload)
+{
+ _mongocrypt_buffer_cleanup (&payload->edcDerivedToken);
+ _mongocrypt_buffer_cleanup (&payload->escDerivedToken);
+ _mongocrypt_buffer_cleanup (&payload->eccDerivedToken);
+ _mongocrypt_buffer_cleanup (&payload->serverEncryptionToken);
+}
+
+#define IF_FIELD(Name) \
+ if (0 == strcmp (field, #Name)) { \
+ if (has_##Name) { \
+ CLIENT_ERR ("Duplicate field '" #Name "' in payload bson"); \
+ goto fail; \
+ } \
+ has_##Name = true;
+
+#define END_IF_FIELD \
+ continue; \
+ }
+
+#define PARSE_BINARY(Name, Dest) \
+ IF_FIELD (Name) \
+ { \
+ bson_subtype_t subtype; \
+ uint32_t len; \
+ const uint8_t *data; \
+ if (bson_iter_type (&iter) != BSON_TYPE_BINARY) { \
+ CLIENT_ERR ("Field '" #Name "' expected to be bindata, got: %d", \
+ bson_iter_type (&iter)); \
+ goto fail; \
+ } \
+ bson_iter_binary (&iter, &subtype, &len, &data); \
+ if (subtype != BSON_SUBTYPE_BINARY) { \
+ CLIENT_ERR ("Field '" #Name \
+ "' expected to be bindata subtype %d, got: %d", \
+ BSON_SUBTYPE_BINARY, \
+ subtype); \
+ goto fail; \
+ } \
+ if (!_mongocrypt_buffer_copy_from_binary_iter (&out->Dest, &iter)) { \
+ CLIENT_ERR ("Unable to create mongocrypt buffer for BSON binary " \
+ "field in '" #Name "'"); \
+ goto fail; \
+ } \
+ } \
+ END_IF_FIELD
+
+#define CHECK_HAS(Name) \
+ if (!has_##Name) { \
+ CLIENT_ERR ("Missing field '" #Name "' in payload"); \
+ goto fail; \
+ }
+
+bool
+mc_FLE2FindEqualityPayload_parse (mc_FLE2FindEqualityPayload_t *out,
+ const bson_t *in,
+ mongocrypt_status_t *status)
+{
+ bson_iter_t iter;
+ bool has_d = false, has_s = false, has_c = false, has_e = false,
+ has_cm = false;
+
+ mc_FLE2FindEqualityPayload_init (out);
+ if (!bson_validate (in, BSON_VALIDATE_NONE, NULL) ||
+ !bson_iter_init (&iter, in)) {
+ CLIENT_ERR ("invalid BSON");
+ return false;
+ }
+
+ while (bson_iter_next (&iter)) {
+ const char *field = bson_iter_key (&iter);
+ BSON_ASSERT (field);
+
+ PARSE_BINARY (d, edcDerivedToken)
+ PARSE_BINARY (s, escDerivedToken)
+ PARSE_BINARY (c, eccDerivedToken)
+ PARSE_BINARY (e, serverEncryptionToken)
+ IF_FIELD (cm)
+ {
+ if (!BSON_ITER_HOLDS_INT64 (&iter)) {
+ CLIENT_ERR ("Field 'cm' expected to hold an int64");
+ goto fail;
+ }
+ out->maxContentionCounter = bson_iter_int64 (&iter);
+ }
+ END_IF_FIELD
+ }
+
+ CHECK_HAS (d);
+ CHECK_HAS (s);
+ CHECK_HAS (c);
+ CHECK_HAS (e);
+ CHECK_HAS (cm);
+
+ return true;
+fail:
+ mc_FLE2FindEqualityPayload_cleanup (out);
+ return false;
+}
+
+#define IUPS_APPEND_BINDATA(name, subtype, value) \
+ if (!_mongocrypt_buffer_append ( \
+ &(value), out, name, (uint32_t) strlen (name))) { \
+ return false; \
+ }
+
+bool
+mc_FLE2FindEqualityPayload_serialize (
+ bson_t *out, const mc_FLE2FindEqualityPayload_t *payload)
+{
+ IUPS_APPEND_BINDATA ("d", BSON_SUBTYPE_BINARY, payload->edcDerivedToken);
+ IUPS_APPEND_BINDATA ("s", BSON_SUBTYPE_BINARY, payload->escDerivedToken);
+ IUPS_APPEND_BINDATA ("c", BSON_SUBTYPE_BINARY, payload->eccDerivedToken);
+ IUPS_APPEND_BINDATA (
+ "e", BSON_SUBTYPE_BINARY, payload->serverEncryptionToken);
+ if (!BSON_APPEND_INT64 (out, "cm", payload->maxContentionCounter)) {
+ return false;
+ }
+ return true;
+}
+#undef IUPS_APPEND_BINDATA
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-insert-update-payload-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-insert-update-payload-private.h
new file mode 100644
index 00000000..9d2b1984
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-insert-update-payload-private.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MC_FLE2_INSERT_UPDATE_PAYLOAD_PRIVATE_H
+#define MC_FLE2_INSERT_UPDATE_PAYLOAD_PRIVATE_H
+
+#include <bson/bson.h>
+
+#include "mongocrypt.h"
+#include "mongocrypt-private.h"
+#include "mongocrypt-buffer-private.h"
+
+/**
+ * FLE2InsertUpdatePayload represents an FLE2 payload of an indexed field to
+ * insert or update. It is created client side.
+ *
+ * FLE2InsertUpdatePayload has the following data layout:
+ *
+ * struct {
+ * uint8_t fle_blob_subtype = 4;
+ * uint8_t bson[16];
+ * } FLE2InsertUpdatePayload;
+ *
+ * bson is a BSON document of this form:
+ * d: <binary> // EDCDerivedFromDataTokenAndCounter
+ * s: <binary> // ESCDerivedFromDataTokenAndCounter
+ * c: <binary> // ECCDerivedFromDataTokenAndCounter
+ * p: <binary> // Encrypted Tokens
+ * u: <UUID> // Index KeyId
+ * t: <int32> // Encrypted type
+ * v: <binary> // Encrypted value
+ * e: <binary> // ServerDataEncryptionLevel1Token
+ *
+ * p is the result of:
+ * Encrypt(
+ * key=ECOCToken,
+ * plaintext=(
+ * ESCDerivedFromDataTokenAndCounter ||
+ * ECCDerivedFromDataTokenAndCounter)
+ * )
+ *
+ * v is the result of:
+ * UserKeyId || EncryptAEAD(
+ * key=UserKey,
+ * plaintext=value
+ * associated_data=UserKeyId)
+ */
+
+typedef struct {
+ _mongocrypt_buffer_t edcDerivedToken; // d
+ _mongocrypt_buffer_t escDerivedToken; // s
+ _mongocrypt_buffer_t eccDerivedToken; // c
+ _mongocrypt_buffer_t encryptedTokens; // p
+ _mongocrypt_buffer_t indexKeyId; // u
+ bson_type_t valueType; // t
+ _mongocrypt_buffer_t value; // v
+ _mongocrypt_buffer_t serverEncryptionToken; // e
+ _mongocrypt_buffer_t plaintext;
+ _mongocrypt_buffer_t userKeyId;
+} mc_FLE2InsertUpdatePayload_t;
+
+void
+mc_FLE2InsertUpdatePayload_init (mc_FLE2InsertUpdatePayload_t *payload);
+
+bool
+mc_FLE2InsertUpdatePayload_parse (mc_FLE2InsertUpdatePayload_t *out,
+ const _mongocrypt_buffer_t *in,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2InsertUpdatePayload_decrypt decrypts ciphertext.
+ * Returns NULL and sets @status on error. It is an error to call before
+ * mc_FLE2InsertUpdatePayload_parse. */
+const _mongocrypt_buffer_t *
+mc_FLE2InsertUpdatePayload_decrypt (_mongocrypt_crypto_t *crypto,
+ mc_FLE2InsertUpdatePayload_t *iup,
+ const _mongocrypt_buffer_t *user_key,
+ mongocrypt_status_t *status);
+
+bool
+mc_FLE2InsertUpdatePayload_serialize (
+ bson_t *out, const mc_FLE2InsertUpdatePayload_t *payload);
+
+void
+mc_FLE2InsertUpdatePayload_cleanup (mc_FLE2InsertUpdatePayload_t *payload);
+
+#endif /* MC_FLE2_INSERT_UPDATE_PAYLOAD_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-insert-update-payload.c b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-insert-update-payload.c
new file mode 100644
index 00000000..aaa4833d
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-insert-update-payload.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bson/bson.h>
+
+#include "mc-fle2-insert-update-payload-private.h"
+#include "mongocrypt.h"
+#include "mongocrypt-buffer-private.h"
+
+void
+mc_FLE2InsertUpdatePayload_init (mc_FLE2InsertUpdatePayload_t *payload)
+{
+ memset (payload, 0, sizeof (mc_FLE2InsertUpdatePayload_t));
+}
+
+void
+mc_FLE2InsertUpdatePayload_cleanup (mc_FLE2InsertUpdatePayload_t *payload)
+{
+ _mongocrypt_buffer_cleanup (&payload->edcDerivedToken);
+ _mongocrypt_buffer_cleanup (&payload->escDerivedToken);
+ _mongocrypt_buffer_cleanup (&payload->eccDerivedToken);
+ _mongocrypt_buffer_cleanup (&payload->encryptedTokens);
+ _mongocrypt_buffer_cleanup (&payload->indexKeyId);
+ _mongocrypt_buffer_cleanup (&payload->value);
+ _mongocrypt_buffer_cleanup (&payload->serverEncryptionToken);
+ _mongocrypt_buffer_cleanup (&payload->plaintext);
+}
+
+#define IF_FIELD(Name) \
+ if (0 == strcmp (field, #Name)) { \
+ if (has_##Name) { \
+ CLIENT_ERR ("Duplicate field '" #Name "' in payload bson"); \
+ goto fail; \
+ } \
+ has_##Name = true;
+
+#define END_IF_FIELD \
+ continue; \
+ }
+
+#define PARSE_BINDATA(Name, Type, Dest) \
+ IF_FIELD (Name) \
+ { \
+ bson_subtype_t subtype; \
+ uint32_t len; \
+ const uint8_t *data; \
+ if (bson_iter_type (&iter) != BSON_TYPE_BINARY) { \
+ CLIENT_ERR ("Field '" #Name "' expected to be bindata, got: %d", \
+ bson_iter_type (&iter)); \
+ goto fail; \
+ } \
+ bson_iter_binary (&iter, &subtype, &len, &data); \
+ if (subtype != Type) { \
+ CLIENT_ERR ("Field '" #Name \
+ "' expected to be bindata subtype %d, got: %d", \
+ Type, \
+ subtype); \
+ goto fail; \
+ } \
+ if (!_mongocrypt_buffer_copy_from_binary_iter (&out->Dest, &iter)) { \
+ CLIENT_ERR ("Unable to create mongocrypt buffer for BSON binary " \
+ "field in '" #Name "'"); \
+ goto fail; \
+ } \
+ } \
+ END_IF_FIELD
+
+#define PARSE_BINARY(Name, Dest) PARSE_BINDATA (Name, BSON_SUBTYPE_BINARY, Dest)
+
+#define CHECK_HAS(Name) \
+ if (!has_##Name) { \
+ CLIENT_ERR ("Missing field '" #Name "' in payload"); \
+ goto fail; \
+ }
+
+bool
+mc_FLE2InsertUpdatePayload_parse (mc_FLE2InsertUpdatePayload_t *out,
+ const _mongocrypt_buffer_t *in,
+ mongocrypt_status_t *status)
+{
+ bson_iter_t iter;
+ bool has_d = false, has_s = false, has_c = false;
+ bool has_p = false, has_u = false, has_t = false;
+ bool has_v = false, has_e = false;
+ bson_t in_bson;
+
+ if (in->len < 1) {
+ CLIENT_ERR ("FLE2InsertUpdatePayload_parse got too short input");
+ return false;
+ }
+
+ if (!bson_init_static (&in_bson, in->data + 1, in->len - 1)) {
+ CLIENT_ERR ("FLE2InsertUpdatePayload_parse got invalid BSON");
+ return false;
+ }
+
+ mc_FLE2InsertUpdatePayload_init (out);
+ if (!bson_validate (&in_bson, BSON_VALIDATE_NONE, NULL) ||
+ !bson_iter_init (&iter, &in_bson)) {
+ CLIENT_ERR ("invalid BSON");
+ return false;
+ }
+
+ while (bson_iter_next (&iter)) {
+ const char *field = bson_iter_key (&iter);
+ BSON_ASSERT (field);
+
+ PARSE_BINARY (d, edcDerivedToken)
+ PARSE_BINARY (s, escDerivedToken)
+ PARSE_BINARY (c, eccDerivedToken)
+ PARSE_BINARY (p, encryptedTokens)
+ PARSE_BINDATA (u, BSON_SUBTYPE_UUID, indexKeyId)
+ IF_FIELD (t)
+ {
+ int32_t type = bson_iter_int32 (&iter);
+ if (!BSON_ITER_HOLDS_INT32 (&iter)) {
+ CLIENT_ERR ("Field 't' expected to hold an int32");
+ goto fail;
+ }
+ if ((type < 0) || (type > 0xFF)) {
+ CLIENT_ERR ("Field 't' must be a valid BSON type, got: %d", type);
+ goto fail;
+ }
+ out->valueType = (bson_type_t) type;
+ }
+ END_IF_FIELD
+ PARSE_BINARY (v, value)
+ PARSE_BINARY (e, serverEncryptionToken)
+ }
+
+ CHECK_HAS (d);
+ CHECK_HAS (s);
+ CHECK_HAS (c);
+ CHECK_HAS (p);
+ CHECK_HAS (u);
+ CHECK_HAS (t);
+ CHECK_HAS (v);
+ CHECK_HAS (e);
+
+ if (!_mongocrypt_buffer_from_subrange (
+ &out->userKeyId, &out->value, 0, UUID_LEN)) {
+ CLIENT_ERR ("failed to create userKeyId buffer");
+ goto fail;
+ }
+ out->userKeyId.subtype = BSON_SUBTYPE_UUID;
+
+ return true;
+fail:
+ mc_FLE2InsertUpdatePayload_cleanup (out);
+ return false;
+}
+
+#define IUPS_APPEND_BINDATA(name, subtype, value) \
+ if (!_mongocrypt_buffer_append ( \
+ &(value), out, name, (uint32_t) strlen (name))) { \
+ return false; \
+ }
+
+bool
+mc_FLE2InsertUpdatePayload_serialize (
+ bson_t *out, const mc_FLE2InsertUpdatePayload_t *payload)
+{
+ IUPS_APPEND_BINDATA ("d", BSON_SUBTYPE_BINARY, payload->edcDerivedToken);
+ IUPS_APPEND_BINDATA ("s", BSON_SUBTYPE_BINARY, payload->escDerivedToken);
+ IUPS_APPEND_BINDATA ("c", BSON_SUBTYPE_BINARY, payload->eccDerivedToken);
+ IUPS_APPEND_BINDATA ("p", BSON_SUBTYPE_BINARY, payload->encryptedTokens);
+ IUPS_APPEND_BINDATA ("u", BSON_SUBTYPE_UUID, payload->indexKeyId);
+ if (!BSON_APPEND_INT32 (out, "t", payload->valueType)) {
+ return false;
+ }
+ IUPS_APPEND_BINDATA ("v", BSON_SUBTYPE_BINARY, payload->value);
+ IUPS_APPEND_BINDATA (
+ "e", BSON_SUBTYPE_BINARY, payload->serverEncryptionToken);
+ return true;
+}
+#undef IUPS_APPEND_BINDATA
+
+const _mongocrypt_buffer_t *
+mc_FLE2InsertUpdatePayload_decrypt (_mongocrypt_crypto_t *crypto,
+ mc_FLE2InsertUpdatePayload_t *iup,
+ const _mongocrypt_buffer_t *user_key,
+ mongocrypt_status_t *status)
+{
+ if (iup->value.len == 0) {
+ CLIENT_ERR ("FLE2InsertUpdatePayload value not parsed");
+ return NULL;
+ }
+
+ _mongocrypt_buffer_t ciphertext;
+ if (!_mongocrypt_buffer_from_subrange (
+ &ciphertext, &iup->value, UUID_LEN, iup->value.len - UUID_LEN)) {
+ CLIENT_ERR ("Failed to create ciphertext buffer");
+ return NULL;
+ }
+
+ _mongocrypt_buffer_resize (
+ &iup->plaintext,
+ _mongocrypt_fle2aead_calculate_plaintext_len (ciphertext.len));
+ uint32_t bytes_written; /* ignored */
+
+ if (!_mongocrypt_fle2aead_do_decryption (crypto,
+ &iup->userKeyId,
+ user_key,
+ &ciphertext,
+ &iup->plaintext,
+ &bytes_written,
+ status)) {
+ return NULL;
+ }
+ return &iup->plaintext;
+}
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-ieev-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-ieev-private.h
new file mode 100644
index 00000000..7398ea4d
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-ieev-private.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MONGOCRYPT_INDEXED_EQUALIY_ENCRYPTED_VALUE_PRIVATE_H
+#define MONGOCRYPT_INDEXED_EQUALIY_ENCRYPTED_VALUE_PRIVATE_H
+
+#include "mongocrypt-buffer-private.h"
+#include "mongocrypt-status-private.h"
+#include "mongocrypt-crypto-private.h"
+
+/**
+ * FLE2IndexedEqualityEncryptedValue represents an FLE2 encrypted value. It is
+ * created server side.
+ */
+
+/* clang-format off */
+/*
+ * FLE2IndexedEqualityEncryptedValue has the following data layout:
+ *
+ * struct {
+ * uint8_t fle_blob_subtype = 7;
+ * uint8_t S_KeyId[16];
+ * uint8_t original_bson_type;
+ * uint8_t InnerEncrypted[InnerEncrypted_length];
+ * } FLE2IndexedEqualityEncryptedValue
+ *
+ * InnerEncrypted is the output of: Encrypt(key=ServerDataLevel1Token, plaintext=Inner)
+ * ServerDataLevel1Token is created from the key identified by S_KeyId.
+ *
+ * struct {
+ * uint64_t length; // sizeof(K_KeyId) + ClientEncryptedValue_length;
+ * uint8_t K_KeyId[16];
+ * uint8_t ClientEncryptedValue[ClientEncryptedValue_length];
+ * uint64_t counter;
+ * uint8_t edc[32]; // EDCDerivedFromDataTokenAndContentionFactorToken
+ * uint8_t esc[32]; // ESCDerivedFromDataTokenAndContentionFactorToken
+ * uint8_t ecc[32]; // ECCDerivedFromDataTokenAndContentionFactorToken
+ *} Inner
+ *
+ * ClientEncryptedValue is the output of: EncryptAEAD(key=K_Key, plaintext=ClientValue, associated_data=K_KeyId)
+ * K_Key is the key identified by K_KeyId.
+ */
+/* clang-format on */
+
+typedef struct _mc_FLE2IndexedEqualityEncryptedValue_t
+ mc_FLE2IndexedEqualityEncryptedValue_t;
+
+mc_FLE2IndexedEqualityEncryptedValue_t *
+mc_FLE2IndexedEqualityEncryptedValue_new (void);
+
+bool
+mc_FLE2IndexedEqualityEncryptedValue_parse (
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ const _mongocrypt_buffer_t *buf,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2IndexedEqualityEncryptedValue_get_original_bson_type returns
+ * original_bson_type. Returns 0 and sets @status on error.
+ * It is an error to call before mc_FLE2IndexedEqualityEncryptedValue_parse. */
+bson_type_t
+mc_FLE2IndexedEqualityEncryptedValue_get_original_bson_type (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2IndexedEqualityEncryptedValue_get_S_KeyId returns S_KeyId. Returns
+ * NULL and sets @status on error. It is an error to call before
+ * mc_FLE2IndexedEqualityEncryptedValue_parse. */
+const _mongocrypt_buffer_t *
+mc_FLE2IndexedEqualityEncryptedValue_get_S_KeyId (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2IndexedEqualityEncryptedValue_add_S_Key decrypts InnerEncrypted.
+ * Returns false and sets @status on error. It is an error to call before
+ * mc_FLE2IndexedEqualityEncryptedValue_parse. */
+bool
+mc_FLE2IndexedEqualityEncryptedValue_add_S_Key (
+ _mongocrypt_crypto_t *crypto,
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ const _mongocrypt_buffer_t *S_Key,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2IndexedEqualityEncryptedValue_get_K_KeyId returns Inner.K_KeyId.
+ * Returns NULL and sets @status on error. It is an error to call before
+ * mc_FLE2IndexedEqualityEncryptedValue_add_S_Key. */
+const _mongocrypt_buffer_t *
+mc_FLE2IndexedEqualityEncryptedValue_get_K_KeyId (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2IndexedEqualityEncryptedValue_add_K_Key decrypts
+ * Inner.ClientEncryptedValue. Returns false and sets @status on error. Must
+ * not be called before mc_FLE2IndexedEqualityEncryptedValue_add_S_Key. */
+bool
+mc_FLE2IndexedEqualityEncryptedValue_add_K_Key (
+ _mongocrypt_crypto_t *crypto,
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ const _mongocrypt_buffer_t *K_Key,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2IndexedEqualityEncryptedValue_get_ClientValue returns the decrypted
+ * Inner.ClientEncryptedValue. Returns NULL and sets @status on error.
+ * It is an error to call before mc_FLE2IndexedEqualityEncryptedValue_add_K_Key.
+ */
+const _mongocrypt_buffer_t *
+mc_FLE2IndexedEqualityEncryptedValue_get_ClientValue (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status);
+
+void
+mc_FLE2IndexedEqualityEncryptedValue_destroy (
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev);
+
+#endif /* MONGOCRYPT_INDEXED_EQUALIY_ENCRYPTED_VALUE_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-ieev.c b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-ieev.c
new file mode 100644
index 00000000..45c57df3
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-ieev.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mongocrypt-private.h"
+
+#include "mc-fle2-payload-ieev-private.h"
+#include "mc-tokens-private.h"
+
+struct _mc_FLE2IndexedEqualityEncryptedValue_t {
+ _mongocrypt_buffer_t S_KeyId;
+ _mongocrypt_buffer_t InnerEncrypted;
+ _mongocrypt_buffer_t Inner;
+ _mongocrypt_buffer_t K_KeyId;
+ _mongocrypt_buffer_t ClientValue;
+ _mongocrypt_buffer_t ClientEncryptedValue;
+ uint8_t original_bson_type;
+ bool parsed;
+ bool inner_decrypted;
+ bool client_value_decrypted;
+};
+
+mc_FLE2IndexedEqualityEncryptedValue_t *
+mc_FLE2IndexedEqualityEncryptedValue_new (void)
+{
+ return bson_malloc0 (sizeof (mc_FLE2IndexedEqualityEncryptedValue_t));
+}
+
+bool
+mc_FLE2IndexedEqualityEncryptedValue_parse (
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ const _mongocrypt_buffer_t *buf,
+ mongocrypt_status_t *status)
+{
+ if (ieev->parsed) {
+ CLIENT_ERR (
+ "mc_FLE2IndexedEqualityEncryptedValue_parse must not be called twice");
+ return false;
+ }
+
+ uint32_t offset = 0;
+ /* Read fle_blob_subtype. */
+ if (offset + 1 > buf->len) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_parse expected byte "
+ "length >= %" PRIu32 " got: %" PRIu32,
+ offset + 1,
+ buf->len);
+ return false;
+ }
+ uint8_t fle_blob_subtype = buf->data[offset];
+ if (fle_blob_subtype != 7) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_parse expected "
+ "fle_blob_subtype=7 got: %" PRIu8,
+ fle_blob_subtype);
+ return false;
+ }
+ offset += 1;
+
+ /* Read S_KeyId. */
+ if (offset + 16 > buf->len) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_parse expected byte "
+ "length >= %" PRIu32 " got: %" PRIu32,
+ offset + 16,
+ buf->len);
+ return false;
+ }
+ if (!_mongocrypt_buffer_copy_from_data_and_size (
+ &ieev->S_KeyId, buf->data + offset, 16)) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_parse failed to copy "
+ "data for S_KeyId");
+ return false;
+ }
+ ieev->S_KeyId.subtype = BSON_SUBTYPE_UUID;
+ offset += 16;
+
+ /* Read original_bson_type. */
+ if (offset + 1 > buf->len) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_parse expected byte "
+ "length >= %" PRIu32 " got: %" PRIu32,
+ offset + 1,
+ buf->len);
+ return false;
+ }
+ ieev->original_bson_type = buf->data[offset];
+ offset += 1;
+
+ /* Read InnerEncrypted. */
+ if (!_mongocrypt_buffer_copy_from_data_and_size (
+ &ieev->InnerEncrypted,
+ buf->data + offset,
+ (size_t) (buf->len - offset))) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_parse failed to copy "
+ "data for InnerEncrypted");
+ return false;
+ }
+
+ ieev->parsed = true;
+ return true;
+}
+
+const _mongocrypt_buffer_t *
+mc_FLE2IndexedEqualityEncryptedValue_get_S_KeyId (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status)
+{
+ if (!ieev->parsed) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_get_S_KeyId must be "
+ "called after mc_FLE2IndexedEqualityEncryptedValue_parse");
+ return NULL;
+ }
+
+ return &ieev->S_KeyId;
+}
+
+bool
+mc_FLE2IndexedEqualityEncryptedValue_add_S_Key (
+ _mongocrypt_crypto_t *crypto,
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ const _mongocrypt_buffer_t *S_Key,
+ mongocrypt_status_t *status)
+{
+ if (!ieev->parsed) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key must be "
+ "called after mc_FLE2IndexedEqualityEncryptedValue_parse");
+ return false;
+ }
+
+ if (ieev->inner_decrypted) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key must not be "
+ "called twice");
+ return false;
+ }
+
+ /* Attempt to decrypt InnerEncrypted */
+ if (S_Key->len != MONGOCRYPT_KEY_LEN) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key expected "
+ "S_Key to be %d bytes, got: %" PRIu32,
+ MONGOCRYPT_KEY_LEN,
+ S_Key->len);
+ return false;
+ }
+
+ /* Get the TokenKey from the last 32 bytes of S_Key */
+ _mongocrypt_buffer_t TokenKey;
+ if (!_mongocrypt_buffer_from_subrange (&TokenKey,
+ S_Key,
+ S_Key->len - MONGOCRYPT_TOKEN_KEY_LEN,
+ MONGOCRYPT_TOKEN_KEY_LEN)) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key unable to "
+ "parse TokenKey from S_Key");
+ return false;
+ }
+
+ /* Use TokenKey to create ServerDataEncryptionLevel1Token and decrypt
+ * InnerEncrypted. */
+ {
+ mc_ServerDataEncryptionLevel1Token_t *token =
+ mc_ServerDataEncryptionLevel1Token_new (crypto, &TokenKey, status);
+ if (!token) {
+ return false;
+ }
+
+ const _mongocrypt_buffer_t *token_buf =
+ mc_ServerDataEncryptionLevel1Token_get (token);
+ uint32_t bytes_written;
+
+ _mongocrypt_buffer_resize (
+ &ieev->Inner,
+ _mongocrypt_fle2_calculate_plaintext_len (ieev->InnerEncrypted.len));
+
+ /* Decrypt InnerEncrypted. */
+ if (!_mongocrypt_fle2_do_decryption (crypto,
+ token_buf,
+ &ieev->InnerEncrypted,
+ &ieev->Inner,
+ &bytes_written,
+ status)) {
+ mc_ServerDataEncryptionLevel1Token_destroy (token);
+ return false;
+ }
+ mc_ServerDataEncryptionLevel1Token_destroy (token);
+ }
+
+ /* Parse Inner for K_KeyId. */
+ uint32_t offset = 0;
+ /* Read uint64_t length. */
+ if (offset + 8 > ieev->Inner.len) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key expected "
+ "Inner byte length >= %" PRIu32 " got: %" PRIu32,
+ offset + 8,
+ ieev->Inner.len);
+ return false;
+ }
+ uint64_t
+ length; /* length is sizeof(K_KeyId) + ClientEncryptedValue_length. */
+ memcpy (&length, ieev->Inner.data, sizeof (uint64_t));
+ length = BSON_UINT64_FROM_LE (length);
+ offset += 8;
+
+ /* Read K_KeyId. */
+ if (offset + UUID_LEN > ieev->Inner.len) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key expected "
+ "Inner byte length >= %" PRIu32 " got: %" PRIu32,
+ offset + UUID_LEN,
+ ieev->Inner.len);
+ return false;
+ }
+ if (!_mongocrypt_buffer_copy_from_data_and_size (
+ &ieev->K_KeyId, ieev->Inner.data + offset, 16)) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key failed to "
+ "copy data for K_KeyId");
+ return false;
+ }
+ offset += 16;
+ ieev->K_KeyId.subtype = BSON_SUBTYPE_UUID;
+
+ /* Read ClientEncryptedValue. */
+ if (offset + (length - 16) > ieev->Inner.len) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_S_Key expected "
+ "Inner byte length >= %" PRIu32 " got: %" PRIu32,
+ offset + (length - 16),
+ ieev->Inner.len);
+ return false;
+ }
+ if (!_mongocrypt_buffer_copy_from_data_and_size (&ieev->ClientEncryptedValue,
+ ieev->Inner.data + offset,
+ (size_t) (length - 16))) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_parse failed to copy "
+ "data for ClientEncryptedValue");
+ return false;
+ }
+
+ ieev->inner_decrypted = true;
+ return true;
+}
+
+const _mongocrypt_buffer_t *
+mc_FLE2IndexedEqualityEncryptedValue_get_K_KeyId (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status)
+{
+ if (!ieev->inner_decrypted) {
+ CLIENT_ERR (
+ "mc_FLE2IndexedEqualityEncryptedValue_get_K_KeyId must be called "
+ "after mc_FLE2IndexedEqualityEncryptedValue_add_S_Key");
+ return NULL;
+ }
+ return &ieev->K_KeyId;
+}
+
+bool
+mc_FLE2IndexedEqualityEncryptedValue_add_K_Key (
+ _mongocrypt_crypto_t *crypto,
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ const _mongocrypt_buffer_t *K_Key,
+ mongocrypt_status_t *status)
+{
+ if (!ieev->inner_decrypted) {
+ CLIENT_ERR (
+ "mc_FLE2IndexedEqualityEncryptedValue_add_K_Key must be called after "
+ "mc_FLE2IndexedEqualityEncryptedValue_add_S_Key");
+ return false;
+ }
+ if (ieev->client_value_decrypted) {
+ CLIENT_ERR ("mc_FLE2IndexedEqualityEncryptedValue_add_K_Key must not be "
+ "called twice");
+ return false;
+ }
+ /* Attempt to decrypt ClientEncryptedValue */
+ _mongocrypt_buffer_resize (&ieev->ClientValue,
+ _mongocrypt_fle2aead_calculate_plaintext_len (
+ ieev->ClientEncryptedValue.len));
+ uint32_t bytes_written;
+ if (!_mongocrypt_fle2aead_do_decryption (crypto,
+ &ieev->K_KeyId,
+ K_Key,
+ &ieev->ClientEncryptedValue,
+ &ieev->ClientValue,
+ &bytes_written,
+ status)) {
+ return false;
+ }
+ ieev->client_value_decrypted = true;
+ return true;
+}
+
+const _mongocrypt_buffer_t *
+mc_FLE2IndexedEqualityEncryptedValue_get_ClientValue (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status)
+{
+ if (!ieev->client_value_decrypted) {
+ CLIENT_ERR (
+ "mc_FLE2IndexedEqualityEncryptedValue_getClientValue must be called "
+ "after mc_FLE2IndexedEqualityEncryptedValue_add_K_Key");
+ return NULL;
+ }
+ return &ieev->ClientValue;
+}
+
+void
+mc_FLE2IndexedEqualityEncryptedValue_destroy (
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev)
+{
+ if (!ieev) {
+ return;
+ }
+ _mongocrypt_buffer_cleanup (&ieev->S_KeyId);
+ _mongocrypt_buffer_cleanup (&ieev->InnerEncrypted);
+ _mongocrypt_buffer_cleanup (&ieev->Inner);
+ _mongocrypt_buffer_cleanup (&ieev->K_KeyId);
+ _mongocrypt_buffer_cleanup (&ieev->ClientValue);
+ _mongocrypt_buffer_cleanup (&ieev->ClientEncryptedValue);
+ bson_free (ieev);
+}
+
+bson_type_t
+mc_FLE2IndexedEqualityEncryptedValue_get_original_bson_type (
+ const mc_FLE2IndexedEqualityEncryptedValue_t *ieev,
+ mongocrypt_status_t *status)
+{
+ if (!ieev->parsed) {
+ CLIENT_ERR (
+ "mc_FLE2IndexedEqualityEncryptedValue_get_original_bson_type must be "
+ "called after mc_FLE2IndexedEqualityEncryptedValue_parse");
+ return 0;
+ }
+ return ieev->original_bson_type;
+}
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-uev-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-uev-private.h
new file mode 100644
index 00000000..dd63927a
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-uev-private.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MONGOCRYPT_FLE2_UNINDEXED_ENCRYPTED_VALUE_PRIVATE_H
+#define MONGOCRYPT_FLE2_UNINDEXED_ENCRYPTED_VALUE_PRIVATE_H
+
+#include "mongocrypt-buffer-private.h"
+#include "mongocrypt-status-private.h"
+#include "mongocrypt-crypto-private.h"
+
+/**
+ * FLE2UnindexedEncryptedValue represents an FLE2 unindexed encrypted value.
+ * It is created client side.
+ *
+ * FLE2UnindexedEncryptedValue has the following data layout:
+ *
+ * struct {
+ * uint8_t fle_blob_subtype = 6;
+ * uint8_t key_uuid[16];
+ * uint8_t original_bson_type;
+ * uint8_t ciphertext[ciphertext_length];
+ * } FLE2UnindexedEncryptedValue;
+ *
+ * ciphertext is the output of:
+ * EncryptAEAD(
+ * key=K_Key,
+ * plaintext=ClientValue,
+ * associated_data=(fle_blob_subtype || key_uuid || original_bson_type))
+ */
+
+typedef struct _mc_FLE2UnindexedEncryptedValue_t
+ mc_FLE2UnindexedEncryptedValue_t;
+
+mc_FLE2UnindexedEncryptedValue_t *
+mc_FLE2UnindexedEncryptedValue_new (void);
+
+bool
+mc_FLE2UnindexedEncryptedValue_parse (mc_FLE2UnindexedEncryptedValue_t *uev,
+ const _mongocrypt_buffer_t *buf,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2UnindexedEncryptedValue_get_original_bson_type returns
+ * original_bson_type. Returns 0 and sets @status on error.
+ * It is an error to call before mc_FLE2UnindexedEncryptedValue_parse. */
+bson_type_t
+mc_FLE2UnindexedEncryptedValue_get_original_bson_type (
+ const mc_FLE2UnindexedEncryptedValue_t *uev, mongocrypt_status_t *status);
+
+/* mc_FLE2UnindexedEncryptedValue_get_key_uuid returns key_uuid. Returns
+ * NULL and sets @status on error. It is an error to call before
+ * mc_FLE2UnindexedEncryptedValue_parse. */
+const _mongocrypt_buffer_t *
+mc_FLE2UnindexedEncryptedValue_get_key_uuid (
+ const mc_FLE2UnindexedEncryptedValue_t *uev, mongocrypt_status_t *status);
+
+/* mc_FLE2UnindexedEncryptedValue_decrypt decrypts ciphertext.
+ * Returns NULL and sets @status on error. It is an error to call before
+ * mc_FLE2UnindexedEncryptedValue_parse. */
+const _mongocrypt_buffer_t *
+mc_FLE2UnindexedEncryptedValue_decrypt (_mongocrypt_crypto_t *crypto,
+ mc_FLE2UnindexedEncryptedValue_t *uev,
+ const _mongocrypt_buffer_t *key,
+ mongocrypt_status_t *status);
+
+/* mc_FLE2UnindexedEncryptedValue_encrypt outputs the ciphertext field of
+ * FLEUnindexedEncryptedValue into @out. Returns false and sets @status on
+ * error. */
+bool
+mc_FLE2UnindexedEncryptedValue_encrypt (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *key_uuid,
+ bson_type_t original_bson_type,
+ const _mongocrypt_buffer_t *plaintext,
+ const _mongocrypt_buffer_t *key,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status);
+
+void
+mc_FLE2UnindexedEncryptedValue_destroy (mc_FLE2UnindexedEncryptedValue_t *uev);
+
+#endif /* MONGOCRYPT_FLE2_UNINDEXED_ENCRYPTED_VALUE_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-uev.c b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-uev.c
new file mode 100644
index 00000000..18694e03
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-fle2-payload-uev.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mc-fle2-payload-uev-private.h"
+#include "mongocrypt-private.h"
+#include "mc-fle-blob-subtype-private.h"
+
+struct _mc_FLE2UnindexedEncryptedValue_t {
+ _mongocrypt_buffer_t key_uuid;
+ uint8_t original_bson_type;
+ _mongocrypt_buffer_t ciphertext;
+ _mongocrypt_buffer_t plaintext;
+ bool parsed;
+};
+
+mc_FLE2UnindexedEncryptedValue_t *
+mc_FLE2UnindexedEncryptedValue_new (void)
+{
+ mc_FLE2UnindexedEncryptedValue_t *uev =
+ bson_malloc0 (sizeof (mc_FLE2UnindexedEncryptedValue_t));
+ return uev;
+}
+
+bool
+mc_FLE2UnindexedEncryptedValue_parse (mc_FLE2UnindexedEncryptedValue_t *uev,
+ const _mongocrypt_buffer_t *buf,
+ mongocrypt_status_t *status)
+{
+ if (uev->parsed) {
+ CLIENT_ERR (
+ "mc_FLE2UnindexedEncryptedValue_parse must not be called twice");
+ return false;
+ }
+
+ uint32_t offset = 0;
+ /* Read fle_blob_subtype. */
+ if (offset + 1 > buf->len) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_parse expected byte "
+ "length >= %" PRIu32 " got: %" PRIu32,
+ offset + 1,
+ buf->len);
+ return false;
+ }
+
+ uint8_t fle_blob_subtype = buf->data[offset];
+ if (fle_blob_subtype != MC_SUBTYPE_FLE2UnindexedEncryptedValue) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_parse expected "
+ "fle_blob_subtype=%d got: %" PRIu8,
+ MC_SUBTYPE_FLE2UnindexedEncryptedValue,
+ fle_blob_subtype);
+ return false;
+ }
+ offset += 1;
+
+ /* Read key_uuid. */
+ if (offset + 16 > buf->len) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_parse expected byte "
+ "length >= %" PRIu32 " got: %" PRIu32,
+ offset + 16,
+ buf->len);
+ return false;
+ }
+ if (!_mongocrypt_buffer_copy_from_data_and_size (
+ &uev->key_uuid, buf->data + offset, 16)) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_parse failed to copy "
+ "data for key_uuid");
+ return false;
+ }
+ uev->key_uuid.subtype = BSON_SUBTYPE_UUID;
+ offset += 16;
+
+ /* Read original_bson_type. */
+ if (offset + 1 > buf->len) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_parse expected byte "
+ "length >= %" PRIu32 " got: %" PRIu32,
+ offset + 1,
+ buf->len);
+ return false;
+ }
+ uev->original_bson_type = buf->data[offset];
+ offset += 1;
+
+ /* Read ciphertext. */
+ if (!_mongocrypt_buffer_copy_from_data_and_size (
+ &uev->ciphertext, buf->data + offset, (size_t) (buf->len - offset))) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_parse failed to copy "
+ "data for ciphertext");
+ return false;
+ }
+
+ uev->parsed = true;
+ return true;
+}
+
+bson_type_t
+mc_FLE2UnindexedEncryptedValue_get_original_bson_type (
+ const mc_FLE2UnindexedEncryptedValue_t *uev, mongocrypt_status_t *status)
+{
+ if (!uev->parsed) {
+ CLIENT_ERR (
+ "mc_FLE2UnindexedEncryptedValue_get_original_bson_type must be "
+ "called after mc_FLE2UnindexedEncryptedValue_parse");
+ return 0;
+ }
+ return uev->original_bson_type;
+}
+
+const _mongocrypt_buffer_t *
+mc_FLE2UnindexedEncryptedValue_get_key_uuid (
+ const mc_FLE2UnindexedEncryptedValue_t *uev, mongocrypt_status_t *status)
+{
+ if (!uev->parsed) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_get_key_uuid must be "
+ "called after mc_FLE2UnindexedEncryptedValue_parse");
+ return NULL;
+ }
+ return &uev->key_uuid;
+}
+
+const _mongocrypt_buffer_t *
+mc_FLE2UnindexedEncryptedValue_decrypt (_mongocrypt_crypto_t *crypto,
+ mc_FLE2UnindexedEncryptedValue_t *uev,
+ const _mongocrypt_buffer_t *key,
+ mongocrypt_status_t *status)
+{
+ if (!uev->parsed) {
+ CLIENT_ERR ("mc_FLE2UnindexedEncryptedValue_decrypt must be "
+ "called after mc_FLE2UnindexedEncryptedValue_parse");
+ return NULL;
+ }
+
+ /* Serialize associated data: fle_blob_subtype || key_uuid ||
+ * original_bson_type */
+ _mongocrypt_buffer_t AD;
+ _mongocrypt_buffer_init (&AD);
+ _mongocrypt_buffer_resize (&AD, 1 + uev->key_uuid.len + 1);
+
+ AD.data[0] = MC_SUBTYPE_FLE2UnindexedEncryptedValue;
+ memcpy (AD.data + 1, uev->key_uuid.data, uev->key_uuid.len);
+ AD.data[1 + uev->key_uuid.len] = uev->original_bson_type;
+ _mongocrypt_buffer_resize (
+ &uev->plaintext,
+ _mongocrypt_fle2aead_calculate_plaintext_len (uev->ciphertext.len));
+
+ uint32_t bytes_written;
+
+ if (!_mongocrypt_fle2aead_do_decryption (crypto,
+ &AD,
+ key,
+ &uev->ciphertext,
+ &uev->plaintext,
+ &bytes_written,
+ status)) {
+ _mongocrypt_buffer_cleanup (&AD);
+ return NULL;
+ }
+
+ _mongocrypt_buffer_cleanup (&AD);
+ return &uev->plaintext;
+}
+
+bool
+mc_FLE2UnindexedEncryptedValue_encrypt (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *key_uuid,
+ bson_type_t original_bson_type,
+ const _mongocrypt_buffer_t *plaintext,
+ const _mongocrypt_buffer_t *key,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_buffer_t iv = {0};
+ _mongocrypt_buffer_t AD = {0};
+ bool res = false;
+
+ _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
+ if (!_mongocrypt_random (crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
+ goto fail;
+ }
+
+ /* Serialize associated data: fle_blob_subtype || key_uuid ||
+ * original_bson_type */
+ {
+ _mongocrypt_buffer_resize (&AD, 1 + key_uuid->len + 1);
+ AD.data[0] = MC_SUBTYPE_FLE2UnindexedEncryptedValue;
+ memcpy (AD.data + 1, key_uuid->data, key_uuid->len);
+ AD.data[1 + key_uuid->len] = (uint8_t) original_bson_type;
+ }
+
+ /* Encrypt. */
+ {
+ _mongocrypt_buffer_resize (
+ out, _mongocrypt_fle2aead_calculate_ciphertext_len (plaintext->len));
+ uint32_t bytes_written; /* unused. */
+ if (!_mongocrypt_fle2aead_do_encryption (
+ crypto, &iv, &AD, key, plaintext, out, &bytes_written, status)) {
+ goto fail;
+ }
+ }
+
+ res = true;
+fail:
+ _mongocrypt_buffer_cleanup (&AD);
+ _mongocrypt_buffer_cleanup (&iv);
+ return res;
+}
+
+void
+mc_FLE2UnindexedEncryptedValue_destroy (mc_FLE2UnindexedEncryptedValue_t *uev)
+{
+ if (NULL == uev) {
+ return;
+ }
+ _mongocrypt_buffer_cleanup (&uev->key_uuid);
+ _mongocrypt_buffer_cleanup (&uev->ciphertext);
+ _mongocrypt_buffer_cleanup (&uev->plaintext);
+
+ bson_free (uev);
+}
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-tokens-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mc-tokens-private.h
new file mode 100644
index 00000000..277e026a
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-tokens-private.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MONGOCRYPT_TOKENS_PRIVATE_H
+#define MONGOCRYPT_TOKENS_PRIVATE_H
+
+#include "mongocrypt-buffer-private.h"
+#include "mongocrypt-crypto-private.h"
+
+/*
+ * ======================= Begin: FLE 2 Token Reference =======================
+ *
+ * v is a BSON value. It is the bytes after "e_name" in "element" in
+ * https://bsonspec.org/spec.html.
+ * u is a "contention factor" counter. It is a uint64_t.
+ * HMAC is the HMAC-SHA-256 function.
+ * Integers are represented as uint64_t in little-endian.
+ *
+ * CollectionsLevel1Token = HMAC(RootKey, 1)
+ * ServerDataEncryptionLevel1Token = HMAC(RootKey, 3)
+ *
+ * EDCToken = HMAC(CollectionsLevel1Token, 1)
+ * ESCToken = HMAC(CollectionsLevel1Token, 2)
+ * ECCToken = HMAC(CollectionsLevel1Token, 3)
+ * ECOCToken = HMAC(CollectionsLevel1Token, 4)
+ *
+ * EDCDerivedFromDataToken = HMAC(EDCToken, v)
+ * ESCDerivedFromDataToken = HMAC(ESCToken, v)
+ * ECCDerivedFromDataToken = HMAC(ECCToken, v)
+ *
+ * EDCDerivedFromDataTokenAndCounter = HMAC(EDCDerivedFromDataToken, u)
+ * ESCDerivedFromDataTokenAndCounter = HMAC(ESCDerivedFromDataToken, u)
+ * ECCDerivedFromDataTokenAndCounter = HMAC(ECCDerivedFromDataToken, u)
+ * ======================== End: FLE 2 Token Reference ========================
+ */
+
+
+#ifndef CONCAT
+#define CONCAT_1(a, b) a##b
+#define CONCAT(a, b) CONCAT_1 (a, b)
+#endif
+#ifndef CONCAT3
+#define CONCAT3(a, b, c) CONCAT (a, CONCAT (b, c))
+#endif
+
+/// Declare a token type named 'Name', with constructor parameters given by the
+/// remaining arguments. Each constructor will also have the implicit first
+/// argument '_mongocrypt_crypto_t* crypto' and a final argument
+/// 'mongocrypt_status_t* status'
+#define DECL_TOKEN_TYPE(Name, ...) \
+ DECL_TOKEN_TYPE_1 (Name, CONCAT (Name, _t), __VA_ARGS__)
+
+#define DECL_TOKEN_TYPE_1(Prefix, T, ...) \
+ /* Opaque typedef the struct */ \
+ typedef struct T T; \
+ /* Data-getter */ \
+ extern const _mongocrypt_buffer_t *CONCAT (Prefix, _get) (const T *t); \
+ /* Destructor */ \
+ extern void CONCAT (Prefix, _destroy) (T * t); \
+ /* Constructor. Parameter list given as variadic args */ \
+ extern T *CONCAT (Prefix, _new) (_mongocrypt_crypto_t * crypto, \
+ __VA_ARGS__, \
+ mongocrypt_status_t * status)
+
+DECL_TOKEN_TYPE (mc_CollectionsLevel1Token, const _mongocrypt_buffer_t *);
+DECL_TOKEN_TYPE (mc_ServerDataEncryptionLevel1Token,
+ const _mongocrypt_buffer_t *);
+DECL_TOKEN_TYPE (mc_EDCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token);
+DECL_TOKEN_TYPE (mc_ESCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token);
+DECL_TOKEN_TYPE (mc_ECCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token);
+DECL_TOKEN_TYPE (mc_ECOCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token);
+DECL_TOKEN_TYPE (mc_EDCDerivedFromDataToken,
+ const mc_EDCToken_t *EDCToken,
+ const _mongocrypt_buffer_t *v);
+DECL_TOKEN_TYPE (mc_ECCDerivedFromDatatoken,
+ const mc_ECCToken_t *ECCToken,
+ const _mongocrypt_buffer_t *v);
+DECL_TOKEN_TYPE (mc_ESCDerivedFromDataToken,
+ const mc_ESCToken_t *ESCToken,
+ const _mongocrypt_buffer_t *v);
+DECL_TOKEN_TYPE (mc_ECCDerivedFromDataToken,
+ const mc_ECCToken_t *ECCToken,
+ const _mongocrypt_buffer_t *v);
+DECL_TOKEN_TYPE (mc_EDCDerivedFromDataTokenAndCounter,
+ const mc_EDCDerivedFromDataToken_t *EDCDerivedFromDataToken,
+ uint64_t u);
+DECL_TOKEN_TYPE (mc_ESCDerivedFromDataTokenAndCounter,
+ const mc_ESCDerivedFromDataToken_t *ESCDerivedFromDataToken,
+ uint64_t u);
+DECL_TOKEN_TYPE (mc_ECCDerivedFromDataTokenAndCounter,
+ const mc_ECCDerivedFromDataToken_t *ECCDerivedFromDataToken,
+ uint64_t u);
+
+#undef DECL_TOKEN_TYPE
+#undef DECL_TOKEN_TYPE_1
+
+#endif /* MONGOCRYPT_TOKENS_PRIVATE_H */
\ No newline at end of file
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mc-tokens.c b/mongodb-1.14.0/src/libmongocrypt/src/mc-tokens.c
new file mode 100644
index 00000000..80fae84c
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mc-tokens.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mc-tokens-private.h"
+
+/// Define a token type of the given name, with constructor parameters given as
+/// the remaining arguments. This macro usage should be followed by the
+/// constructor body, with the implicit first argument '_mongocrypt_crypto_t*
+/// crypto' and final argument 'mongocrypt_status_t* status'
+#define DEF_TOKEN_TYPE(Name, ...) \
+ DEF_TOKEN_TYPE_1 (Name, CONCAT (Name, _t), __VA_ARGS__)
+
+#define DEF_TOKEN_TYPE_1(Prefix, T, ...) \
+ /* Define the struct for the token */ \
+ struct T { \
+ _mongocrypt_buffer_t data; \
+ }; \
+ /* Data-getter */ \
+ const _mongocrypt_buffer_t *CONCAT (Prefix, _get) (const T *self) \
+ { \
+ return &self->data; \
+ } \
+ /* Destructor */ \
+ void CONCAT (Prefix, _destroy) (T * self) \
+ { \
+ if (!self) { \
+ return; \
+ } \
+ _mongocrypt_buffer_cleanup (&self->data); \
+ bson_free (self); \
+ } \
+ /* Constructor. Parameter list given as variadic args. */ \
+ T *CONCAT (Prefix, _new) (_mongocrypt_crypto_t * crypto, \
+ __VA_ARGS__, \
+ mongocrypt_status_t * status)
+
+#define IMPL_TOKEN_NEW_1(Name, Key, Arg, Clean) \
+ { \
+ CONCAT (Name, _t) *t = bson_malloc (sizeof (CONCAT (Name, _t))); \
+ _mongocrypt_buffer_init (&t->data); \
+ _mongocrypt_buffer_resize (&t->data, MONGOCRYPT_HMAC_SHA256_LEN); \
+ \
+ if (!_mongocrypt_hmac_sha_256 (crypto, Key, Arg, &t->data, status)) { \
+ CONCAT (Name, _destroy) (t); \
+ Clean; \
+ return NULL; \
+ } \
+ Clean; \
+ return t; \
+ }
+
+// Define the implementation of a token where Arg is a _mongocrypt_buffer_t.
+#define IMPL_TOKEN_NEW(Name, Key, Arg) \
+ IMPL_TOKEN_NEW_1 (Name, Key, Arg, (void) 0)
+
+// Define the implementation of a token where Arg is a uint64_t.
+#define IMPL_TOKEN_NEW_CONST(Name, Key, Arg) \
+ { \
+ _mongocrypt_buffer_t to_hash; \
+ _mongocrypt_buffer_copy_from_uint64_le (&to_hash, Arg); \
+ IMPL_TOKEN_NEW_1 ( \
+ Name, Key, &to_hash, _mongocrypt_buffer_cleanup (&to_hash)) \
+ }
+
+DEF_TOKEN_TYPE (mc_CollectionsLevel1Token, const _mongocrypt_buffer_t *RootKey)
+IMPL_TOKEN_NEW_CONST (mc_CollectionsLevel1Token, RootKey, 1)
+
+DEF_TOKEN_TYPE (mc_ServerDataEncryptionLevel1Token,
+ const _mongocrypt_buffer_t *RootKey)
+IMPL_TOKEN_NEW_CONST (mc_ServerDataEncryptionLevel1Token, RootKey, 3)
+
+DEF_TOKEN_TYPE (mc_EDCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token)
+IMPL_TOKEN_NEW_CONST (mc_EDCToken,
+ mc_CollectionsLevel1Token_get (CollectionsLevel1Token),
+ 1)
+
+DEF_TOKEN_TYPE (mc_ESCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token)
+IMPL_TOKEN_NEW_CONST (mc_ESCToken,
+ mc_CollectionsLevel1Token_get (CollectionsLevel1Token),
+ 2)
+
+DEF_TOKEN_TYPE (mc_ECCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token)
+IMPL_TOKEN_NEW_CONST (mc_ECCToken,
+ mc_CollectionsLevel1Token_get (CollectionsLevel1Token),
+ 3)
+
+DEF_TOKEN_TYPE (mc_ECOCToken,
+ const mc_CollectionsLevel1Token_t *CollectionsLevel1Token)
+IMPL_TOKEN_NEW_CONST (mc_ECOCToken,
+ mc_CollectionsLevel1Token_get (CollectionsLevel1Token),
+ 4)
+
+DEF_TOKEN_TYPE (mc_EDCDerivedFromDataToken,
+ const mc_EDCToken_t *EDCToken,
+ const _mongocrypt_buffer_t *v)
+IMPL_TOKEN_NEW (mc_EDCDerivedFromDataToken, mc_EDCToken_get (EDCToken), v)
+
+DEF_TOKEN_TYPE (mc_ESCDerivedFromDataToken,
+ const mc_ESCToken_t *ESCToken,
+ const _mongocrypt_buffer_t *v)
+IMPL_TOKEN_NEW (mc_ESCDerivedFromDataToken, mc_ESCToken_get (ESCToken), v)
+
+DEF_TOKEN_TYPE (mc_ECCDerivedFromDataToken,
+ const mc_ECCToken_t *ECCToken,
+ const _mongocrypt_buffer_t *v)
+IMPL_TOKEN_NEW (mc_ECCDerivedFromDataToken, mc_ECCToken_get (ECCToken), v)
+
+DEF_TOKEN_TYPE (mc_EDCDerivedFromDataTokenAndCounter,
+ const mc_EDCDerivedFromDataToken_t *EDCDerivedFromDataToken,
+ uint64_t u)
+IMPL_TOKEN_NEW_CONST (mc_EDCDerivedFromDataTokenAndCounter,
+ mc_EDCDerivedFromDataToken_get (EDCDerivedFromDataToken),
+ u)
+
+DEF_TOKEN_TYPE (mc_ESCDerivedFromDataTokenAndCounter,
+ const mc_ESCDerivedFromDataToken_t *ESCDerivedFromDataToken,
+ uint64_t u)
+IMPL_TOKEN_NEW_CONST (mc_ESCDerivedFromDataTokenAndCounter,
+ mc_ESCDerivedFromDataToken_get (ESCDerivedFromDataToken),
+ u)
+
+DEF_TOKEN_TYPE (mc_ECCDerivedFromDataTokenAndCounter,
+ const mc_ECCDerivedFromDataToken_t *ECCDerivedFromDataToken,
+ uint64_t u)
+IMPL_TOKEN_NEW_CONST (mc_ECCDerivedFromDataTokenAndCounter,
+ mc_ECCDerivedFromDataToken_get (ECCDerivedFromDataToken),
+ u)
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mlib/error.h b/mongodb-1.14.0/src/libmongocrypt/src/mlib/error.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mlib/error.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mlib/error.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mlib/path.h b/mongodb-1.14.0/src/libmongocrypt/src/mlib/path.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mlib/path.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mlib/path.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mlib/str.h b/mongodb-1.14.0/src/libmongocrypt/src/mlib/str.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongocrypt/src/mlib/str.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mlib/str.h
index 33b4fb62..b8672deb 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mlib/str.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mlib/str.h
@@ -1,922 +1,927 @@
#ifndef MONGOCRYPT_STR_PRIVATE_H
#define MONGOCRYPT_STR_PRIVATE_H
#include "./user-check.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
/**
* @brief A simple non-owning string-view type.
*
* The viewed string can be treated as an array of char. It's pointed-to data
* must not be freed or manipulated.
*
* @note The viewed string is NOT guaranteed to be null-terminated. It WILL
* be null-terminated if: Directly created from a string literal via
* @ref mstrv_lit, OR created by accessing the @ref mstr::view member of an
* @ref mstr object, OR returned from @ref mstrv_view_cstr.
*/
typedef struct mstr_view {
/**
* @brief Pointer to the beginning of the code unit array.
*
* @note DO NOT MODIFY
*/
const char *data;
/**
* @brief Length of the pointed-to code unit array
*
* @note DO NOT MODIFY
*/
size_t len;
} mstr_view;
/**
* @brief A simple string utility type.
*
* This string type has the following semantics:
*
* The member `data` is a pointer to the beginning of a read-only array of code
* units. This array will always be null-terminated, but MAY contain
* intermittent null characters. The member `len` is the length of the code unit
* array (not including the null terminator). These two members should not be
* modified.
*
* The `view` member is a union member that will view the `mstr` as an
* @ref mstr_view.
*
* If you create an @ref mstr, it MUST eventually be passed to @ref mstr_free()
*
* The pointed-to code units of an mstr are immutable. To initialize the
* contents of an mstr, @ref mstr_new returns an @ref mstr_mut, which can then
* be "sealed" by converting it to an @ref mstr through the @ref mstr_mut::mstr
* union member.
*
* By convention, passing/returning an `mstr` to/from a function should
* relinquish ownership of that `mstr` to the callee/caller, respectively.
* Passing or returning an `mstr_view` is non-owning.
*/
typedef struct mstr {
union {
struct {
/**
* @brief Pointer to the beginning of the code unit array.
*
* @note DO NOT MODIFY
*/
const char *data;
/**
* @brief Length of the pointed-to code unit array
*
* @note DO NOT MODIFY
*/
size_t len;
};
/**
* @brief A non-owning `mstr_view` of the string
*/
mstr_view view;
};
} mstr;
/**
* @brief An interface for initializing the contents of an mstr.
*
* Returned by @ref mstr_new(). Once initialization is complete, the result can
* be used as an @ref mstr by accessing the @ref mstr_mut::mstr member.
*/
typedef struct mstr_mut {
union {
struct {
/**
* @brief Pointer to the beginning of the mutable code unit array.
*
* @note DO NOT MODIFY THE POINTER VALUE. Only modify the pointed-to
* characters.
*/
char *data;
/**
* @brief Length of the pointed-to code unit array.
*
* @note DO NOT MODIFY
*/
size_t len;
};
/// Convert the mutable string to an immutable string
struct mstr mstr;
/// Convert the mutable string to an immutable string view
mstr_view view;
};
} mstr_mut;
/**
* @brief A null @ref mstr
*/
#define MSTR_NULL ((mstr){{{.data = NULL, .len = 0}}})
/**
* @brief A null @ref mstr_view
*/
#define MSTRV_NULL ((mstr_view){.data = NULL, .len = 0})
/**
* @brief Create an @ref mstr_view that views the given string literal
*/
#define mstrv_lit(String) (mstrv_view_data (String "", (sizeof String) - 1))
/**
* @brief Create a new mutable code-unit array of the given length,
* zero-initialized. The caller can then modify the code units in the array via
* the @ref mstr_mut::data member. Once finished modifying, can be converted to
* an immutable mstr by copying the @ref mtsr_mut::mstr union member.
*
* @param len The length of the new string.
* @return mstr_mut A new mstr_mut
*
* @note The @ref mstr_mut::mstr member MUST eventually be given to
* @ref mstr_free().
*/
static inline mstr_mut
mstr_new (size_t len)
{
#ifndef __clang_analyzer__
- return (mstr_mut){{{.data = calloc (1, len + 1), .len = len}}};
+ return (mstr_mut){{{.data = (char *) calloc (1, len + 1), .len = len}}};
#else
// Clang-analyzer is smart enough to see the calloc(), but not smart enough
// to link it to the free() in mstr_free()
return (mstr_mut){};
#endif
}
/**
* @brief Create a non-owning @ref mstr_view from the given C string and length
*
* @param s A pointer to the beginning of a character array.
* @param len The length of the character array, in code units
* @return mstr_view A non-owning string.
*/
static inline mstr_view
mstrv_view_data (const char *s, size_t len)
{
return (mstr_view){.data = s, .len = len};
}
/**
* @brief Create a non-owning @ref mstr_view from a C-style null-terminated
* string.
*
* @param s A pointer to a null-terminated character array
* @return mstr_view A view of the pointed-to string
*/
static inline mstr_view
mstrv_view_cstr (const char *s)
{
return mstrv_view_data (s, strlen (s));
}
/**
* @brief Create an @ref mstr from the given character array and length.
*
* @param s A pointer to a character array
* @param len The length of the string to create
* @return mstr A new null-terminated string with the contents copied from the
* pointed-to array.
*
* @note The resulting string will be null-terminated.
*/
static inline mstr
mstr_copy_data (const char *s, size_t len)
{
mstr_mut r = mstr_new (len);
memcpy (r.data, s, len);
return r.mstr;
}
/**
* @brief Create an @ref mstr from A C-style null-terminated string.
*
* @param s A pointer to a null-terminated character array
* @return mstr A new string copied from the pointed-to string
*/
static inline mstr
mstr_copy_cstr (const char *s)
{
return mstr_copy_data (s, strlen (s));
}
/**
* @brief Copy the contents of the given string view
*
* @param s A string view to copy from
* @return mstr A new string copied from the given view
*/
static inline mstr
mstr_copy (mstr_view s)
{
return mstr_copy_data (s.data, s.len);
}
/**
* @brief Free the resources of the given string
*
* @param s The string to free
*/
static inline void
mstr_free (mstr s)
{
free ((char *) s.data);
}
/**
* @brief Resize the given mutable string, maintaining the existing content, and
* zero-initializing any added characters.
*
* @param s The @ref mstr_mut to update
* @param new_len The new length of the string
*/
static inline void
mstrm_resize (mstr_mut *s, size_t new_len)
{
if (new_len <= s->len) {
s->len = new_len;
} else {
const size_t old_len = s->len;
#ifndef __clang_analyzer__
// Clang-analyzer is smart enough to see the calloc(), but not smart
// enough to link it to the free() in mstr_free()
- s->data = realloc ((char *) s->data, new_len + 1);
+ s->data = (char *) realloc ((char *) s->data, new_len + 1);
#endif
s->len = new_len;
memset (s->data + old_len, 0, new_len - old_len);
}
s->data[new_len] = (char) 0;
}
/**
* @brief Free and re-assign the given @ref mstr
*
* @param s Pointer to an @ref mstr. This will be freed, then updated to the
* value of @ref from
* @param from An @ref mstr to take from.
*
* @note Ownership of the resource is handed to the pointed-to @ref s.
* Equivalent to:
*
* ```c
* mstr s = some_mstr();
* mstr another = get_another_mstr();
* mstr_free(s);
* s = another;
* ```
*
* Intended as a convenience for rebinding an @ref mstr in a single statement
* from an expression returning a new @ref mstr, which may itself use @ref s,
* without requiring a temporary variable, for example:
*
* ```c
* mstr s = get_mstr();
* mstr_assign(&s, convert_to_uppercase(s.view));
* ```
*/
static inline void
mstr_assign (mstr *s, mstr from)
{
mstr_free (*s);
*s = from;
}
/**
* @brief Find the index of the first occurrence of the given "needle" as a
* substring of another string.
*
* @param given A string to search within
* @param needle The substring to search for
* @return int The zero-based index of the first instance of `needle` in
* `given`, or -1 if no substring is found.
*/
static inline int
mstr_find (mstr_view given, mstr_view needle)
{
const char *const scan_end = given.data + given.len;
const char *const needle_end = needle.data + needle.len;
for (const char *scan = given.data; scan != scan_end; ++scan) {
size_t remain = scan_end - scan;
if (remain < needle.len) {
break;
}
const char *subscan = scan;
for (const char *nscan = needle.data; nscan != needle_end;
++nscan, ++subscan) {
if (*nscan == *subscan) {
continue;
} else {
goto skip;
}
}
// Got through the whole loop of scanning the needle
return (int) (scan - given.data);
skip:
(void) 0;
}
return -1;
}
/**
* @brief Find the index of the last occurrence of the given "needle" as a
* substring of another string.
*
* @param given A string to search within
* @param needle The substring to search for
* @return int The zero-based index of the last instance of `needle` in
* `given`, or -1 if no substring is found.
*/
static inline int
mstr_rfind (mstr_view given, mstr_view needle)
{
if (needle.len > given.len) {
return -1;
}
const char *scan = given.data + given.len - needle.len;
const char *const needle_end = needle.data + needle.len;
for (; scan >= given.data; --scan) {
const char *subscan = scan;
for (const char *nscan = needle.data; nscan != needle_end;
++nscan, ++subscan) {
if (*nscan == *subscan) {
continue;
} else {
goto skip;
}
}
// Got through the whole loop of scanning the needle
return (int) (scan - given.data);
skip:
(void) 0;
}
return -1;
}
/**
* @brief Modify a string by deleting and/or inserting another string.
*
* @param s The string to modify
* @param at The position at which to insert and delete characters
* @param del_count The number of characters to delete. Clamped to the string
* length.
* @param insert The string to insert at `at`.
* @return mstr A new string that is the result of the splice
*/
static inline mstr
mstr_splice (mstr_view s, size_t at, size_t del_count, mstr_view insert)
{
assert (at <= s.len);
const size_t remain = s.len - at;
if (del_count > remain) {
del_count = remain;
}
const size_t new_size = s.len - del_count + insert.len;
mstr_mut ret = mstr_new (new_size);
char *p = ret.data;
memcpy (p, s.data, at);
p += at;
if (insert.data) {
memcpy (p, insert.data, insert.len);
p += insert.len;
}
memcpy (p, s.data + at + del_count, s.len - at - del_count);
return ret.mstr;
}
/**
* @brief Append the given suffix to the given string
*/
static inline mstr
mstr_append (mstr_view s, mstr_view suffix)
{
return mstr_splice (s, s.len, 0, suffix);
}
/**
* @brief Prepend the given prefix to the given string
*/
static inline mstr
mstr_prepend (mstr_view s, mstr_view prefix)
{
return mstr_splice (s, 0, 0, prefix);
}
/**
* @brief Insert the given string into another string
*
* @param s The string to start with
* @param at The position in `s` where `infix` will be inserted
* @param infix The string to insert into `s`
* @return mstr A new string with `infix` inserted
*/
static inline mstr
mstr_insert (mstr_view s, size_t at, mstr_view infix)
{
return mstr_splice (s, at, 0, infix);
}
/**
* @brief Erase characters from the given string
*
* @param s The string to start with
* @param at The position at which to begin deleting characters
* @param count The number of characters to remove
* @return mstr A new string with the deletion result.
*/
static inline mstr
mstr_erase (mstr_view s, size_t at, size_t count)
{
return mstr_splice (s, at, count, mstrv_view_cstr (""));
}
/**
* @brief Erase `len` characters from the beginning of the string
*/
static inline mstr
mstr_remove_prefix (mstr_view s, size_t len)
{
return mstr_erase (s, 0, len);
}
/**
* @brief Erase `len` characters from the end of the string
*/
static inline mstr
mstr_remove_suffix (mstr_view s, size_t len)
{
return mstr_erase (s, s.len - len, len);
}
/**
* @brief Obtain a substring of the given string
*
* @param s The string to start with
* @param at The beginning position of the new string
* @param len The number of characters to include. Automatically clamped to the
* remaining length.
* @return mstr A new string that is a substring of `s`
*/
static inline mstr
mstr_substr (mstr_view s, size_t at, size_t len)
{
assert (at <= s.len);
const size_t remain = s.len - at;
if (len > remain) {
len = remain;
}
mstr_mut r = mstr_new (len);
memcpy (r.data, s.data + at, len);
return r.mstr;
}
/**
* @brief Obtain a view of a substring of another string.
*
* @param s The string to view
* @param at The position at which the new view will begin
* @param len The number of characters to view. Automatically clamped to the
* remaining length.
* @return mstr_view A view of `s`.
*/
static inline mstr_view
mstrv_subview (mstr_view s, size_t at, size_t len)
{
assert (at <= s.len);
const size_t remain = s.len - at;
if (len > remain) {
len = remain;
}
return (mstr_view){.data = s.data + at, .len = len};
}
/**
* @brief Obtain a view of another string by removing `len` characters from the
* front
*/
static inline mstr_view
mstrv_remove_prefix (mstr_view s, size_t len)
{
return mstrv_subview (s, len, s.len);
}
/**
* @brief Obtain a view of another string by removing `len` characters from the
* end.
*/
static inline mstr_view
mstrv_remove_suffix (mstr_view s, size_t len)
{
return mstrv_subview (s, 0, s.len - len);
}
/**
* @brief Truncate the given string to `new_len` characters.
*
* @param s The string to truncate
* @param new_len The new length of the string
* @return mstr A new string copied from the beginning of `s`
*/
static inline mstr
mstr_trunc (mstr_view s, size_t new_len)
{
assert (new_len <= s.len);
return mstr_remove_suffix (s, s.len - new_len);
}
/**
* @brief Obtain a new string with all occurrences of a string replaced with a
* different string
*
* @param string The string to start with
* @param find The substring that will be replaced
* @param subst The string to insert in place of `find`
* @return mstr A new string modified from `string`
*
* @note If `find` is empty, returns a copy of `string`
*/
static inline mstr
mstr_replace (const mstr_view string,
const mstr_view find,
const mstr_view subst)
{
if (find.len == 0) {
// Finding an empty string would loop forever
return mstr_copy (string);
}
// First copy the string
mstr ret = mstr_copy (string);
// Keep an index of how far we have processed
size_t whence = 0;
for (;;) {
// Chop off the front that has already been processed
mstr_view tail = mstrv_subview (ret.view, whence, ~0);
// Find where in that tail is the next needle
int pos = mstr_find (tail, find);
if (pos == -1) {
// We're done
break;
}
// Do the replacement
mstr_assign (
&ret, mstr_splice (ret.view, (size_t) pos + whence, find.len, subst));
// Advance our position by how many chars we skipped and how many we
// inserted
whence += pos + subst.len;
}
return ret;
}
/**
* @brief Determine whether two strings are equivalent.
*/
static inline bool
mstr_eq (mstr_view left, mstr_view right)
{
if (left.len != right.len) {
return false;
}
return memcmp (left.data, right.data, left.len) == 0;
}
/// Determine whether the given character is an printable ASCII codepoint
static inline bool
mstr_is_printable (char c)
{
return (c >= ' ' && c <= '~');
}
/// Write the given string to `out`, rendering non-printable characters as hex
/// escapes
static inline void
_mstr_write_str_repr_ (FILE *out, mstr_view s)
{
for (char const *it = s.data; it != s.data + s.len; ++it) {
if (mstr_is_printable (*it)) {
fputc (*it, out);
} else {
fprintf (out, "\\x%.2x", (unsigned) (unsigned char) *it);
}
}
}
static inline void
_mstr_assert_fail_ (mstr_view left,
const char *predicate,
mstr_view right,
const char *file,
int line)
{
fprintf (stderr, "%s:%d: ASSERTION FAILED: \"", file, line);
_mstr_write_str_repr_ (stderr, left);
fprintf (stderr, "\" %s \"", predicate);
_mstr_write_str_repr_ (stderr, right);
fprintf (stderr, "\"\n");
abort ();
}
static inline void
_mstr_assert_ (mstr_view left,
mstr_view right,
bool (*pred) (mstr_view left, mstr_view right),
bool B,
const char *pred_str,
const char *file,
int line)
{
if (pred (left, right) != B) {
mstr pstr = mstr_copy_cstr (pred_str);
if (!B) {
mstr_assign (&pstr, mstr_prepend (pstr.view, mstrv_lit ("not ")));
}
_mstr_assert_fail_ (left, pstr.data, right, file, line);
}
}
#define MSTR_ASSERT(Bool, Left, Pred, Right) \
(_mstr_assert_ ( \
(Left), (Right), mstr_##Pred, (Bool), #Pred, __FILE__, __LINE__))
/**
* @brief Assert that two strings are equivalent.
*
* Prints and error message and aborts if they are not
*/
#define MSTR_ASSERT_EQ(Left, Right) MSTR_ASSERT (true, Left, eq, Right)
/**
* @brief Determine whether the given string contains the given substring
*
* @param given A string to search within
* @param needle A substring to search for
* @return true If `given` contains at least one occurrence of `needle`
* @return false Otherwise
*/
static inline bool
mstr_contains (mstr_view given, mstr_view needle)
{
return mstr_find (given, needle) >= 0;
}
/**
* @brief Determine whether `given` starts with `prefix`
*/
static inline bool
mstr_starts_with (mstr_view given, mstr_view prefix)
{
given = mstrv_subview (given, 0, prefix.len);
return mstr_eq (given, prefix);
}
/**
* @brief Determine whether `given` ends with `suffix`
*/
static inline bool
mstr_ends_with (mstr_view given, mstr_view suffix)
{
if (suffix.len > given.len) {
return false;
}
given = mstrv_subview (given, given.len - suffix.len, ~0);
return mstr_eq (given, suffix);
}
/// Compound in-place version of @ref mstr_splice
static inline void
mstr_inplace_splice (mstr *s, size_t at, size_t del_count, mstr_view insert)
{
mstr_assign (s, mstr_splice (s->view, at, del_count, insert));
}
/// Compound in-place version of @ref mstr_append
static inline void
mstr_inplace_append (mstr *s, mstr_view suffix)
{
mstr_assign (s, mstr_append (s->view, suffix));
}
/// Compound in-place version of @ref mstr_prepend
static inline void
mstr_inplace_prepend (mstr *s, mstr_view prefix)
{
mstr_assign (s, mstr_prepend (s->view, prefix));
}
/// Compound in-place version of @ref mstr_insert
static inline void
mstr_inplace_insert (mstr *s, size_t at, mstr_view infix)
{
mstr_assign (s, mstr_insert (s->view, at, infix));
}
/// Compound in-place version of @ref mstr_erase
static inline void
mstr_inplace_erase (mstr *s, size_t at, size_t count)
{
mstr_assign (s, mstr_erase (s->view, at, count));
}
/// Compound in-place version of @ref mstr_remove_prefix
static inline void
mstr_inplace_remove_prefix (mstr *s, size_t len)
{
mstr_assign (s, mstr_remove_prefix (s->view, len));
}
/// Compound in-place version of @ref mstr_remove_suffix
static inline void
mstr_inplace_remove_suffix (mstr *s, size_t len)
{
mstr_assign (s, mstr_remove_suffix (s->view, len));
}
/// Compound in-place version of @ref mstr_substr
static inline void
mstr_inplace_substr (mstr *s, size_t at, size_t count)
{
mstr_assign (s, mstr_substr (s->view, at, count));
}
/// Compound in-place version of @ref mstr_trunc
static inline void
mstr_inplace_trunc (mstr *s, size_t new_len)
{
mstr_assign (s, mstr_trunc (s->view, new_len));
}
/// Compound in-place version of @ref mstr_replace
static inline void
mstr_inplace_replace (mstr *s, mstr_view find, mstr_view subst)
{
mstr_assign (s, mstr_replace (s->view, find, subst));
}
#ifdef _WIN32
#include "./windows-lean.h"
/**
* @brief The result type of mstr_win32_widen
*/
typedef struct mstr_widen_result {
wchar_t *wstring;
int error;
} mstr_widen_result;
/**
* @brief Widen a UTF-8 string using Win32 MultiBytetoWideChar
*
* @param str The UTF-8 string to widen.
* @return mstr_widen_result The result of widening, which may contain an error.
*
* @note The returned @ref mstr_widen_result::wstring must be given to free()
*/
static inline mstr_widen_result
mstr_win32_widen (mstr_view str)
{
int length = MultiByteToWideChar (
CP_UTF8, MB_ERR_INVALID_CHARS, str.data, (int) str.len, NULL, 0);
if (length == 0 && str.len != 0) {
return (mstr_widen_result){.wstring = NULL, .error = GetLastError ()};
}
wchar_t *ret = calloc (length + 1, sizeof (wchar_t));
int got_length = MultiByteToWideChar (
CP_UTF8, MB_ERR_INVALID_CHARS, str.data, (int) str.len, ret, length + 1);
assert (got_length == length);
return (mstr_widen_result){.wstring = ret, .error = 0};
}
/**
* @brief The result type of mstr_win32_narrow
*/
typedef struct mstr_narrow_result {
mstr string;
int error;
} mstr_narrow_result;
/**
* @brief Narrow a UTF-16 string to UTF-8 using Win32 WideCharToMultiByte
*
* @param wstring A null-terminated UTF-16 string to narrow
* @return mstr_narrow_result The result of narrowing, which may contain an
* error.
*
* @note The returned @ref mstr_narrow_result::string must be freed with
* mstr_free()
*/
static inline mstr_narrow_result
mstr_win32_narrow (const wchar_t *wstring)
{
+ // Some older versions of MinGW fail to include the WC_ERR_INVALID_CHARS
+ // flag, so we will specify it manually:
+ DWORD wcflags = 0x80; // WC_ERR_INVALID_CHARS
int length = WideCharToMultiByte (CP_UTF8,
- WC_ERR_INVALID_CHARS,
+ wcflags,
wstring,
-1 /* wstring is null-terminated */,
NULL,
0,
NULL,
NULL);
if (length == 0 && wstring[0] != 0) {
return (mstr_narrow_result){.string = MSTR_NULL,
.error = GetLastError ()};
}
- mstr_mut ret = mstr_new ((size_t) length);
+ // Allocate a new string, not including the null terminator
+ mstr_mut ret = mstr_new ((size_t) (length - 1));
int got_len = WideCharToMultiByte (CP_UTF8,
- WC_ERR_INVALID_CHARS,
+ wcflags,
wstring,
-1,
ret.data,
- (int) ret.len,
+ // Plus one byte for the NUL
+ (int) (ret.len + 1),
NULL,
NULL);
assert (length == got_len);
return (mstr_narrow_result){.string = ret.mstr, .error = 0};
}
#endif
/// Iteration state for string splitting
struct _mstr_split_iter_ {
/// What hasn't been parsed yet
mstr_view remaining;
/// The current part
mstr_view part;
/// The string that we split on
mstr_view splitter;
/// A once-var for the inner loop. Set to 1 by iter_next, then decremented
int once;
/// The loop state. Starts at zero. Set to one when we part the final split.
/// Set to two to break out of the loop.
int state;
};
/// Hidden function to advance a string-split iterator
static inline void
_mstr_split_iter_next_ (struct _mstr_split_iter_ *iter)
{
if (iter->once == 1) {
// We only get here if the loop body hit a 'break', skipping the decrement
// of the 'once'. Break out of the whole loop, as the user expects.
iter->state = 2;
return;
}
if (iter->state == 1) {
// We just completed the final loop pass.
iter->state = 2;
return;
}
// Find the next occurence of the token
const int pos = mstr_find (iter->remaining, iter->splitter);
if (pos < 0) {
// There are no more occurences. yield the remaining string
iter->part = iter->remaining;
iter->remaining = mstrv_subview (iter->remaining, iter->remaining.len, 0);
// Set state to 1 to break on the next pass
iter->state = 1;
} else {
// Advance our parts:
iter->part = mstrv_subview (iter->remaining, 0, pos);
iter->remaining =
mstrv_subview (iter->remaining, pos + iter->splitter.len, ~0);
}
// Prime the inner "loop" to execute once
iter->once = 1;
}
/// init a new split iterator
static inline struct _mstr_split_iter_
_mstr_split_iter_begin_ (mstr_view str, mstr_view split)
{
struct _mstr_split_iter_ iter = {.remaining = str, .splitter = split};
_mstr_split_iter_next_ (&iter);
return iter;
}
/// Check whether we are done iterating
static inline bool
_mstr_split_iter_done_ (struct _mstr_split_iter_ *iter)
{
return iter->state == 2;
}
// clang-format off
#define MSTR_ITER_SPLIT(LineVar, String, SplitToken) \
/* Open the main outer loop */ \
for (/* Declare an init the iterator */ \
struct _mstr_split_iter_ _iter_var_ = \
_mstr_split_iter_begin_ ((String), (SplitToken)); \
/* Iterate until it is marked as done */ \
!_mstr_split_iter_done_ (&_iter_var_); \
_mstr_split_iter_next_ (&_iter_var_)) \
/* This inner loop will only execute once, but gives us */ \
/* a point to declare the loop variable: */ \
for (mstr_view LineVar = _iter_var_.part; \
_iter_var_.once; \
--_iter_var_.once)
// clang-format on
#endif // MONGOCRYPT_STR_PRIVATE_H
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mlib/thread.h b/mongodb-1.14.0/src/libmongocrypt/src/mlib/thread.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mlib/thread.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mlib/thread.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mlib/user-check.h b/mongodb-1.14.0/src/libmongocrypt/src/mlib/user-check.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mlib/user-check.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mlib/user-check.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mlib/windows-lean.h b/mongodb-1.14.0/src/libmongocrypt/src/mlib/windows-lean.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mlib/windows-lean.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mlib/windows-lean.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongo_csfle-v1.h b/mongodb-1.14.0/src/libmongocrypt/src/mongo_crypt-v1.h
similarity index 56%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongo_csfle-v1.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongo_crypt-v1.h
index b4e7b99e..b489dd37 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongo_csfle-v1.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongo_crypt-v1.h
@@ -1,319 +1,319 @@
/**
* Copyright (C) 2021-present MongoDB, Inc.
*/
-#ifndef CSFLE_SUPPORT_H
-#define CSFLE_SUPPORT_H
+#ifndef MONGO_CRYPT_SUPPORT_H
+#define MONGO_CRYPT_SUPPORT_H
#include <stddef.h>
#include <stdint.h>
#pragma push_macro("MONGO_API_CALL")
#undef MONGO_API_CALL
#pragma push_macro("MONGO_API_IMPORT")
#undef MONGO_API_IMPORT
#pragma push_macro("MONGO_API_EXPORT")
#undef MONGO_API_EXPORT
-#pragma push_macro("CSFLE_SUPPORT_API")
-#undef CSFLE_SUPPORT_API
+#pragma push_macro("MONGO_CRYPT_SUPPORT_API")
+#undef MONGO_CRYPT_SUPPORT_API
#if defined(_WIN32)
#define MONGO_API_CALL __cdecl
#define MONGO_API_IMPORT __declspec(dllimport)
#define MONGO_API_EXPORT __declspec(dllexport)
#else
#define MONGO_API_CALL
#define MONGO_API_IMPORT __attribute__((visibility("default")))
#define MONGO_API_EXPORT __attribute__((used, visibility("default")))
#endif
-#if defined(CSFLE_SUPPORT_STATIC)
-#define MONGO_CSFLE_API
+#if defined(MONGO_CRYPT_SUPPORT_STATIC)
+#define MONGO_CRYPT_API
#else
-#if defined(CSFLE_SUPPORT_COMPILING)
-#define MONGO_CSFLE_API MONGO_API_EXPORT
+#if defined(MONGO_CRYPT_SUPPORT_COMPILING)
+#define MONGO_CRYPT_API MONGO_API_EXPORT
#else
-#define MONGO_CSFLE_API MONGO_API_IMPORT
+#define MONGO_CRYPT_API MONGO_API_IMPORT
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* An object which describes the details of the failure of an operation.
*
- * The CSFLE Library uses allocated objects of this type to report the details of any
- * failure, when an operation cannot be completed. Several `mongo_csfle_v1_status` functions are
+ * The Mongo Crypt Shared Library uses allocated objects of this type to report the details of any
+ * failure, when an operation cannot be completed. Several `mongo_crypt_v1_status` functions are
* provided which permit observing the details of these failures. Further a construction function
* and a destruction function for these objects are also provided.
*
* The use of status objects from multiple threads is not thread safe unless all of the threads
* accessing a single status object are passing that object as a const-qualified (const
- * mongo_csfle_v1_status *) pointer. If a single thread is passing a status object to a function
- * taking it by non-const-qualified (mongo_csfle_v1_status*) pointer, then no other thread may
+ * mongo_crypt_v1_status *) pointer. If a single thread is passing a status object to a function
+ * taking it by non-const-qualified (mongo_crypt_v1_status*) pointer, then no other thread may
* access the status object.
*
- * The `status` parameter is optional for all `mongo_csfle_v1_` functions that can take a status
+ * The `status` parameter is optional for all `mongo_crypt_v1_` functions that can take a status
* pointer. The caller may pass NULL instead of a valid `status` object, in which case the function
* will execute normally but will not provide any detailed error information in the caes of a
* failure.
*
- * All `mongo_csfle_v1_status` functions can be used before the CSFLE library is
+ * All `mongo_crypt_v1_status` functions can be used before the Mongo Crypt Shared library is
* initialized. This facilitates detailed error reporting from all library functions.
*/
-typedef struct mongo_csfle_v1_status mongo_csfle_v1_status;
+typedef struct mongo_crypt_v1_status mongo_crypt_v1_status;
/**
* Allocate and construct an API-return-status buffer object.
*
- * Returns NULL when construction of a mongo_csfle_v1_status object fails.
+ * Returns NULL when construction of a mongo_crypt_v1_status object fails.
*
- * This function may be called before mongo_csfle_v1_lib_create().
+ * This function may be called before mongo_crypt_v1_lib_create().
*/
-MONGO_CSFLE_API mongo_csfle_v1_status* MONGO_API_CALL mongo_csfle_v1_status_create(void);
+MONGO_CRYPT_API mongo_crypt_v1_status* MONGO_API_CALL mongo_crypt_v1_status_create(void);
/**
* Destroys a valid status object.
*
- * The status object must be a valid mongo_csfle_v1_status object or NULL.
+ * The status object must be a valid mongo_crypt_v1_status object or NULL.
*
* This function is not thread safe, and it must not execute concurrently with any other function
* that accesses the status object being destroyed. It is, however, safe to destroy distinct status
* objects on distinct threads.
*
* This function does not report failures.
*
- * This function may be called before `mongo_csfle_v1_lib_create()`.
+ * This function may be called before `mongo_crypt_v1_lib_create()`.
*
* This function causes all storage associated with the specified status object to be released,
* including the storage referenced by functions that returned observable storage buffers from this
* status, such as strings.
*/
-MONGO_CSFLE_API void MONGO_API_CALL mongo_csfle_v1_status_destroy(mongo_csfle_v1_status* status);
+MONGO_CRYPT_API void MONGO_API_CALL mongo_crypt_v1_status_destroy(mongo_crypt_v1_status* status);
/**
- * The error codes reported by `mongo_csfle_v1` functions will be given the symbolic names as
+ * The error codes reported by `mongo_crypt_v1` functions will be given the symbolic names as
* mapped by this enum.
*
- * When a `mongo_csfle_v1` function fails (and it has been documented to report errors) it will
+ * When a `mongo_crypt_v1` function fails (and it has been documented to report errors) it will
* report that error in the form of an `int` status code. That status code will always be returned
* as the type `int`; however, the values in this enum can be used to classify the failure.
*/
typedef enum {
- MONGO_CSFLE_V1_ERROR_IN_REPORTING_ERROR = -2,
- MONGO_CSFLE_V1_ERROR_UNKNOWN = -1,
+ MONGO_CRYPT_V1_ERROR_IN_REPORTING_ERROR = -2,
+ MONGO_CRYPT_V1_ERROR_UNKNOWN = -1,
- MONGO_CSFLE_V1_SUCCESS = 0,
+ MONGO_CRYPT_V1_SUCCESS = 0,
- MONGO_CSFLE_V1_ERROR_ENOMEM = 1,
- MONGO_CSFLE_V1_ERROR_EXCEPTION = 2,
- MONGO_CSFLE_V1_ERROR_LIBRARY_ALREADY_INITIALIZED = 3,
- MONGO_CSFLE_V1_ERROR_LIBRARY_NOT_INITIALIZED = 4,
- MONGO_CSFLE_V1_ERROR_INVALID_LIB_HANDLE = 5,
- MONGO_CSFLE_V1_ERROR_REENTRANCY_NOT_ALLOWED = 6,
-} mongo_csfle_v1_error;
+ MONGO_CRYPT_V1_ERROR_ENOMEM = 1,
+ MONGO_CRYPT_V1_ERROR_EXCEPTION = 2,
+ MONGO_CRYPT_V1_ERROR_LIBRARY_ALREADY_INITIALIZED = 3,
+ MONGO_CRYPT_V1_ERROR_LIBRARY_NOT_INITIALIZED = 4,
+ MONGO_CRYPT_V1_ERROR_INVALID_LIB_HANDLE = 5,
+ MONGO_CRYPT_V1_ERROR_REENTRANCY_NOT_ALLOWED = 6,
+} mongo_crypt_v1_error;
/**
- * Gets an error code from a `mongo_csfle_v1_status` object.
+ * Gets an error code from a `mongo_crypt_v1_status` object.
*
- * When a `mongo_csfle_v1` function fails (and it has been documented to report errors) it will
+ * When a `mongo_crypt_v1` function fails (and it has been documented to report errors) it will
* report its error in the form of an `int` status code which is stored into a supplied
- * `mongo_csfle_v1_status` object, if provided. Some of these functions may also report extra
- * information, which will be reported by other observer functions. Every `mongo_csfle_v1`
+ * `mongo_crypt_v1_status` object, if provided. Some of these functions may also report extra
+ * information, which will be reported by other observer functions. Every `mongo_crypt_v1`
* function which reports errors will always update the `Error` code stored in a
- * `mongo_csfle_v1_status` object, even upon success.
+ * `mongo_crypt_v1_status` object, even upon success.
*
* This function does not report its own failures.
*/
-MONGO_CSFLE_API int MONGO_API_CALL
-mongo_csfle_v1_status_get_error(const mongo_csfle_v1_status* status);
+MONGO_CRYPT_API int MONGO_API_CALL
+mongo_crypt_v1_status_get_error(const mongo_crypt_v1_status* status);
/**
- * Gets a descriptive error message from a `mongo_csfle_v1_status` object.
+ * Gets a descriptive error message from a `mongo_crypt_v1_status` object.
*
- * For failures where the error is MONGO_CSFLE_V1_ERROR_EXCEPTION, this returns a string
+ * For failures where the error is MONGO_CRYPT_V1_ERROR_EXCEPTION, this returns a string
* representation of the internal C++ exception.
*
* The function to which the specified status object was passed must not have returned
- * MONGO_CSFLE_V1_SUCCESS as its error code.
+ * MONGO_CRYPT_V1_SUCCESS as its error code.
*
* The storage for the returned string is associated with the specified status object, and therefore
- * it will be deallocated when the status is destroyed using mongo_csfle_v1_status_destroy().
+ * it will be deallocated when the status is destroyed using mongo_crypt_v1_status_destroy().
*
* This function does not report its own failures.
*/
-MONGO_CSFLE_API const char* MONGO_API_CALL
-mongo_csfle_v1_status_get_explanation(const mongo_csfle_v1_status* status);
+MONGO_CRYPT_API const char* MONGO_API_CALL
+mongo_crypt_v1_status_get_explanation(const mongo_crypt_v1_status* status);
/**
- * Gets a status code from a `mongo_csfle_v1_status` object.
+ * Gets a status code from a `mongo_crypt_v1_status` object.
*
* Returns a numeric status code associated with the status parameter which indicates a sub-category
* of failure.
*
- * For any status object that does not have MONGO_CSFLE_V1_ERROR_EXCEPTION as its error, the
+ * For any status object that does not have MONGO_CRYPT_V1_ERROR_EXCEPTION as its error, the
* value of this code is unspecified.
*
* This function does not report its own failures.
*/
-MONGO_CSFLE_API int MONGO_API_CALL
-mongo_csfle_v1_status_get_code(const mongo_csfle_v1_status* status);
+MONGO_CRYPT_API int MONGO_API_CALL
+mongo_crypt_v1_status_get_code(const mongo_crypt_v1_status* status);
/**
- * An object which describes the runtime state of the CSFLE Library.
+ * An object which describes the runtime state of the Mongo Crypt Shared Library.
*
- * The CSFLE Library uses allocated objects of this type to indicate the present state of
- * the library. Some operations which the library provides need access to this object. Further a
+ * The Mongo Crypt Shared Library uses allocated objects of this type to indicate the present state
+ * of the library. Some operations which the library provides need access to this object. Further a
* construction function and a destruction function for these objects are also provided. No more
* than a single object instance of this type may exist at any given time.
*
- * The use of `mongo_csfle_v1_lib` objects from multiple threads is not thread safe unless all of
- * the threads accessing a single `mongo_csfle_v1_lib` object are not destroying this object. If
- * a single thread is passing a `mongo_csfle_v1_lib` to its destruction function, then no other
- * thread may access the `mongo_csfle_v1_lib` object.
+ * The use of `mongo_crypt_v1_lib` objects from multiple threads is not thread safe unless all of
+ * the threads accessing a single `mongo_crypt_v1_lib` object are not destroying this object. If
+ * a single thread is passing a `mongo_crypt_v1_lib` to its destruction function, then no other
+ * thread may access the `mongo_crypt_v1_lib` object.
*/
-typedef struct mongo_csfle_v1_lib mongo_csfle_v1_lib;
+typedef struct mongo_crypt_v1_lib mongo_crypt_v1_lib;
/**
- * Creates a mongo_csfle_v1_lib object, which stores context for the CSFLE library. A
- * process should only ever have one mongo_csfle_v1_lib instance.
+ * Creates a mongo_crypt_v1_lib object, which stores context for the Mongo Crypt Shared library. A
+ * process should only ever have one mongo_crypt_v1_lib instance.
*
* On failure, returns NULL and populates the 'status' object if it is not NULL.
*/
-MONGO_CSFLE_API mongo_csfle_v1_lib* MONGO_API_CALL
-mongo_csfle_v1_lib_create(mongo_csfle_v1_status* status);
+MONGO_CRYPT_API mongo_crypt_v1_lib* MONGO_API_CALL
+mongo_crypt_v1_lib_create(mongo_crypt_v1_status* status);
/**
- * Tears down the state of this library. Existing mongo_csfle_v1_status objects remain valid.
- * Existing mongo_csfle_v1_query_analyzer objects created from this library MUST BE destroyed
+ * Tears down the state of this library. Existing mongo_crypt_v1_status objects remain valid.
+ * Existing mongo_crypt_v1_query_analyzer objects created from this library MUST BE destroyed
* before destroying the library object.
*
- * The 'lib' parameter must be a valid mongo_csfle_v1_lib instance and must not be NULL.
+ * The 'lib' parameter must be a valid mongo_crypt_v1_lib instance and must not be NULL.
*
- * The 'status' parameter may be NULL, but must be a valid mongo_csfle_v1_status instance if it
+ * The 'status' parameter may be NULL, but must be a valid mongo_crypt_v1_status instance if it
* is not NULL.
*
- * Returns MONGO_CSFLE_V1_SUCCESS on success.
+ * Returns MONGO_CRYPT_V1_SUCCESS on success.
*
- * Returns MONGO_CSFLE_V1_ERROR_LIBRARY_NOT_INITIALIZED and modifies 'status' if
- * mongo_csfle_v1_lib_create() has not been called previously.
+ * Returns MONGO_CRYPT_V1_ERROR_LIBRARY_NOT_INITIALIZED and modifies 'status' if
+ * mongo_crypt_v1_lib_create() has not been called previously.
*/
-MONGO_CSFLE_API int MONGO_API_CALL mongo_csfle_v1_lib_destroy(mongo_csfle_v1_lib* lib,
- mongo_csfle_v1_status* status);
+MONGO_CRYPT_API int MONGO_API_CALL mongo_crypt_v1_lib_destroy(mongo_crypt_v1_lib* lib,
+ mongo_crypt_v1_status* status);
/**
* Returns a product version in 64-bit integer in four 16-bit words, from high to low:
*
* - Major version
* - Minor version
* - Revision
* - Reserved
*
* For example, version 6.2.1 would be encoded as: 0x0006000200010000
*
*/
-MONGO_CSFLE_API uint64_t MONGO_API_CALL mongo_csfle_v1_get_version(void);
+MONGO_CRYPT_API uint64_t MONGO_API_CALL mongo_crypt_v1_get_version(void);
/**
* Returns a product version as a text string. The string should not be modified or released
*
* Examples:
- * Dev Build/patch: mongo_csfle_v1-rhel80-6.2.1-alpha4-284-g8662e7d
- * Release build: mongo_csfle_v1-rhel80-6.2.1
+ * Dev Build/patch: mongo_crypt_v1-rhel80-6.2.1-alpha4-284-g8662e7d
+ * Release build: mongo_crypt_v1-rhel80-6.2.1
*/
-MONGO_CSFLE_API const char* MONGO_API_CALL mongo_csfle_v1_get_version_str(void);
+MONGO_CRYPT_API const char* MONGO_API_CALL mongo_crypt_v1_get_version_str(void);
/**
- * A single query analyzer can be used across repeated calls to mongo_csfle_v1_analyze_query.
+ * A single query analyzer can be used across repeated calls to mongo_crypt_v1_analyze_query.
*
- * It is not safe to simultaneously invoke mongo_csfle_v1_query_analyzer_create on the same
+ * It is not safe to simultaneously invoke mongo_crypt_v1_query_analyzer_create on the same
* query analyzer from multiple threads
*
- * It is the client's responsibility to call mongo_csfle_v1_query_analyzer_destroy() to free up
+ * It is the client's responsibility to call mongo_crypt_v1_query_analyzer_destroy() to free up
* resources used by the query analyzer. Once a query analyzer is destroyed, it is not safe to
- * call mongo_csfle_v1_analyze_query.
+ * call mongo_crypt_v1_analyze_query.
*/
-typedef struct mongo_csfle_v1_query_analyzer mongo_csfle_v1_query_analyzer;
+typedef struct mongo_crypt_v1_query_analyzer mongo_crypt_v1_query_analyzer;
/**
- * Creates a mongo_csfle_v1_query_analyzer object, which stores a parsed collation.
+ * Creates a mongo_crypt_v1_query_analyzer object, which stores a parsed collation.
*
- * The 'lib' parameter must be a valid mongo_csfle_v1_lib instance and must not be NULL.
+ * The 'lib' parameter must be a valid mongo_crypt_v1_lib instance and must not be NULL.
*
* On failure, it returns NULL and populates the 'status' object if it is not NULL.
*/
-MONGO_CSFLE_API mongo_csfle_v1_query_analyzer* MONGO_API_CALL
-mongo_csfle_v1_query_analyzer_create(mongo_csfle_v1_lib* lib, mongo_csfle_v1_status* status);
+MONGO_CRYPT_API mongo_crypt_v1_query_analyzer* MONGO_API_CALL
+mongo_crypt_v1_query_analyzer_create(mongo_crypt_v1_lib* lib, mongo_crypt_v1_status* status);
/**
- * Destroys a valid mongo_csfle_v1_query_analyzer object.
+ * Destroys a valid mongo_crypt_v1_query_analyzer object.
*
* This function is not thread safe, and it must not execute concurrently with any other function
* that accesses the collation object being destroyed including those that access a matcher,
* projection or update object which references the collation object.
*
* This function does not report failures.
*/
-MONGO_CSFLE_API void MONGO_API_CALL
-mongo_csfle_v1_query_analyzer_destroy(mongo_csfle_v1_query_analyzer* analyzer);
+MONGO_CRYPT_API void MONGO_API_CALL
+mongo_crypt_v1_query_analyzer_destroy(mongo_crypt_v1_query_analyzer* analyzer);
/**
* Analyzes the 'documentBSON' input document which includes a JSON schema for namespace 'ns_str'
* and returns a new BSON document that replaces fields that need encryption with BinData
* (subtype 6, first byte 0) placeholders.
*
* The input document must be a valid OP_MSG document supports aggregate, count, delete, distinct,
* explain, find, findAndModify, insert and update.
* In addition, the input document must include two additional top-level fields:
* - jsonSchema : document - contains a valid JSON schema
* - isRemoteSchema : bool - true if schema comes from MongoD as opposed to client-side
*
* The 'analyzer' and 'documentBSON' parameters must point to initialized objects of their
* respective types.
*
* When the analysis is successful, this function returns non-null value which points to a valid
* BSON document and updates bson_len with the length of the BSON document
*/
-MONGO_CSFLE_API uint8_t* MONGO_API_CALL
-mongo_csfle_v1_analyze_query(mongo_csfle_v1_query_analyzer* analyzer,
+MONGO_CRYPT_API uint8_t* MONGO_API_CALL
+mongo_crypt_v1_analyze_query(mongo_crypt_v1_query_analyzer* analyzer,
const uint8_t* documentBSON,
const char* ns_str,
uint32_t ns_len,
uint32_t* bson_len,
- mongo_csfle_v1_status* status);
+ mongo_crypt_v1_status* status);
/**
- * Free the memory of a BSON buffer returned by mongo_csfle_v1_analyze_query(). This function can be
+ * Free the memory of a BSON buffer returned by mongo_crypt_v1_analyze_query(). This function can be
* safely called on a NULL pointer.
*
* This function can be called at any time to deallocate a BSON buffer and will not invalidate any
* library object.
*/
-MONGO_CSFLE_API void MONGO_API_CALL mongo_csfle_v1_bson_free(uint8_t* bson);
+MONGO_CRYPT_API void MONGO_API_CALL mongo_crypt_v1_bson_free(uint8_t* bson);
#ifdef __cplusplus
} // extern "C"
#endif
-#undef CSFLE_SUPPORT_API
-#pragma pop_macro("CSFLE_SUPPORT_API")
+#undef MONGO_CRYPT_SUPPORT_API
+#pragma pop_macro("MONGO_CRYPT_SUPPORT_API")
#undef MONGO_API_EXPORT
#pragma push_macro("MONGO_API_EXPORT")
#undef MONGO_API_IMPORT
#pragma push_macro("MONGO_API_IMPORT")
#undef MONGO_API_CALL
#pragma pop_macro("MONGO_API_CALL")
-#endif // CSFLE_SUPPORT_H
+#endif // MONGO_CRYPT_SUPPORT_H
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-binary-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-binary-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-binary-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-binary-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-binary.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-binary.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-binary.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-binary.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-buffer-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-buffer-private.h
similarity index 87%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-buffer-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-buffer-private.h
index 9219dd00..9bb79097 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-buffer-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-buffer-private.h
@@ -1,204 +1,225 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_BUFFER_H
#define MONGOCRYPT_BUFFER_H
#include <bson/bson.h>
#include "mongocrypt-binary-private.h"
#include "mongocrypt-compat.h"
+#define UUID_LEN 16
+
struct _mongocrypt_binary_t;
/* An internal struct to make working with binary values more convenient.
* - a non-owning buffer can be constructed from a bson_iter_t.
* - a non-owning buffer can become an owned buffer by copying.
* - a buffer can be appended as a BSON binary in a bson_t.
*/
typedef struct __mongocrypt_buffer_t {
uint8_t *data;
uint32_t len;
bool owned;
bson_subtype_t subtype;
mongocrypt_binary_t bin;
} _mongocrypt_buffer_t;
void
_mongocrypt_buffer_init (_mongocrypt_buffer_t *buf);
void
_mongocrypt_buffer_resize (_mongocrypt_buffer_t *buf, uint32_t len);
+void
+_mongocrypt_buffer_init_size (_mongocrypt_buffer_t *buf, uint32_t len);
void
_mongocrypt_buffer_steal (_mongocrypt_buffer_t *buf, _mongocrypt_buffer_t *src);
/* @iter is iterated to a BSON binary value. */
bool
_mongocrypt_buffer_copy_from_binary_iter (
_mongocrypt_buffer_t *buf, bson_iter_t *iter) MONGOCRYPT_WARN_UNUSED_RESULT;
/* @iter is iterated to a BSON binary value. */
bool
_mongocrypt_buffer_from_binary_iter (
_mongocrypt_buffer_t *buf, bson_iter_t *iter) MONGOCRYPT_WARN_UNUSED_RESULT;
/* @iter is iterated to a BSON document value. */
bool
_mongocrypt_buffer_from_document_iter (
_mongocrypt_buffer_t *buf, bson_iter_t *iter) MONGOCRYPT_WARN_UNUSED_RESULT;
/* @iter is iterated to a BSON document value. */
bool
_mongocrypt_buffer_copy_from_document_iter (
_mongocrypt_buffer_t *buf, bson_iter_t *iter) MONGOCRYPT_WARN_UNUSED_RESULT;
void
_mongocrypt_buffer_steal_from_bson (_mongocrypt_buffer_t *buf, bson_t *bson);
void
_mongocrypt_buffer_from_bson (_mongocrypt_buffer_t *buf, const bson_t *bson);
bool
_mongocrypt_buffer_to_bson (const _mongocrypt_buffer_t *buf,
bson_t *bson) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_buffer_append (const _mongocrypt_buffer_t *buf,
bson_t *bson,
const char *key,
uint32_t key_len) MONGOCRYPT_WARN_UNUSED_RESULT;
void
_mongocrypt_buffer_from_binary (_mongocrypt_buffer_t *buf,
const struct _mongocrypt_binary_t *binary);
void
_mongocrypt_buffer_copy_from_binary (_mongocrypt_buffer_t *buf,
const struct _mongocrypt_binary_t *binary);
void
_mongocrypt_buffer_to_binary (const _mongocrypt_buffer_t *buf,
struct _mongocrypt_binary_t *binary);
void
_mongocrypt_buffer_copy_to (const _mongocrypt_buffer_t *src,
_mongocrypt_buffer_t *dst);
void
_mongocrypt_buffer_set_to (const _mongocrypt_buffer_t *src,
_mongocrypt_buffer_t *dst);
int
_mongocrypt_buffer_cmp (const _mongocrypt_buffer_t *a,
const _mongocrypt_buffer_t *b);
void
_mongocrypt_buffer_cleanup (_mongocrypt_buffer_t *buf);
bool
_mongocrypt_buffer_empty (const _mongocrypt_buffer_t *buf);
bool
_mongocrypt_buffer_to_bson_value (_mongocrypt_buffer_t *plaintext,
uint8_t type,
bson_value_t *out)
MONGOCRYPT_WARN_UNUSED_RESULT;
void
_mongocrypt_buffer_from_iter (_mongocrypt_buffer_t *plaintext,
bson_iter_t *iter);
bool
_mongocrypt_buffer_from_uuid_iter (_mongocrypt_buffer_t *buf, bson_iter_t *iter)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_buffer_copy_from_uuid_iter (
_mongocrypt_buffer_t *buf, bson_iter_t *iter) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_buffer_is_uuid (_mongocrypt_buffer_t *buf)
MONGOCRYPT_WARN_UNUSED_RESULT;
void
_mongocrypt_buffer_copy_from_hex (_mongocrypt_buffer_t *buf, const char *hex);
int
_mongocrypt_buffer_cmp_hex (_mongocrypt_buffer_t *buf, const char *hex);
char *
_mongocrypt_buffer_to_hex (_mongocrypt_buffer_t *buf)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_buffer_concat (_mongocrypt_buffer_t *dst,
const _mongocrypt_buffer_t *srcs,
uint32_t num_srcs);
struct _mongocrypt_binary_t *
_mongocrypt_buffer_as_binary (_mongocrypt_buffer_t *buf);
/* _mongocrypt_buffer_copy_from_data_and_size initializes @buf and copies @len
* bytes from @data.
* - Returns false on error.
* - Caller must call _mongocrypt_buffer_cleanup. */
bool
_mongocrypt_buffer_copy_from_data_and_size (_mongocrypt_buffer_t *buf,
const uint8_t *data,
size_t len)
MONGOCRYPT_WARN_UNUSED_RESULT;
/* _mongocrypt_buffer_steal_from_data_and_size initializes @buf from @data and
* @len and takes ownership of @data.
* - Returns false on error.
* - @buf does not take ownership of @str on error.
* - Caller must call _mongocrypt_buffer_cleanup. */
bool
_mongocrypt_buffer_steal_from_data_and_size (_mongocrypt_buffer_t *buf,
uint8_t *data,
size_t len)
MONGOCRYPT_WARN_UNUSED_RESULT;
/* _mongocrypt_buffer_steal_from_string initializes @buf from @str and takes
* ownership of @str.
* @buf retains a pointer to @str.
* @str must be NULL terminated.
* - Returns false on error.
* - @buf does not take ownership of @str on error.
* - Caller must call _mongocrypt_buffer_cleanup. */
bool
_mongocrypt_buffer_steal_from_string (_mongocrypt_buffer_t *buf,
char *str) MONGOCRYPT_WARN_UNUSED_RESULT;
+/* _mongocrypt_buffer_copy_from_uint64_le initializes @buf from the little-endian
+ * byte representation of @value.
+ * Caller must call _mongocrypt_buffer_cleanup.
+ * @value is expected to be in machine's native endianness.
+ */
+void
+_mongocrypt_buffer_copy_from_uint64_le (_mongocrypt_buffer_t *buf, uint64_t value);
+
+/* _mongocrypt_buffer_from_subrange initializes @out as a non-owning buffer to a
+ * range of data from @in specified by @offset and @len. Returns false on error.
+ */
+bool
+_mongocrypt_buffer_from_subrange (_mongocrypt_buffer_t *out,
+ const _mongocrypt_buffer_t *in,
+ uint32_t offset,
+ uint32_t len) MONGOCRYPT_WARN_UNUSED_RESULT;
+
#endif /* MONGOCRYPT_BUFFER_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-buffer.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-buffer.c
similarity index 89%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-buffer.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-buffer.c
index 688a3e01..f2f163a0 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-buffer.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-buffer.c
@@ -1,534 +1,585 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongocrypt-buffer-private.h"
+#include "mongocrypt-endian-private.h"
#include "mongocrypt-util-private.h"
#define INT32_LEN 4
#define TYPE_LEN 1
#define NULL_BYTE_LEN 1
#define NULL_BYTE_VAL 0x00
/* if a buffer is not owned, copy the data and make it owned. */
static void
_make_owned (_mongocrypt_buffer_t *buf)
{
uint8_t *tmp;
BSON_ASSERT (buf);
if (buf->owned) {
return;
}
tmp = buf->data;
- buf->data = bson_malloc (buf->len);
- BSON_ASSERT (buf->data);
+ if (buf->len > 0) {
+ buf->data = bson_malloc (buf->len);
+ BSON_ASSERT (buf->data);
+ memcpy (buf->data, tmp, buf->len);
+ } else {
+ buf->data = NULL;
+ }
- memcpy (buf->data, tmp, buf->len);
buf->owned = true;
}
/* TODO CDRIVER-2990 have buffer operations require initialized buffer to
* prevent leaky code. */
void
_mongocrypt_buffer_init (_mongocrypt_buffer_t *buf)
{
memset (buf, 0, sizeof (*buf));
}
void
_mongocrypt_buffer_resize (_mongocrypt_buffer_t *buf, uint32_t len)
{
BSON_ASSERT (buf);
/* Currently this just wipes whatever was in data before,
but a fancier implementation could copy over up to 'len'
bytes from the old buffer to the new one. */
if (buf->owned) {
buf->data = bson_realloc (buf->data, len);
buf->len = len;
return;
}
buf->data = bson_malloc (len);
BSON_ASSERT (buf->data);
buf->len = len;
buf->owned = true;
}
+void
+_mongocrypt_buffer_init_size (_mongocrypt_buffer_t *buf, uint32_t len)
+{
+ _mongocrypt_buffer_init (buf);
+ _mongocrypt_buffer_resize (buf, len);
+}
+
+
void
_mongocrypt_buffer_steal (_mongocrypt_buffer_t *buf, _mongocrypt_buffer_t *src)
{
if (!src->owned) {
_mongocrypt_buffer_copy_to (src, buf);
_mongocrypt_buffer_init (src);
return;
}
buf->data = src->data;
buf->len = src->len;
buf->owned = true;
_mongocrypt_buffer_init (src);
}
bool
_mongocrypt_buffer_from_binary_iter (_mongocrypt_buffer_t *buf,
bson_iter_t *iter)
{
if (!BSON_ITER_HOLDS_BINARY (iter)) {
return false;
}
_mongocrypt_buffer_init (buf);
bson_iter_binary (
iter, &buf->subtype, &buf->len, (const uint8_t **) &buf->data);
buf->owned = false;
return true;
}
bool
_mongocrypt_buffer_copy_from_binary_iter (_mongocrypt_buffer_t *buf,
bson_iter_t *iter)
{
if (!_mongocrypt_buffer_from_binary_iter (buf, iter)) {
return false;
}
_make_owned (buf);
return true;
}
bool
_mongocrypt_buffer_from_document_iter (_mongocrypt_buffer_t *buf,
bson_iter_t *iter)
{
if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
return false;
}
_mongocrypt_buffer_init (buf);
bson_iter_document (iter, &buf->len, (const uint8_t **) &buf->data);
buf->owned = false;
return true;
}
bool
_mongocrypt_buffer_copy_from_document_iter (_mongocrypt_buffer_t *buf,
bson_iter_t *iter)
{
if (!_mongocrypt_buffer_from_document_iter (buf, iter)) {
return false;
}
_make_owned (buf);
return true;
}
void
_mongocrypt_buffer_steal_from_bson (_mongocrypt_buffer_t *buf, bson_t *bson)
{
_mongocrypt_buffer_init (buf);
buf->data = bson_destroy_with_steal (bson, true, &buf->len);
buf->owned = true;
}
void
_mongocrypt_buffer_from_bson (_mongocrypt_buffer_t *buf, const bson_t *bson)
{
_mongocrypt_buffer_init (buf);
buf->data = (uint8_t *) bson_get_data (bson);
buf->len = bson->len;
buf->owned = false;
}
bool
_mongocrypt_buffer_to_bson (const _mongocrypt_buffer_t *buf, bson_t *bson)
{
BSON_ASSERT (buf);
BSON_ASSERT (bson);
return bson_init_static (bson, buf->data, buf->len);
}
bool
_mongocrypt_buffer_append (const _mongocrypt_buffer_t *buf,
bson_t *bson,
const char *key,
uint32_t key_len)
{
return bson_append_binary (
bson, key, key_len, buf->subtype, buf->data, buf->len);
}
void
_mongocrypt_buffer_from_binary (_mongocrypt_buffer_t *buf,
const mongocrypt_binary_t *binary)
{
_mongocrypt_buffer_init (buf);
buf->data = binary->data;
buf->len = binary->len;
buf->owned = false;
}
void
_mongocrypt_buffer_copy_from_binary (_mongocrypt_buffer_t *buf,
const struct _mongocrypt_binary_t *binary)
{
BSON_ASSERT (buf);
BSON_ASSERT (binary);
_mongocrypt_buffer_from_binary (buf, binary);
_make_owned (buf);
}
void
_mongocrypt_buffer_to_binary (const _mongocrypt_buffer_t *buf,
mongocrypt_binary_t *binary)
{
binary->data = buf->data;
binary->len = buf->len;
}
void
_mongocrypt_buffer_copy_to (const _mongocrypt_buffer_t *src,
_mongocrypt_buffer_t *dst)
{
if (src == dst) {
return;
}
BSON_ASSERT (src);
BSON_ASSERT (dst);
_mongocrypt_buffer_cleanup (dst);
if (src->len == 0) {
return;
}
dst->data = bson_malloc ((size_t) src->len);
BSON_ASSERT (dst->data);
memcpy (dst->data, src->data, src->len);
dst->len = src->len;
dst->subtype = src->subtype;
dst->owned = true;
}
void
_mongocrypt_buffer_set_to (const _mongocrypt_buffer_t *src,
_mongocrypt_buffer_t *dst)
{
if (src == dst) {
return;
}
BSON_ASSERT (src);
BSON_ASSERT (dst);
dst->data = src->data;
dst->len = src->len;
dst->subtype = src->subtype;
dst->owned = false;
}
int
_mongocrypt_buffer_cmp (const _mongocrypt_buffer_t *a,
const _mongocrypt_buffer_t *b)
{
if (a->len != b->len) {
return a->len - b->len;
}
+ if (0 == a->len) {
+ return 0;
+ }
return memcmp (a->data, b->data, a->len);
}
void
_mongocrypt_buffer_cleanup (_mongocrypt_buffer_t *buf)
{
if (buf && buf->owned) {
bson_free (buf->data);
}
}
bool
_mongocrypt_buffer_empty (const _mongocrypt_buffer_t *buf)
{
return buf->data == NULL;
}
bool
_mongocrypt_buffer_to_bson_value (_mongocrypt_buffer_t *plaintext,
uint8_t type,
bson_value_t *out)
{
bool ret = false;
bson_iter_t iter;
bson_t wrapper;
uint32_t data_len;
uint32_t le_data_len;
uint8_t *data;
uint8_t data_prefix;
data_prefix = INT32_LEN /* adds document size */
+ TYPE_LEN /* element type */
+ NULL_BYTE_LEN; /* and doc's null byte terminator */
data_len = (plaintext->len + data_prefix + NULL_BYTE_LEN);
le_data_len = BSON_UINT32_TO_LE (data_len);
data = bson_malloc0 (data_len);
BSON_ASSERT (data);
memcpy (data + data_prefix, plaintext->data, plaintext->len);
memcpy (data, &le_data_len, INT32_LEN);
memcpy (data + INT32_LEN, &type, TYPE_LEN);
data[data_len - 1] = NULL_BYTE_VAL;
if (!bson_init_static (&wrapper, data, data_len)) {
goto fail;
}
if (!bson_validate (&wrapper, BSON_VALIDATE_NONE, NULL)) {
goto fail;
}
if (!bson_iter_init_find (&iter, &wrapper, "")) {
goto fail;
}
bson_value_copy (bson_iter_value (&iter), out);
/* Due to an open libbson bug (CDRIVER-3340), give an empty
* binary payload a real address. TODO: remove this after
* CDRIVER-3340 is fixed. */
if (out->value_type == BSON_TYPE_BINARY &&
0 == out->value.v_binary.data_len) {
out->value.v_binary.data =
bson_malloc (1); /* Freed in bson_value_destroy */
}
ret = true;
fail:
bson_free (data);
return ret;
}
void
_mongocrypt_buffer_from_iter (_mongocrypt_buffer_t *plaintext,
bson_iter_t *iter)
{
bson_t wrapper = BSON_INITIALIZER;
int32_t offset = INT32_LEN /* skips document size */
+ TYPE_LEN /* element type */
+ NULL_BYTE_LEN; /* and the key's null byte terminator */
uint8_t *wrapper_data;
/* It is not straightforward to transform a bson_value_t to a string of
* bytes. As a workaround, we wrap the value in a bson document with an empty
* key, then use the raw buffer from inside the new bson_t, skipping the
* length and type header information and the key name. */
bson_append_iter (&wrapper, "", 0, iter);
wrapper_data = ((uint8_t *) bson_get_data (&wrapper));
plaintext->len =
wrapper.len - offset - NULL_BYTE_LEN; /* the final null byte */
plaintext->data = bson_malloc (plaintext->len);
BSON_ASSERT (plaintext->data);
plaintext->owned = true;
memcpy (plaintext->data, wrapper_data + offset, plaintext->len);
bson_destroy (&wrapper);
}
bool
_mongocrypt_buffer_from_uuid_iter (_mongocrypt_buffer_t *buf, bson_iter_t *iter)
{
const uint8_t *data;
bson_subtype_t subtype;
uint32_t len;
if (!BSON_ITER_HOLDS_BINARY (iter)) {
return false;
}
bson_iter_binary (iter, &subtype, &len, &data);
if (subtype != BSON_SUBTYPE_UUID) {
return false;
}
- if (len != 16) {
+ if (len != UUID_LEN) {
return false;
}
_mongocrypt_buffer_init (buf);
buf->data = (uint8_t *) data;
buf->len = len;
buf->subtype = subtype;
buf->owned = false;
return true;
}
bool
_mongocrypt_buffer_copy_from_uuid_iter (_mongocrypt_buffer_t *buf,
bson_iter_t *iter)
{
if (!_mongocrypt_buffer_from_uuid_iter (buf, iter)) {
return false;
}
_make_owned (buf);
return true;
}
bool
_mongocrypt_buffer_is_uuid (_mongocrypt_buffer_t *buf)
{
- return buf->len == 16 && buf->subtype == BSON_SUBTYPE_UUID;
+ return buf->len == UUID_LEN && buf->subtype == BSON_SUBTYPE_UUID;
}
void
_mongocrypt_buffer_copy_from_hex (_mongocrypt_buffer_t *buf, const char *hex)
{
uint32_t i;
+ if (strlen (hex) == 0) {
+ _mongocrypt_buffer_init (buf);
+ return;
+ }
+
buf->len = (uint32_t) strlen (hex) / 2;
buf->data = bson_malloc (buf->len);
BSON_ASSERT (buf->data);
buf->owned = true;
for (i = 0; i < buf->len; i++) {
int tmp;
BSON_ASSERT (sscanf (hex + (2 * i), "%02x", &tmp));
*(buf->data + i) = (uint8_t) tmp;
}
}
int
_mongocrypt_buffer_cmp_hex (_mongocrypt_buffer_t *buf, const char *hex)
{
_mongocrypt_buffer_t tmp;
int res;
_mongocrypt_buffer_copy_from_hex (&tmp, hex);
res = _mongocrypt_buffer_cmp (buf, &tmp);
_mongocrypt_buffer_cleanup (&tmp);
return res;
}
char *
_mongocrypt_buffer_to_hex (_mongocrypt_buffer_t *buf)
{
char *hex = bson_malloc0 (buf->len * 2 + 1);
BSON_ASSERT (hex);
char *out = hex;
for (uint32_t i = 0; i < buf->len; i++, out += 2) {
sprintf (out, "%02X", buf->data[i]);
}
return hex;
}
bool
_mongocrypt_buffer_concat (_mongocrypt_buffer_t *dst,
const _mongocrypt_buffer_t *srcs,
uint32_t num_srcs)
{
uint32_t total = 0;
uint32_t offset;
uint32_t i;
for (i = 0; i < num_srcs; i++) {
uint32_t old_total = total;
total += srcs[i].len;
if (total < old_total) {
return false;
}
}
_mongocrypt_buffer_init (dst);
_mongocrypt_buffer_resize (dst, total);
offset = 0;
for (i = 0; i < num_srcs; i++) {
- memcpy (dst->data + offset, srcs[i].data, srcs[i].len);
+ if (srcs[i].len) {
+ memcpy (dst->data + offset, srcs[i].data, srcs[i].len);
+ }
offset += srcs[i].len;
}
return true;
}
struct _mongocrypt_binary_t *
_mongocrypt_buffer_as_binary (_mongocrypt_buffer_t *buf)
{
buf->bin.data = buf->data;
buf->bin.len = buf->len;
return &buf->bin;
}
bool
_mongocrypt_buffer_copy_from_data_and_size (_mongocrypt_buffer_t *buf,
const uint8_t *data,
size_t len)
{
_mongocrypt_buffer_init (buf);
if (!size_to_uint32 (len, &buf->len)) {
return false;
}
buf->data = bson_malloc (len);
memcpy (buf->data, data, len);
buf->owned = true;
return true;
}
bool
_mongocrypt_buffer_steal_from_data_and_size (_mongocrypt_buffer_t *buf,
uint8_t *data,
size_t len)
{
_mongocrypt_buffer_init (buf);
if (!size_to_uint32 (len, &buf->len)) {
return false;
}
buf->data = data;
buf->owned = true;
return true;
}
bool
_mongocrypt_buffer_steal_from_string (_mongocrypt_buffer_t *buf, char *str)
{
_mongocrypt_buffer_init (buf);
if (!size_to_uint32 (strlen (str), &buf->len)) {
return false;
}
buf->data = (uint8_t *) str;
buf->owned = true;
return true;
}
+
+void
+_mongocrypt_buffer_copy_from_uint64_le (_mongocrypt_buffer_t *buf,
+ uint64_t value)
+{
+ uint64_t value_le = MONGOCRYPT_UINT64_TO_LE (value);
+ _mongocrypt_buffer_init (buf);
+ _mongocrypt_buffer_resize (buf, sizeof (value));
+ memcpy (buf->data, &value_le, buf->len);
+}
+
+bool
+_mongocrypt_buffer_from_subrange (_mongocrypt_buffer_t *out,
+ const _mongocrypt_buffer_t *in,
+ uint32_t offset,
+ uint32_t len)
+{
+ BSON_ASSERT_PARAM (out);
+ BSON_ASSERT_PARAM (in);
+
+ _mongocrypt_buffer_init (out);
+ if (offset + len > in->len) {
+ return false;
+ }
+ out->data = in->data + offset;
+ out->len = len;
+ return true;
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-collinfo.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-collinfo.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-collinfo.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-collinfo.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-key-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-key-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-key-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-key-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-key.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-key.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-key.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-key.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-oauth-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-oauth-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-oauth-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-oauth-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-oauth.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-oauth.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-oauth.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-oauth.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-cache.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-cache.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ciphertext-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
similarity index 84%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
index 9491106a..66f83346 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ciphertext-private.h
@@ -1,56 +1,64 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_CIPHERTEXT_PRIVATE_H
#define MONGOCRYPT_CIPHERTEXT_PRIVATE_H
+#include "mc-fle-blob-subtype-private.h"
#include "mongocrypt-buffer-private.h"
#include "mongocrypt.h"
+/**
+ * Produced by mongocrypt-marking.c from _mongocrypt_marking_t
+ * as encrypted payloads for blob_subtypes:
+ * FLE1DeterministicEncryptedValue(1)
+ * FLE1RandomEncryptedValue(2)
+ * FLE2InsertUpdatePayload(4)
+ */
typedef struct {
_mongocrypt_buffer_t key_id;
- uint8_t blob_subtype;
+ mc_fle_blob_subtype_t blob_subtype;
uint8_t original_bson_type;
_mongocrypt_buffer_t data;
} _mongocrypt_ciphertext_t;
void
_mongocrypt_ciphertext_init (_mongocrypt_ciphertext_t *ciphertext);
void
_mongocrypt_ciphertext_cleanup (_mongocrypt_ciphertext_t *ciphertext);
bool
_mongocrypt_ciphertext_parse_unowned (_mongocrypt_buffer_t *in,
_mongocrypt_ciphertext_t *ciphertext,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_serialize_ciphertext (_mongocrypt_ciphertext_t *ciphertext,
_mongocrypt_buffer_t *out)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_ciphertext_serialize_associated_data (
_mongocrypt_ciphertext_t *ciphertext,
_mongocrypt_buffer_t *out) MONGOCRYPT_WARN_UNUSED_RESULT;
#endif /* MONGOCRYPT_CIPHERTEXT_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ciphertext.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ciphertext.c
similarity index 92%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ciphertext.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ciphertext.c
index a26cd1b0..baa2be7a 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ciphertext.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ciphertext.c
@@ -1,195 +1,195 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongocrypt-private.h"
#include "mongocrypt-ciphertext-private.h"
void
_mongocrypt_ciphertext_init (_mongocrypt_ciphertext_t *ciphertext)
{
memset (ciphertext, 0, sizeof (*ciphertext));
}
void
_mongocrypt_ciphertext_cleanup (_mongocrypt_ciphertext_t *ciphertext)
{
_mongocrypt_buffer_cleanup (&ciphertext->key_id);
_mongocrypt_buffer_cleanup (&ciphertext->data);
}
bool
_mongocrypt_ciphertext_parse_unowned (_mongocrypt_buffer_t *in,
_mongocrypt_ciphertext_t *ciphertext,
mongocrypt_status_t *status)
{
uint32_t offset;
/* From BSON Binary subtype 6 specification:
struct fle_blob {
uint8 fle_blob_subtype = (1 or 2);
uint8 key_uuid[16];
uint8 original_bson_type;
uint8 ciphertext[ciphertext_length];
}
*/
if (!ciphertext) {
CLIENT_ERR ("ciphertext cannot be null");
return false;
}
if (!in) {
CLIENT_ERR ("in parameter cannot be null");
return false;
}
if (!status) {
CLIENT_ERR ("status cannot be null");
return false;
}
offset = 0;
/* At a minimum, a ciphertext must be 19 bytes:
* fle_blob_subtype (1) +
* key_uuid (16) +
* original_bson_type (1) +
* ciphertext (> 0)
*/
if (in->len < 19) {
CLIENT_ERR ("malformed ciphertext, too small");
return false;
}
ciphertext->blob_subtype = in->data[0];
offset += 1;
/* TODO: merge new changes. */
if (ciphertext->blob_subtype != 1 && ciphertext->blob_subtype != 2) {
CLIENT_ERR ("malformed ciphertext, expected blob subtype of 1 or 2");
return false;
}
_mongocrypt_buffer_init (&ciphertext->key_id);
ciphertext->key_id.data = in->data + offset;
ciphertext->key_id.len = 16;
ciphertext->key_id.subtype = BSON_SUBTYPE_UUID;
offset += 16;
ciphertext->original_bson_type = in->data[offset];
offset += 1;
memset (&ciphertext->data, 0, sizeof (ciphertext->data));
ciphertext->data.data = in->data + offset;
ciphertext->data.len = in->len - offset;
return true;
}
bool
_mongocrypt_serialize_ciphertext (_mongocrypt_ciphertext_t *ciphertext,
_mongocrypt_buffer_t *out)
{
uint32_t offset;
/* From BSON Binary subtype 6 specification:
struct fle_blob {
uint8 fle_blob_subtype = (1 or 2);
uint8 key_uuid[16];
uint8 original_bson_type;
uint8 ciphertext[ciphertext_length];
}
*/
if (!ciphertext || !out) {
return false;
}
if (ciphertext->key_id.len != 16) {
return false;
}
_mongocrypt_buffer_init (out);
offset = 0;
out->len = 1 + ciphertext->key_id.len + 1 + ciphertext->data.len;
out->data = bson_malloc0 (out->len);
BSON_ASSERT (out->data);
out->owned = true;
out->data[offset] = ciphertext->blob_subtype;
offset += 1;
memcpy (out->data + offset, ciphertext->key_id.data, ciphertext->key_id.len);
offset += ciphertext->key_id.len;
out->data[offset] = ciphertext->original_bson_type;
offset += 1;
memcpy (out->data + offset, ciphertext->data.data, ciphertext->data.len);
return true;
}
/*
From "FLE and AEAD" doc:
A = Associated Data = fle_blob_subtype + key_uuid[16] + original_bson_type
*/
bool
_mongocrypt_ciphertext_serialize_associated_data (
_mongocrypt_ciphertext_t *ciphertext, _mongocrypt_buffer_t *out)
{
- int32_t bytes_written;
+ int32_t bytes_written = 0;
if (!out) {
return false;
}
_mongocrypt_buffer_init (out);
if (!ciphertext->original_bson_type) {
return false;
}
if (!_mongocrypt_buffer_is_uuid (&ciphertext->key_id)) {
return false;
}
- if (ciphertext->blob_subtype !=
- MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC &&
- ciphertext->blob_subtype != MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM) {
+ if ((ciphertext->blob_subtype !=
+ MC_SUBTYPE_FLE1DeterministicEncryptedValue) &&
+ (ciphertext->blob_subtype != MC_SUBTYPE_FLE1RandomEncryptedValue)) {
return false;
}
out->len = 1 + ciphertext->key_id.len + 1;
out->data = bson_malloc (out->len);
BSON_ASSERT (out->data);
-
out->owned = true;
- memcpy (out->data, &ciphertext->blob_subtype, 1);
- bytes_written = 1;
+
+ out->data[bytes_written++] = (uint8_t) ciphertext->blob_subtype;
memcpy (out->data + bytes_written,
ciphertext->key_id.data,
ciphertext->key_id.len);
bytes_written += ciphertext->key_id.len;
- memcpy (out->data + bytes_written, &ciphertext->original_bson_type, 1);
+ out->data[bytes_written++] = (uint8_t) ciphertext->original_bson_type;
+
return true;
}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-compat.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-compat.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-compat.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-compat.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-config.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-config.h
similarity index 90%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-config.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-config.h
index 11abe183..18fb619e 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-config.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-config.h
@@ -1,76 +1,87 @@
/*
* Copyright 2019-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_CONFIG_H
#define MONGOCRYPT_CONFIG_H
+/* clang-format off */
+
+/**
+ * @def MONGOCRYPT_VERSION
+ * @brief The version string describing libmongocrypt.
+ * Has the form x.y.z-<pre>+<date>+git<sha>.
+ */
+#define MONGOCRYPT_VERSION "1.5.0"
+
/*
* MONGOCRYPT_ENABLE_CRYPTO_CNG is set from configure to determine if we are
* compiled with Native Crypto support on Windows
*/
#define MONGOCRYPT_ENABLE_CRYPTO_CNG 0
#if MONGOCRYPT_ENABLE_CRYPTO_CNG != 1
# undef MONGOCRYPT_ENABLE_CRYPTO_CNG
#endif
/*
* MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are
* compiled with Native Crypto support on Darwin
*/
#define MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO 0
#if MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO != 1
# undef MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO
#endif
/*
* MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are
* compiled with OpenSSL/LibreSSL (which both use libcrypto) support.
*/
#define MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO 1
#define MONGOCRYPT_ENABLE_CRYPTO_OPENSSL 1
#if MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO != 1
# undef MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO
# undef MONGOCRYPT_ENABLE_CRYPTO_OPENSSL
#endif
/*
* MONGOCRYPT_ENABLE_CRYPTO is set from configure to determine if we are
* compiled with any crypto support.
*/
#define MONGOCRYPT_ENABLE_CRYPTO 1
#if MONGOCRYPT_ENABLE_CRYPTO != 1
# undef MONGOCRYPT_ENABLE_CRYPTO
#endif
/*
* MONGOCRYPT_ENABLE_TRACE is set from configure to determine if we are
* compiled with tracing support.
*/
#define MONGOCRYPT_ENABLE_TRACE 1
#if MONGOCRYPT_ENABLE_TRACE != 1
# undef MONGOCRYPT_ENABLE_TRACE
#endif
+/* clang-format on */
+
#endif /* MONGOCRYPT_CONFIG_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-config.h.in b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-config.h.in
similarity index 90%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-config.h.in
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-config.h.in
index 97a20901..af4fbf2c 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-config.h.in
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-config.h.in
@@ -1,76 +1,87 @@
/*
* Copyright 2019-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_CONFIG_H
#define MONGOCRYPT_CONFIG_H
+/* clang-format off */
+
+/**
+ * @def MONGOCRYPT_VERSION
+ * @brief The version string describing libmongocrypt.
+ * Has the form x.y.z-<pre>+<date>+git<sha>.
+ */
+#define MONGOCRYPT_VERSION "@MONGOCRYPT_BUILD_VERSION@"
+
/*
* MONGOCRYPT_ENABLE_CRYPTO_CNG is set from configure to determine if we are
* compiled with Native Crypto support on Windows
*/
#define MONGOCRYPT_ENABLE_CRYPTO_CNG @MONGOCRYPT_ENABLE_CRYPTO_CNG@
#if MONGOCRYPT_ENABLE_CRYPTO_CNG != 1
# undef MONGOCRYPT_ENABLE_CRYPTO_CNG
#endif
/*
* MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are
* compiled with Native Crypto support on Darwin
*/
#define MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO @MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO@
#if MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO != 1
# undef MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO
#endif
/*
* MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are
* compiled with OpenSSL/LibreSSL (which both use libcrypto) support.
*/
#define MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO @MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO@
#define MONGOCRYPT_ENABLE_CRYPTO_OPENSSL @MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO@
#if MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO != 1
# undef MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO
# undef MONGOCRYPT_ENABLE_CRYPTO_OPENSSL
#endif
/*
* MONGOCRYPT_ENABLE_CRYPTO is set from configure to determine if we are
* compiled with any crypto support.
*/
#define MONGOCRYPT_ENABLE_CRYPTO @MONGOCRYPT_ENABLE_CRYPTO@
#if MONGOCRYPT_ENABLE_CRYPTO != 1
# undef MONGOCRYPT_ENABLE_CRYPTO
#endif
/*
* MONGOCRYPT_ENABLE_TRACE is set from configure to determine if we are
* compiled with tracing support.
*/
#define MONGOCRYPT_ENABLE_TRACE @MONGOCRYPT_ENABLE_TRACE@
#if MONGOCRYPT_ENABLE_TRACE != 1
# undef MONGOCRYPT_ENABLE_TRACE
#endif
+/* clang-format on */
+
#endif /* MONGOCRYPT_CONFIG_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-crypto-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-crypto-private.h
similarity index 51%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-crypto-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-crypto-private.h
index 53a06023..4a82d9df 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-crypto-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-crypto-private.h
@@ -1,174 +1,297 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_CRYPTO_PRIVATE_H
#define MONGOCRYPT_CRYPTO_PRIVATE_H
#include "mongocrypt.h"
#include "mongocrypt-buffer-private.h"
#define MONGOCRYPT_KEY_LEN 96
#define MONGOCRYPT_IV_KEY_LEN 32
#define MONGOCRYPT_MAC_KEY_LEN 32
#define MONGOCRYPT_ENC_KEY_LEN 32
#define MONGOCRYPT_IV_LEN 16
#define MONGOCRYPT_HMAC_SHA512_LEN 64
#define MONGOCRYPT_HMAC_LEN 32
#define MONGOCRYPT_BLOCK_SIZE 16
-
+#define MONGOCRYPT_HMAC_SHA256_LEN 32
+#define MONGOCRYPT_TOKEN_KEY_LEN 32
typedef struct {
int hooks_enabled;
mongocrypt_crypto_fn aes_256_cbc_encrypt;
mongocrypt_crypto_fn aes_256_cbc_decrypt;
+ mongocrypt_crypto_fn aes_256_ctr_encrypt;
+ mongocrypt_crypto_fn aes_256_ctr_decrypt;
+ mongocrypt_crypto_fn aes_256_ecb_encrypt;
mongocrypt_random_fn random;
mongocrypt_hmac_fn hmac_sha_512;
mongocrypt_hmac_fn hmac_sha_256;
mongocrypt_hash_fn sha_256;
void *ctx;
} _mongocrypt_crypto_t;
uint32_t
_mongocrypt_calculate_ciphertext_len (uint32_t plaintext_len);
+/* _mongocrypt_fle2aead_calculate_ciphertext_len returns the required length of
+ * the ciphertext for _mongocrypt_fle2aead_do_encryption. */
+uint32_t
+_mongocrypt_fle2aead_calculate_ciphertext_len (uint32_t plaintext_len);
+
+/* _mongocrypt_fle2_calculate_ciphertext_len returns the required length of
+ * the ciphertext for _mongocrypt_fle2_do_encryption. */
+uint32_t
+_mongocrypt_fle2_calculate_ciphertext_len (uint32_t plaintext_len);
+
uint32_t
_mongocrypt_calculate_plaintext_len (uint32_t ciphertext_len);
+/* _mongocrypt_fle2aead_calculate_plaintext_len returns the required length of
+ * the plaintext for _mongocrypt_fle2aead_do_decryption. */
+uint32_t
+_mongocrypt_fle2aead_calculate_plaintext_len (uint32_t ciphertext_len);
+
+/* _mongocrypt_fle2_calculate_plaintext_len returns the required length of
+ * the plaintext for _mongocrypt_fle2_do_decryption. */
+uint32_t
+_mongocrypt_fle2_calculate_plaintext_len (uint32_t ciphertext_len);
+
bool
_mongocrypt_do_encryption (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *iv,
const _mongocrypt_buffer_t *associated_data,
const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *plaintext,
_mongocrypt_buffer_t *ciphertext,
uint32_t *bytes_written,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_do_decryption (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *associated_data,
const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *ciphertext,
_mongocrypt_buffer_t *plaintext,
uint32_t *bytes_written,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
+/* _mongocrypt_fle2aead_do_encryption does AEAD encryption.
+ * It follows the construction described in the [AEAD with
+ * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/)
+ *
+ * Note: The 96 byte key is split differently for FLE 2.
+ * - FLE 1 uses first 32 bytes as the mac key, and the second 32 bytes as the
+ * encryption key.
+ * - FLE 2 uses first 32 bytes as encryption key, and the
+ * second 32 bytes as the mac key.
+ * Note: Attempting to encrypt a 0 length plaintext is an error.
+ */
+bool
+_mongocrypt_fle2aead_do_encryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *iv,
+ const _mongocrypt_buffer_t *associated_data,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *plaintext,
+ _mongocrypt_buffer_t *ciphertext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
+bool
+_mongocrypt_fle2aead_do_decryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *associated_data,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *ciphertext,
+ _mongocrypt_buffer_t *plaintext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
+/* _mongocrypt_fle2_do_encryption does non-AEAD encryption.
+ * @key is expected to be only an encryption key of size MONGOCRYPT_ENC_KEY_LEN.
+ * Note: Attempting to encrypt a 0 length plaintext is an error.
+ */
+bool
+_mongocrypt_fle2_do_encryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *iv,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *plaintext,
+ _mongocrypt_buffer_t *ciphertext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
+/* _mongocrypt_fle2_do_decryption does non-AEAD decryption.
+ * @key is expected to be only an encryption key of size MONGOCRYPT_ENC_KEY_LEN.
+ */
+bool
+_mongocrypt_fle2_do_decryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *ciphertext,
+ _mongocrypt_buffer_t *plaintext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
bool
_mongocrypt_random (_mongocrypt_crypto_t *crypto,
_mongocrypt_buffer_t *out,
uint32_t count,
mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT;
+/* Generates a random number in the range [0, exclusive_upper_bound) in out. */
+bool
+_mongocrypt_random_uint64 (_mongocrypt_crypto_t *crypto,
+ uint64_t exclusive_upper_bound,
+ uint64_t *out,
+ mongocrypt_status_t *status)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
+/* Generates a random number in the range [0, exclusive_upper_bound) in out. */
+bool
+_mongocrypt_random_int64 (_mongocrypt_crypto_t *crypto,
+ int64_t exclusive_upper_bound,
+ int64_t *out,
+ mongocrypt_status_t *status)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
/* Returns 0 if equal, non-zero otherwise */
int
_mongocrypt_memequal (const void *const b1, const void *const b2, size_t len);
/*
* _mongocrypt_wrap_key encrypts a DEK with a KEK.
* kek is an input Key Encryption Key.
* dek is an input Data Encryption Key.
* encrypted_dek the result of encrypting dek with kek.
* encrypted_dek is always initialized.
* Returns true if no error occurred.
* Returns false and sets @status if an error occurred.
*/
bool
_mongocrypt_wrap_key (_mongocrypt_crypto_t *crypto,
_mongocrypt_buffer_t *kek,
_mongocrypt_buffer_t *dek,
_mongocrypt_buffer_t *encrypted_dek,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
/*
* _mongocrypt_unwrap_key decrypts an encrypted DEK with a KEK.
*
* kek is an input Key Encryption Key.
* encrypted_dek is an input encrypted Data Encryption Key.
* dek is the result of decrypting encrypted_dek with kek.
* dek is always initialized.
* Returns true if no error occurred.
* Returns false and sets @status if an error occurred.
*/
bool
_mongocrypt_unwrap_key (_mongocrypt_crypto_t *crypto,
_mongocrypt_buffer_t *kek,
_mongocrypt_buffer_t *encrypted_dek,
_mongocrypt_buffer_t *dek,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_calculate_deterministic_iv (
_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *plaintext,
const _mongocrypt_buffer_t *associated_data,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT;
+/*
+ * _mongocrypt_hmac_sha_256 computes the HMAC SHA-256.
+ *
+ * Uses the hmac_sha_256 hook set on @crypto if set, and otherwise
+ * calls the native implementation.
+ *
+ * @out must have length 32 bytes.
+ *
+ * Returns true if no error occurred.
+ * Returns false sets @status if an error occurred.
+ */
+bool
+_mongocrypt_hmac_sha_256 (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status);
+
/* Crypto implementations must implement these functions. */
/* This variable must be defined in implementation
files, and must be set to true when _crypto_init
is successful. */
extern bool _native_crypto_initialized;
void
_native_crypto_init ();
typedef struct {
const _mongocrypt_buffer_t *key;
const _mongocrypt_buffer_t *iv;
const _mongocrypt_buffer_t *in;
_mongocrypt_buffer_t *out;
uint32_t *bytes_written;
mongocrypt_status_t *status;
} aes_256_args_t;
bool
_native_crypto_aes_256_cbc_encrypt (aes_256_args_t args)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_native_crypto_aes_256_cbc_decrypt (aes_256_args_t args)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_native_crypto_hmac_sha_512 (const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *in,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_native_crypto_random (_mongocrypt_buffer_t *out,
uint32_t count,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_native_crypto_aes_256_ctr_encrypt (aes_256_args_t args)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_native_crypto_aes_256_ctr_decrypt (aes_256_args_t args)
MONGOCRYPT_WARN_UNUSED_RESULT;
+bool
+_native_crypto_hmac_sha_256 (const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
#endif /* MONGOCRYPT_CRYPTO_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-crypto.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-crypto.c
similarity index 55%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-crypto.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-crypto.c
index 5ac0bec7..a8c5a0d7 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-crypto.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-crypto.c
@@ -1,993 +1,1728 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Comments in this implementation refer to:
* [MCGREW] https://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-05
*/
#include <bson/bson.h>
#include "mongocrypt-binary-private.h"
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-crypto-private.h"
#include "mongocrypt-log-private.h"
#include "mongocrypt-private.h"
#include "mongocrypt-status-private.h"
#include <inttypes.h>
+/* This function uses ECB callback to simulate CTR encrypt and decrypt
+ *
+ * Note: the same function performs both encrypt and decrypt using same ECB
+ * encryption function
+ */
+
+static bool
+_crypto_aes_256_ctr_encrypt_decrypt_via_ecb (
+ void *ctx,
+ mongocrypt_crypto_fn aes_256_ecb_encrypt,
+ aes_256_args_t args,
+ mongocrypt_status_t *status)
+{
+ BSON_ASSERT (args.iv && args.iv->len);
+ BSON_ASSERT (args.out);
+
+ if (args.out->len < args.in->len) {
+ CLIENT_ERR ("output buffer too small");
+ return false;
+ }
+
+ _mongocrypt_buffer_t ctr, tmp;
+ mongocrypt_binary_t key_bin, out_bin, in_bin, ctr_bin, tmp_bin;
+ bool ret;
+
+ _mongocrypt_buffer_to_binary (args.key, &key_bin);
+ _mongocrypt_buffer_init (&ctr);
+ _mongocrypt_buffer_copy_to (args.iv, &ctr);
+ _mongocrypt_buffer_to_binary (&ctr, &ctr_bin);
+ _mongocrypt_buffer_to_binary (args.out, &out_bin);
+ _mongocrypt_buffer_to_binary (args.in, &in_bin);
+ _mongocrypt_buffer_init_size (&tmp, args.iv->len);
+ _mongocrypt_buffer_to_binary (&tmp, &tmp_bin);
+
+ for (uint32_t ptr = 0; ptr < args.in->len;) {
+ /* Encrypt value in CTR buffer */
+ uint32_t bytes_written = 0;
+ if (!aes_256_ecb_encrypt (
+ ctx, &key_bin, NULL, &ctr_bin, &tmp_bin, &bytes_written, status)) {
+ ret = false;
+ goto cleanup;
+ }
+
+ if (bytes_written != tmp_bin.len) {
+ CLIENT_ERR ("encryption hook returned unexpected length");
+ ret = false;
+ goto cleanup;
+ }
+
+ /* XOR resulting stream with original data */
+ for (uint32_t i = 0; i < bytes_written && ptr < args.in->len;
+ i++, ptr++) {
+ out_bin.data[ptr] = in_bin.data[ptr] ^ tmp_bin.data[i];
+ }
+
+ /* Increment value in CTR buffer */
+ uint32_t carry = 1;
+ for (int i = ctr_bin.len - 1; i >= 0 && carry != 0; --i) {
+ uint32_t bpp = carry + ctr_bin.data[i];
+ carry = bpp >> 8;
+ ctr_bin.data[i] = bpp & 0xFF;
+ }
+ }
+
+ if (args.bytes_written) {
+ *args.bytes_written = args.in->len;
+ }
+
+ ret = true;
+
+cleanup:
+ _mongocrypt_buffer_cleanup (&ctr);
+ _mongocrypt_buffer_cleanup (&tmp);
+ return ret;
+}
+
/* Crypto primitives. These either call the native built in crypto primitives or
* user supplied hooks. */
static bool
-_crypto_aes_256_cbc_encrypt (_mongocrypt_crypto_t *crypto,
- aes_256_args_t args)
+_crypto_aes_256_cbc_encrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
{
mongocrypt_status_t *status = args.status;
if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
CLIENT_ERR ("invalid encryption key length");
return false;
}
if (args.iv->len != MONGOCRYPT_IV_LEN) {
CLIENT_ERR ("invalid iv length");
return false;
}
if (crypto->hooks_enabled) {
mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
bool ret;
_mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
_mongocrypt_buffer_to_binary (args.iv, &iv_bin);
_mongocrypt_buffer_to_binary (args.out, &out_bin);
_mongocrypt_buffer_to_binary (args.in, &in_bin);
ret = crypto->aes_256_cbc_encrypt (crypto->ctx,
&enc_key_bin,
&iv_bin,
&in_bin,
&out_bin,
args.bytes_written,
status);
return ret;
}
return _native_crypto_aes_256_cbc_encrypt (args);
}
+static bool
+_crypto_aes_256_ctr_encrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
+{
+ mongocrypt_status_t *status = args.status;
+ if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
+ CLIENT_ERR ("invalid encryption key length");
+ return false;
+ }
+
+ if (args.iv->len != MONGOCRYPT_IV_LEN) {
+ CLIENT_ERR ("invalid iv length");
+ return false;
+ }
+
+ if (crypto->aes_256_ctr_encrypt) {
+ mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
+ bool ret;
+
+ _mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
+ _mongocrypt_buffer_to_binary (args.iv, &iv_bin);
+ _mongocrypt_buffer_to_binary (args.out, &out_bin);
+ _mongocrypt_buffer_to_binary (args.in, &in_bin);
+
+ ret = crypto->aes_256_ctr_encrypt (crypto->ctx,
+ &enc_key_bin,
+ &iv_bin,
+ &in_bin,
+ &out_bin,
+ args.bytes_written,
+ status);
+ return ret;
+ }
+
+ if (crypto->aes_256_ecb_encrypt) {
+ return _crypto_aes_256_ctr_encrypt_decrypt_via_ecb (
+ crypto->ctx, crypto->aes_256_ecb_encrypt, args, status);
+ }
+
+ return _native_crypto_aes_256_ctr_encrypt (args);
+}
static bool
-_crypto_aes_256_cbc_decrypt (_mongocrypt_crypto_t *crypto,
- aes_256_args_t args)
+_crypto_aes_256_cbc_decrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
{
mongocrypt_status_t *status = args.status;
if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
CLIENT_ERR ("invalid encryption key length");
return false;
}
if (crypto->hooks_enabled) {
mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
bool ret;
_mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
_mongocrypt_buffer_to_binary (args.iv, &iv_bin);
_mongocrypt_buffer_to_binary (args.out, &out_bin);
_mongocrypt_buffer_to_binary (args.in, &in_bin);
ret = crypto->aes_256_cbc_decrypt (crypto->ctx,
&enc_key_bin,
&iv_bin,
&in_bin,
&out_bin,
args.bytes_written,
status);
return ret;
}
return _native_crypto_aes_256_cbc_decrypt (args);
}
+static bool
+_crypto_aes_256_ctr_decrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
+{
+ mongocrypt_status_t *status = args.status;
+ if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
+ CLIENT_ERR ("invalid encryption key length");
+ return false;
+ }
+
+ if (crypto->aes_256_ctr_decrypt) {
+ mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
+ bool ret;
+
+ _mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
+ _mongocrypt_buffer_to_binary (args.iv, &iv_bin);
+ _mongocrypt_buffer_to_binary (args.out, &out_bin);
+ _mongocrypt_buffer_to_binary (args.in, &in_bin);
+
+ ret = crypto->aes_256_ctr_decrypt (crypto->ctx,
+ &enc_key_bin,
+ &iv_bin,
+ &in_bin,
+ &out_bin,
+ args.bytes_written,
+ status);
+ return ret;
+ }
+
+ if (crypto->aes_256_ecb_encrypt) {
+ return _crypto_aes_256_ctr_encrypt_decrypt_via_ecb (
+ crypto->ctx, crypto->aes_256_ecb_encrypt, args, status);
+ }
+
+ return _native_crypto_aes_256_ctr_decrypt (args);
+}
static bool
_crypto_hmac_sha_512 (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *hmac_key,
const _mongocrypt_buffer_t *in,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status)
{
if (hmac_key->len != MONGOCRYPT_MAC_KEY_LEN) {
CLIENT_ERR ("invalid hmac key length");
return false;
}
if (out->len != MONGOCRYPT_HMAC_SHA512_LEN) {
CLIENT_ERR ("out does not contain %d bytes", MONGOCRYPT_HMAC_SHA512_LEN);
return false;
}
if (crypto->hooks_enabled) {
mongocrypt_binary_t hmac_key_bin, out_bin, in_bin;
bool ret;
_mongocrypt_buffer_to_binary (hmac_key, &hmac_key_bin);
_mongocrypt_buffer_to_binary (out, &out_bin);
_mongocrypt_buffer_to_binary (in, &in_bin);
ret = crypto->hmac_sha_512 (
crypto->ctx, &hmac_key_bin, &in_bin, &out_bin, status);
return ret;
}
return _native_crypto_hmac_sha_512 (hmac_key, in, out, status);
}
static bool
_crypto_random (_mongocrypt_crypto_t *crypto,
_mongocrypt_buffer_t *out,
uint32_t count,
mongocrypt_status_t *status)
{
if (out->len != count) {
CLIENT_ERR ("out does not contain %u bytes", count);
return false;
}
if (crypto->hooks_enabled) {
mongocrypt_binary_t out_bin;
_mongocrypt_buffer_to_binary (out, &out_bin);
return crypto->random (crypto->ctx, &out_bin, count, status);
}
return _native_crypto_random (out, count, status);
}
/*
* Secure memcmp copied from the C driver.
*/
int
_mongocrypt_memequal (const void *const b1, const void *const b2, size_t len)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;
for (; len > 0; len--) {
ret |= *p1++ ^ *p2++;
}
return ret;
}
/* ----------------------------------------------------------------------------
*
* _mongocrypt_calculate_ciphertext_len --
*
* For a given plaintext length, return the length of the ciphertext.
* This includes IV and HMAC.
*
* To compute that I'm following section 2.3 in [MCGREW]:
* L = 16 * ( floor(M / 16) + 2)
* This formula includes space for the IV, but not the sha512 HMAC.
* Add 32 for the sha512 HMAC.
*
* Parameters:
* @plaintext_len then length of the plaintext.
*
* Returns:
* The calculated length of the ciphertext.
*
* ----------------------------------------------------------------------------
*/
uint32_t
_mongocrypt_calculate_ciphertext_len (uint32_t plaintext_len)
{
return 16 * ((plaintext_len / 16) + 2) + MONGOCRYPT_HMAC_LEN;
}
+uint32_t
+_mongocrypt_fle2aead_calculate_ciphertext_len (uint32_t plaintext_len)
+{
+ /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
+ return MONGOCRYPT_IV_LEN + plaintext_len + MONGOCRYPT_HMAC_LEN;
+}
+
+uint32_t
+_mongocrypt_fle2_calculate_ciphertext_len (uint32_t plaintext_len)
+{
+ /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
+ return MONGOCRYPT_IV_LEN + plaintext_len;
+}
+
/* ----------------------------------------------------------------------------
*
* _mongocrypt_calculate_plaintext_len --
*
* For a given ciphertext length, return the length of the plaintext.
* This excludes the IV and HMAC, but includes the padding.
*
* Parameters:
* @ciphertext_len then length of the ciphertext.
*
* Returns:
* The calculated length of the plaintext.
*
* ----------------------------------------------------------------------------
*/
uint32_t
_mongocrypt_calculate_plaintext_len (uint32_t ciphertext_len)
{
BSON_ASSERT (ciphertext_len >= MONGOCRYPT_HMAC_LEN + MONGOCRYPT_IV_LEN +
MONGOCRYPT_BLOCK_SIZE);
return ciphertext_len - (MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
}
+uint32_t
+_mongocrypt_fle2aead_calculate_plaintext_len (uint32_t ciphertext_len)
+{
+ /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
+ BSON_ASSERT (ciphertext_len >= MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
+ return ciphertext_len - MONGOCRYPT_IV_LEN - MONGOCRYPT_HMAC_LEN;
+}
+
+uint32_t
+_mongocrypt_fle2_calculate_plaintext_len (uint32_t ciphertext_len)
+{
+ /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
+ BSON_ASSERT (ciphertext_len >= MONGOCRYPT_IV_LEN);
+ return ciphertext_len - MONGOCRYPT_IV_LEN;
+}
/* ----------------------------------------------------------------------------
*
* _aes256_cbc_encrypt --
*
* Encrypts using AES256 CBC using a secret key and a known IV.
*
* Parameters:
* @iv a 16 byte IV.
* @enc_key a 32 byte key.
* @plaintext the plaintext to encrypt.
* @ciphertext the resulting ciphertext.
* @bytes_written a location for the resulting number of bytes written into
* ciphertext->data.
* @status set on error.
*
* Returns:
* True on success. On error, sets @status and returns false.
*
* Preconditions:
* 1. ciphertext->data has been pre-allocated with enough space for the
* resulting ciphertext.
*
* Postconditions:
* 1. bytes_written is set to the length of the written ciphertext. This
* is the same as _mongocrypt_calculate_ciphertext_len (plaintext->len).
*
* ----------------------------------------------------------------------------
*/
static bool
_encrypt_step (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *iv,
const _mongocrypt_buffer_t *enc_key,
const _mongocrypt_buffer_t *plaintext,
_mongocrypt_buffer_t *ciphertext,
uint32_t *bytes_written,
mongocrypt_status_t *status)
{
uint32_t unaligned;
uint32_t padding_byte;
_mongocrypt_buffer_t intermediates[2];
_mongocrypt_buffer_t to_encrypt;
uint8_t final_block_storage[MONGOCRYPT_BLOCK_SIZE];
bool ret = false;
_mongocrypt_buffer_init (&to_encrypt);
BSON_ASSERT (bytes_written);
*bytes_written = 0;
if (MONGOCRYPT_IV_LEN != iv->len) {
CLIENT_ERR ("IV should have length %d, but has length %d",
MONGOCRYPT_IV_LEN,
iv->len);
goto done;
}
if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) {
CLIENT_ERR ("Encryption key should have length %d, but has length %d",
MONGOCRYPT_ENC_KEY_LEN,
enc_key->len);
goto done;
}
/* calculate how many extra bytes there are after a block boundary */
unaligned = plaintext->len % MONGOCRYPT_BLOCK_SIZE;
/* Some crypto providers disallow variable length inputs, and require
* the input to be a multiple of the block size. So add everything up
* to but excluding the last block if not block aligned, then add
* the last block with padding. */
_mongocrypt_buffer_init (&intermediates[0]);
_mongocrypt_buffer_init (&intermediates[1]);
intermediates[0].data = (uint8_t *) plaintext->data;
intermediates[0].len = plaintext->len - unaligned;
intermediates[1].data = final_block_storage;
intermediates[1].len = sizeof (final_block_storage);
/* [MCGREW]: "Prior to CBC encryption, the plaintext P is padded by appending
* a padding string PS to that data, to ensure that len(P || PS) is a
* multiple of 128". This is also known as PKCS #7 padding. */
if (unaligned) {
/* Copy the unaligned bytes. */
memcpy (intermediates[1].data,
plaintext->data + (plaintext->len - unaligned),
unaligned);
/* Fill the rest with the padding byte. */
padding_byte = MONGOCRYPT_BLOCK_SIZE - unaligned;
memset (intermediates[1].data + unaligned, padding_byte, padding_byte);
} else {
/* Fill the rest with the padding byte. */
padding_byte = MONGOCRYPT_BLOCK_SIZE;
memset (intermediates[1].data, padding_byte, padding_byte);
}
if (!_mongocrypt_buffer_concat (&to_encrypt, intermediates, 2)) {
CLIENT_ERR ("failed to allocate buffer");
goto done;
}
if (!_crypto_aes_256_cbc_encrypt (
crypto,
(aes_256_args_t){.key = enc_key,
.iv = iv,
.in = &to_encrypt,
.out = ciphertext,
.bytes_written = bytes_written,
.status = status})) {
goto done;
}
if (*bytes_written % MONGOCRYPT_BLOCK_SIZE != 0) {
CLIENT_ERR ("encryption failure, wrote %d bytes, not a multiple of %d",
*bytes_written,
MONGOCRYPT_BLOCK_SIZE);
goto done;
}
ret = true;
done:
_mongocrypt_buffer_cleanup (&to_encrypt);
return ret;
}
/* ----------------------------------------------------------------------------
*
* _hmac_sha512 --
*
* Compute the SHA512 HMAC with a secret key.
*
* Parameters:
* @mac_key a 32 byte key.
* @associated_data associated data to add into the HMAC. This may be
* an empty buffer.
* @ciphertext the ciphertext to add into the HMAC.
* @out a location for the resulting HMAC tag.
* @status set on error.
*
* Returns:
* True on success. On error, sets @status and returns false.
*
* Preconditions:
* 1. out->data has been pre-allocated with at least 64 bytes.
*
* Postconditions:
* 1. out->data will have a 64 byte tag appended.
*
* ----------------------------------------------------------------------------
*/
static bool
_hmac_step (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *mac_key,
const _mongocrypt_buffer_t *associated_data,
const _mongocrypt_buffer_t *ciphertext,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status)
{
_mongocrypt_buffer_t intermediates[3];
_mongocrypt_buffer_t to_hmac;
uint64_t associated_data_len_be;
uint8_t tag_storage[64];
_mongocrypt_buffer_t tag;
bool ret = false;
_mongocrypt_buffer_init (&to_hmac);
if (MONGOCRYPT_MAC_KEY_LEN != mac_key->len) {
CLIENT_ERR ("HMAC key wrong length: %d", mac_key->len);
goto done;
}
if (out->len != MONGOCRYPT_HMAC_LEN) {
CLIENT_ERR ("out wrong length: %d", out->len);
goto done;
}
/* [MCGREW]:
* """
* 4. The octet string AL is equal to the number of bits in A expressed as a
* 64-bit unsigned integer in network byte order.
* 5. A message authentication tag T is computed by applying HMAC [RFC2104]
* to the following data, in order:
* the associated data A,
* the ciphertext S computed in the previous step, and
* the octet string AL defined above.
* """
*/
/* Add associated data. */
_mongocrypt_buffer_init (&intermediates[0]);
_mongocrypt_buffer_init (&intermediates[1]);
_mongocrypt_buffer_init (&intermediates[2]);
intermediates[0].data = associated_data->data;
intermediates[0].len = associated_data->len;
/* Add ciphertext. */
intermediates[1].data = ciphertext->data;
intermediates[1].len = ciphertext->len;
/* Add associated data length in bits. */
associated_data_len_be = 8 * (uint64_t) associated_data->len;
associated_data_len_be = BSON_UINT64_TO_BE (associated_data_len_be);
intermediates[2].data = (uint8_t *) &associated_data_len_be;
intermediates[2].len = sizeof (uint64_t);
tag.data = tag_storage;
tag.len = sizeof (tag_storage);
if (!_mongocrypt_buffer_concat (&to_hmac, intermediates, 3)) {
CLIENT_ERR ("failed to allocate buffer");
goto done;
}
if (!_crypto_hmac_sha_512 (crypto, mac_key, &to_hmac, &tag, status)) {
goto done;
}
/* [MCGREW 2.7] "The HMAC-SHA-512 value is truncated to T_LEN=32 octets" */
memcpy (out->data, tag.data, MONGOCRYPT_HMAC_LEN);
ret = true;
done:
_mongocrypt_buffer_cleanup (&to_hmac);
return ret;
}
/* ----------------------------------------------------------------------------
*
* _mongocrypt_do_encryption --
*
* Defer encryption to whichever crypto library libmongocrypt is using.
*
* Parameters:
* @iv a 16 byte IV.
* @associated_data associated data for the HMAC. May be NULL.
* @key a 96 byte key.
* @plaintext the plaintext to encrypt.
* @ciphertext a location for the resulting ciphertext and HMAC tag.
* @bytes_written a location for the resulting bytes written.
* @status set on error.
*
* Returns:
* True on success. On error, sets @status and returns false.
*
* Preconditions:
* 1. ciphertext->data has been pre-allocated with enough space for the
* resulting ciphertext. Use _mongocrypt_calculate_ciphertext_len.
*
* Postconditions:
* 1. bytes_written is set to the length of the written ciphertext. This
* is the same as _mongocrypt_calculate_ciphertext_len (plaintext->len).
*
* ----------------------------------------------------------------------------
*/
bool
_mongocrypt_do_encryption (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *iv,
const _mongocrypt_buffer_t *associated_data,
const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *plaintext,
_mongocrypt_buffer_t *ciphertext,
uint32_t *bytes_written,
mongocrypt_status_t *status)
{
_mongocrypt_buffer_t mac_key = {0}, enc_key = {0}, intermediate = {0},
intermediate_hmac = {0}, empty_buffer = {0};
uint32_t intermediate_bytes_written = 0;
memset (ciphertext->data, 0, ciphertext->len);
BSON_ASSERT (iv);
BSON_ASSERT (key);
BSON_ASSERT (plaintext);
BSON_ASSERT (ciphertext);
if (ciphertext->len !=
_mongocrypt_calculate_ciphertext_len (plaintext->len)) {
CLIENT_ERR ("output ciphertext should have been allocated with %d bytes",
_mongocrypt_calculate_ciphertext_len (plaintext->len));
return false;
}
*bytes_written = 0;
if (MONGOCRYPT_IV_LEN != iv->len) {
CLIENT_ERR ("IV should have length %d, but has length %d",
MONGOCRYPT_IV_LEN,
iv->len);
return false;
}
if (MONGOCRYPT_KEY_LEN != key->len) {
CLIENT_ERR ("key should have length %d, but has length %d",
MONGOCRYPT_KEY_LEN,
key->len);
return false;
}
intermediate.len = ciphertext->len;
intermediate.data = ciphertext->data;
/* [MCGREW]: Step 1. "MAC_KEY consists of the initial MAC_KEY_LEN octets of
* K, in order. ENC_KEY consists of the final ENC_KEY_LEN octets of K, in
* order." */
mac_key.data = (uint8_t *) key->data;
mac_key.len = MONGOCRYPT_MAC_KEY_LEN;
enc_key.data = (uint8_t *) key->data + MONGOCRYPT_MAC_KEY_LEN;
enc_key.len = MONGOCRYPT_ENC_KEY_LEN;
/* Prepend the IV. */
memcpy (intermediate.data, iv->data, iv->len);
intermediate.data += iv->len;
intermediate.len -= iv->len;
*bytes_written += iv->len;
/* [MCGREW]: Steps 2 & 3. */
if (!_encrypt_step (crypto,
iv,
&enc_key,
plaintext,
&intermediate,
&intermediate_bytes_written,
status)) {
return false;
}
*bytes_written += intermediate_bytes_written;
/* Append the HMAC tag. */
intermediate_hmac.data = ciphertext->data + *bytes_written;
intermediate_hmac.len = MONGOCRYPT_HMAC_LEN;
intermediate.data = ciphertext->data;
intermediate.len = *bytes_written;
/* [MCGREW]: Steps 4 & 5, compute the HMAC. */
if (!_hmac_step (crypto,
&mac_key,
associated_data ? associated_data : &empty_buffer,
&intermediate,
&intermediate_hmac,
status)) {
return false;
}
*bytes_written += MONGOCRYPT_HMAC_LEN;
return true;
}
/* ----------------------------------------------------------------------------
*
* _aes256_cbc_decrypt --
*
* Decrypts using AES256 CBC using a secret key and a known IV.
*
* Parameters:
* @enc_key a 32 byte key.
* @ciphertext the ciphertext to decrypt.
* @plaintext the resulting plaintext.
* @bytes_written a location for the resulting number of bytes written into
* plaintext->data.
* @status set on error.
*
* Returns:
* True on success. On error, sets @status and returns false.
*
* Preconditions:
* 1. plaintext->data has been pre-allocated with enough space for the
* resulting plaintext.
*
* Postconditions:
* 1. bytes_written is set to the length of the written plaintext, excluding
* padding. This may be less than
* _mongocrypt_calculate_plaintext_len (ciphertext->len).
*
* ----------------------------------------------------------------------------
*/
static bool
_decrypt_step (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *iv,
const _mongocrypt_buffer_t *enc_key,
const _mongocrypt_buffer_t *ciphertext,
_mongocrypt_buffer_t *plaintext,
uint32_t *bytes_written,
mongocrypt_status_t *status)
{
uint8_t padding_byte;
BSON_ASSERT (bytes_written);
*bytes_written = 0;
if (MONGOCRYPT_IV_LEN != iv->len) {
CLIENT_ERR ("IV should have length %d, but has length %d",
MONGOCRYPT_IV_LEN,
iv->len);
return false;
}
if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) {
CLIENT_ERR ("encryption key should have length %d, but has length %d",
MONGOCRYPT_ENC_KEY_LEN,
enc_key->len);
return false;
}
if (ciphertext->len % MONGOCRYPT_BLOCK_SIZE > 0) {
CLIENT_ERR ("error, ciphertext length is not a multiple of block size");
return false;
}
if (!_crypto_aes_256_cbc_decrypt (
crypto,
(aes_256_args_t){.iv = iv,
.key = enc_key,
.in = ciphertext,
.out = plaintext,
.bytes_written = bytes_written,
.status = status})) {
return false;
}
padding_byte = plaintext->data[*bytes_written - 1];
if (padding_byte > 16) {
CLIENT_ERR ("error, ciphertext malformed padding");
return false;
}
*bytes_written -= padding_byte;
return true;
}
/* ----------------------------------------------------------------------------
*
* _mongocrypt_do_decryption --
*
* Defer decryption to whichever crypto library libmongocrypt is using.
*
* Parameters:
* @associated_data associated data for the HMAC. May be NULL.
* @key a 96 byte key.
* @ciphertext the ciphertext to decrypt. This contains the IV prepended.
* @plaintext a location for the resulting plaintext.
* @bytes_written a location for the resulting bytes written.
* @status set on error.
*
* Returns:
* True on success. On error, sets @status and returns false.
*
* Preconditions:
* 1. plaintext->data has been pre-allocated with enough space for the
* resulting plaintext and padding. See _mongocrypt_calculate_plaintext_len.
*
* Postconditions:
* 1. bytes_written is set to the length of the written plaintext, excluding
* padding. This may be less than
* _mongocrypt_calculate_plaintext_len (ciphertext->len).
*
* ----------------------------------------------------------------------------
*/
bool
_mongocrypt_do_decryption (_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *associated_data,
const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *ciphertext,
_mongocrypt_buffer_t *plaintext,
uint32_t *bytes_written,
mongocrypt_status_t *status)
{
bool ret = false;
_mongocrypt_buffer_t mac_key = {0}, enc_key = {0}, intermediate = {0},
hmac_tag = {0}, iv = {0}, empty_buffer = {0};
uint8_t hmac_tag_storage[MONGOCRYPT_HMAC_LEN];
BSON_ASSERT (key);
BSON_ASSERT (ciphertext);
BSON_ASSERT (plaintext);
BSON_ASSERT (bytes_written);
BSON_ASSERT (status);
if (plaintext->len !=
_mongocrypt_calculate_plaintext_len (ciphertext->len)) {
CLIENT_ERR ("output plaintext should have been allocated with %d bytes, "
"but has: %d",
_mongocrypt_calculate_plaintext_len (ciphertext->len),
plaintext->len);
return false;
}
if (MONGOCRYPT_KEY_LEN != key->len) {
CLIENT_ERR ("key should have length %d, but has length %d",
MONGOCRYPT_KEY_LEN,
key->len);
return false;
}
if (ciphertext->len <
MONGOCRYPT_HMAC_LEN + MONGOCRYPT_IV_LEN + MONGOCRYPT_BLOCK_SIZE) {
CLIENT_ERR ("corrupt ciphertext - must be > %d bytes",
MONGOCRYPT_HMAC_LEN + MONGOCRYPT_IV_LEN +
MONGOCRYPT_BLOCK_SIZE);
goto done;
}
mac_key.data = (uint8_t *) key->data;
mac_key.len = MONGOCRYPT_MAC_KEY_LEN;
enc_key.data = (uint8_t *) key->data + MONGOCRYPT_MAC_KEY_LEN;
enc_key.len = MONGOCRYPT_ENC_KEY_LEN;
iv.data = ciphertext->data;
iv.len = MONGOCRYPT_IV_LEN;
intermediate.data = (uint8_t *) ciphertext->data;
intermediate.len = ciphertext->len - MONGOCRYPT_HMAC_LEN;
hmac_tag.data = hmac_tag_storage;
hmac_tag.len = MONGOCRYPT_HMAC_LEN;
/* [MCGREW 2.2]: Step 3: HMAC check. */
if (!_hmac_step (crypto,
&mac_key,
associated_data ? associated_data : &empty_buffer,
&intermediate,
&hmac_tag,
status)) {
goto done;
}
/* [MCGREW] "using a comparison routine that takes constant time". */
if (0 != _mongocrypt_memequal (hmac_tag.data,
ciphertext->data +
(ciphertext->len - MONGOCRYPT_HMAC_LEN),
MONGOCRYPT_HMAC_LEN)) {
CLIENT_ERR ("HMAC validation failure");
goto done;
}
/* Decrypt data excluding IV + HMAC. */
intermediate.data = (uint8_t *) ciphertext->data + MONGOCRYPT_IV_LEN;
intermediate.len =
ciphertext->len - (MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
if (!_decrypt_step (crypto,
&iv,
&enc_key,
&intermediate,
plaintext,
bytes_written,
status)) {
goto done;
}
ret = true;
done:
return ret;
}
/* ----------------------------------------------------------------------------
*
* _mongocrypt_random --
*
* Generates a string of random bytes.
*
* Parameters:
* @out an output buffer that has been pre-allocated.
* @status set on error.
* @count the size of the random string in bytes.
*
* Returns:
* True on success. On error, sets @status and returns false.
*
* Preconditions:
* 1. out has been pre-allocated with at least 'count' bytes of space.
*
* ----------------------------------------------------------------------------
*/
bool
_mongocrypt_random (_mongocrypt_crypto_t *crypto,
_mongocrypt_buffer_t *out,
uint32_t count,
mongocrypt_status_t *status)
{
BSON_ASSERT (out);
BSON_ASSERT (status);
if (count != out->len) {
CLIENT_ERR (
"out should have length %d, but has length %d", count, out->len);
return false;
}
return _crypto_random (crypto, out, count, status);
}
/* ----------------------------------------------------------------------------
*
* _mongocrypt_calculate_deterministic_iv --
*
* Compute the IV for deterministic encryption from the plaintext and IV
* key by using HMAC function.
*
* Parameters:
* @key the 96 byte key. The last 32 represent the IV key.
* @plaintext the plaintext to be encrypted.
* @associated_data associated data to include in the HMAC.
* @out an output buffer that has been pre-allocated.
* @status set on error.
*
* Returns:
* True on success. On error, sets @status and returns false.
*
* Preconditions:
* 1. out has been pre-allocated with at least MONGOCRYPT_IV_LEN bytes.
*
* ----------------------------------------------------------------------------
*/
bool
_mongocrypt_calculate_deterministic_iv (
_mongocrypt_crypto_t *crypto,
const _mongocrypt_buffer_t *key,
const _mongocrypt_buffer_t *plaintext,
const _mongocrypt_buffer_t *associated_data,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status)
{
_mongocrypt_buffer_t intermediates[3];
_mongocrypt_buffer_t to_hmac;
_mongocrypt_buffer_t iv_key;
uint64_t associated_data_len_be;
uint8_t tag_storage[64];
_mongocrypt_buffer_t tag;
bool ret = false;
_mongocrypt_buffer_init (&to_hmac);
BSON_ASSERT (key);
BSON_ASSERT (plaintext);
BSON_ASSERT (associated_data);
BSON_ASSERT (out);
BSON_ASSERT (status);
if (MONGOCRYPT_KEY_LEN != key->len) {
CLIENT_ERR ("key should have length %d, but has length %d\n",
MONGOCRYPT_KEY_LEN,
key->len);
goto done;
}
if (MONGOCRYPT_IV_LEN != out->len) {
CLIENT_ERR ("out should have length %d, but has length %d\n",
MONGOCRYPT_IV_LEN,
out->len);
goto done;
}
_mongocrypt_buffer_init (&iv_key);
iv_key.data = key->data + MONGOCRYPT_ENC_KEY_LEN + MONGOCRYPT_MAC_KEY_LEN;
iv_key.len = MONGOCRYPT_IV_KEY_LEN;
_mongocrypt_buffer_init (&intermediates[0]);
_mongocrypt_buffer_init (&intermediates[1]);
_mongocrypt_buffer_init (&intermediates[2]);
/* Add associated data. */
intermediates[0].data = associated_data->data;
intermediates[0].len = associated_data->len;
/* Add associated data length in bits. */
associated_data_len_be = 8 * (uint64_t) associated_data->len;
associated_data_len_be = BSON_UINT64_TO_BE (associated_data_len_be);
intermediates[1].data = (uint8_t *) &associated_data_len_be;
intermediates[1].len = sizeof (uint64_t);
/* Add plaintext. */
intermediates[2].data = (uint8_t *) plaintext->data;
intermediates[2].len = plaintext->len;
tag.data = tag_storage;
tag.len = sizeof (tag_storage);
if (!_mongocrypt_buffer_concat (&to_hmac, intermediates, 3)) {
CLIENT_ERR ("failed to allocate buffer");
goto done;
}
if (!_crypto_hmac_sha_512 (crypto, &iv_key, &to_hmac, &tag, status)) {
goto done;
}
/* Truncate to IV length */
memcpy (out->data, tag.data, MONGOCRYPT_IV_LEN);
ret = true;
done:
_mongocrypt_buffer_cleanup (&to_hmac);
return ret;
}
bool
_mongocrypt_wrap_key (_mongocrypt_crypto_t *crypto,
_mongocrypt_buffer_t *kek,
_mongocrypt_buffer_t *dek,
_mongocrypt_buffer_t *encrypted_dek,
mongocrypt_status_t *status)
{
uint32_t bytes_written;
_mongocrypt_buffer_t iv = {0};
bool ret = false;
_mongocrypt_buffer_init (encrypted_dek);
if (dek->len != MONGOCRYPT_KEY_LEN) {
CLIENT_ERR ("data encryption key is incorrect length, expected: %" PRIu32
", got: %" PRIu32,
MONGOCRYPT_KEY_LEN,
dek->len);
goto done;
}
_mongocrypt_buffer_resize (encrypted_dek,
_mongocrypt_calculate_ciphertext_len (dek->len));
_mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
if (!_mongocrypt_random (crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
goto done;
}
if (!_mongocrypt_do_encryption (crypto,
&iv,
NULL /* associated data. */,
kek,
dek,
encrypted_dek,
&bytes_written,
status)) {
goto done;
}
ret = true;
done:
_mongocrypt_buffer_cleanup (&iv);
return ret;
}
bool
_mongocrypt_unwrap_key (_mongocrypt_crypto_t *crypto,
_mongocrypt_buffer_t *kek,
_mongocrypt_buffer_t *encrypted_dek,
_mongocrypt_buffer_t *dek,
mongocrypt_status_t *status)
{
uint32_t bytes_written;
_mongocrypt_buffer_init (dek);
_mongocrypt_buffer_resize (
dek, _mongocrypt_calculate_plaintext_len (encrypted_dek->len));
if (!_mongocrypt_do_decryption (crypto,
NULL /* associated data. */,
kek,
encrypted_dek,
dek,
&bytes_written,
status)) {
return false;
}
dek->len = bytes_written;
if (dek->len != MONGOCRYPT_KEY_LEN) {
CLIENT_ERR ("decrypted key is incorrect length, expected: %" PRIu32
", got: %" PRIu32,
MONGOCRYPT_KEY_LEN,
dek->len);
return false;
}
return true;
}
+
+bool
+_mongocrypt_hmac_sha_256 (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ if (key->len != MONGOCRYPT_MAC_KEY_LEN) {
+ CLIENT_ERR ("invalid hmac_sha_256 key length. Got %" PRIu32
+ ", expected: %" PRIu32,
+ key->len,
+ MONGOCRYPT_MAC_KEY_LEN);
+ return false;
+ }
+
+ if (crypto->hooks_enabled) {
+ mongocrypt_binary_t key_bin, out_bin, in_bin;
+ _mongocrypt_buffer_to_binary (key, &key_bin);
+ _mongocrypt_buffer_to_binary (out, &out_bin);
+ _mongocrypt_buffer_to_binary (in, &in_bin);
+
+ return crypto->hmac_sha_256 (
+ crypto->ctx, &key_bin, &in_bin, &out_bin, status);
+ }
+ return _native_crypto_hmac_sha_256 (key, in, out, status);
+}
+
+bool
+_mongocrypt_fle2aead_do_encryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *iv,
+ const _mongocrypt_buffer_t *associated_data,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *plaintext,
+ _mongocrypt_buffer_t *ciphertext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+{
+ BSON_ASSERT_PARAM (crypto);
+ BSON_ASSERT_PARAM (iv);
+ BSON_ASSERT_PARAM (associated_data);
+ BSON_ASSERT_PARAM (key);
+ BSON_ASSERT_PARAM (plaintext);
+ BSON_ASSERT_PARAM (ciphertext);
+ BSON_ASSERT_PARAM (bytes_written);
+ BSON_ASSERT_PARAM (status);
+
+ if (ciphertext->len !=
+ _mongocrypt_fle2aead_calculate_ciphertext_len (plaintext->len)) {
+ CLIENT_ERR (
+ "output ciphertext must be allocated with %" PRIu32 " bytes",
+ _mongocrypt_fle2aead_calculate_ciphertext_len (plaintext->len));
+ return false;
+ }
+
+ if (plaintext->len <= 0) {
+ CLIENT_ERR ("input plaintext too small. Must be more than zero bytes.");
+ return false;
+ }
+
+ if (MONGOCRYPT_IV_LEN != iv->len) {
+ CLIENT_ERR ("IV must be length %d, but is length %" PRIu32,
+ MONGOCRYPT_IV_LEN,
+ iv->len);
+ return false;
+ }
+ if (MONGOCRYPT_KEY_LEN != key->len) {
+ CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
+ MONGOCRYPT_KEY_LEN,
+ key->len);
+ return false;
+ }
+
+ memset (ciphertext->data, 0, ciphertext->len);
+ *bytes_written = 0;
+
+ /* Declare variable names matching [AEAD with
+ * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
+ */
+ /* M is the input plaintext. */
+ _mongocrypt_buffer_t M;
+ if (!_mongocrypt_buffer_from_subrange (&M, plaintext, 0, plaintext->len)) {
+ CLIENT_ERR ("unable to create M view from plaintext");
+ return false;
+ }
+ /* Ke is 32 byte Key for encryption. */
+ _mongocrypt_buffer_t Ke;
+ if (!_mongocrypt_buffer_from_subrange (
+ &Ke, key, 0, MONGOCRYPT_ENC_KEY_LEN)) {
+ CLIENT_ERR ("unable to create Ke view from key");
+ return false;
+ }
+ /* IV is 16 byte IV. */
+ _mongocrypt_buffer_t IV;
+ if (!_mongocrypt_buffer_from_subrange (&IV, iv, 0, iv->len)) {
+ CLIENT_ERR ("unable to create IV view from iv");
+ return false;
+ }
+ /* Km is 32 byte Key for HMAC. */
+ _mongocrypt_buffer_t Km;
+ if (!_mongocrypt_buffer_from_subrange (
+ &Km, key, MONGOCRYPT_ENC_KEY_LEN, MONGOCRYPT_MAC_KEY_LEN)) {
+ CLIENT_ERR ("unable to create Km view from key");
+ return false;
+ }
+ /* AD is Associated Data. */
+ _mongocrypt_buffer_t AD;
+ if (!_mongocrypt_buffer_from_subrange (
+ &AD, associated_data, 0, associated_data->len)) {
+ CLIENT_ERR ("unable to create AD view from associated_data");
+ return false;
+ }
+ /* C is the output ciphertext. */
+ _mongocrypt_buffer_t C;
+ if (!_mongocrypt_buffer_from_subrange (&C, ciphertext, 0, ciphertext->len)) {
+ CLIENT_ERR ("unable to create C view from ciphertext");
+ return false;
+ }
+ /* S is the output of the symmetric cipher. It is appended after IV in C. */
+ _mongocrypt_buffer_t S;
+ if (!_mongocrypt_buffer_from_subrange (&S,
+ &C,
+ MONGOCRYPT_IV_LEN,
+ C.len - MONGOCRYPT_IV_LEN -
+ MONGOCRYPT_HMAC_LEN)) {
+ CLIENT_ERR ("unable to create S view from C");
+ return false;
+ }
+ uint32_t S_bytes_written = 0;
+ /* T is the output of the HMAC tag. It is appended after S in C. */
+ _mongocrypt_buffer_t T;
+ if (!_mongocrypt_buffer_from_subrange (
+ &T, &C, C.len - MONGOCRYPT_HMAC_LEN, MONGOCRYPT_HMAC_LEN)) {
+ CLIENT_ERR ("unable to create T view from C");
+ return false;
+ }
+
+ /* Compute S = AES-CTR.Enc(Ke, IV, M). */
+ if (!_crypto_aes_256_ctr_encrypt (
+ crypto,
+ (aes_256_args_t){.key = &Ke,
+ .iv = &IV,
+ .in = &M,
+ .out = &S,
+ .bytes_written = &S_bytes_written,
+ .status = status})) {
+ return false;
+ }
+
+ /* Compute T = HMAC-SHA256(Km, AD || IV || S). */
+ {
+ _mongocrypt_buffer_t hmac_inputs[] = {AD, IV, S};
+ _mongocrypt_buffer_t hmac_input = {0};
+ _mongocrypt_buffer_concat (&hmac_input, hmac_inputs, 3);
+ if (!_mongocrypt_hmac_sha_256 (crypto, &Km, &hmac_input, &T, status)) {
+ _mongocrypt_buffer_cleanup (&hmac_input);
+ return false;
+ }
+ _mongocrypt_buffer_cleanup (&hmac_input);
+ }
+
+ /* Output C = IV || S || T. */
+ /* S and T are already in C. Prepend IV. */
+ memmove (C.data, IV.data, MONGOCRYPT_IV_LEN);
+
+ *bytes_written = MONGOCRYPT_IV_LEN + S_bytes_written + MONGOCRYPT_HMAC_LEN;
+ return true;
+}
+
+bool
+_mongocrypt_fle2aead_do_decryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *associated_data,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *ciphertext,
+ _mongocrypt_buffer_t *plaintext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+{
+ BSON_ASSERT_PARAM (crypto);
+ BSON_ASSERT_PARAM (associated_data);
+ BSON_ASSERT_PARAM (key);
+ BSON_ASSERT_PARAM (ciphertext);
+ BSON_ASSERT_PARAM (plaintext);
+ BSON_ASSERT_PARAM (bytes_written);
+ BSON_ASSERT_PARAM (status);
+
+ if (ciphertext->len <= MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN) {
+ CLIENT_ERR ("input ciphertext too small. Must be more than %" PRIu32
+ " bytes",
+ MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
+ return false;
+ }
+
+ if (plaintext->len !=
+ _mongocrypt_fle2aead_calculate_plaintext_len (ciphertext->len)) {
+ CLIENT_ERR (
+ "output plaintext must be allocated with %" PRIu32 " bytes",
+ _mongocrypt_fle2aead_calculate_plaintext_len (ciphertext->len));
+ return false;
+ }
+
+ if (MONGOCRYPT_KEY_LEN != key->len) {
+ CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
+ MONGOCRYPT_KEY_LEN,
+ key->len);
+ return false;
+ }
+
+ memset (plaintext->data, 0, plaintext->len);
+ *bytes_written = 0;
+
+ /* Declare variable names matching [AEAD with
+ * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
+ */
+ /* C is the input ciphertext. */
+ _mongocrypt_buffer_t C;
+ if (!_mongocrypt_buffer_from_subrange (&C, ciphertext, 0, ciphertext->len)) {
+ CLIENT_ERR ("unable to create C view from ciphertext");
+ return false;
+ }
+ /* IV is 16 byte IV. It is the first part of C. */
+ _mongocrypt_buffer_t IV;
+ if (!_mongocrypt_buffer_from_subrange (
+ &IV, ciphertext, 0, MONGOCRYPT_IV_LEN)) {
+ CLIENT_ERR ("unable to create IV view from ciphertext");
+ return false;
+ }
+ /* S is the symmetric cipher output from C. It is after the IV in C. */
+ _mongocrypt_buffer_t S;
+ if (!_mongocrypt_buffer_from_subrange (&S,
+ ciphertext,
+ MONGOCRYPT_IV_LEN,
+ C.len - MONGOCRYPT_IV_LEN -
+ MONGOCRYPT_HMAC_LEN)) {
+ CLIENT_ERR ("unable to create S view from C");
+ return false;
+ }
+ /* T is the HMAC tag from C. It is after S in C. */
+ _mongocrypt_buffer_t T;
+ if (!_mongocrypt_buffer_from_subrange (
+ &T, &C, C.len - MONGOCRYPT_HMAC_LEN, MONGOCRYPT_HMAC_LEN)) {
+ CLIENT_ERR ("unable to create T view from C");
+ return false;
+ }
+ /* Tp is the computed HMAC of the input. */
+ _mongocrypt_buffer_t Tp = {0};
+ /* M is the output plaintext. */
+ _mongocrypt_buffer_t M;
+ if (!_mongocrypt_buffer_from_subrange (&M, plaintext, 0, plaintext->len)) {
+ CLIENT_ERR ("unable to create M view from plaintext");
+ return false;
+ }
+ /* Ke is 32 byte Key for encryption. */
+ _mongocrypt_buffer_t Ke;
+ if (!_mongocrypt_buffer_from_subrange (
+ &Ke, key, 0, MONGOCRYPT_ENC_KEY_LEN)) {
+ CLIENT_ERR ("unable to create Ke view from key");
+ return false;
+ }
+ /* Km is 32 byte Key for HMAC. */
+ _mongocrypt_buffer_t Km;
+ if (!_mongocrypt_buffer_from_subrange (
+ &Km, key, MONGOCRYPT_ENC_KEY_LEN, MONGOCRYPT_MAC_KEY_LEN)) {
+ CLIENT_ERR ("unable to create Km view from key");
+ return false;
+ }
+ /* AD is Associated Data. */
+ _mongocrypt_buffer_t AD;
+ if (!_mongocrypt_buffer_from_subrange (
+ &AD, associated_data, 0, associated_data->len)) {
+ CLIENT_ERR ("unable to create AD view from associated_data");
+ return false;
+ }
+
+ /* Compute Tp = HMAC-SHA256(Km, AD || IV || S). Check that it matches input
+ * ciphertext T. */
+ {
+ _mongocrypt_buffer_t hmac_inputs[] = {AD, IV, S};
+ _mongocrypt_buffer_t hmac_input = {0};
+ _mongocrypt_buffer_concat (&hmac_input, hmac_inputs, 3);
+ _mongocrypt_buffer_resize (&Tp, MONGOCRYPT_HMAC_LEN);
+ if (!_mongocrypt_hmac_sha_256 (crypto, &Km, &hmac_input, &Tp, status)) {
+ _mongocrypt_buffer_cleanup (&hmac_input);
+ _mongocrypt_buffer_cleanup (&Tp);
+ return false;
+ }
+ if (0 != _mongocrypt_buffer_cmp (&T, &Tp)) {
+ CLIENT_ERR ("decryption error");
+ _mongocrypt_buffer_cleanup (&hmac_input);
+ _mongocrypt_buffer_cleanup (&Tp);
+ return false;
+ }
+ _mongocrypt_buffer_cleanup (&hmac_input);
+ _mongocrypt_buffer_cleanup (&Tp);
+ }
+
+ /* Compute and output M = AES-CTR.Dec(Ke, S) */
+ if (!_crypto_aes_256_ctr_decrypt (
+ crypto,
+ (aes_256_args_t){.key = &Ke,
+ .iv = &IV,
+ .in = &S,
+ .out = &M,
+ .bytes_written = bytes_written,
+ .status = status})) {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+_mongocrypt_fle2_do_encryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *iv,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *plaintext,
+ _mongocrypt_buffer_t *ciphertext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+{
+ BSON_ASSERT_PARAM (crypto);
+ BSON_ASSERT_PARAM (iv);
+ BSON_ASSERT_PARAM (key);
+ BSON_ASSERT_PARAM (plaintext);
+ BSON_ASSERT_PARAM (ciphertext);
+ BSON_ASSERT_PARAM (bytes_written);
+ BSON_ASSERT_PARAM (status);
+
+ if (ciphertext->len !=
+ _mongocrypt_fle2_calculate_ciphertext_len (plaintext->len)) {
+ CLIENT_ERR ("output ciphertext must be allocated with %" PRIu32 " bytes",
+ _mongocrypt_fle2_calculate_ciphertext_len (plaintext->len));
+ return false;
+ }
+
+ if (plaintext->len <= 0) {
+ CLIENT_ERR ("input plaintext too small. Must be more than zero bytes.");
+ return false;
+ }
+
+ if (MONGOCRYPT_IV_LEN != iv->len) {
+ CLIENT_ERR ("IV must be length %d, but is length %" PRIu32,
+ MONGOCRYPT_IV_LEN,
+ iv->len);
+ return false;
+ }
+ if (MONGOCRYPT_ENC_KEY_LEN != key->len) {
+ CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
+ MONGOCRYPT_ENC_KEY_LEN,
+ key->len);
+ return false;
+ }
+
+ memset (ciphertext->data + MONGOCRYPT_IV_LEN,
+ 0,
+ ciphertext->len - MONGOCRYPT_IV_LEN);
+ *bytes_written = 0;
+
+ /* Declare variable names matching [AEAD with
+ * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
+ */
+ /* M is the input plaintext. */
+ _mongocrypt_buffer_t M = *plaintext;
+ /* Ke is 32 byte Key for encryption. */
+ _mongocrypt_buffer_t Ke = *key;
+ /* IV is 16 byte IV. */
+ _mongocrypt_buffer_t IV = *iv;
+ /* C is the output ciphertext. */
+ _mongocrypt_buffer_t C = *ciphertext;
+ /* S is the output of the symmetric cipher. It is appended after IV in C. */
+ _mongocrypt_buffer_t S;
+ if (!_mongocrypt_buffer_from_subrange (
+ &S, &C, MONGOCRYPT_IV_LEN, C.len - MONGOCRYPT_IV_LEN)) {
+ CLIENT_ERR ("unable to create S view from C");
+ return false;
+ }
+ uint32_t S_bytes_written = 0;
+
+ /* Compute S = AES-CTR.Enc(Ke, IV, M). */
+ if (!_crypto_aes_256_ctr_encrypt (
+ crypto,
+ (aes_256_args_t){.key = &Ke,
+ .iv = &IV,
+ .in = &M,
+ .out = &S,
+ .bytes_written = &S_bytes_written,
+ .status = status})) {
+ return false;
+ }
+
+ if (S_bytes_written != M.len) {
+ CLIENT_ERR ("expected S_bytes_written=%" PRIu32 " got %" PRIu32,
+ M.len,
+ S_bytes_written);
+ return false;
+ }
+
+ /* Output C = IV || S. */
+ /* S is already in C. Prepend IV. */
+ memmove (C.data, IV.data, MONGOCRYPT_IV_LEN);
+
+ *bytes_written = MONGOCRYPT_IV_LEN + S_bytes_written;
+ return true;
+}
+
+bool
+_mongocrypt_fle2_do_decryption (_mongocrypt_crypto_t *crypto,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *ciphertext,
+ _mongocrypt_buffer_t *plaintext,
+ uint32_t *bytes_written,
+ mongocrypt_status_t *status)
+{
+ BSON_ASSERT_PARAM (crypto);
+ BSON_ASSERT_PARAM (key);
+ BSON_ASSERT_PARAM (ciphertext);
+ BSON_ASSERT_PARAM (plaintext);
+ BSON_ASSERT_PARAM (bytes_written);
+ BSON_ASSERT_PARAM (status);
+
+ if (ciphertext->len <= MONGOCRYPT_IV_LEN) {
+ CLIENT_ERR ("input ciphertext too small. Must be more than %" PRIu32
+ " bytes",
+ MONGOCRYPT_IV_LEN);
+ return false;
+ }
+
+ if (plaintext->len !=
+ _mongocrypt_fle2_calculate_plaintext_len (ciphertext->len)) {
+ CLIENT_ERR ("output plaintext must be allocated with %" PRIu32 " bytes",
+ _mongocrypt_fle2_calculate_plaintext_len (ciphertext->len));
+ return false;
+ }
+
+ if (MONGOCRYPT_ENC_KEY_LEN != key->len) {
+ CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
+ MONGOCRYPT_ENC_KEY_LEN,
+ key->len);
+ return false;
+ }
+
+ memset (plaintext->data, 0, plaintext->len);
+ *bytes_written = 0;
+
+ /* Declare variable names matching [AEAD with
+ * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
+ */
+ /* C is the input ciphertext. */
+ _mongocrypt_buffer_t C = *ciphertext;
+ /* IV is 16 byte IV. It is the first part of C. */
+ _mongocrypt_buffer_t IV;
+ if (!_mongocrypt_buffer_from_subrange (
+ &IV, ciphertext, 0, MONGOCRYPT_IV_LEN)) {
+ CLIENT_ERR ("unable to create IV view from ciphertext");
+ return false;
+ }
+ /* S is the symmetric cipher output from C. It is after the IV in C. */
+ _mongocrypt_buffer_t S;
+ if (!_mongocrypt_buffer_from_subrange (
+ &S, ciphertext, MONGOCRYPT_IV_LEN, C.len - MONGOCRYPT_IV_LEN)) {
+ CLIENT_ERR ("unable to create S view from C");
+ return false;
+ }
+ /* M is the output plaintext. */
+ _mongocrypt_buffer_t M = *plaintext;
+ /* Ke is 32 byte Key for encryption. */
+ _mongocrypt_buffer_t Ke = *key;
+
+ /* Compute and output M = AES-CTR.Dec(Ke, S) */
+ if (!_crypto_aes_256_ctr_decrypt (
+ crypto,
+ (aes_256_args_t){.key = &Ke,
+ .iv = &IV,
+ .in = &S,
+ .out = &M,
+ .bytes_written = bytes_written,
+ .status = status})) {
+ return false;
+ }
+
+ if (*bytes_written != S.len) {
+ CLIENT_ERR ("expected bytes_written=%" PRIu32 " got %" PRIu32,
+ S.len,
+ *bytes_written);
+ return false;
+ }
+
+ return true;
+}
+
+/* This implementation avoids modulo bias. It is based on arc4random_uniform:
+https://github.com/openbsd/src/blob/2207c4325726fdc5c4bcd0011af0fdf7d3dab137/lib/libc/crypt/arc4random_uniform.c#L33
+*/
+bool
+_mongocrypt_random_uint64 (_mongocrypt_crypto_t *crypto,
+ uint64_t exclusive_upper_bound,
+ uint64_t *out,
+ mongocrypt_status_t *status)
+{
+ *out = 0;
+
+ if (exclusive_upper_bound < 2) {
+ *out = 0;
+ return true;
+ }
+
+ /* 2**64 % x == (2**64 - x) % x */
+ uint64_t min = (0 - exclusive_upper_bound) % exclusive_upper_bound;
+
+ _mongocrypt_buffer_t rand_u64_buf;
+ _mongocrypt_buffer_init (&rand_u64_buf);
+ _mongocrypt_buffer_resize (&rand_u64_buf, (uint32_t) sizeof (uint64_t));
+
+ uint64_t rand_u64;
+ for (;;) {
+ if (!_mongocrypt_random (
+ crypto, &rand_u64_buf, rand_u64_buf.len, status)) {
+ _mongocrypt_buffer_cleanup (&rand_u64_buf);
+ return false;
+ }
+
+ memcpy (&rand_u64, rand_u64_buf.data, rand_u64_buf.len);
+
+ if (rand_u64 >= min) {
+ break;
+ }
+ }
+
+ *out = rand_u64 % exclusive_upper_bound;
+
+ _mongocrypt_buffer_cleanup (&rand_u64_buf);
+ return true;
+}
+
+bool
+_mongocrypt_random_int64 (_mongocrypt_crypto_t *crypto,
+ int64_t exclusive_upper_bound,
+ int64_t *out,
+ mongocrypt_status_t *status)
+{
+ if (exclusive_upper_bound <= 0) {
+ CLIENT_ERR ("Expected exclusive_upper_bound > 0");
+ return false;
+ }
+
+ uint64_t u64_exclusive_upper_bound = (uint64_t) exclusive_upper_bound;
+ uint64_t u64_out;
+
+ if (!_mongocrypt_random_uint64 (crypto, u64_exclusive_upper_bound, &u64_out, status)) {
+ return false;
+ }
+
+ /* Zero the leading bit to ensure rand_i64 is non-negative. */
+ u64_out &= (~(1ull << 63));
+ *out = (int64_t) u64_out;
+ return true;
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-datakey.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
similarity index 95%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
index b7c7adb8..f49c1978 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-datakey.c
@@ -1,502 +1,508 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongocrypt.h"
#include "mongocrypt-private.h"
#include "mongocrypt-ctx-private.h"
#include "mongocrypt-crypto-private.h"
static void
_cleanup (mongocrypt_ctx_t *ctx)
{
_mongocrypt_ctx_datakey_t *dkctx;
dkctx = (_mongocrypt_ctx_datakey_t *) ctx;
_mongocrypt_buffer_cleanup (&dkctx->key_doc);
_mongocrypt_kms_ctx_cleanup (&dkctx->kms);
_mongocrypt_buffer_cleanup (&dkctx->encrypted_key_material);
_mongocrypt_buffer_cleanup (&dkctx->plaintext_key_material);
_mongocrypt_buffer_cleanup (&dkctx->kmip_secretdata);
bson_free ((void *) dkctx->kmip_unique_identifier);
}
static mongocrypt_kms_ctx_t *
_next_kms_ctx (mongocrypt_ctx_t *ctx)
{
_mongocrypt_ctx_datakey_t *dkctx;
dkctx = (_mongocrypt_ctx_datakey_t *) ctx;
if (dkctx->kms_returned) {
return NULL;
}
dkctx->kms_returned = true;
return &dkctx->kms;
}
static bool
_kms_kmip_start (mongocrypt_ctx_t *ctx)
{
bool ret = false;
_mongocrypt_ctx_datakey_t *dkctx = (_mongocrypt_ctx_datakey_t *) ctx;
char *user_supplied_keyid = NULL;
_mongocrypt_endpoint_t *endpoint = NULL;
mongocrypt_status_t *status = ctx->status;
_mongocrypt_buffer_t secretdata = {0};
if (ctx->opts.kek.kms_provider != MONGOCRYPT_KMS_PROVIDER_KMIP) {
CLIENT_ERR ("KMS provider is not KMIP");
goto fail;
}
user_supplied_keyid = ctx->opts.kek.provider.kmip.key_id;
if (ctx->opts.kek.provider.kmip.endpoint) {
endpoint = ctx->opts.kek.provider.kmip.endpoint;
- } else if (ctx->crypt->opts.kms_provider_kmip.endpoint) {
- endpoint = ctx->crypt->opts.kms_provider_kmip.endpoint;
+ } else if (_mongocrypt_ctx_kms_providers(ctx)->kmip.endpoint) {
+ endpoint = _mongocrypt_ctx_kms_providers(ctx)->kmip.endpoint;
} else {
CLIENT_ERR ("endpoint not set for KMIP request");
goto fail;
}
/* The KMIP createDataKey flow is the following:
*
* 1. Send a KMIP Register request with a new 96 byte key as a SecretData
* managed object. This returns a Unique Identifier.
* 2. Send a KMIP Activate request with the Unique Identifier.
* This returns the same Unique Identifier.
* 3. Send a KMIP Get request with the Unique Identifier.
* This returns the 96 byte SecretData.
* 4. Use the 96 byte SecretData to encrypt a new DEK.
*
* If the user set a 'keyId' to use, the flow begins at step 3.
*/
if (user_supplied_keyid && !dkctx->kmip_unique_identifier) {
/* User set a 'keyId'. */
dkctx->kmip_unique_identifier = bson_strdup (user_supplied_keyid);
dkctx->kmip_activated = true;
/* Fall through to Step 3. */
}
if (!dkctx->kmip_unique_identifier) {
/* User did not set a 'keyId'. */
/* Step 1. Send a KMIP Register request with a new 96 byte SecretData. */
_mongocrypt_buffer_init (&secretdata);
_mongocrypt_buffer_resize (&secretdata, MONGOCRYPT_KEY_LEN);
if (!_mongocrypt_random (ctx->crypt->crypto,
&secretdata,
MONGOCRYPT_KEY_LEN,
ctx->status)) {
goto fail;
}
if (!_mongocrypt_kms_ctx_init_kmip_register (&dkctx->kms,
endpoint,
secretdata.data,
secretdata.len,
&ctx->crypt->log)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
goto fail;
}
-
ctx->state = MONGOCRYPT_CTX_NEED_KMS;
+
goto success;
}
if (!dkctx->kmip_activated) {
/* Step 2. Send a KMIP Activate request. */
if (!_mongocrypt_kms_ctx_init_kmip_activate (
&dkctx->kms,
endpoint,
dkctx->kmip_unique_identifier,
&ctx->crypt->log)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
goto fail;
}
ctx->state = MONGOCRYPT_CTX_NEED_KMS;
goto success;
}
if (!dkctx->kmip_secretdata.data) {
/* Step 3. Send a KMIP Get request with the Unique Identifier. */
if (!_mongocrypt_kms_ctx_init_kmip_get (&dkctx->kms,
endpoint,
dkctx->kmip_unique_identifier,
&ctx->crypt->log)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
goto fail;
}
ctx->state = MONGOCRYPT_CTX_NEED_KMS;
goto success;
}
/* Step 4. Use the 96 byte SecretData to encrypt a new DEK. */
if (!_mongocrypt_wrap_key (ctx->crypt->crypto,
&dkctx->kmip_secretdata,
&dkctx->plaintext_key_material,
&dkctx->encrypted_key_material,
ctx->status)) {
goto fail;
}
if (!ctx->opts.kek.provider.kmip.key_id) {
/* If there was no user supplied key_id, set it from the
* UniqueIdentifer of the newly registered SecretData. */
ctx->opts.kek.provider.kmip.key_id =
bson_strdup (dkctx->kmip_unique_identifier);
}
ctx->state = MONGOCRYPT_CTX_READY;
success:
ret = true;
fail:
if (!ret) {
_mongocrypt_ctx_fail (ctx);
}
_mongocrypt_buffer_cleanup (&secretdata);
return ret;
}
/* For local, immediately encrypt.
* For AWS, create the KMS request to encrypt.
* For Azure/GCP, auth first if needed, otherwise encrypt.
*/
static bool
_kms_start (mongocrypt_ctx_t *ctx)
{
bool ret = false;
_mongocrypt_ctx_datakey_t *dkctx;
char *access_token = NULL;
+ _mongocrypt_opts_kms_providers_t *const kms_providers =
+ _mongocrypt_ctx_kms_providers(ctx);
dkctx = (_mongocrypt_ctx_datakey_t *) ctx;
/* Clear out any pre-existing initialized KMS context, and zero it (so it is
* safe to call cleanup again). */
_mongocrypt_kms_ctx_cleanup (&dkctx->kms);
memset (&dkctx->kms, 0, sizeof (dkctx->kms));
dkctx->kms_returned = false;
if (ctx->opts.kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_LOCAL) {
if (!_mongocrypt_wrap_key (ctx->crypt->crypto,
- &ctx->crypt->opts.kms_provider_local.key,
+ &kms_providers->local.key,
&dkctx->plaintext_key_material,
&dkctx->encrypted_key_material,
ctx->status)) {
_mongocrypt_ctx_fail (ctx);
goto done;
}
ctx->state = MONGOCRYPT_CTX_READY;
} else if (ctx->opts.kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_AWS) {
/* For AWS provider, AWS credentials are supplied in
* mongocrypt_setopt_kms_provider_aws. Data keys are encrypted with an
* "encrypt" HTTP message to KMS. */
if (!_mongocrypt_kms_ctx_init_aws_encrypt (&dkctx->kms,
- &ctx->crypt->opts,
+ kms_providers,
&ctx->opts,
&dkctx->plaintext_key_material,
&ctx->crypt->log,
ctx->crypt->crypto)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
_mongocrypt_ctx_fail (ctx);
goto done;
}
ctx->state = MONGOCRYPT_CTX_NEED_KMS;
} else if (ctx->opts.kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_AZURE) {
access_token =
_mongocrypt_cache_oauth_get (ctx->crypt->cache_oauth_azure);
if (access_token) {
if (!_mongocrypt_kms_ctx_init_azure_wrapkey (
&dkctx->kms,
&ctx->crypt->log,
- &ctx->crypt->opts,
+ kms_providers,
&ctx->opts,
access_token,
&dkctx->plaintext_key_material)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
_mongocrypt_ctx_fail (ctx);
goto done;
}
} else {
if (!_mongocrypt_kms_ctx_init_azure_auth (
&dkctx->kms,
&ctx->crypt->log,
- &ctx->crypt->opts,
+ kms_providers,
ctx->opts.kek.provider.azure.key_vault_endpoint)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
_mongocrypt_ctx_fail (ctx);
goto done;
}
}
ctx->state = MONGOCRYPT_CTX_NEED_KMS;
} else if (ctx->opts.kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_GCP) {
access_token = _mongocrypt_cache_oauth_get (ctx->crypt->cache_oauth_gcp);
if (access_token) {
if (!_mongocrypt_kms_ctx_init_gcp_encrypt (
&dkctx->kms,
&ctx->crypt->log,
- &ctx->crypt->opts,
+ kms_providers,
&ctx->opts,
access_token,
&dkctx->plaintext_key_material)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
_mongocrypt_ctx_fail (ctx);
goto done;
}
} else {
if (!_mongocrypt_kms_ctx_init_gcp_auth (
&dkctx->kms,
&ctx->crypt->log,
&ctx->crypt->opts,
+ kms_providers,
ctx->opts.kek.provider.gcp.endpoint)) {
mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status);
_mongocrypt_ctx_fail (ctx);
goto done;
}
}
ctx->state = MONGOCRYPT_CTX_NEED_KMS;
} else if (ctx->opts.kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_KMIP) {
if (!_kms_kmip_start (ctx)) {
goto done;
}
} else {
_mongocrypt_ctx_fail_w_msg (ctx, "unsupported KMS provider");
goto done;
}
ret = true;
done:
bson_free (access_token);
return ret;
}
static bool
_kms_done (mongocrypt_ctx_t *ctx)
{
_mongocrypt_ctx_datakey_t *dkctx;
mongocrypt_status_t *status;
dkctx = (_mongocrypt_ctx_datakey_t *) ctx;
status = ctx->status;
if (!mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status)) {
return _mongocrypt_ctx_fail (ctx);
}
if (mongocrypt_kms_ctx_bytes_needed (&dkctx->kms) != 0) {
return _mongocrypt_ctx_fail_w_msg (ctx, "KMS response unfinished");
}
/* If this was an oauth request, store the response and proceed to encrypt.
*/
if (dkctx->kms.req_type == MONGOCRYPT_KMS_AZURE_OAUTH) {
bson_t oauth_response;
BSON_ASSERT (
_mongocrypt_buffer_to_bson (&dkctx->kms.result, &oauth_response));
if (!_mongocrypt_cache_oauth_add (
ctx->crypt->cache_oauth_azure, &oauth_response, status)) {
return _mongocrypt_ctx_fail (ctx);
}
return _kms_start (ctx);
} else if (dkctx->kms.req_type == MONGOCRYPT_KMS_GCP_OAUTH) {
bson_t oauth_response;
BSON_ASSERT (
_mongocrypt_buffer_to_bson (&dkctx->kms.result, &oauth_response));
if (!_mongocrypt_cache_oauth_add (
ctx->crypt->cache_oauth_gcp, &oauth_response, status)) {
return _mongocrypt_ctx_fail (ctx);
}
return _kms_start (ctx);
} else if (dkctx->kms.req_type == MONGOCRYPT_KMS_KMIP_REGISTER) {
dkctx->kmip_unique_identifier =
bson_strdup ((const char *) dkctx->kms.result.data);
return _kms_start (ctx);
} else if (dkctx->kms.req_type == MONGOCRYPT_KMS_KMIP_ACTIVATE) {
dkctx->kmip_activated = true;
return _kms_start (ctx);
} else if (dkctx->kms.req_type == MONGOCRYPT_KMS_KMIP_GET) {
_mongocrypt_buffer_copy_to (&dkctx->kms.result, &dkctx->kmip_secretdata);
return _kms_start (ctx);
}
/* Store the result. */
if (!_mongocrypt_kms_ctx_result (&dkctx->kms,
&dkctx->encrypted_key_material)) {
BSON_ASSERT (!mongocrypt_kms_ctx_status (&dkctx->kms, ctx->status));
return _mongocrypt_ctx_fail (ctx);
}
/* The encrypted key material must be at least as large as the plaintext. */
if (dkctx->encrypted_key_material.len < MONGOCRYPT_KEY_LEN) {
return _mongocrypt_ctx_fail_w_msg (ctx,
"key material not expected length");
}
ctx->state = MONGOCRYPT_CTX_READY;
return true;
}
/* Append a UUID _id. Confer with libmongoc's `_mongoc_server_session_uuid`. */
static bool
_append_id (mongocrypt_t *crypt, bson_t *bson, mongocrypt_status_t *status)
{
_mongocrypt_buffer_t uuid;
-#define UUID_LEN 16
_mongocrypt_buffer_init (&uuid);
uuid.data = bson_malloc (UUID_LEN);
BSON_ASSERT (uuid.data);
uuid.len = UUID_LEN;
uuid.subtype = BSON_SUBTYPE_UUID;
uuid.owned = true;
if (!_mongocrypt_random (crypt->crypto, &uuid, UUID_LEN, status)) {
_mongocrypt_buffer_cleanup (&uuid);
return false;
}
uuid.data[6] = (uint8_t) (0x40 | (uuid.data[6] & 0xf));
uuid.data[8] = (uint8_t) (0x80 | (uuid.data[8] & 0x3f));
if (!_mongocrypt_buffer_append (&uuid, bson, "_id", 3)) {
_mongocrypt_buffer_cleanup (&uuid);
return false;
}
_mongocrypt_buffer_cleanup (&uuid);
return true;
}
static bool
_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
{
_mongocrypt_ctx_datakey_t *dkctx;
bson_t key_doc, child;
struct timeval tp;
#define BSON_CHECK(_stmt) \
if (!(_stmt)) { \
bson_destroy (&key_doc); \
return _mongocrypt_ctx_fail_w_msg (ctx, "unable to construct BSON doc"); \
}
dkctx = (_mongocrypt_ctx_datakey_t *) ctx;
bson_init (&key_doc);
if (!_append_id (ctx->crypt, &key_doc, ctx->status)) {
return _mongocrypt_ctx_fail (ctx);
}
if (ctx->opts.key_alt_names) {
_mongocrypt_key_alt_name_t *alt_name = ctx->opts.key_alt_names;
int i;
bson_append_array_begin (&key_doc, "keyAltNames", -1, &child);
for (i = 0; alt_name; i++) {
char *key = bson_strdup_printf ("%d", i);
bson_append_value (&child, key, -1, &alt_name->value);
bson_free (key);
alt_name = alt_name->next;
}
bson_append_array_end (&key_doc, &child);
}
if (!_mongocrypt_buffer_append (&dkctx->encrypted_key_material,
&key_doc,
MONGOCRYPT_STR_AND_LEN ("keyMaterial"))) {
bson_destroy (&key_doc);
return _mongocrypt_ctx_fail_w_msg (ctx, "could not append keyMaterial");
}
bson_gettimeofday (&tp);
BSON_CHECK (bson_append_timeval (
&key_doc, MONGOCRYPT_STR_AND_LEN ("creationDate"), &tp));
BSON_CHECK (bson_append_timeval (
&key_doc, MONGOCRYPT_STR_AND_LEN ("updateDate"), &tp));
BSON_CHECK (bson_append_int32 (
&key_doc, MONGOCRYPT_STR_AND_LEN ("status"), 0)); /* 0 = enabled. */
BSON_CHECK (bson_append_document_begin (
&key_doc, MONGOCRYPT_STR_AND_LEN ("masterKey"), &child));
if (!_mongocrypt_kek_append (&ctx->opts.kek, &child, ctx->status)) {
bson_destroy (&key_doc);
return _mongocrypt_ctx_fail (ctx);
}
BSON_CHECK (bson_append_document_end (&key_doc, &child));
_mongocrypt_buffer_steal_from_bson (&dkctx->key_doc, &key_doc);
_mongocrypt_buffer_to_binary (&dkctx->key_doc, out);
ctx->state = MONGOCRYPT_CTX_DONE;
return true;
}
bool
mongocrypt_ctx_datakey_init (mongocrypt_ctx_t *ctx)
{
_mongocrypt_ctx_datakey_t *dkctx;
_mongocrypt_ctx_opts_spec_t opts_spec;
bool ret;
if (!ctx) {
return false;
}
ret = false;
memset (&opts_spec, 0, sizeof (opts_spec));
opts_spec.kek = OPT_REQUIRED;
opts_spec.key_alt_names = OPT_OPTIONAL;
opts_spec.key_material = OPT_OPTIONAL;
if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
return false;
}
dkctx = (_mongocrypt_ctx_datakey_t *) ctx;
ctx->type = _MONGOCRYPT_TYPE_CREATE_DATA_KEY;
ctx->vtable.mongo_op_keys = NULL;
ctx->vtable.mongo_feed_keys = NULL;
ctx->vtable.mongo_done_keys = NULL;
ctx->vtable.next_kms_ctx = _next_kms_ctx;
+ ctx->vtable.after_kms_credentials_provided = _kms_start;
ctx->vtable.kms_done = _kms_done;
ctx->vtable.finalize = _finalize;
ctx->vtable.cleanup = _cleanup;
_mongocrypt_buffer_init (&dkctx->plaintext_key_material);
if (ctx->opts.key_material.owned) {
/* Use keyMaterial provided by user via DataKeyOpts. */
_mongocrypt_buffer_steal (&dkctx->plaintext_key_material,
&ctx->opts.key_material);
} else {
/* Generate keyMaterial instead. */
dkctx->plaintext_key_material.data = bson_malloc (MONGOCRYPT_KEY_LEN);
BSON_ASSERT (dkctx->plaintext_key_material.data);
dkctx->plaintext_key_material.len = MONGOCRYPT_KEY_LEN;
dkctx->plaintext_key_material.owned = true;
if (!_mongocrypt_random (ctx->crypt->crypto,
&dkctx->plaintext_key_material,
MONGOCRYPT_KEY_LEN,
ctx->status)) {
_mongocrypt_ctx_fail (ctx);
goto done;
}
}
- if (!_kms_start (ctx)) {
+ if (_mongocrypt_needs_credentials_for_provider (
+ ctx->crypt, ctx->opts.kek.kms_provider)) {
+ ctx->state = MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS;
+ } else if (!_kms_start (ctx)) {
goto done;
}
ret = true;
done:
return ret;
}
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c
new file mode 100644
index 00000000..a42e4da9
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-decrypt.c
@@ -0,0 +1,711 @@
+/*
+ * Copyright 2019-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mongocrypt-ciphertext-private.h"
+#include "mongocrypt-crypto-private.h"
+#include "mongocrypt-ctx-private.h"
+#include "mongocrypt-traverse-util-private.h"
+#include "mc-fle2-payload-ieev-private.h"
+#include "mc-fle-blob-subtype-private.h"
+#include "mc-fle2-payload-uev-private.h"
+#include "mc-fle2-insert-update-payload-private.h"
+
+static bool
+_replace_FLE2IndexedEqualityEncryptedValue_with_plaintext (
+ void *ctx,
+ _mongocrypt_buffer_t *in,
+ bson_value_t *out,
+ mongocrypt_status_t *status)
+{
+ bool ret = false;
+ _mongocrypt_key_broker_t *kb = ctx;
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev =
+ mc_FLE2IndexedEqualityEncryptedValue_new ();
+ _mongocrypt_buffer_t S_Key = {0};
+ _mongocrypt_buffer_t K_Key = {0};
+
+ if (!mc_FLE2IndexedEqualityEncryptedValue_parse (ieev, in, status)) {
+ goto fail;
+ }
+
+ const _mongocrypt_buffer_t *S_KeyId =
+ mc_FLE2IndexedEqualityEncryptedValue_get_S_KeyId (ieev, status);
+ if (!S_KeyId) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, S_KeyId, &S_Key)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ /* Decrypt InnerEncrypted to get K_KeyId. */
+ if (!mc_FLE2IndexedEqualityEncryptedValue_add_S_Key (
+ kb->crypt->crypto, ieev, &S_Key, status)) {
+ goto fail;
+ }
+
+ const _mongocrypt_buffer_t *K_KeyId =
+ mc_FLE2IndexedEqualityEncryptedValue_get_K_KeyId (ieev, status);
+ if (!K_KeyId) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, K_KeyId, &K_Key)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ /* Decrypt ClientEncryptedValue. */
+ if (!mc_FLE2IndexedEqualityEncryptedValue_add_K_Key (
+ kb->crypt->crypto, ieev, &K_Key, status)) {
+ goto fail;
+ }
+
+ const _mongocrypt_buffer_t *clientValue =
+ mc_FLE2IndexedEqualityEncryptedValue_get_ClientValue (ieev, status);
+ if (!clientValue) {
+ goto fail;
+ }
+
+ uint8_t original_bson_type =
+ mc_FLE2IndexedEqualityEncryptedValue_get_original_bson_type (ieev,
+ status);
+ if (0 == original_bson_type) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_buffer_to_bson_value (
+ (_mongocrypt_buffer_t *) clientValue, original_bson_type, out)) {
+ CLIENT_ERR ("decrypted clientValue is not valid BSON");
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ _mongocrypt_buffer_cleanup (&K_Key);
+ _mongocrypt_buffer_cleanup (&S_Key);
+ mc_FLE2IndexedEqualityEncryptedValue_destroy (ieev);
+ return ret;
+}
+
+static bool
+_replace_FLE2UnindexedEncryptedValue_with_plaintext (
+ void *ctx,
+ _mongocrypt_buffer_t *in,
+ bson_value_t *out,
+ mongocrypt_status_t *status)
+{
+ bool ret = false;
+ _mongocrypt_key_broker_t *kb = ctx;
+ mc_FLE2UnindexedEncryptedValue_t *uev =
+ mc_FLE2UnindexedEncryptedValue_new ();
+ _mongocrypt_buffer_t key = {0};
+
+ if (!mc_FLE2UnindexedEncryptedValue_parse (uev, in, status)) {
+ goto fail;
+ }
+
+ const _mongocrypt_buffer_t *key_uuid =
+ mc_FLE2UnindexedEncryptedValue_get_key_uuid (uev, status);
+ if (!key_uuid) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, key_uuid, &key)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ /* Decrypt ciphertext. */
+ const _mongocrypt_buffer_t *plaintext =
+ mc_FLE2UnindexedEncryptedValue_decrypt (
+ kb->crypt->crypto, uev, &key, status);
+ if (!plaintext) {
+ goto fail;
+ }
+
+ uint8_t original_bson_type =
+ mc_FLE2UnindexedEncryptedValue_get_original_bson_type (uev, status);
+ if (0 == original_bson_type) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_buffer_to_bson_value (
+ (_mongocrypt_buffer_t *) plaintext, original_bson_type, out)) {
+ CLIENT_ERR ("decrypted plaintext is not valid BSON");
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ _mongocrypt_buffer_cleanup (&key);
+ mc_FLE2UnindexedEncryptedValue_destroy (uev);
+ return ret;
+}
+
+static bool
+_replace_FLE2InsertUpdatePayload_with_plaintext (void *ctx,
+ _mongocrypt_buffer_t *in,
+ bson_value_t *out,
+ mongocrypt_status_t *status)
+{
+ bool ret = false;
+ _mongocrypt_key_broker_t *kb = ctx;
+ mc_FLE2InsertUpdatePayload_t iup;
+ _mongocrypt_buffer_t key = {0};
+
+ mc_FLE2InsertUpdatePayload_init (&iup);
+
+ if (!mc_FLE2InsertUpdatePayload_parse (&iup, in, status)) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, &iup.userKeyId, &key)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ /* Decrypt ciphertext. */
+ const _mongocrypt_buffer_t *plaintext = mc_FLE2InsertUpdatePayload_decrypt (
+ kb->crypt->crypto, &iup, &key, status);
+ if (!plaintext) {
+ goto fail;
+ }
+
+ uint8_t original_bson_type = (uint8_t) iup.valueType;
+
+ if (!_mongocrypt_buffer_to_bson_value (
+ (_mongocrypt_buffer_t *) plaintext, original_bson_type, out)) {
+ CLIENT_ERR ("decrypted plaintext is not valid BSON");
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ _mongocrypt_buffer_cleanup (&key);
+ mc_FLE2InsertUpdatePayload_cleanup (&iup);
+ return ret;
+}
+
+static bool
+_replace_ciphertext_with_plaintext (void *ctx,
+ _mongocrypt_buffer_t *in,
+ bson_value_t *out,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_key_broker_t *kb;
+ _mongocrypt_ciphertext_t ciphertext;
+ _mongocrypt_buffer_t plaintext;
+ _mongocrypt_buffer_t key_material;
+ _mongocrypt_buffer_t associated_data;
+ uint32_t bytes_written;
+ bool ret = false;
+
+ BSON_ASSERT (ctx);
+ BSON_ASSERT (in);
+ BSON_ASSERT (out);
+
+ if (in->data[0] == MC_SUBTYPE_FLE2IndexedEqualityEncryptedValue) {
+ return _replace_FLE2IndexedEqualityEncryptedValue_with_plaintext (
+ ctx, in, out, status);
+ }
+
+ if (in->data[0] == MC_SUBTYPE_FLE2UnindexedEncryptedValue) {
+ return _replace_FLE2UnindexedEncryptedValue_with_plaintext (
+ ctx, in, out, status);
+ }
+
+ if (in->data[0] == MC_SUBTYPE_FLE2InsertUpdatePayload) {
+ return _replace_FLE2InsertUpdatePayload_with_plaintext (
+ ctx, in, out, status);
+ }
+
+ _mongocrypt_buffer_init (&plaintext);
+ _mongocrypt_buffer_init (&associated_data);
+ _mongocrypt_buffer_init (&key_material);
+ kb = (_mongocrypt_key_broker_t *) ctx;
+
+ if (!_mongocrypt_ciphertext_parse_unowned (in, &ciphertext, status)) {
+ goto fail;
+ }
+
+ /* look up the key */
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (
+ kb, &ciphertext.key_id, &key_material)) {
+ CLIENT_ERR ("key not found");
+ goto fail;
+ }
+
+ plaintext.len = _mongocrypt_calculate_plaintext_len (ciphertext.data.len);
+ plaintext.data = bson_malloc0 (plaintext.len);
+ BSON_ASSERT (plaintext.data);
+
+ plaintext.owned = true;
+
+ if (!_mongocrypt_ciphertext_serialize_associated_data (&ciphertext,
+ &associated_data)) {
+ CLIENT_ERR ("could not serialize associated data");
+ goto fail;
+ }
+
+ if (!_mongocrypt_do_decryption (kb->crypt->crypto,
+ &associated_data,
+ &key_material,
+ &ciphertext.data,
+ &plaintext,
+ &bytes_written,
+ status)) {
+ goto fail;
+ }
+
+ plaintext.len = bytes_written;
+
+ if (!_mongocrypt_buffer_to_bson_value (
+ &plaintext, ciphertext.original_bson_type, out)) {
+ CLIENT_ERR ("malformed encrypted bson");
+ goto fail;
+ }
+ ret = true;
+
+fail:
+ _mongocrypt_buffer_cleanup (&plaintext);
+ _mongocrypt_buffer_cleanup (&associated_data);
+ _mongocrypt_buffer_cleanup (&key_material);
+ return ret;
+}
+
+
+static bool
+_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ bson_t as_bson, final_bson;
+ bson_iter_t iter;
+ _mongocrypt_ctx_decrypt_t *dctx;
+ bool res;
+
+ if (!ctx) {
+ return false;
+ }
+
+ if (!out) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "null out parameter");
+ }
+
+ dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
+
+ if (ctx->nothing_to_do) {
+ _mongocrypt_buffer_to_binary (&dctx->original_doc, out);
+ ctx->state = MONGOCRYPT_CTX_DONE;
+ return true;
+ }
+
+ if (!_mongocrypt_buffer_to_bson (&dctx->original_doc, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
+ }
+
+ bson_iter_init (&iter, &as_bson);
+ bson_init (&final_bson);
+ res = _mongocrypt_transform_binary_in_bson (
+ _replace_ciphertext_with_plaintext,
+ &ctx->kb,
+ TRAVERSE_MATCH_CIPHERTEXT,
+ &iter,
+ &final_bson,
+ ctx->status);
+ if (!res) {
+ bson_destroy (&final_bson);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ _mongocrypt_buffer_steal_from_bson (&dctx->decrypted_doc, &final_bson);
+ out->data = dctx->decrypted_doc.data;
+ out->len = dctx->decrypted_doc.len;
+ ctx->state = MONGOCRYPT_CTX_DONE;
+ return true;
+}
+
+static bool
+_collect_S_KeyID_from_FLE2IndexedEqualityEncryptedValue (
+ void *ctx, _mongocrypt_buffer_t *in, mongocrypt_status_t *status)
+{
+ bool ret = false;
+ _mongocrypt_key_broker_t *kb = ctx;
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev;
+
+ ieev = mc_FLE2IndexedEqualityEncryptedValue_new ();
+
+ if (!mc_FLE2IndexedEqualityEncryptedValue_parse (ieev, in, status)) {
+ goto fail;
+ }
+
+ const _mongocrypt_buffer_t *S_KeyId =
+ mc_FLE2IndexedEqualityEncryptedValue_get_S_KeyId (ieev, status);
+ if (!S_KeyId) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_request_id (kb, S_KeyId)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ mc_FLE2IndexedEqualityEncryptedValue_destroy (ieev);
+ return ret;
+}
+
+static bool
+_collect_K_KeyID_from_FLE2IndexedEqualityEncryptedValue (
+ void *ctx, _mongocrypt_buffer_t *in, mongocrypt_status_t *status)
+{
+ bool ret = false;
+ _mongocrypt_key_broker_t *kb = ctx;
+ mc_FLE2IndexedEqualityEncryptedValue_t *ieev;
+ _mongocrypt_buffer_t S_Key = {0};
+
+ /* Ignore other ciphertext types. */
+ if (in->data[0] != MC_SUBTYPE_FLE2IndexedEqualityEncryptedValue) {
+ return true;
+ }
+
+ ieev = mc_FLE2IndexedEqualityEncryptedValue_new ();
+
+ if (!mc_FLE2IndexedEqualityEncryptedValue_parse (ieev, in, status)) {
+ goto fail;
+ }
+
+ const _mongocrypt_buffer_t *S_KeyId =
+ mc_FLE2IndexedEqualityEncryptedValue_get_S_KeyId (ieev, status);
+ if (!S_KeyId) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, S_KeyId, &S_Key)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ /* Decrypt InnerEncrypted to get K_KeyId. */
+ if (!mc_FLE2IndexedEqualityEncryptedValue_add_S_Key (
+ kb->crypt->crypto, ieev, &S_Key, status)) {
+ goto fail;
+ }
+
+ /* Add request for K_KeyId. */
+ const _mongocrypt_buffer_t *K_KeyId =
+ mc_FLE2IndexedEqualityEncryptedValue_get_K_KeyId (ieev, status);
+ if (!K_KeyId) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_request_id (kb, K_KeyId)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ _mongocrypt_buffer_cleanup (&S_Key);
+ mc_FLE2IndexedEqualityEncryptedValue_destroy (ieev);
+ return ret;
+}
+
+
+/* _check_for_K_KeyId must be called after requests for all S_KeyId are
+ * satisfied. */
+static bool
+_check_for_K_KeyId (mongocrypt_ctx_t *ctx)
+{
+ if (ctx->kb.state != KB_DONE) {
+ return true;
+ }
+
+ if (!_mongocrypt_key_broker_restart (&ctx->kb)) {
+ _mongocrypt_key_broker_status (&ctx->kb, ctx->status);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ bson_t as_bson;
+ bson_iter_t iter;
+ _mongocrypt_ctx_decrypt_t *dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
+ if (!_mongocrypt_buffer_to_bson (&dctx->original_doc, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "error converting original_doc to bson");
+ }
+ bson_iter_init (&iter, &as_bson);
+
+ if (!_mongocrypt_traverse_binary_in_bson (
+ _collect_K_KeyID_from_FLE2IndexedEqualityEncryptedValue,
+ &ctx->kb,
+ TRAVERSE_MATCH_CIPHERTEXT,
+ &iter,
+ ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ if (!_mongocrypt_key_broker_requests_done (&ctx->kb)) {
+ _mongocrypt_key_broker_status (&ctx->kb, ctx->status);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ return true;
+}
+
+static bool
+_collect_key_uuid_from_FLE2UnindexedEncryptedValue (void *ctx,
+ _mongocrypt_buffer_t *in,
+ mongocrypt_status_t *status)
+{
+ bool ret = false;
+ _mongocrypt_key_broker_t *kb = ctx;
+ mc_FLE2UnindexedEncryptedValue_t *uev;
+
+ uev = mc_FLE2UnindexedEncryptedValue_new ();
+
+ if (!mc_FLE2UnindexedEncryptedValue_parse (uev, in, status)) {
+ goto fail;
+ }
+
+ const _mongocrypt_buffer_t *key_uuid =
+ mc_FLE2UnindexedEncryptedValue_get_key_uuid (uev, status);
+ if (!key_uuid) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_request_id (kb, key_uuid)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ mc_FLE2UnindexedEncryptedValue_destroy (uev);
+ return ret;
+}
+
+static bool
+_collect_key_uuid_from_FLE2InsertUpdatePayload (void *ctx,
+ _mongocrypt_buffer_t *in,
+ mongocrypt_status_t *status)
+{
+ bool ret = false;
+ _mongocrypt_key_broker_t *kb = ctx;
+ mc_FLE2InsertUpdatePayload_t iup;
+
+ mc_FLE2InsertUpdatePayload_init (&iup);
+
+ if (!mc_FLE2InsertUpdatePayload_parse (&iup, in, status)) {
+ goto fail;
+ }
+
+ if (!_mongocrypt_key_broker_request_id (kb, &iup.userKeyId)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ mc_FLE2InsertUpdatePayload_cleanup (&iup);
+ return ret;
+}
+
+static bool
+_collect_key_from_ciphertext (void *ctx,
+ _mongocrypt_buffer_t *in,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_ciphertext_t ciphertext;
+ _mongocrypt_key_broker_t *kb;
+
+ BSON_ASSERT (ctx);
+ BSON_ASSERT (in);
+
+ kb = (_mongocrypt_key_broker_t *) ctx;
+
+ if (in->data[0] == MC_SUBTYPE_FLE2IndexedEqualityEncryptedValue) {
+ return _collect_S_KeyID_from_FLE2IndexedEqualityEncryptedValue (
+ ctx, in, status);
+ }
+
+ if (in->data[0] == MC_SUBTYPE_FLE2UnindexedEncryptedValue) {
+ return _collect_key_uuid_from_FLE2UnindexedEncryptedValue (
+ ctx, in, status);
+ }
+
+ if (in->data[0] == MC_SUBTYPE_FLE2InsertUpdatePayload) {
+ return _collect_key_uuid_from_FLE2InsertUpdatePayload (ctx, in, status);
+ }
+
+ if (!_mongocrypt_ciphertext_parse_unowned (in, &ciphertext, status)) {
+ return false;
+ }
+
+ if (!_mongocrypt_key_broker_request_id (kb, &ciphertext.key_id)) {
+ return _mongocrypt_key_broker_status (kb, status);
+ }
+
+ return true;
+}
+
+
+static void
+_cleanup (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_decrypt_t *dctx;
+
+ dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
+ _mongocrypt_buffer_cleanup (&dctx->original_doc);
+ _mongocrypt_buffer_cleanup (&dctx->decrypted_doc);
+}
+
+
+bool
+mongocrypt_ctx_explicit_decrypt_init (mongocrypt_ctx_t *ctx,
+ mongocrypt_binary_t *msg)
+{
+ bson_iter_t iter;
+ bson_t as_bson;
+
+ if (!ctx) {
+ return false;
+ }
+
+ if (!msg || !msg->data) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "invalid msg");
+ }
+
+ if (ctx->crypt->log.trace_enabled) {
+ char *msg_val;
+ msg_val = _mongocrypt_new_json_string_from_binary (msg);
+ _mongocrypt_log (&ctx->crypt->log,
+ MONGOCRYPT_LOG_LEVEL_TRACE,
+ "%s (%s=\"%s\")",
+ BSON_FUNC,
+ "msg",
+ msg_val);
+
+ bson_free (msg_val);
+ }
+
+ /* Expect msg to be the BSON a document of the form:
+ { "v" : (BSON BINARY value of subtype 6) }
+ */
+ if (!_mongocrypt_binary_to_bson (msg, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
+ }
+
+ if (!bson_iter_init_find (&iter, &as_bson, "v")) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "invalid msg, must contain 'v'");
+ }
+
+ if (!BSON_ITER_HOLDS_BINARY (&iter)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "invalid msg, 'v' must contain a binary");
+ }
+
+ if (!mongocrypt_ctx_decrypt_init (ctx, msg)) {
+ return false;
+ }
+ return true;
+}
+
+static bool
+_mongo_done_keys (mongocrypt_ctx_t *ctx)
+{
+ (void) _mongocrypt_key_broker_docs_done (&ctx->kb);
+ if (!_check_for_K_KeyId (ctx)) {
+ return false;
+ }
+ return _mongocrypt_ctx_state_from_key_broker (ctx);
+}
+
+static bool
+_kms_done (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_opts_kms_providers_t *kms_providers =
+ _mongocrypt_ctx_kms_providers (ctx);
+ if (!_mongocrypt_key_broker_kms_done (&ctx->kb, kms_providers)) {
+ BSON_ASSERT (!_mongocrypt_key_broker_status (&ctx->kb, ctx->status));
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ if (!_check_for_K_KeyId (ctx)) {
+ return false;
+ }
+ return _mongocrypt_ctx_state_from_key_broker (ctx);
+}
+
+bool
+mongocrypt_ctx_decrypt_init (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *doc)
+{
+ _mongocrypt_ctx_decrypt_t *dctx;
+ bson_t as_bson;
+ bson_iter_t iter;
+ _mongocrypt_ctx_opts_spec_t opts_spec;
+
+ memset (&opts_spec, 0, sizeof (opts_spec));
+ if (!ctx) {
+ return false;
+ }
+
+ if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
+ return false;
+ }
+
+ if (!doc || !doc->data) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "invalid doc");
+ }
+
+ if (ctx->crypt->log.trace_enabled) {
+ char *doc_val;
+ doc_val = _mongocrypt_new_json_string_from_binary (doc);
+ _mongocrypt_log (&ctx->crypt->log,
+ MONGOCRYPT_LOG_LEVEL_TRACE,
+ "%s (%s=\"%s\")",
+ BSON_FUNC,
+ "doc",
+ doc_val);
+ bson_free (doc_val);
+ }
+ dctx = (_mongocrypt_ctx_decrypt_t *) ctx;
+ ctx->type = _MONGOCRYPT_TYPE_DECRYPT;
+ ctx->vtable.finalize = _finalize;
+ ctx->vtable.cleanup = _cleanup;
+ ctx->vtable.mongo_done_keys = _mongo_done_keys;
+ ctx->vtable.kms_done = _kms_done;
+
+ _mongocrypt_buffer_copy_from_binary (&dctx->original_doc, doc);
+ /* get keys. */
+ if (!_mongocrypt_buffer_to_bson (&dctx->original_doc, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
+ }
+
+ bson_iter_init (&iter, &as_bson);
+ if (!_mongocrypt_traverse_binary_in_bson (_collect_key_from_ciphertext,
+ &ctx->kb,
+ TRAVERSE_MATCH_CIPHERTEXT,
+ &iter,
+ ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ (void) _mongocrypt_key_broker_requests_done (&ctx->kb);
+
+ if (!_check_for_K_KeyId (ctx)) {
+ return false;
+ }
+ return _mongocrypt_ctx_state_from_key_broker (ctx);
+}
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c
new file mode 100644
index 00000000..74e8b12a
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-encrypt.c
@@ -0,0 +1,2582 @@
+/*
+ * Copyright 2019-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mongocrypt-ciphertext-private.h"
+#include "mongocrypt-crypto-private.h"
+#include "mongocrypt-ctx-private.h"
+#include "mongocrypt-key-broker-private.h"
+#include "mongocrypt-marking-private.h"
+#include "mongocrypt-traverse-util-private.h"
+#include "mc-tokens-private.h"
+
+/* _fle2_append_encryptedFieldConfig copies encryptedFieldConfig and applies
+ * default state collection names for escCollection, eccCollection, and
+ * ecocCollection if required. */
+static bool
+_fle2_append_encryptedFieldConfig (bson_t *dst,
+ bson_t *encryptedFieldConfig,
+ const char *coll_name,
+ mongocrypt_status_t *status)
+{
+ bson_iter_t iter;
+ bool has_escCollection = false;
+ bool has_eccCollection = false;
+ bool has_ecocCollection = false;
+
+ if (!bson_iter_init (&iter, encryptedFieldConfig)) {
+ CLIENT_ERR ("unable to iterate encryptedFieldConfig");
+ return false;
+ }
+
+ while (bson_iter_next (&iter)) {
+ if (strcmp (bson_iter_key (&iter), "escCollection") == 0) {
+ has_escCollection = true;
+ }
+ if (strcmp (bson_iter_key (&iter), "eccCollection") == 0) {
+ has_eccCollection = true;
+ }
+ if (strcmp (bson_iter_key (&iter), "ecocCollection") == 0) {
+ has_ecocCollection = true;
+ }
+ if (!BSON_APPEND_VALUE (
+ dst, bson_iter_key (&iter), bson_iter_value (&iter))) {
+ CLIENT_ERR ("unable to append field: %s", bson_iter_key (&iter));
+ return false;
+ }
+ }
+
+ if (!has_escCollection) {
+ char *default_escCollection =
+ bson_strdup_printf ("enxcol_.%s.esc", coll_name);
+ if (!BSON_APPEND_UTF8 (dst, "escCollection", default_escCollection)) {
+ CLIENT_ERR ("unable to append escCollection");
+ bson_free (default_escCollection);
+ return false;
+ }
+ bson_free (default_escCollection);
+ }
+ if (!has_eccCollection) {
+ char *default_eccCollection =
+ bson_strdup_printf ("enxcol_.%s.ecc", coll_name);
+ if (!BSON_APPEND_UTF8 (dst, "eccCollection", default_eccCollection)) {
+ CLIENT_ERR ("unable to append eccCollection");
+ bson_free (default_eccCollection);
+ return false;
+ }
+ bson_free (default_eccCollection);
+ }
+ if (!has_ecocCollection) {
+ char *default_ecocCollection =
+ bson_strdup_printf ("enxcol_.%s.ecoc", coll_name);
+ if (!BSON_APPEND_UTF8 (dst, "ecocCollection", default_ecocCollection)) {
+ CLIENT_ERR ("unable to append ecocCollection");
+ bson_free (default_ecocCollection);
+ return false;
+ }
+ bson_free (default_ecocCollection);
+ }
+ return true;
+}
+
+static bool
+_fle2_append_encryptionInformation (bson_t *dst,
+ const char *ns,
+ bson_t *encryptedFieldConfig,
+ bson_t *deleteTokens,
+ const char *coll_name,
+ mongocrypt_status_t *status)
+{
+ bson_t encryption_information_bson;
+ bson_t schema_bson;
+ bson_t encrypted_field_config_bson;
+
+ if (!BSON_APPEND_DOCUMENT_BEGIN (
+ dst, "encryptionInformation", &encryption_information_bson)) {
+ CLIENT_ERR ("unable to begin appending 'encryptionInformation'");
+ return false;
+ }
+ if (!BSON_APPEND_INT32 (&encryption_information_bson, "type", 1)) {
+ CLIENT_ERR ("unable to append type to 'encryptionInformation'");
+ return false;
+ }
+ if (!BSON_APPEND_DOCUMENT_BEGIN (
+ &encryption_information_bson, "schema", &schema_bson)) {
+ CLIENT_ERR (
+ "unable to begin appending 'schema' to 'encryptionInformation'");
+ return false;
+ }
+
+ if (!BSON_APPEND_DOCUMENT_BEGIN (
+ &schema_bson, ns, &encrypted_field_config_bson)) {
+ CLIENT_ERR ("unable to begin appending 'encryptedFieldConfig' to "
+ "'encryptionInformation'.'schema'");
+ return false;
+ }
+
+ if (!_fle2_append_encryptedFieldConfig (&encrypted_field_config_bson,
+ encryptedFieldConfig,
+ coll_name,
+ status)) {
+ return false;
+ }
+
+ if (!bson_append_document_end (&schema_bson, &encrypted_field_config_bson)) {
+ CLIENT_ERR ("unable to end appending 'encryptedFieldConfig' to "
+ "'encryptionInformation'.'schema'");
+ return false;
+ }
+ if (!bson_append_document_end (&encryption_information_bson, &schema_bson)) {
+ CLIENT_ERR (
+ "unable to end appending 'schema' to 'encryptionInformation'");
+ return false;
+ }
+
+ if (deleteTokens != NULL) {
+ bson_t delete_tokens_bson;
+ if (!BSON_APPEND_DOCUMENT_BEGIN (&encryption_information_bson,
+ "deleteTokens",
+ &delete_tokens_bson)) {
+ CLIENT_ERR ("unable to begin appending 'deleteTokens' to "
+ "'encryptionInformation'");
+ return false;
+ }
+ if (!BSON_APPEND_DOCUMENT (&delete_tokens_bson, ns, deleteTokens)) {
+ CLIENT_ERR ("unable to append '%s' to 'deleteTokens'", ns);
+ return false;
+ }
+ if (!bson_append_document_end (&encryption_information_bson,
+ &delete_tokens_bson)) {
+ CLIENT_ERR ("unable to end appending 'deleteTokens' to "
+ "'encryptionInformation'");
+ return false;
+ }
+ }
+
+ if (!bson_append_document_end (dst, &encryption_information_bson)) {
+ CLIENT_ERR ("unable to end appending 'encryptionInformation'");
+ return false;
+ }
+ return true;
+}
+
+typedef enum { MC_TO_CSFLE, MC_TO_MONGOCRYPTD, MC_TO_MONGOD } mc_cmd_target_t;
+
+/**
+ * @brief Add "encryptionInformation" to a command.
+ *
+ * @param cmd_name The name of the command.
+ * @param cmd The command being rewritten. It is an input and output.
+ * @param ns The <db>.<collection> namespace for the command.
+ * @param encryptedFieldConfig The "encryptedFields" document for the
+ * collection.
+ * @param deleteTokens Delete tokens to append to "encryptionInformation". May
+ * be NULL.
+ * @param coll_name The collection name.
+ * @param cmd_target The intended destination of the command. csfle,
+ * mongocryptd, and mongod have different requirements for the location of
+ * "encryptionInformation".
+ * @param status Output status.
+ * @return true On success
+ * @return false Otherwise. Sets a failing status message in this case.
+ */
+static bool
+_fle2_insert_encryptionInformation (const char *cmd_name,
+ bson_t *cmd /* in and out */,
+ const char *ns,
+ bson_t *encryptedFieldConfig,
+ bson_t *deleteTokens,
+ const char *coll_name,
+ mc_cmd_target_t cmd_target,
+ mongocrypt_status_t *status)
+{
+ bson_t out = BSON_INITIALIZER;
+ bson_t explain = BSON_INITIALIZER;
+ bson_iter_t iter;
+ bool ok = false;
+
+ if (0 != strcmp (cmd_name, "explain") || cmd_target == MC_TO_MONGOCRYPTD) {
+ // All commands except "explain" expect "encryptionInformation"
+ // at top-level. "explain" sent to mongocryptd expects
+ // "encryptionInformation" at top-level.
+ if (!_fle2_append_encryptionInformation (
+ cmd, ns, encryptedFieldConfig, deleteTokens, coll_name, status)) {
+ goto fail;
+ }
+ goto success;
+ }
+
+ // The "explain" command for csfle is a special case.
+ // mongocryptd expects "encryptionInformation" to be a sibling of the
+ // "explain" document. Example:
+ // {
+ // "explain": { "find": "to-mongocryptd" },
+ // "encryptionInformation": {}
+ // }
+ // csfle and mongod expect "encryptionInformation" to be nested in the
+ // "explain" document. Example:
+ // {
+ // "explain": {
+ // "find": "to-csfle-or-mongod"
+ // "encryptionInformation": {}
+ // }
+ // }
+ BSON_ASSERT (bson_iter_init_find (&iter, cmd, "explain"));
+ if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ CLIENT_ERR ("expected 'explain' to be document");
+ goto fail;
+ }
+
+ {
+ bson_t tmp;
+ const uint8_t *data;
+ uint32_t len;
+ bson_iter_document (&iter, &len, &data);
+ bson_init_static (&tmp, data, (size_t) len);
+ bson_copy_to (&tmp, &explain);
+ }
+
+ if (!_fle2_append_encryptionInformation (&explain,
+ ns,
+ encryptedFieldConfig,
+ deleteTokens,
+ coll_name,
+ status)) {
+ goto fail;
+ }
+
+ if (!BSON_APPEND_DOCUMENT (&out, "explain", &explain)) {
+ CLIENT_ERR ("unable to append 'explain' document");
+ goto fail;
+ }
+
+ bson_copy_to_excluding_noinit (cmd, &out, "explain", NULL);
+ bson_destroy (cmd);
+ if (!bson_steal (cmd, &out)) {
+ CLIENT_ERR ("failed to steal BSON without encryptionInformation");
+ goto fail;
+ }
+
+success:
+ ok = true;
+fail:
+ bson_destroy (&explain);
+ if (!ok) {
+ bson_destroy (&out);
+ }
+ return ok;
+}
+
+/* Construct the list collections command to send. */
+static bool
+_mongo_op_collinfo (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bson_t *cmd;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ cmd = BCON_NEW ("name", BCON_UTF8 (ectx->coll_name));
+ CRYPT_TRACEF (&ectx->parent.crypt->log, "constructed: %s\n", tmp_json (cmd));
+ _mongocrypt_buffer_steal_from_bson (&ectx->list_collections_filter, cmd);
+ out->data = ectx->list_collections_filter.data;
+ out->len = ectx->list_collections_filter.len;
+ return true;
+}
+
+static bool
+_set_schema_from_collinfo (mongocrypt_ctx_t *ctx, bson_t *collinfo)
+{
+ bson_iter_t iter;
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bool found_jsonschema = false;
+
+ /* Parse out the schema. */
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ /* Disallow views. */
+ if (bson_iter_init_find (&iter, collinfo, "type") &&
+ BSON_ITER_HOLDS_UTF8 (&iter) && bson_iter_utf8 (&iter, NULL) &&
+ 0 == strcmp ("view", bson_iter_utf8 (&iter, NULL))) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "cannot auto encrypt a view");
+ }
+
+ if (!bson_iter_init (&iter, collinfo)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "BSON malformed");
+ }
+
+ if (bson_iter_find_descendant (&iter, "options.encryptedFields", &iter)) {
+ if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "options.encryptedFields is not a BSON document");
+ }
+ if (!_mongocrypt_buffer_copy_from_document_iter (
+ &ectx->encrypted_field_config, &iter)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "unable to copy options.encryptedFields");
+ }
+ bson_t efc_bson;
+ if (!_mongocrypt_buffer_to_bson (&ectx->encrypted_field_config,
+ &efc_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "unable to create BSON from encrypted_field_config");
+ }
+ if (!mc_EncryptedFieldConfig_parse (&ectx->efc, &efc_bson, ctx->status)) {
+ _mongocrypt_ctx_fail (ctx);
+ return false;
+ }
+ }
+
+ BSON_ASSERT (bson_iter_init (&iter, collinfo));
+
+ if (bson_iter_find_descendant (&iter, "options.validator", &iter) &&
+ BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ if (!bson_iter_recurse (&iter, &iter)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "BSON malformed");
+ }
+ while (bson_iter_next (&iter)) {
+ const char *key;
+
+ key = bson_iter_key (&iter);
+ BSON_ASSERT (key);
+ if (0 == strcmp ("$jsonSchema", key)) {
+ if (found_jsonschema) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "duplicate $jsonSchema fields found");
+ }
+ if (!_mongocrypt_buffer_copy_from_document_iter (&ectx->schema,
+ &iter)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed $jsonSchema");
+ }
+ found_jsonschema = true;
+ } else {
+ ectx->collinfo_has_siblings = true;
+ }
+ }
+ }
+
+ if (!found_jsonschema) {
+ bson_t empty = BSON_INITIALIZER;
+
+ _mongocrypt_buffer_steal_from_bson (&ectx->schema, &empty);
+ }
+
+
+ return true;
+}
+
+/* get_command_name returns the name of a command. The command name is the first
+ * field. For example, the command name of: {"find": "foo", "filter": {"bar":
+ * 1}} is "find". */
+const char *
+get_command_name (_mongocrypt_buffer_t *cmd, mongocrypt_status_t *status)
+{
+ bson_t cmd_bson;
+ bson_iter_t iter;
+ const char *cmd_name;
+
+ if (!_mongocrypt_buffer_to_bson (cmd, &cmd_bson)) {
+ CLIENT_ERR ("unable to convert command buffer to BSON");
+ return NULL;
+ }
+
+ if (!bson_iter_init (&iter, &cmd_bson)) {
+ CLIENT_ERR ("unable to iterate over command BSON");
+ return NULL;
+ }
+
+ /* The command name is the first key. */
+ if (!bson_iter_next (&iter)) {
+ CLIENT_ERR ("unexpected empty BSON for command");
+ return NULL;
+ }
+
+ cmd_name = bson_iter_key (&iter);
+ if (!cmd_name) {
+ CLIENT_ERR ("unable to get command name from BSON");
+ return NULL;
+ }
+ return cmd_name;
+}
+
+static bool
+command_needs_deleteTokens (const char *command_name)
+{
+ const char *cmds_needing_deleteTokens[] = {
+ "delete", "update", "findAndModify"};
+
+ size_t i;
+ for (i = 0; i < sizeof (cmds_needing_deleteTokens) /
+ sizeof (cmds_needing_deleteTokens[0]);
+ i++) {
+ if (0 == strcmp (cmds_needing_deleteTokens[i], command_name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/* context_uses_fle2 returns true if the context uses FLE 2 behavior.
+ * If a collection has an encryptedFields document, it uses FLE 2.
+ */
+static bool
+context_uses_fle2 (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ return !_mongocrypt_buffer_empty (&ectx->encrypted_field_config);
+}
+
+/* _fle2_collect_keys_for_deleteTokens requests keys required to produce
+ * deleteTokens. deleteTokens is only applicable to FLE 2. */
+static bool
+_fle2_collect_keys_for_deleteTokens (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+
+ /* deleteTokens are only appended for FLE 2. */
+ if (!context_uses_fle2 (ctx)) {
+ return true;
+ }
+
+ const char *cmd_name = ectx->cmd_name;
+
+ if (!command_needs_deleteTokens (cmd_name)) {
+ /* Command does not require deleteTokens. */
+ return true;
+ }
+
+ mc_EncryptedField_t *field;
+
+ for (field = ectx->efc.fields; field != NULL; field = field->next) {
+ if (field->has_queries) {
+ if (!_mongocrypt_key_broker_request_id (&ctx->kb, &field->keyId)) {
+ _mongocrypt_key_broker_status (&ctx->kb, ctx->status);
+ _mongocrypt_ctx_fail (ctx);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/* _fle2_collect_keys_for_compact requests keys required to produce
+ * compactionTokens. compactionTokens is only applicable to FLE 2. */
+static bool
+_fle2_collect_keys_for_compact (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ /* compactionTokens are only appended for FLE 2. */
+ if (!context_uses_fle2 (ctx)) {
+ return true;
+ }
+
+ const char *cmd_name = ectx->cmd_name;
+
+ if (0 != strcmp (cmd_name, "compactStructuredEncryptionData")) {
+ return true;
+ }
+
+ /* compactStructuredEncryptionData must not be sent to mongocryptd. */
+ ectx->bypass_query_analysis = true;
+
+ mc_EncryptedField_t *field;
+
+ for (field = ectx->efc.fields; field != NULL; field = field->next) {
+ if (!_mongocrypt_key_broker_request_id (&ctx->kb, &field->keyId)) {
+ _mongocrypt_key_broker_status (&ctx->kb, ctx->status);
+ _mongocrypt_ctx_fail (ctx);
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool
+_mongo_feed_collinfo (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
+{
+ bson_t as_bson;
+
+ _mongocrypt_ctx_encrypt_t *ectx;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ if (!bson_init_static (&as_bson, in->data, in->len)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "BSON malformed");
+ }
+
+ /* Cache the received collinfo. */
+ if (!_mongocrypt_cache_add_copy (
+ &ctx->crypt->cache_collinfo, ectx->ns, &as_bson, ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ if (!_set_schema_from_collinfo (ctx, &as_bson)) {
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+_try_run_csfle_marking (mongocrypt_ctx_t *ctx);
+
+static bool
+_mongo_done_collinfo (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ if (_mongocrypt_buffer_empty (&ectx->schema)) {
+ bson_t empty_collinfo = BSON_INITIALIZER;
+
+ /* If no collinfo was fed, cache an empty collinfo. */
+ if (!_mongocrypt_cache_add_copy (&ctx->crypt->cache_collinfo,
+ ectx->ns,
+ &empty_collinfo,
+ ctx->status)) {
+ bson_destroy (&empty_collinfo);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ bson_destroy (&empty_collinfo);
+ }
+
+ if (!_fle2_collect_keys_for_deleteTokens (ctx)) {
+ return false;
+ }
+
+ if (!_fle2_collect_keys_for_compact (ctx)) {
+ return false;
+ }
+
+ if (ectx->bypass_query_analysis) {
+ /* Keys may have been requested for deleteTokens or compactionTokens.
+ * Finish key requests. */
+ _mongocrypt_key_broker_requests_done (&ctx->kb);
+ return _mongocrypt_ctx_state_from_key_broker (ctx);
+ }
+ ectx->parent.state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
+ return _try_run_csfle_marking (ctx);
+}
+
+
+static bool
+_fle2_mongo_op_markings (mongocrypt_ctx_t *ctx, bson_t *out)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bson_t cmd_bson = BSON_INITIALIZER,
+ encrypted_field_config_bson = BSON_INITIALIZER;
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ BSON_ASSERT (ctx->state == MONGOCRYPT_CTX_NEED_MONGO_MARKINGS);
+ BSON_ASSERT (context_uses_fle2 (ctx));
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &cmd_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "unable to convert original_cmd to BSON");
+ }
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->encrypted_field_config,
+ &encrypted_field_config_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "unable to convert encrypted_field_config to BSON");
+ }
+
+ const char *cmd_name = ectx->cmd_name;
+
+ // If input command included $db, do not include it in the command to
+ // mongocryptd. Drivers are expected to append $db in the RunCommand helper
+ // used to send the command.
+ bson_init (out);
+ bson_copy_to_excluding_noinit (&cmd_bson, out, "$db", NULL);
+ if (!_fle2_insert_encryptionInformation (
+ cmd_name,
+ out,
+ ectx->ns,
+ &encrypted_field_config_bson,
+ NULL /* deleteTokens */,
+ ectx->coll_name,
+ ctx->crypt->csfle.okay ? MC_TO_CSFLE : MC_TO_MONGOCRYPTD,
+ ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ return true;
+}
+
+
+/**
+ * @brief Create the server-side command that contains information for
+ * generating encryption markings via query analysis.
+ *
+ * @param ctx The encryption context.
+ * @param out The destination of the generate BSON document
+ * @return true On success
+ * @return false Otherwise. Sets a failing status message in this case.
+ */
+static bool
+_create_markings_cmd_bson (mongocrypt_ctx_t *ctx, bson_t *out)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ if (context_uses_fle2 (ctx)) {
+ // Defer to FLE2 to generate the markings command
+ return _fle2_mongo_op_markings (ctx, out);
+ }
+
+ // For FLE1:
+ // Get the original command document
+ bson_t bson_view = BSON_INITIALIZER;
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &bson_view)) {
+ _mongocrypt_ctx_fail_w_msg (ctx, "invalid BSON cmd");
+ return false;
+ }
+
+ // Copy the command to the output
+ // If input command included $db, do not include it in the command to
+ // mongocryptd. Drivers are expected to append $db in the RunCommand helper
+ // used to send the command.
+ bson_init (out);
+ bson_copy_to_excluding_noinit (&bson_view, out, "$db", NULL);
+
+ if (!_mongocrypt_buffer_empty (&ectx->schema)) {
+ // We have a schema buffer. View it as BSON:
+ if (!_mongocrypt_buffer_to_bson (&ectx->schema, &bson_view)) {
+ _mongocrypt_ctx_fail_w_msg (ctx, "invalid BSON schema");
+ return false;
+ }
+ // Append the jsonSchema to the output command
+ BSON_APPEND_DOCUMENT (out, "jsonSchema", &bson_view);
+ } else {
+ bson_t empty = BSON_INITIALIZER;
+ BSON_APPEND_DOCUMENT (out, "jsonSchema", &empty);
+ }
+
+ // if a local schema was not set, set isRemoteSchema=true
+ BSON_APPEND_BOOL (out, "isRemoteSchema", !ectx->used_local_schema);
+ return true;
+}
+
+
+static bool
+_mongo_op_markings (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ if (ectx->ismaster.needed) {
+ if (_mongocrypt_buffer_empty (&ectx->ismaster.cmd)) {
+ bson_t ismaster_cmd = BSON_INITIALIZER;
+ // Store the generated command:
+ BSON_APPEND_INT32 (&ismaster_cmd, "isMaster", 1);
+ _mongocrypt_buffer_steal_from_bson (&ectx->ismaster.cmd,
+ &ismaster_cmd);
+ }
+
+ out->data = ectx->ismaster.cmd.data;
+ out->len = ectx->ismaster.cmd.len;
+ return true;
+ }
+
+ if (_mongocrypt_buffer_empty (&ectx->mongocryptd_cmd)) {
+ // We need to generate the command document
+ bson_t cmd_bson = BSON_INITIALIZER;
+ if (!_create_markings_cmd_bson (ctx, &cmd_bson)) {
+ // Failed
+ bson_destroy (&cmd_bson);
+ return false;
+ }
+ // Store the generated command:
+ _mongocrypt_buffer_steal_from_bson (&ectx->mongocryptd_cmd, &cmd_bson);
+ }
+
+ // If we reach here, we have a valid mongocrypt_cmd
+ out->data = ectx->mongocryptd_cmd.data;
+ out->len = ectx->mongocryptd_cmd.len;
+ return true;
+}
+
+
+static bool
+_collect_key_from_marking (void *ctx,
+ _mongocrypt_buffer_t *in,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_marking_t marking;
+ _mongocrypt_key_broker_t *kb;
+ bool res;
+
+ kb = (_mongocrypt_key_broker_t *) ctx;
+
+ if (!_mongocrypt_marking_parse_unowned (in, &marking, status)) {
+ _mongocrypt_marking_cleanup (&marking);
+ return false;
+ }
+
+ if (marking.type == MONGOCRYPT_MARKING_FLE1_BY_ID) {
+ res = _mongocrypt_key_broker_request_id (kb, &marking.key_id);
+ } else if (marking.type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME) {
+ res = _mongocrypt_key_broker_request_name (kb, &marking.key_alt_name);
+ } else {
+ BSON_ASSERT (marking.type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
+ res =
+ _mongocrypt_key_broker_request_id (kb, &marking.fle2.index_key_id) &&
+ _mongocrypt_key_broker_request_id (kb, &marking.fle2.user_key_id);
+ }
+
+ if (!res) {
+ _mongocrypt_key_broker_status (kb, status);
+ _mongocrypt_marking_cleanup (&marking);
+ return false;
+ }
+
+ _mongocrypt_marking_cleanup (&marking);
+
+ return true;
+}
+
+
+static bool
+_mongo_feed_markings (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
+{
+ /* Find keys. */
+ bson_t as_bson;
+ bson_iter_t iter;
+ _mongocrypt_ctx_encrypt_t *ectx;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ if (!_mongocrypt_binary_to_bson (in, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed BSON");
+ }
+
+ if (ectx->ismaster.needed) {
+ /* This is a response to the 'isMaster' command. */
+ if (!bson_iter_init_find (&iter, &as_bson, "maxWireVersion")) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx,
+ "expected to find 'maxWireVersion' in isMaster response, but did "
+ "not.");
+ }
+ if (!BSON_ITER_HOLDS_INT32 (&iter)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "expected 'maxWireVersion' to be int32.");
+ }
+ ectx->ismaster.maxwireversion = bson_iter_int32 (&iter);
+ return true;
+ }
+
+ if (bson_iter_init_find (&iter, &as_bson, "schemaRequiresEncryption") &&
+ !bson_iter_as_bool (&iter)) {
+ /* TODO: update cache: this schema does not require encryption. */
+
+ /* If using a local schema, warn if there are no encrypted fields. */
+ if (ectx->used_local_schema) {
+ _mongocrypt_log (
+ &ctx->crypt->log,
+ MONGOCRYPT_LOG_LEVEL_WARNING,
+ "local schema used but does not have encryption specifiers");
+ }
+ return true;
+ } else {
+ /* if the schema requires encryption, but has sibling validators, error.
+ */
+ if (ectx->collinfo_has_siblings) {
+ return _mongocrypt_ctx_fail_w_msg (ctx,
+ "schema requires encryption, "
+ "but collection JSON schema "
+ "validator has siblings");
+ }
+ }
+
+ if (bson_iter_init_find (&iter, &as_bson, "hasEncryptedPlaceholders") &&
+ !bson_iter_as_bool (&iter)) {
+ return true;
+ }
+
+ if (!bson_iter_init_find (&iter, &as_bson, "result")) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed marking, no 'result'");
+ }
+
+ if (!_mongocrypt_buffer_copy_from_document_iter (&ectx->marked_cmd, &iter)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "malformed marking, 'result' must be a document");
+ }
+
+ if (!bson_iter_recurse (&iter, &iter)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "malformed marking, could not recurse into 'result'");
+ }
+ if (!_mongocrypt_traverse_binary_in_bson (_collect_key_from_marking,
+ (void *) &ctx->kb,
+ TRAVERSE_MATCH_MARKING,
+ &iter,
+ ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ return true;
+}
+
+static bool
+mongocrypt_ctx_encrypt_ismaster_done (mongocrypt_ctx_t *ctx);
+
+static bool
+_mongo_done_markings (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ if (ectx->ismaster.needed) {
+ return mongocrypt_ctx_encrypt_ismaster_done (ctx);
+ }
+ (void) _mongocrypt_key_broker_requests_done (&ctx->kb);
+ return _mongocrypt_ctx_state_from_key_broker (ctx);
+}
+
+/**
+ * @brief Append $db to a command being passed to csfle.
+ */
+static bool
+_add_dollar_db (const char *cmd_name,
+ bson_t *cmd,
+ const char *db_name,
+ mongocrypt_status_t *status)
+{
+ bson_t out = BSON_INITIALIZER;
+ bson_t explain = BSON_INITIALIZER;
+ bson_iter_t iter;
+ bool ok = false;
+
+ if (!bson_iter_init_find (&iter, cmd, "$db")) {
+ if (!BSON_APPEND_UTF8 (cmd, "$db", db_name)) {
+ CLIENT_ERR ("failed to append '$db'");
+ goto fail;
+ }
+ }
+
+ if (0 != strcmp (cmd_name, "explain")) {
+ goto success;
+ }
+
+ // The "explain" command for csfle is a special case.
+ // csfle expects "$db" to be nested in the "explain" document and match the
+ // top-level "$db". Example:
+ // {
+ // "explain": {
+ // "find": "to-csfle"
+ // "$db": "db"
+ // }
+ // "$db": "db"
+ // }
+ BSON_ASSERT (bson_iter_init_find (&iter, cmd, "explain"));
+ if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ CLIENT_ERR ("expected 'explain' to be document");
+ goto fail;
+ }
+
+ {
+ bson_t tmp;
+ const uint8_t *data;
+ uint32_t len;
+ bson_iter_document (&iter, &len, &data);
+ bson_init_static (&tmp, data, (size_t) len);
+ bson_copy_to (&tmp, &explain);
+ }
+
+ if (!BSON_APPEND_UTF8 (&explain, "$db", db_name)) {
+ CLIENT_ERR ("failed to append '$db'");
+ goto fail;
+ }
+
+ if (!BSON_APPEND_DOCUMENT (&out, "explain", &explain)) {
+ CLIENT_ERR ("unable to append 'explain' document");
+ goto fail;
+ }
+
+ bson_copy_to_excluding_noinit (cmd, &out, "explain", NULL);
+ bson_destroy (cmd);
+ if (!bson_steal (cmd, &out)) {
+ CLIENT_ERR ("failed to steal BSON without encryptionInformation");
+ goto fail;
+ }
+
+success:
+ ok = true;
+fail:
+ bson_destroy (&explain);
+ if (!ok) {
+ bson_destroy (&out);
+ }
+ return ok;
+}
+
+/**
+ * @brief Attempt to generate csfle markings using a csfle dynamic library.
+ *
+ * @param ctx A context which has state NEED_MONGO_MARKINGS
+ * @return true On success
+ * @return false On error.
+ *
+ * This should be called only when we are ready for markings in the command
+ * document. This function will only do anything if the csfle dynamic library
+ * is loaded, otherwise it returns success immediately and leaves the state
+ * as NEED_MONGO_MARKINGS.
+ *
+ * If csfle is loaded, this function will request the csfle library generate a
+ * marked command document based on the caller's schema. If successful, the
+ * state will be changed via @ref _mongo_done_markings().
+ *
+ * The purpose of this function is to short-circuit the phase of encryption
+ * wherein we would normally return to the driver and give them the opportunity
+ * to generate the markings by passing a special command to a mongocryptd daemon
+ * process. Instead, we'll do it ourselves here, if possible.
+ */
+static bool
+_try_run_csfle_marking (mongocrypt_ctx_t *ctx)
+{
+ BSON_ASSERT (
+ ctx->state == MONGOCRYPT_CTX_NEED_MONGO_MARKINGS &&
+ "_try_run_csfle_marking() should only be called when mongocrypt is "
+ "ready for markings");
+
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ // We have a valid schema and just need to mark the fields for encryption
+ if (!ctx->crypt->csfle.okay) {
+ // We don't have a csfle library to use to obtain the markings. It's up to
+ // caller to resolve them.
+ return true;
+ }
+
+ _mongo_crypt_v1_vtable csfle = ctx->crypt->csfle;
+ mongo_crypt_v1_lib *csfle_lib = ctx->crypt->csfle_lib;
+ BSON_ASSERT (csfle_lib);
+ bool okay = false;
+
+ // Obtain the command for markings
+ bson_t cmd = BSON_INITIALIZER;
+ if (!_create_markings_cmd_bson (ctx, &cmd)) {
+ goto fail_create_cmd;
+ }
+
+ const char *cmd_name = ectx->cmd_name;
+
+ if (!_add_dollar_db (cmd_name, &cmd, ectx->db_name, ctx->status)) {
+ _mongocrypt_ctx_fail (ctx);
+ goto fail_create_cmd;
+ }
+
+#define CHECK_CSFLE_ERROR(Func, FailLabel) \
+ if (1) { \
+ if (csfle.status_get_error (status)) { \
+ _mongocrypt_set_error (ctx->status, \
+ MONGOCRYPT_STATUS_ERROR_CRYPT_SHARED, \
+ MONGOCRYPT_GENERIC_ERROR_CODE, \
+ "csfle " #Func \
+ " failed: %s [Error %d, code %d]", \
+ csfle.status_get_explanation (status), \
+ csfle.status_get_error (status), \
+ csfle.status_get_code (status)); \
+ _mongocrypt_ctx_fail (ctx); \
+ goto FailLabel; \
+ } \
+ } else \
+ ((void) 0)
+
+ mongo_crypt_v1_status *status = csfle.status_create ();
+ BSON_ASSERT (status);
+
+ mongo_crypt_v1_query_analyzer *qa =
+ csfle.query_analyzer_create (csfle_lib, status);
+ CHECK_CSFLE_ERROR ("query_analyzer_create", fail_qa_create);
+
+ uint32_t marked_bson_len = 0;
+ uint8_t *marked_bson = csfle.analyze_query (qa,
+ bson_get_data (&cmd),
+ ectx->ns,
+ (uint32_t) strlen (ectx->ns),
+ &marked_bson_len,
+ status);
+ CHECK_CSFLE_ERROR ("analyze_query", fail_analyze_query);
+
+ // Copy out the marked document.
+ mongocrypt_binary_t *marked =
+ mongocrypt_binary_new_from_data (marked_bson, marked_bson_len);
+ if (!_mongo_feed_markings (ctx, marked)) {
+ _mongocrypt_ctx_fail_w_msg (
+ ctx, "Consuming the generated csfle markings failed");
+ goto fail_feed_markings;
+ }
+
+ okay = _mongo_done_markings (ctx);
+ if (!okay) {
+ _mongocrypt_ctx_fail_w_msg (
+ ctx, "Finalizing the generated csfle markings failed");
+ }
+
+fail_feed_markings:
+ mongocrypt_binary_destroy (marked);
+ csfle.bson_free (marked_bson);
+fail_analyze_query:
+ csfle.query_analyzer_destroy (qa);
+fail_qa_create:
+ csfle.status_destroy (status);
+fail_create_cmd:
+ bson_destroy (&cmd);
+ return okay;
+}
+
+
+static bool
+_marking_to_bson_value (void *ctx,
+ _mongocrypt_marking_t *marking,
+ bson_value_t *out,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_ciphertext_t ciphertext;
+ _mongocrypt_buffer_t serialized_ciphertext = {0};
+ bool ret = false;
+
+ BSON_ASSERT (out);
+
+ _mongocrypt_ciphertext_init (&ciphertext);
+
+ if (!_mongocrypt_marking_to_ciphertext (ctx, marking, &ciphertext, status)) {
+ goto fail;
+ }
+
+ if ((ciphertext.blob_subtype == MC_SUBTYPE_FLE2InsertUpdatePayload) ||
+ (ciphertext.blob_subtype == MC_SUBTYPE_FLE2FindEqualityPayload)) {
+ /* ciphertext_data is already a BSON object, just need to prepend
+ * blob_subtype */
+ _mongocrypt_buffer_init_size (&serialized_ciphertext,
+ ciphertext.data.len + 1);
+ serialized_ciphertext.data[0] = ciphertext.blob_subtype;
+ memcpy (serialized_ciphertext.data + 1,
+ ciphertext.data.data,
+ ciphertext.data.len);
+
+ } else if (!_mongocrypt_serialize_ciphertext (&ciphertext,
+ &serialized_ciphertext)) {
+ CLIENT_ERR ("malformed ciphertext");
+ goto fail;
+ };
+
+ /* ownership of serialized_ciphertext is transferred to caller. */
+ out->value_type = BSON_TYPE_BINARY;
+ out->value.v_binary.data = serialized_ciphertext.data;
+ out->value.v_binary.data_len = serialized_ciphertext.len;
+ out->value.v_binary.subtype = (bson_subtype_t) 6;
+
+ ret = true;
+
+fail:
+ _mongocrypt_ciphertext_cleanup (&ciphertext);
+ return ret;
+}
+
+
+static bool
+_replace_marking_with_ciphertext (void *ctx,
+ _mongocrypt_buffer_t *in,
+ bson_value_t *out,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_marking_t marking;
+ bool ret;
+
+ BSON_ASSERT (in);
+
+ memset (&marking, 0, sizeof (marking));
+
+ if (!_mongocrypt_marking_parse_unowned (in, &marking, status)) {
+ _mongocrypt_marking_cleanup (&marking);
+ return false;
+ }
+
+ ret = _marking_to_bson_value (ctx, &marking, out, status);
+ _mongocrypt_marking_cleanup (&marking);
+ return ret;
+}
+
+
+/* generate_delete_tokens generates the 'deleteTokens' document to be appended
+ * to 'encryptionInformation'. */
+static bson_t *
+generate_delete_tokens (_mongocrypt_crypto_t *crypto,
+ _mongocrypt_key_broker_t *kb,
+ mc_EncryptedFieldConfig_t *efc,
+ mongocrypt_status_t *status)
+{
+ bool ret = false;
+ bson_t *out = bson_new ();
+ mc_EncryptedField_t *ef;
+
+ for (ef = efc->fields; ef != NULL; ef = ef->next) {
+ _mongocrypt_buffer_t IndexKey = {0};
+ _mongocrypt_buffer_t TokenKey = {0};
+ mc_ServerDataEncryptionLevel1Token_t *sdel1t = NULL;
+ mc_CollectionsLevel1Token_t *cl1t = NULL;
+ mc_ECOCToken_t *ecoc = NULL;
+ bool loop_ok = false;
+ /* deleteTokens are only necessary for indexed fields. */
+ if (!ef->has_queries) {
+ goto loop_continue;
+ }
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (
+ kb, &ef->keyId, &IndexKey)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto loop_fail;
+ }
+
+ /* Get the TokenKey from the last 32 bytes of IndexKey */
+ if (!_mongocrypt_buffer_from_subrange (&TokenKey,
+ &IndexKey,
+ IndexKey.len -
+ MONGOCRYPT_TOKEN_KEY_LEN,
+ MONGOCRYPT_TOKEN_KEY_LEN)) {
+ CLIENT_ERR (
+ "generate_delete_tokens unable to parse TokenKey from IndexKey");
+ goto loop_fail;
+ }
+
+ sdel1t =
+ mc_ServerDataEncryptionLevel1Token_new (crypto, &TokenKey, status);
+ if (!sdel1t) {
+ goto loop_fail;
+ }
+
+ cl1t = mc_CollectionsLevel1Token_new (crypto, &TokenKey, status);
+ if (!cl1t) {
+ goto loop_fail;
+ }
+
+ ecoc = mc_ECOCToken_new (crypto, cl1t, status);
+ if (!ecoc) {
+ goto loop_fail;
+ }
+
+ bson_t field_bson;
+ if (!BSON_APPEND_DOCUMENT_BEGIN (out, ef->path, &field_bson)) {
+ CLIENT_ERR ("failed to begin document for 'deleteTokens.%s'",
+ ef->path);
+ goto loop_fail;
+ }
+
+ if (!BSON_APPEND_BINARY (
+ &field_bson,
+ "e",
+ BSON_SUBTYPE_BINARY,
+ mc_ServerDataEncryptionLevel1Token_get (sdel1t)->data,
+ mc_ServerDataEncryptionLevel1Token_get (sdel1t)->len)) {
+ CLIENT_ERR ("failed to append ServerDataEncryptionLevel1Token for %s",
+ ef->path);
+ goto loop_fail;
+ }
+
+ if (!BSON_APPEND_BINARY (&field_bson,
+ "o",
+ BSON_SUBTYPE_BINARY,
+ mc_ECOCToken_get (ecoc)->data,
+ mc_ECOCToken_get (ecoc)->len)) {
+ CLIENT_ERR ("failed to append ECOCToken for %s", ef->path);
+ goto loop_fail;
+ }
+
+ if (!bson_append_document_end (out, &field_bson)) {
+ CLIENT_ERR ("failed to end document for 'deleteTokens.%s'", ef->path);
+ goto loop_fail;
+ }
+
+ loop_continue:
+ loop_ok = true;
+ loop_fail:
+ _mongocrypt_buffer_cleanup (&IndexKey);
+ _mongocrypt_buffer_cleanup (&TokenKey);
+ mc_ServerDataEncryptionLevel1Token_destroy (sdel1t);
+ mc_CollectionsLevel1Token_destroy (cl1t);
+ mc_ECOCToken_destroy (ecoc);
+ if (!loop_ok) {
+ goto fail;
+ }
+ }
+
+ ret = true;
+fail:
+ if (!ret) {
+ bson_destroy (out);
+ return NULL;
+ }
+ return out;
+}
+
+static bool
+_check_for_payload_requiring_encryptionInformation (void *ctx,
+ _mongocrypt_buffer_t *in,
+ mongocrypt_status_t *status)
+{
+ bool *out = (bool *) ctx;
+
+ if (in->len < 1) {
+ CLIENT_ERR ("unexpected empty FLE payload");
+ return false;
+ }
+
+ if (in->data[0] == MC_SUBTYPE_FLE2InsertUpdatePayload) {
+ *out = true;
+ return true;
+ }
+
+ if (in->data[0] == MC_SUBTYPE_FLE2FindEqualityPayload) {
+ *out = true;
+ return true;
+ }
+
+ return true;
+}
+
+typedef struct {
+ bool must_omit;
+ bool ok;
+} moe_result;
+
+// must_omit_encryptionInformation returns true if the command
+// must omit the "encryptionInformation" field when sent to mongod / mongos.
+static moe_result
+must_omit_encryptionInformation (const char *command_name,
+ const bson_t *command,
+ mongocrypt_status_t *status)
+{
+ // eligible_commands may omit encryptionInformation if the command does not
+ // contain payloads requiring encryption.
+ const char *eligible_commands[] = {
+ "find", "aggregate", "distinct", "count", "insert"};
+ size_t i;
+ bool found = false;
+
+ // prohibited_commands prohibit encryptionInformation on mongod / mongos.
+ const char *prohibited_commands[] = {
+ "compactStructuredEncryptionData", "create", "collMod", "createIndexes"};
+
+ for (i = 0;
+ i < sizeof (prohibited_commands) / sizeof (prohibited_commands[0]);
+ i++) {
+ if (0 == strcmp (prohibited_commands[i], command_name)) {
+ return (moe_result){.ok = true, .must_omit = true};
+ }
+ }
+
+ for (i = 0; i < sizeof (eligible_commands) / sizeof (eligible_commands[0]);
+ i++) {
+ if (0 == strcmp (eligible_commands[i], command_name)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return (moe_result){.ok = true};
+ }
+
+ bool has_payload_requiring_encryptionInformation = false;
+ bson_iter_t iter;
+ if (!bson_iter_init (&iter, command)) {
+ CLIENT_ERR ("unable to iterate command");
+ return (moe_result){.ok = false};
+ }
+ if (!_mongocrypt_traverse_binary_in_bson (
+ _check_for_payload_requiring_encryptionInformation,
+ &has_payload_requiring_encryptionInformation,
+ TRAVERSE_MATCH_SUBTYPE6,
+ &iter,
+ status)) {
+ return (moe_result){.ok = false};
+ }
+
+ if (!has_payload_requiring_encryptionInformation) {
+ return (moe_result){.ok = true, .must_omit = true};
+ }
+ return (moe_result){.ok = true, .must_omit = false};
+}
+
+/* _fle2_append_compactionTokens appends compactionTokens if command_name is
+ * "compactStructuredEncryptionData" */
+static bool
+_fle2_append_compactionTokens (_mongocrypt_crypto_t *crypto,
+ _mongocrypt_key_broker_t *kb,
+ mc_EncryptedFieldConfig_t *efc,
+ const char *command_name,
+ bson_t *out,
+ mongocrypt_status_t *status)
+{
+ bson_t result_compactionTokens;
+ bool ret = false;
+
+ if (0 != strcmp (command_name, "compactStructuredEncryptionData")) {
+ return true;
+ }
+
+ BSON_APPEND_DOCUMENT_BEGIN (
+ out, "compactionTokens", &result_compactionTokens);
+
+ mc_EncryptedField_t *ptr;
+ for (ptr = efc->fields; ptr != NULL; ptr = ptr->next) {
+ /* Append ECOC token. */
+ _mongocrypt_buffer_t key = {0};
+ _mongocrypt_buffer_t tokenkey = {0};
+ mc_CollectionsLevel1Token_t *cl1t = NULL;
+ mc_ECOCToken_t *ecoct = NULL;
+ bool ecoc_ok = false;
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, &ptr->keyId, &key)) {
+ _mongocrypt_key_broker_status (kb, status);
+ goto ecoc_fail;
+ }
+ /* The last 32 bytes of the user key are the token key. */
+ if (!_mongocrypt_buffer_from_subrange (&tokenkey,
+ &key,
+ key.len - MONGOCRYPT_TOKEN_KEY_LEN,
+ MONGOCRYPT_TOKEN_KEY_LEN)) {
+ CLIENT_ERR ("unable to get TokenKey from Data Encryption Key");
+ goto ecoc_fail;
+ }
+ cl1t = mc_CollectionsLevel1Token_new (crypto, &tokenkey, status);
+ if (!cl1t) {
+ goto ecoc_fail;
+ }
+
+ ecoct = mc_ECOCToken_new (crypto, cl1t, status);
+ if (!ecoct) {
+ goto ecoc_fail;
+ }
+
+ const _mongocrypt_buffer_t *ecoct_buf = mc_ECOCToken_get (ecoct);
+
+ BSON_APPEND_BINARY (&result_compactionTokens,
+ ptr->path,
+ BSON_SUBTYPE_BINARY,
+ ecoct_buf->data,
+ ecoct_buf->len);
+
+ ecoc_ok = true;
+ ecoc_fail:
+ mc_ECOCToken_destroy (ecoct);
+ mc_CollectionsLevel1Token_destroy (cl1t);
+ _mongocrypt_buffer_cleanup (&key);
+ if (!ecoc_ok) {
+ goto fail;
+ }
+ }
+
+ bson_append_document_end (out, &result_compactionTokens);
+
+ ret = true;
+fail:
+ return ret;
+}
+
+
+/**
+ * @brief Removes "encryptionInformation" from cmd.
+ */
+static bool
+_fle2_strip_encryptionInformation (const char *cmd_name,
+ bson_t *cmd /* in and out */,
+ mongocrypt_status_t *status)
+{
+ bson_t stripped = BSON_INITIALIZER;
+ bool ok = false;
+
+ if (0 != strcmp (cmd_name, "explain")) {
+ bson_copy_to_excluding_noinit (
+ cmd, &stripped, "encryptionInformation", NULL);
+ goto success;
+ }
+
+ // The 'explain' command is a special case.
+ // 'encryptionInformation' is returned from mongocryptd and csfle nested
+ // inside 'explain'. Example:
+ // {
+ // "explain": {
+ // "find": "coll"
+ // "encryptionInformation": {}
+ // }
+ // }
+ bson_iter_t iter;
+ bson_t explain;
+
+ BSON_ASSERT (bson_iter_init_find (&iter, cmd, "explain"));
+ if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ CLIENT_ERR ("expected 'explain' to be document");
+ goto fail;
+ }
+
+ {
+ bson_t tmp;
+ const uint8_t *data;
+ uint32_t len;
+ bson_iter_document (&iter, &len, &data);
+ bson_init_static (&tmp, data, (size_t) len);
+ bson_init (&explain);
+ bson_copy_to_excluding_noinit (
+ &tmp, &explain, "encryptionInformation", NULL);
+ }
+
+ if (!BSON_APPEND_DOCUMENT (&stripped, "explain", &explain)) {
+ bson_destroy (&explain);
+ CLIENT_ERR ("unable to append 'explain'");
+ goto fail;
+ }
+ bson_destroy (&explain);
+ bson_copy_to_excluding_noinit (cmd, &stripped, "explain", NULL);
+
+success:
+ bson_destroy (cmd);
+ if (!bson_steal (cmd, &stripped)) {
+ CLIENT_ERR ("failed to steal BSON without encryptionInformation");
+ goto fail;
+ }
+ ok = true;
+fail:
+ if (!ok) {
+ bson_destroy (&stripped);
+ }
+ return ok;
+}
+
+/* Process a call to mongocrypt_ctx_finalize when an encryptedFieldConfig is
+ * associated with the command. */
+static bool
+_fle2_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ bson_t converted;
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bson_t encrypted_field_config_bson;
+ bson_t original_cmd_bson;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ BSON_ASSERT (context_uses_fle2 (ctx));
+ BSON_ASSERT (ctx->state == MONGOCRYPT_CTX_READY);
+
+ if (ectx->explicit) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "explicit encryption is not yet supported. See MONGOCRYPT-409.");
+ }
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->encrypted_field_config,
+ &encrypted_field_config_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "malformed bson in encrypted_field_config_bson");
+ }
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &original_cmd_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson in original_cmd");
+ }
+
+ /* If marked_cmd buffer is empty, there are no markings to encrypt. */
+ if (_mongocrypt_buffer_empty (&ectx->marked_cmd)) {
+ /* Append 'encryptionInformation' to the original command. */
+ bson_init (&converted);
+ bson_copy_to (&original_cmd_bson, &converted);
+ } else {
+ bson_t as_bson;
+ bson_iter_t iter;
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->marked_cmd, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
+ }
+
+ bson_iter_init (&iter, &as_bson);
+ bson_init (&converted);
+ if (!_mongocrypt_transform_binary_in_bson (
+ _replace_marking_with_ciphertext,
+ &ctx->kb,
+ TRAVERSE_MATCH_MARKING,
+ &iter,
+ &converted,
+ ctx->status)) {
+ bson_destroy (&converted);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ const char *command_name = ectx->cmd_name;
+
+ /* Remove the 'encryptionInformation' field. It is appended in the response
+ * from mongocryptd or csfle. */
+ if (!_fle2_strip_encryptionInformation (
+ command_name, &converted, ctx->status)) {
+ bson_destroy (&converted);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ bson_t *deleteTokens = NULL;
+ if (command_needs_deleteTokens (command_name)) {
+ deleteTokens = generate_delete_tokens (
+ ctx->crypt->crypto, &ctx->kb, &ectx->efc, ctx->status);
+ if (!deleteTokens) {
+ bson_destroy (&converted);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ moe_result result =
+ must_omit_encryptionInformation (command_name, &converted, ctx->status);
+ if (!result.ok) {
+ return false;
+ }
+
+ /* Append a new 'encryptionInformation'. */
+ if (!result.must_omit) {
+ if (!_fle2_insert_encryptionInformation (command_name,
+ &converted,
+ ectx->ns,
+ &encrypted_field_config_bson,
+ deleteTokens,
+ ectx->coll_name,
+ MC_TO_MONGOD,
+ ctx->status)) {
+ bson_destroy (&converted);
+ bson_destroy (deleteTokens);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+ bson_destroy (deleteTokens);
+
+ if (!_fle2_append_compactionTokens (ctx->crypt->crypto,
+ &ctx->kb,
+ &ectx->efc,
+ command_name,
+ &converted,
+ ctx->status)) {
+ bson_destroy (&converted);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ // If input command has $db, ensure output command has $db.
+ bson_iter_t iter;
+ if (bson_iter_init_find (&iter, &original_cmd_bson, "$db")) {
+ if (!bson_iter_init_find (&iter, &converted, "$db")) {
+ BSON_APPEND_UTF8 (&converted, "$db", ectx->db_name);
+ }
+ }
+
+ _mongocrypt_buffer_steal_from_bson (&ectx->encrypted_cmd, &converted);
+ _mongocrypt_buffer_to_binary (&ectx->encrypted_cmd, out);
+ ctx->state = MONGOCRYPT_CTX_DONE;
+
+ return true;
+}
+
+static bool
+_fle2_finalize_explicit (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ bool ret = false;
+ _mongocrypt_marking_t marking;
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ BSON_ASSERT (ctx->opts.index_type.set);
+
+ _mongocrypt_marking_init (&marking);
+ marking.type = MONGOCRYPT_MARKING_FLE2_ENCRYPTION;
+ if (ctx->opts.query_type.set) {
+ switch (ctx->opts.query_type.value) {
+ case MONGOCRYPT_QUERY_TYPE_EQUALITY:
+ marking.fle2.type = MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND;
+ break;
+ default:
+ _mongocrypt_ctx_fail_w_msg (ctx,
+ "Invalid value for EncryptOpts.queryType");
+ goto fail;
+ }
+ } else {
+ marking.fle2.type = MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT;
+ }
+
+ switch (ctx->opts.index_type.value) {
+ case MONGOCRYPT_INDEX_TYPE_EQUALITY:
+ marking.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_EQUALITY;
+ break;
+ case MONGOCRYPT_INDEX_TYPE_NONE:
+ marking.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED;
+ break;
+ default:
+ // This might be unreachable because of other validation. Better safe than
+ // sorry.
+ _mongocrypt_ctx_fail_w_msg (ctx,
+ "Invalid value for EncryptOpts.indexType");
+ goto fail;
+ }
+
+ /* Get iterator to input 'v' BSON value. */
+ {
+ bson_t as_bson;
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &as_bson)) {
+ _mongocrypt_ctx_fail_w_msg (ctx, "unable to convert input to BSON");
+ goto fail;
+ }
+
+ if (!bson_iter_init_find (&marking.v_iter, &as_bson, "v")) {
+ _mongocrypt_ctx_fail_w_msg (ctx,
+ "invalid input BSON, must contain 'v'");
+ goto fail;
+ }
+ }
+
+ _mongocrypt_buffer_copy_to (&ctx->opts.key_id, &marking.fle2.user_key_id);
+ if (!_mongocrypt_buffer_empty (&ctx->opts.index_key_id)) {
+ _mongocrypt_buffer_copy_to (&ctx->opts.index_key_id,
+ &marking.fle2.index_key_id);
+ } else {
+ _mongocrypt_buffer_copy_to (&ctx->opts.key_id,
+ &marking.fle2.index_key_id);
+ }
+
+ if (ctx->opts.contention_factor.set) {
+ marking.fle2.maxContentionCounter = ctx->opts.contention_factor.value;
+ } else if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY) {
+ _mongocrypt_ctx_fail_w_msg (
+ ctx, "contention factor required for indexed algorithm");
+ goto fail;
+ }
+
+ /* Convert marking to ciphertext. */
+ {
+ bson_value_t v_out;
+ /* v_wrapped is the BSON document { 'v': <v_out> }. */
+ bson_t v_wrapped = BSON_INITIALIZER;
+
+ if (!_marking_to_bson_value (&ctx->kb, &marking, &v_out, ctx->status)) {
+ bson_destroy (&v_wrapped);
+ _mongocrypt_ctx_fail (ctx);
+ goto fail;
+ }
+
+ bson_append_value (&v_wrapped, MONGOCRYPT_STR_AND_LEN ("v"), &v_out);
+ _mongocrypt_buffer_steal_from_bson (&ectx->encrypted_cmd, &v_wrapped);
+ _mongocrypt_buffer_to_binary (&ectx->encrypted_cmd, out);
+ ctx->state = MONGOCRYPT_CTX_DONE;
+ bson_value_destroy (&v_out);
+ }
+
+ ret = true;
+fail:
+ _mongocrypt_marking_cleanup (&marking);
+ return ret;
+}
+
+static bool
+_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ bson_t as_bson, converted;
+ bson_iter_t iter;
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bool res;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ if (context_uses_fle2 (ctx)) {
+ return _fle2_finalize (ctx, out);
+ } else if (ctx->opts.index_type.set) {
+ return _fle2_finalize_explicit (ctx, out);
+ }
+
+ if (!ectx->explicit) {
+ if (ctx->nothing_to_do) {
+ _mongocrypt_buffer_to_binary (&ectx->original_cmd, out);
+ ctx->state = MONGOCRYPT_CTX_DONE;
+ return true;
+ }
+ if (!_mongocrypt_buffer_to_bson (&ectx->marked_cmd, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
+ }
+
+ bson_iter_init (&iter, &as_bson);
+ bson_init (&converted);
+ if (!_mongocrypt_transform_binary_in_bson (
+ _replace_marking_with_ciphertext,
+ &ctx->kb,
+ TRAVERSE_MATCH_MARKING,
+ &iter,
+ &converted,
+ ctx->status)) {
+ bson_destroy (&converted);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ bson_t original_cmd_bson;
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd,
+ &original_cmd_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx,
+ "malformed bson in original_cmd");
+ }
+
+ // If input command has $db, ensure output command has $db.
+ bson_iter_t iter;
+ if (bson_iter_init_find (&iter, &original_cmd_bson, "$db")) {
+ if (!bson_iter_init_find (&iter, &converted, "$db")) {
+ BSON_APPEND_UTF8 (&converted, "$db", ectx->db_name);
+ }
+ }
+ } else {
+ /* For explicit encryption, we have no marking, but we can fake one */
+ _mongocrypt_marking_t marking;
+ bson_value_t value;
+
+ memset (&value, 0, sizeof (value));
+
+ _mongocrypt_marking_init (&marking);
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed bson");
+ }
+
+ if (!bson_iter_init_find (&iter, &as_bson, "v")) {
+ return _mongocrypt_ctx_fail_w_msg (ctx,
+ "invalid msg, must contain 'v'");
+ }
+
+
+ memcpy (&marking.v_iter, &iter, sizeof (bson_iter_t));
+ marking.algorithm = ctx->opts.algorithm;
+ _mongocrypt_buffer_set_to (&ctx->opts.key_id, &marking.key_id);
+ if (ctx->opts.key_alt_names) {
+ bson_value_copy (&ctx->opts.key_alt_names->value,
+ &marking.key_alt_name);
+ marking.type = MONGOCRYPT_MARKING_FLE1_BY_ALTNAME;
+ }
+
+ bson_init (&converted);
+ res = _marking_to_bson_value (&ctx->kb, &marking, &value, ctx->status);
+ if (res) {
+ bson_append_value (&converted, MONGOCRYPT_STR_AND_LEN ("v"), &value);
+ }
+
+ bson_value_destroy (&value);
+ _mongocrypt_marking_cleanup (&marking);
+
+ if (!res) {
+ bson_destroy (&converted);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ _mongocrypt_buffer_steal_from_bson (&ectx->encrypted_cmd, &converted);
+ _mongocrypt_buffer_to_binary (&ectx->encrypted_cmd, out);
+ ctx->state = MONGOCRYPT_CTX_DONE;
+
+ return true;
+}
+
+
+static void
+_cleanup (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ bson_free (ectx->ns);
+ bson_free (ectx->db_name);
+ bson_free (ectx->coll_name);
+ _mongocrypt_buffer_cleanup (&ectx->list_collections_filter);
+ _mongocrypt_buffer_cleanup (&ectx->schema);
+ _mongocrypt_buffer_cleanup (&ectx->encrypted_field_config);
+ _mongocrypt_buffer_cleanup (&ectx->original_cmd);
+ _mongocrypt_buffer_cleanup (&ectx->mongocryptd_cmd);
+ _mongocrypt_buffer_cleanup (&ectx->marked_cmd);
+ _mongocrypt_buffer_cleanup (&ectx->encrypted_cmd);
+ _mongocrypt_buffer_cleanup (&ectx->ismaster.cmd);
+ mc_EncryptedFieldConfig_cleanup (&ectx->efc);
+}
+
+
+static bool
+_try_schema_from_schema_map (mongocrypt_ctx_t *ctx)
+{
+ mongocrypt_t *crypt;
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bson_t schema_map;
+ bson_iter_t iter;
+
+ crypt = ctx->crypt;
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ if (_mongocrypt_buffer_empty (&crypt->opts.schema_map)) {
+ /* No schema map set. */
+ return true;
+ }
+
+ if (!_mongocrypt_buffer_to_bson (&crypt->opts.schema_map, &schema_map)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed schema map");
+ }
+
+ if (bson_iter_init_find (&iter, &schema_map, ectx->ns)) {
+ if (!_mongocrypt_buffer_copy_from_document_iter (&ectx->schema, &iter)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "malformed schema map");
+ }
+ ectx->used_local_schema = true;
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
+ }
+
+ /* No schema found in map. */
+ return true;
+}
+
+/* Check if the local encrypted field config map has an entry for this
+ * collection.
+ * If an encrypted field config is found, the context transitions to
+ * MONGOCRYPT_CTX_NEED_MONGO_MARKINGS. */
+static bool
+_fle2_try_encrypted_field_config_from_map (mongocrypt_ctx_t *ctx)
+{
+ mongocrypt_t *crypt;
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bson_t encrypted_field_config_map;
+ bson_iter_t iter;
+
+ crypt = ctx->crypt;
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ if (_mongocrypt_buffer_empty (&crypt->opts.encrypted_field_config_map)) {
+ /* No encrypted_field_config_map set. */
+ return true;
+ }
+
+ if (!_mongocrypt_buffer_to_bson (&crypt->opts.encrypted_field_config_map,
+ &encrypted_field_config_map)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "unable to convert encrypted_field_config_map to BSON");
+ }
+
+ if (bson_iter_init_find (&iter, &encrypted_field_config_map, ectx->ns)) {
+ if (!_mongocrypt_buffer_copy_from_document_iter (
+ &ectx->encrypted_field_config, &iter)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx,
+ "unable to copy encrypted_field_config from "
+ "encrypted_field_config_map");
+ }
+ bson_t efc_bson;
+ if (!_mongocrypt_buffer_to_bson (&ectx->encrypted_field_config,
+ &efc_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "unable to create BSON from encrypted_field_config");
+ }
+ if (!mc_EncryptedFieldConfig_parse (&ectx->efc, &efc_bson, ctx->status)) {
+ _mongocrypt_ctx_fail (ctx);
+ return false;
+ }
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
+ }
+
+ /* No encrypted_field_config found in map. */
+ return true;
+}
+
+
+static bool
+_try_schema_from_cache (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bson_t *collinfo = NULL;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ /* Otherwise, we need a remote schema. Check if we have a response to
+ * listCollections cached. */
+ if (!_mongocrypt_cache_get (&ctx->crypt->cache_collinfo,
+ ectx->ns /* null terminated */,
+ (void **) &collinfo)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "failed to retrieve from cache");
+ }
+
+ if (collinfo) {
+ if (!_set_schema_from_collinfo (ctx, collinfo)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
+ } else {
+ /* we need to get it. */
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_COLLINFO;
+ }
+
+ bson_destroy (collinfo);
+ return true;
+}
+
+/* _try_empty_schema_for_create uses an empty JSON schema for the create
+ * command. This is to avoid an unnecessary 'listCollections' command for
+ * create. */
+static bool
+_try_empty_schema_for_create (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ /* As a special case, use an empty schema for the 'create' command. */
+ const char *cmd_name = ectx->cmd_name;
+
+ if (0 != strcmp (cmd_name, "create")) {
+ return true;
+ }
+
+ bson_t empty = BSON_INITIALIZER;
+ _mongocrypt_buffer_steal_from_bson (&ectx->schema, &empty);
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
+ return true;
+}
+
+/* _try_schema_from_create_cmd tries to find a JSON schema included in a create
+ * command by checking for "validator.$jsonSchema". Example:
+ * {
+ * "create" : "coll",
+ * "validator" : {
+ * "$jsonSchema" : {
+ * "properties" : { "a" : { "bsonType" : "number" } }
+ * }
+ * }
+ * }
+ * If the "create" command does not include a JSON schema, an empty JSON schema
+ * is returned. This is to avoid an unnecessary 'listCollections' command for
+ * create. */
+static bool
+_try_schema_from_create_cmd (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+ mongocrypt_status_t *status = ctx->status;
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ /* As a special case, use an empty schema for the 'create' command. */
+ const char *cmd_name = ectx->cmd_name;
+
+ if (0 != strcmp (cmd_name, "create")) {
+ return true;
+ }
+
+ bson_t cmd_bson;
+ bson_iter_t iter;
+
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &cmd_bson)) {
+ CLIENT_ERR ("unable to convert command buffer to BSON");
+ _mongocrypt_ctx_fail (ctx);
+ return false;
+ }
+
+ if (!bson_iter_init (&iter, &cmd_bson)) {
+ CLIENT_ERR ("unable to iterate over command BSON");
+ _mongocrypt_ctx_fail (ctx);
+ return false;
+ }
+
+ if (bson_iter_find_descendant (&iter, "validator.$jsonSchema", &iter)) {
+ if (!_mongocrypt_buffer_copy_from_document_iter (&ectx->schema, &iter)) {
+ CLIENT_ERR (
+ "failed to parse BSON document from create validator.$jsonSchema");
+ _mongocrypt_ctx_fail (ctx);
+ return false;
+ }
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
+ return true;
+ }
+
+ return true;
+}
+
+static bool
+_permitted_for_encryption (bson_iter_t *iter,
+ mongocrypt_encryption_algorithm_t algo,
+ mongocrypt_status_t *status)
+{
+ bson_type_t bson_type;
+ const bson_value_t *bson_value = bson_iter_value (iter);
+ bool ret = false;
+
+ if (!bson_value) {
+ CLIENT_ERR ("Unknown BSON type");
+ goto fail;
+ }
+ bson_type = bson_value->value_type;
+ switch (bson_type) {
+ case BSON_TYPE_NULL:
+ case BSON_TYPE_MINKEY:
+ case BSON_TYPE_MAXKEY:
+ case BSON_TYPE_UNDEFINED:
+ CLIENT_ERR ("BSON type invalid for encryption");
+ goto fail;
+ case BSON_TYPE_BINARY:
+ if (bson_value->value.v_binary.subtype == 6) {
+ CLIENT_ERR ("BSON binary subtype 6 is invalid for encryption");
+ goto fail;
+ }
+ /* ok */
+ break;
+ case BSON_TYPE_DOUBLE:
+ case BSON_TYPE_DOCUMENT:
+ case BSON_TYPE_ARRAY:
+ case BSON_TYPE_CODEWSCOPE:
+ case BSON_TYPE_BOOL:
+ case BSON_TYPE_DECIMAL128:
+ if (algo == MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC) {
+ CLIENT_ERR ("BSON type invalid for deterministic encryption");
+ goto fail;
+ }
+ break;
+ case BSON_TYPE_UTF8:
+ case BSON_TYPE_OID:
+ case BSON_TYPE_DATE_TIME:
+ case BSON_TYPE_REGEX:
+ case BSON_TYPE_DBPOINTER:
+ case BSON_TYPE_CODE:
+ case BSON_TYPE_SYMBOL:
+ case BSON_TYPE_INT32:
+ case BSON_TYPE_TIMESTAMP:
+ case BSON_TYPE_INT64:
+ /* ok */
+ break;
+ case BSON_TYPE_EOD:
+ default:
+ CLIENT_ERR ("invalid BSON value type 00");
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ return ret;
+}
+
+bool
+mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t *ctx,
+ mongocrypt_binary_t *msg)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+ bson_t as_bson;
+ bson_iter_t iter;
+ _mongocrypt_ctx_opts_spec_t opts_spec;
+
+ if (!ctx) {
+ return false;
+ }
+ memset (&opts_spec, 0, sizeof (opts_spec));
+ opts_spec.key_descriptor = OPT_REQUIRED;
+ opts_spec.algorithm = OPT_OPTIONAL;
+
+ if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
+ return false;
+ }
+
+ /* Error if any mutually exclusive FLE 1 and FLE 2 options are set. */
+ {
+ /* key_alt_names is FLE 1 only. */
+ if (ctx->opts.key_alt_names != NULL) {
+ if (ctx->opts.index_type.set) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set both key alt name and index type");
+ }
+ if (!_mongocrypt_buffer_empty (&ctx->opts.index_key_id)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set both key alt name and index key id");
+ }
+ if (ctx->opts.contention_factor.set) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set both key alt name and contention factor");
+ }
+ if (ctx->opts.query_type.set) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set both key alt name and query type");
+ }
+ }
+ /* algorithm is FLE 1 only. */
+ if (ctx->opts.algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE) {
+ if (!_mongocrypt_buffer_empty (&ctx->opts.index_key_id)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set both algorithm and index key id");
+ }
+ if (ctx->opts.contention_factor.set) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set both algorithm and contention factor");
+ }
+ if (ctx->opts.query_type.set) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set both algorithm and query type");
+ }
+ }
+ }
+
+ if (ctx->opts.algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE &&
+ !ctx->opts.index_type.set) {
+ return _mongocrypt_ctx_fail_w_msg (ctx,
+ "algorithm or index type required");
+ }
+
+ if (ctx->opts.contention_factor.set && ctx->opts.index_type.set &&
+ ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_NONE) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set contention factor with no index type");
+ }
+
+ if (ctx->opts.query_type.set && ctx->opts.index_type.set &&
+ ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_NONE) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "cannot set query type with no index type");
+ }
+
+ if (ctx->opts.contention_factor.set &&
+ !mc_validate_contention (ctx->opts.contention_factor.value,
+ ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ if (ctx->opts.index_type.set &&
+ ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY &&
+ !ctx->opts.contention_factor.set) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "contention factor is required for indexed algorithm");
+ }
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ ctx->type = _MONGOCRYPT_TYPE_ENCRYPT;
+ ectx->explicit = true;
+ ctx->vtable.finalize = _finalize;
+ ctx->vtable.cleanup = _cleanup;
+
+ if (!msg || !msg->data) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "msg required for explicit encryption");
+ }
+
+ if (ctx->opts.key_alt_names) {
+ if (!_mongocrypt_key_broker_request_name (
+ &ctx->kb, &ctx->opts.key_alt_names->value)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ } else {
+ if (!_mongocrypt_key_broker_request_id (&ctx->kb, &ctx->opts.key_id)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ if (!_mongocrypt_buffer_empty (&ctx->opts.index_key_id)) {
+ if (!_mongocrypt_key_broker_request_id (&ctx->kb,
+ &ctx->opts.index_key_id)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ _mongocrypt_buffer_init (&ectx->original_cmd);
+
+ _mongocrypt_buffer_copy_from_binary (&ectx->original_cmd, msg);
+ if (!_mongocrypt_buffer_to_bson (&ectx->original_cmd, &as_bson)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "msg must be bson");
+ }
+
+ if (ctx->crypt->log.trace_enabled) {
+ char *cmd_val;
+ cmd_val = _mongocrypt_new_json_string_from_binary (msg);
+ _mongocrypt_log (&ctx->crypt->log,
+ MONGOCRYPT_LOG_LEVEL_TRACE,
+ "%s (%s=\"%s\")",
+ BSON_FUNC,
+ "msg",
+ cmd_val);
+ bson_free (cmd_val);
+ }
+
+ if (!bson_iter_init_find (&iter, &as_bson, "v")) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "invalid msg, must contain 'v'");
+ }
+
+ if (!_permitted_for_encryption (&iter, ctx->opts.algorithm, ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ (void) _mongocrypt_key_broker_requests_done (&ctx->kb);
+ return _mongocrypt_ctx_state_from_key_broker (ctx);
+}
+
+static bool
+_check_cmd_for_auto_encrypt (mongocrypt_binary_t *cmd,
+ bool *bypass,
+ char **collname,
+ mongocrypt_status_t *status)
+{
+ bson_t as_bson;
+ bson_iter_t iter, ns_iter;
+ const char *cmd_name;
+ bool eligible = false;
+
+ *bypass = false;
+
+ if (!_mongocrypt_binary_to_bson (cmd, &as_bson) ||
+ !bson_iter_init (&iter, &as_bson)) {
+ CLIENT_ERR ("invalid BSON");
+ return false;
+ }
+
+ /* The command name is the first key. */
+ if (!bson_iter_next (&iter)) {
+ CLIENT_ERR ("invalid empty BSON");
+ return false;
+ }
+
+ cmd_name = bson_iter_key (&iter);
+ BSON_ASSERT (cmd_name);
+
+ /* get the collection name (or NULL if database/client command). */
+ if (0 == strcmp (cmd_name, "explain")) {
+ if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ CLIENT_ERR ("explain value is not a document");
+ return false;
+ }
+ if (!bson_iter_recurse (&iter, &ns_iter)) {
+ CLIENT_ERR ("malformed BSON for encrypt command");
+ return false;
+ }
+ if (!bson_iter_next (&ns_iter)) {
+ CLIENT_ERR ("invalid empty BSON");
+ return false;
+ }
+ } else {
+ memcpy (&ns_iter, &iter, sizeof (iter));
+ }
+
+ if (BSON_ITER_HOLDS_UTF8 (&ns_iter)) {
+ *collname = bson_strdup (bson_iter_utf8 (&ns_iter, NULL));
+ } else {
+ *collname = NULL;
+ }
+
+ /* check if command is eligible for auto encryption, bypassed, or ineligible.
+ */
+ if (0 == strcmp (cmd_name, "aggregate")) {
+ /* collection level aggregate ok, database/client is not. */
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "count")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "distinct")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "delete")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "find")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "findAndModify")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "getMore")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "insert")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "update")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "authenticate")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "getnonce")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "logout")) {
+ *bypass = true;
+ } else if (0 == bson_strcasecmp (cmd_name, "isMaster")) {
+ /* use case insensitive compare for ismaster, since some drivers send
+ * "ismaster" and others send "isMaster" */
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "abortTransaction")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "commitTransaction")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "endSessions")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "startSession")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "create")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "createIndexes")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "drop")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "dropDatabase")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "dropIndexes")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "killCursors")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "listCollections")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "listDatabases")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "listIndexes")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "renameCollection")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "explain")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "ping")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "saslStart")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "saslContinue")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "killAllSessions")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "killSessions")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "killAllSessionsByPattern")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "refreshSessions")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "compactStructuredEncryptionData")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "collMod")) {
+ eligible = true;
+ } else if (0 == strcmp (cmd_name, "hello")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "buildInfo")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "getCmdLineOpts")) {
+ *bypass = true;
+ } else if (0 == strcmp (cmd_name, "getLog")) {
+ *bypass = true;
+ }
+
+ /* database/client commands are ineligible. */
+ if (eligible) {
+ if (!*collname) {
+ CLIENT_ERR (
+ "non-collection command not supported for auto encryption: %s",
+ cmd_name);
+ return false;
+ }
+ if (0 == strlen (*collname)) {
+ CLIENT_ERR ("empty collection name on command: %s", cmd_name);
+ return false;
+ }
+ }
+
+ if (eligible || *bypass) {
+ return true;
+ }
+
+ CLIENT_ERR ("command not supported for auto encryption: %s", cmd_name);
+ return false;
+}
+
+static bool
+needs_ismaster_check (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ bool using_mongocryptd =
+ !ectx->bypass_query_analysis && !ctx->crypt->csfle.okay;
+ // The "create" and "createIndexes" command require an isMaster check when
+ // using mongocryptd. See MONGOCRYPT-429.
+ return using_mongocryptd && (0 == strcmp (ectx->cmd_name, "create") ||
+ 0 == strcmp (ectx->cmd_name, "createIndexes"));
+}
+
+bool
+mongocrypt_ctx_encrypt_init (mongocrypt_ctx_t *ctx,
+ const char *db,
+ int32_t db_len,
+ mongocrypt_binary_t *cmd)
+{
+ _mongocrypt_ctx_encrypt_t *ectx;
+ _mongocrypt_ctx_opts_spec_t opts_spec;
+ bool bypass;
+
+ if (!ctx) {
+ return false;
+ }
+ memset (&opts_spec, 0, sizeof (opts_spec));
+ opts_spec.schema = OPT_OPTIONAL;
+ if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
+ return false;
+ }
+
+ ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+ ctx->type = _MONGOCRYPT_TYPE_ENCRYPT;
+ ectx->explicit = false;
+ ctx->vtable.mongo_op_collinfo = _mongo_op_collinfo;
+ ctx->vtable.mongo_feed_collinfo = _mongo_feed_collinfo;
+ ctx->vtable.mongo_done_collinfo = _mongo_done_collinfo;
+ ctx->vtable.mongo_op_collinfo = _mongo_op_collinfo;
+ ctx->vtable.mongo_op_markings = _mongo_op_markings;
+ ctx->vtable.mongo_feed_markings = _mongo_feed_markings;
+ ctx->vtable.mongo_done_markings = _mongo_done_markings;
+ ctx->vtable.finalize = _finalize;
+ ctx->vtable.cleanup = _cleanup;
+ ctx->vtable.mongo_op_collinfo = _mongo_op_collinfo;
+ ctx->vtable.mongo_feed_collinfo = _mongo_feed_collinfo;
+ ctx->vtable.mongo_done_collinfo = _mongo_done_collinfo;
+ ectx->bypass_query_analysis = ctx->crypt->opts.bypass_query_analysis;
+
+
+ if (!cmd || !cmd->data) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "invalid command");
+ }
+
+ _mongocrypt_buffer_copy_from_binary (&ectx->original_cmd, cmd);
+
+ ectx->cmd_name = get_command_name (&ectx->original_cmd, ctx->status);
+ if (!ectx->cmd_name) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ if (!_check_cmd_for_auto_encrypt (
+ cmd, &bypass, &ectx->coll_name, ctx->status)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ if (bypass) {
+ ctx->nothing_to_do = true;
+ ctx->state = MONGOCRYPT_CTX_READY;
+ return true;
+ }
+
+ /* if _check_cmd_for_auto_encrypt did not bypass or error, a collection name
+ * must have been set. */
+ if (!ectx->coll_name) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx,
+ "unexpected error: did not bypass or error but no collection name");
+ }
+
+ if (!_mongocrypt_validate_and_copy_string (db, db_len, &ectx->db_name) ||
+ 0 == strlen (ectx->db_name)) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "invalid db");
+ }
+
+ ectx->ns = bson_strdup_printf ("%s.%s", ectx->db_name, ectx->coll_name);
+
+ if (ctx->opts.kek.provider.aws.region || ctx->opts.kek.provider.aws.cmk) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "aws masterkey options must not be set");
+ }
+
+ if (!_mongocrypt_buffer_empty (&ctx->opts.key_id)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "key_id must not be set for auto encryption");
+ }
+
+ if (ctx->opts.algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "algorithm must not be set for auto encryption");
+ }
+
+ if (ctx->crypt->log.trace_enabled) {
+ char *cmd_val;
+ cmd_val = _mongocrypt_new_json_string_from_binary (cmd);
+ _mongocrypt_log (&ctx->crypt->log,
+ MONGOCRYPT_LOG_LEVEL_TRACE,
+ "%s (%s=\"%s\", %s=%d, %s=\"%s\")",
+ BSON_FUNC,
+ "db",
+ ectx->db_name,
+ "db_len",
+ db_len,
+ "cmd",
+ cmd_val);
+ bson_free (cmd_val);
+ }
+
+ /* The "create" and "createIndexes" command require sending an isMaster
+ * request to mongocryptd. */
+ if (needs_ismaster_check (ctx)) {
+ /* We are using mongocryptd. We need to ensure that mongocryptd
+ * maxWireVersion >= 17. */
+ ectx->ismaster.needed = true;
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
+ return true;
+ }
+
+ return mongocrypt_ctx_encrypt_ismaster_done (ctx);
+}
+
+#define WIRE_VERSION_SERVER_6 17
+/* mongocrypt_ctx_encrypt_ismaster_done is called when:
+ * 1. The max wire version of mongocryptd is known.
+ * 2. The max wire version of mongocryptd is not required for the command.
+ */
+static bool
+mongocrypt_ctx_encrypt_ismaster_done (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
+
+ ectx->ismaster.needed = false;
+
+ /* The "create" and "createIndexes" command require bypassing on mongocryptd
+ * older than version 6.0. */
+ if (needs_ismaster_check (ctx)) {
+ if (ectx->ismaster.maxwireversion < WIRE_VERSION_SERVER_6) {
+ /* Bypass. */
+ ctx->nothing_to_do = true;
+ ctx->state = MONGOCRYPT_CTX_READY;
+ return true;
+ }
+ }
+
+ /* Check if there is an encrypted field config in encrypted_field_config_map
+ */
+ if (!_fle2_try_encrypted_field_config_from_map (ctx)) {
+ return false;
+ }
+ if (_mongocrypt_buffer_empty (&ectx->encrypted_field_config)) {
+ if (!_try_schema_from_create_cmd (ctx)) {
+ return false;
+ }
+
+ /* Check if we have a local schema from schema_map */
+ if (_mongocrypt_buffer_empty (&ectx->schema)) {
+ if (!_try_schema_from_schema_map (ctx)) {
+ return false;
+ }
+ }
+
+ /* If we didn't have a local schema, try the cache. */
+ if (_mongocrypt_buffer_empty (&ectx->schema)) {
+ if (!_try_schema_from_cache (ctx)) {
+ return false;
+ }
+ }
+
+ /* If we did not have a local or cached schema, check if this is a
+ * "create" command. If it is a "create" command, do not run
+ * "listCollections" to get a server-side schema. */
+ if (_mongocrypt_buffer_empty (&ectx->schema) &&
+ !_try_empty_schema_for_create (ctx)) {
+ return false;
+ }
+
+ /* Otherwise, we need the the driver to fetch the schema. */
+ if (_mongocrypt_buffer_empty (&ectx->schema)) {
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_COLLINFO;
+ }
+ }
+
+ /* If an encrypted_field_config was set, check if keys are required for
+ * delete tokens. */
+ if (!_fle2_collect_keys_for_deleteTokens (ctx)) {
+ return false;
+ }
+
+ if (!_fle2_collect_keys_for_compact (ctx)) {
+ return false;
+ }
+
+ if (ctx->state == MONGOCRYPT_CTX_NEED_MONGO_MARKINGS) {
+ if (ectx->bypass_query_analysis) {
+ /* Keys may have been requested for deleteTokens or compactionTokens.
+ * Finish key requests.
+ */
+ _mongocrypt_key_broker_requests_done (&ctx->kb);
+ return _mongocrypt_ctx_state_from_key_broker (ctx);
+ }
+ // We're ready for markings. Try to generate them ourself.
+ return _try_run_csfle_marking (ctx);
+ } else {
+ // Other state, return to caller.
+ return true;
+ }
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-private.h
similarity index 67%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-private.h
index 68459aae..3133cd22 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-private.h
@@ -1,174 +1,252 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_CTX_PRIVATE_H
#define MONGOCRYPT_CTX_PRIVATE_H
#include "mongocrypt.h"
#include "mongocrypt-private.h"
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-key-broker-private.h"
#include "mongocrypt-key-private.h"
#include "mongocrypt-endpoint-private.h"
+#include "mc-efc-private.h"
typedef enum {
_MONGOCRYPT_TYPE_NONE,
_MONGOCRYPT_TYPE_ENCRYPT,
_MONGOCRYPT_TYPE_DECRYPT,
_MONGOCRYPT_TYPE_CREATE_DATA_KEY,
+ _MONGOCRYPT_TYPE_REWRAP_MANY_DATAKEY,
+ _MONGOCRYPT_TYPE_COMPACT,
} _mongocrypt_ctx_type_t;
+typedef enum {
+ MONGOCRYPT_INDEX_TYPE_NONE = 1,
+ MONGOCRYPT_INDEX_TYPE_EQUALITY = 2
+} mongocrypt_index_type_t;
+
+typedef enum { MONGOCRYPT_QUERY_TYPE_EQUALITY = 1 } mongocrypt_query_type_t;
+
/* Option values are validated when set.
* Different contexts accept/require different options,
* validated when a context is initialized.
*/
typedef struct __mongocrypt_ctx_opts_t {
_mongocrypt_buffer_t key_id;
_mongocrypt_key_alt_name_t *key_alt_names;
_mongocrypt_buffer_t key_material;
mongocrypt_encryption_algorithm_t algorithm;
_mongocrypt_kek_t kek;
+ struct {
+ mongocrypt_index_type_t value;
+ bool set;
+ } index_type;
+ _mongocrypt_buffer_t index_key_id;
+ struct {
+ int64_t value;
+ bool set;
+ } contention_factor;
+ struct {
+ mongocrypt_query_type_t value;
+ bool set;
+ } query_type;
} _mongocrypt_ctx_opts_t;
/* All derived contexts may override these methods. */
typedef struct {
bool (*mongo_op_collinfo) (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);
bool (*mongo_feed_collinfo) (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in);
bool (*mongo_done_collinfo) (mongocrypt_ctx_t *ctx);
bool (*mongo_op_markings) (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);
bool (*mongo_feed_markings) (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in);
bool (*mongo_done_markings) (mongocrypt_ctx_t *ctx);
bool (*mongo_op_keys) (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);
bool (*mongo_feed_keys) (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in);
bool (*mongo_done_keys) (mongocrypt_ctx_t *ctx);
+ bool (*after_kms_credentials_provided) (mongocrypt_ctx_t *ctx);
mongocrypt_kms_ctx_t *(*next_kms_ctx) (mongocrypt_ctx_t *ctx);
bool (*kms_done) (mongocrypt_ctx_t *ctx);
bool (*finalize) (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);
void (*cleanup) (mongocrypt_ctx_t *ctx);
} _mongocrypt_vtable_t;
struct _mongocrypt_ctx_t {
mongocrypt_t *crypt;
mongocrypt_ctx_state_t state;
_mongocrypt_ctx_type_t type;
mongocrypt_status_t *status;
_mongocrypt_key_broker_t kb;
_mongocrypt_vtable_t vtable;
_mongocrypt_ctx_opts_t opts;
+ _mongocrypt_opts_kms_providers_t per_ctx_kms_providers; /* owned */
+ _mongocrypt_opts_kms_providers_t
+ kms_providers; /* not owned, is merged from per-ctx / per-mongocrypt_t */
bool initialized;
- bool
- nothing_to_do; /* set to true if no encryption/decryption is required. */
+ /* nothing_to_do is set to true under these conditions:
+ * 1. No keys are requested
+ * 2. The command is bypassed for automatic encryption (e.g. ping).
+ * 3. bypass_query_analysis is true.
+ * TODO (MONGOCRYPT-422) replace nothing_to_do.
+ */
+ bool nothing_to_do;
};
/* Transition to the error state. An error status must have been set. */
bool
_mongocrypt_ctx_fail (mongocrypt_ctx_t *ctx);
/* Set an error status and transition to the error state. */
bool
_mongocrypt_ctx_fail_w_msg (mongocrypt_ctx_t *ctx, const char *msg);
typedef struct {
mongocrypt_ctx_t parent;
bool explicit;
char *coll_name;
char *db_name;
char *ns;
_mongocrypt_buffer_t list_collections_filter;
_mongocrypt_buffer_t schema;
/* TODO CDRIVER-3150: audit + rename these buffers.
* original_cmd for explicit is {v: <BSON value>}, for auto is the command to
* be encrypted.
*
* mongocryptd_cmd is only applicable for auto encryption. It is the original
* command with JSONSchema appended.
*
* marked_cmd is the value of the 'result' field in mongocryptd response
*
* encrypted_cmd is the final output, the original command encrypted, or for
* explicit, the {v: <ciphertext>} doc.
*/
_mongocrypt_buffer_t original_cmd;
_mongocrypt_buffer_t mongocryptd_cmd;
_mongocrypt_buffer_t marked_cmd;
_mongocrypt_buffer_t encrypted_cmd;
_mongocrypt_buffer_t key_id;
bool used_local_schema;
/* collinfo_has_siblings is true if the schema came from a remote JSON
* schema, and there were siblings. */
bool collinfo_has_siblings;
+ /* encrypted_field_config is set when:
+ * 1. <db_name>.<coll_name> is present in an encrypted_field_config_map.
+ * 2. (TODO MONGOCRYPT-414) The collection has encryptedFields in the
+ * response to listCollections. encrypted_field_config is true if and only if
+ * encryption is using FLE 2.0.
+ */
+ _mongocrypt_buffer_t encrypted_field_config;
+ mc_EncryptedFieldConfig_t efc;
+ /* bypass_query_analysis is set to true to skip the
+ * MONGOCRYPT_CTX_NEED_MONGO_MARKINGS state. */
+ bool bypass_query_analysis;
+ struct {
+ bool needed;
+ _mongocrypt_buffer_t cmd;
+ int32_t maxwireversion;
+ } ismaster;
+ // cmd_name is the first BSON field in original_cmd for auto encryption.
+ const char *cmd_name;
} _mongocrypt_ctx_encrypt_t;
typedef struct {
mongocrypt_ctx_t parent;
- bool explicit;
/* TODO CDRIVER-3150: audit + rename these buffers.
* Unlike ctx_encrypt, unwrapped_doc holds the binary value of the {v:
* <ciphertext>} doc.
* */
_mongocrypt_buffer_t original_doc;
- _mongocrypt_buffer_t unwrapped_doc; /* explicit only */
_mongocrypt_buffer_t decrypted_doc;
} _mongocrypt_ctx_decrypt_t;
typedef struct {
mongocrypt_ctx_t parent;
mongocrypt_kms_ctx_t kms;
bool kms_returned;
_mongocrypt_buffer_t key_doc;
_mongocrypt_buffer_t plaintext_key_material;
_mongocrypt_buffer_t encrypted_key_material;
const char *kmip_unique_identifier;
bool kmip_activated;
_mongocrypt_buffer_t kmip_secretdata;
} _mongocrypt_ctx_datakey_t;
+typedef struct _mongocrypt_ctx_rmd_datakey_t _mongocrypt_ctx_rmd_datakey_t;
+
+struct _mongocrypt_ctx_rmd_datakey_t {
+ _mongocrypt_ctx_rmd_datakey_t *next;
+ mongocrypt_ctx_t *dkctx;
+ _mongocrypt_key_doc_t *doc;
+};
+
+typedef struct {
+ mongocrypt_ctx_t parent;
+ _mongocrypt_buffer_t filter;
+ mongocrypt_kms_ctx_t kms;
+ _mongocrypt_ctx_rmd_datakey_t *datakeys;
+ _mongocrypt_ctx_rmd_datakey_t *datakeys_iter;
+ _mongocrypt_buffer_t results;
+} _mongocrypt_ctx_rewrap_many_datakey_t;
+
+typedef struct {
+ mongocrypt_ctx_t parent;
+ _mongocrypt_buffer_t result;
+ mc_EncryptedFieldConfig_t efc;
+} _mongocrypt_ctx_compact_t;
+
+
/* Used for option validation. True means required. False means prohibited. */
typedef enum {
OPT_PROHIBITED = 0,
OPT_REQUIRED,
OPT_OPTIONAL
} _mongocrypt_ctx_opt_spec_t;
+
typedef struct {
_mongocrypt_ctx_opt_spec_t kek;
_mongocrypt_ctx_opt_spec_t schema;
_mongocrypt_ctx_opt_spec_t key_descriptor; /* a key_id or key_alt_name */
_mongocrypt_ctx_opt_spec_t key_alt_names;
_mongocrypt_ctx_opt_spec_t key_material;
_mongocrypt_ctx_opt_spec_t algorithm;
} _mongocrypt_ctx_opts_spec_t;
/* Common initialization. */
bool
_mongocrypt_ctx_init (mongocrypt_ctx_t *ctx,
_mongocrypt_ctx_opts_spec_t *opt_spec)
MONGOCRYPT_WARN_UNUSED_RESULT;
/* Set the state of the context from the state of keys in the key broker. */
bool
_mongocrypt_ctx_state_from_key_broker (mongocrypt_ctx_t *ctx)
MONGOCRYPT_WARN_UNUSED_RESULT;
+/* Get the KMS providers for the current context, fall back to the ones
+ * from mongocrypt_t if none are provided for the context specifically. */
+_mongocrypt_opts_kms_providers_t *
+_mongocrypt_ctx_kms_providers (mongocrypt_ctx_t *ctx);
+
#endif /* MONGOCRYPT_CTX_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c
new file mode 100644
index 00000000..1e4f4116
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mongocrypt-ctx-private.h"
+
+
+static bool
+_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ bson_t doc = BSON_INITIALIZER;
+ bson_t array = BSON_INITIALIZER;
+
+ BSON_ASSERT_PARAM (ctx);
+
+ BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (&doc, "v", &array));
+ {
+ _mongocrypt_ctx_rmd_datakey_t *iter = NULL;
+ size_t idx = 0u;
+
+ for (iter = rmdctx->datakeys; iter; (iter = iter->next), (++idx)) {
+ mongocrypt_binary_t bin;
+ bson_t bson;
+ bson_t elem = BSON_INITIALIZER;
+
+ if (!mongocrypt_ctx_finalize (iter->dkctx, &bin)) {
+ return _mongocrypt_ctx_fail_w_msg (
+ ctx, "failed to encrypt datakey with new provider");
+ }
+
+ BSON_ASSERT (bson_init_static (&bson, bin.data, bin.len));
+
+ /* Among all (possible) fields in key document, the only fields
+ * required by caller to construct the corresponding bulk write
+ * operations to update the key document with rewrapped key material
+ * are:
+ * - _id (same as original key)
+ * - keyMaterial (updated)
+ * - masterKey (updated)
+ * Which means the following fields can be excluded:
+ * - _id (discard new ID generated during rewrapping)
+ * - creationDate
+ * - updateDate (updated via the $currentDate operator)
+ * - status
+ * - keyAltNames
+ */
+ bson_copy_to_excluding_noinit (&bson,
+ &elem,
+ "_id",
+ "creationDate",
+ "updateDate",
+ "status",
+ "keyAltNames",
+ NULL);
+
+ /* Preserve key ID of original document. */
+ BSON_ASSERT (BSON_APPEND_BINARY (&elem,
+ "_id",
+ BSON_SUBTYPE_UUID,
+ iter->doc->id.data,
+ iter->doc->id.len));
+
+ /* Array indicies must be specified manually. */
+ {
+ char *idx_str = bson_strdup_printf ("%zu", idx);
+ BSON_ASSERT (BSON_APPEND_DOCUMENT (&array, idx_str, &elem));
+ bson_free (idx_str);
+ }
+
+ bson_destroy (&elem);
+ }
+ }
+ BSON_ASSERT (bson_append_array_end (&doc, &array));
+
+ /* Extend lifetime of bson so it can be referenced by out parameter. */
+ _mongocrypt_buffer_steal_from_bson (&rmdctx->results, &doc);
+
+ out->data = rmdctx->results.data;
+ out->len = rmdctx->results.len;
+
+ ctx->state = MONGOCRYPT_CTX_DONE;
+
+ return true;
+}
+
+static bool
+_kms_done_encrypt (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ BSON_ASSERT_PARAM (ctx);
+
+ {
+ _mongocrypt_ctx_rmd_datakey_t *iter;
+
+ for (iter = rmdctx->datakeys; iter; iter = iter->next) {
+ if (iter->dkctx->state == MONGOCRYPT_CTX_NEED_KMS &&
+ !mongocrypt_ctx_kms_done (iter->dkctx)) {
+ _mongocrypt_status_copy_to (iter->dkctx->status, ctx->status);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+ }
+
+ /* Some providers may require multiple rounds of KMS requests. Reiterate
+ * through datakey contexts to verify if more work needs to be done. */
+ rmdctx->datakeys_iter = rmdctx->datakeys;
+
+ while (rmdctx->datakeys_iter &&
+ rmdctx->datakeys_iter->dkctx->state != MONGOCRYPT_CTX_NEED_KMS) {
+ rmdctx->datakeys_iter = rmdctx->datakeys_iter->next;
+ }
+
+ if (rmdctx->datakeys_iter) {
+ /* More work to be done, remain in MONGOCRYPT_CTX_NEED_KMS state. */
+ return true;
+ }
+
+ /* All datakeys have been encrypted and are ready to be finalized. */
+ ctx->state = MONGOCRYPT_CTX_READY;
+ ctx->vtable.finalize = _finalize;
+
+ return true;
+}
+
+static mongocrypt_kms_ctx_t *
+_next_kms_ctx_encrypt (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ mongocrypt_ctx_t *dkctx = NULL;
+
+ BSON_ASSERT_PARAM (ctx);
+
+ /* No more datakey contexts requiring KMS. */
+ if (!rmdctx->datakeys_iter) {
+ return NULL;
+ }
+
+ dkctx = rmdctx->datakeys_iter->dkctx;
+
+ /* Skip next iterator ahead to next datakey context that needs KMS. */
+ do {
+ rmdctx->datakeys_iter = rmdctx->datakeys_iter->next;
+ } while (rmdctx->datakeys_iter &&
+ rmdctx->datakeys_iter->dkctx->state != MONGOCRYPT_CTX_NEED_KMS);
+
+ return mongocrypt_ctx_next_kms_ctx (dkctx);
+}
+
+static bool
+_add_new_datakey (mongocrypt_ctx_t *ctx, key_returned_t *key)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ _mongocrypt_ctx_rmd_datakey_t *const datakey =
+ bson_malloc0 (sizeof (_mongocrypt_ctx_rmd_datakey_t));
+
+ datakey->dkctx = mongocrypt_ctx_new (ctx->crypt);
+ datakey->next = rmdctx->datakeys;
+ datakey->doc = key->doc;
+ rmdctx->datakeys = datakey; /* Ownership transfer. */
+
+ /* Set new provider and master key (rewrapManyDataKeyOpts). */
+ if (ctx->opts.kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_NONE) {
+ /* Reuse current KMS provider if option not set. */
+ _mongocrypt_kek_copy_to (&key->doc->kek, &datakey->dkctx->opts.kek);
+ } else {
+ /* Apply new KMS provider as given by options. */
+ _mongocrypt_kek_copy_to (&ctx->opts.kek, &datakey->dkctx->opts.kek);
+ }
+
+ /* Preserve alt names. */
+ datakey->dkctx->opts.key_alt_names =
+ _mongocrypt_key_alt_name_copy_all (key->doc->key_alt_names);
+
+ /* Preserve key material. */
+ _mongocrypt_buffer_copy_to (&key->decrypted_key_material,
+ &datakey->dkctx->opts.key_material);
+
+ if (!mongocrypt_ctx_datakey_init (datakey->dkctx)) {
+ _mongocrypt_status_copy_to (datakey->dkctx->status, ctx->status);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ /* Reuse KMS credentials provided during decryption. */
+ if (datakey->dkctx->state == MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS) {
+ memcpy (&datakey->dkctx->kms_providers,
+ _mongocrypt_ctx_kms_providers (ctx),
+ sizeof (_mongocrypt_opts_kms_providers_t));
+ if (!datakey->dkctx->vtable.after_kms_credentials_provided (
+ datakey->dkctx)) {
+ _mongocrypt_status_copy_to (datakey->dkctx->status, ctx->status);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ return true;
+}
+
+static bool
+_start_kms_encrypt (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ BSON_ASSERT_PARAM (ctx);
+
+ /* Finish KMS requests for decryption if there were any. */
+ if (ctx->state == MONGOCRYPT_CTX_NEED_KMS) {
+ _mongocrypt_opts_kms_providers_t *const providers =
+ _mongocrypt_ctx_kms_providers (ctx);
+
+ if (!_mongocrypt_key_broker_kms_done (&ctx->kb, providers)) {
+ _mongocrypt_status_copy_to (ctx->kb.status, ctx->status);
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ /* For all decrypted datakeys, initialize a corresponding datakey context. */
+ {
+ key_returned_t *key;
+
+ /* Some decrypted keys may have been cached. */
+ for (key = ctx->kb.keys_cached; key; key = key->next) {
+ if (!_add_new_datakey (ctx, key)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ /* Remaining keys were decrypted via KMS requests. */
+ for (key = ctx->kb.keys_returned; key; key = key->next) {
+ if (!_add_new_datakey (ctx, key)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+ }
+
+ /* Prepare iterator used by _next_kms_ctx_encrypt. */
+ rmdctx->datakeys_iter = rmdctx->datakeys;
+
+ /* Skip datakeys that do not require a KMS request. */
+ while (rmdctx->datakeys_iter &&
+ rmdctx->datakeys_iter->dkctx->state == MONGOCRYPT_CTX_READY) {
+ rmdctx->datakeys_iter = rmdctx->datakeys_iter->next;
+ }
+
+ /* Skip to READY state if no KMS requests are required. */
+ if (!rmdctx->datakeys_iter) {
+ ctx->state = MONGOCRYPT_CTX_READY;
+ ctx->vtable.finalize = _finalize;
+ return true;
+ }
+
+ ctx->state = MONGOCRYPT_CTX_NEED_KMS;
+ ctx->vtable.next_kms_ctx = _next_kms_ctx_encrypt;
+ ctx->vtable.kms_done = _kms_done_encrypt;
+
+ return true;
+}
+
+static bool
+_mongo_done_keys (mongocrypt_ctx_t *ctx)
+{
+ BSON_ASSERT_PARAM (ctx);
+
+ if (!_mongocrypt_key_broker_docs_done (&ctx->kb) ||
+ !_mongocrypt_ctx_state_from_key_broker (ctx)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+
+ /* No keys to rewrap, no work to be done. */
+ if (!ctx->kb.key_requests) {
+ ctx->state = MONGOCRYPT_CTX_DONE;
+ return true;
+ }
+
+ /* No KMS required, skip straight to encryption. */
+ if (ctx->state == MONGOCRYPT_CTX_READY) {
+ return _start_kms_encrypt (ctx);
+ }
+
+ /* KMS requests needed to decrypt keys. */
+ BSON_ASSERT (ctx->state == MONGOCRYPT_CTX_NEED_KMS);
+
+ return true;
+}
+
+static bool
+_mongo_op_keys (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ BSON_ASSERT_PARAM (ctx);
+ BSON_ASSERT_PARAM (out);
+
+ _mongocrypt_buffer_to_binary (&rmdctx->filter, out);
+
+ return true;
+}
+
+static bool
+_kms_start_decrypt (mongocrypt_ctx_t *ctx)
+{
+ BSON_ASSERT_PARAM (ctx);
+
+ return _mongocrypt_key_broker_request_any (&ctx->kb) &&
+ _mongocrypt_ctx_state_from_key_broker (ctx);
+}
+
+static void
+_cleanup (mongocrypt_ctx_t *ctx)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ BSON_ASSERT_PARAM (ctx);
+
+ _mongocrypt_buffer_cleanup (&rmdctx->results);
+
+ while (rmdctx->datakeys) {
+ _mongocrypt_ctx_rmd_datakey_t *result = rmdctx->datakeys;
+ rmdctx->datakeys = result->next;
+
+ mongocrypt_ctx_destroy (result->dkctx);
+ bson_free (result);
+ }
+
+ _mongocrypt_kms_ctx_cleanup (&rmdctx->kms);
+ _mongocrypt_buffer_cleanup (&rmdctx->filter);
+}
+
+bool
+mongocrypt_ctx_rewrap_many_datakey_init (mongocrypt_ctx_t *ctx,
+ mongocrypt_binary_t *filter)
+{
+ _mongocrypt_ctx_rewrap_many_datakey_t *const rmdctx =
+ (_mongocrypt_ctx_rewrap_many_datakey_t *) ctx;
+
+ if (!ctx) {
+ return false;
+ }
+
+ if (!filter) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "filter must not be null");
+ }
+
+ {
+ _mongocrypt_ctx_opts_spec_t opts_spec;
+ memset (&opts_spec, 0, sizeof (opts_spec));
+
+ opts_spec.kek = OPT_OPTIONAL;
+
+ if (!_mongocrypt_ctx_init (ctx, &opts_spec)) {
+ return _mongocrypt_ctx_fail (ctx);
+ }
+ }
+
+ ctx->type = _MONGOCRYPT_TYPE_REWRAP_MANY_DATAKEY;
+ ctx->state = MONGOCRYPT_CTX_NEED_MONGO_KEYS;
+ ctx->vtable.cleanup = _cleanup;
+ ctx->vtable.kms_done = _start_kms_encrypt;
+ ctx->vtable.mongo_op_keys = _mongo_op_keys;
+ ctx->vtable.mongo_done_keys = _mongo_done_keys;
+
+ _mongocrypt_buffer_copy_from_binary (&rmdctx->filter, filter);
+
+ /* Obtain KMS credentials for use during decryption and encryption. */
+ if (_mongocrypt_needs_credentials (ctx->crypt)) {
+ ctx->state = MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS;
+ ctx->vtable.after_kms_credentials_provided = _kms_start_decrypt;
+ return true;
+ }
+
+ return _kms_start_decrypt (ctx);
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx.c
similarity index 78%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx.c
index 06b16d07..8d9b0809 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-ctx.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-ctx.c
@@ -1,967 +1,1142 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongocrypt-ctx-private.h"
#include "mongocrypt-key-broker-private.h"
-#define ALGORITHM_DETERMINISTIC "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
-#define ALGORITHM_DETERMINISTIC_LEN 43
-#define ALGORITHM_RANDOM "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
-#define ALGORITHM_RANDOM_LEN 36
-
bool
_mongocrypt_ctx_fail_w_msg (mongocrypt_ctx_t *ctx, const char *msg)
{
_mongocrypt_set_error (ctx->status,
MONGOCRYPT_STATUS_ERROR_CLIENT,
MONGOCRYPT_GENERIC_ERROR_CODE,
"%s",
msg);
return _mongocrypt_ctx_fail (ctx);
}
/* A failure status has already been set. */
bool
_mongocrypt_ctx_fail (mongocrypt_ctx_t *ctx)
{
if (mongocrypt_status_ok (ctx->status)) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "unexpected, failing but no error status set");
}
ctx->state = MONGOCRYPT_CTX_ERROR;
return false;
}
static bool
_set_binary_opt (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *binary,
_mongocrypt_buffer_t *buf,
bson_subtype_t subtype)
{
BSON_ASSERT (ctx);
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
if (!binary || !binary->data) {
return _mongocrypt_ctx_fail_w_msg (ctx, "option must be non-NULL");
}
if (!_mongocrypt_buffer_empty (buf)) {
return _mongocrypt_ctx_fail_w_msg (ctx, "option already set");
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (subtype == BSON_SUBTYPE_UUID && binary->len != 16) {
return _mongocrypt_ctx_fail_w_msg (ctx, "expected 16 byte UUID");
}
_mongocrypt_buffer_copy_from_binary (buf, binary);
buf->subtype = subtype;
return true;
}
bool
mongocrypt_ctx_setopt_key_id (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_id)
{
if (!ctx) {
return false;
}
if (ctx->crypt->log.trace_enabled && key_id && key_id->data) {
char *key_id_val;
key_id_val =
_mongocrypt_new_string_from_bytes (key_id->data, key_id->len);
_mongocrypt_log (&ctx->crypt->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%s\")",
BSON_FUNC,
"key_id",
key_id_val);
bson_free (key_id_val);
}
return _set_binary_opt (ctx, key_id, &ctx->opts.key_id, BSON_SUBTYPE_UUID);
}
bool
mongocrypt_ctx_setopt_key_alt_name (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_alt_name)
{
bson_t as_bson;
bson_iter_t iter;
_mongocrypt_key_alt_name_t *new_key_alt_name;
const char *key;
if (!ctx) {
return false;
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
if (!key_alt_name || !key_alt_name->data) {
return _mongocrypt_ctx_fail_w_msg (ctx, "option must be non-NULL");
}
if (!_mongocrypt_binary_to_bson (key_alt_name, &as_bson)) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid keyAltName bson object");
}
if (!bson_iter_init (&iter, &as_bson) || !bson_iter_next (&iter)) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid bson");
}
key = bson_iter_key (&iter);
BSON_ASSERT (key);
if (0 != strcmp (key, "keyAltName")) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "keyAltName must have field 'keyAltName'");
}
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
return _mongocrypt_ctx_fail_w_msg (ctx, "keyAltName expected to be UTF8");
}
new_key_alt_name = _mongocrypt_key_alt_name_new (bson_iter_value (&iter));
if (ctx->opts.key_alt_names &&
_mongocrypt_key_alt_name_intersects (ctx->opts.key_alt_names,
new_key_alt_name)) {
_mongocrypt_key_alt_name_destroy_all (new_key_alt_name);
return _mongocrypt_ctx_fail_w_msg (ctx, "duplicate keyAltNames found");
}
new_key_alt_name->next = ctx->opts.key_alt_names;
ctx->opts.key_alt_names = new_key_alt_name;
if (bson_iter_next (&iter)) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "unrecognized field, only keyAltName expected");
}
return true;
}
bool
mongocrypt_ctx_setopt_key_material (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_material)
{
bson_t as_bson;
bson_iter_t iter;
const char *key;
_mongocrypt_buffer_t buffer;
if (!ctx) {
return false;
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (ctx->opts.key_material.owned) {
return _mongocrypt_ctx_fail_w_msg (ctx, "keyMaterial already set");
}
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
if (!key_material || !key_material->data) {
return _mongocrypt_ctx_fail_w_msg (ctx, "option must be non-NULL");
}
if (!_mongocrypt_binary_to_bson (key_material, &as_bson)) {
return _mongocrypt_ctx_fail_w_msg (ctx,
"invalid keyMaterial bson object");
}
/* TODO: use _mongocrypt_parse_required_binary once MONGOCRYPT-380 is
* resolved.*/
if (!bson_iter_init (&iter, &as_bson) || !bson_iter_next (&iter)) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid bson");
}
key = bson_iter_key (&iter);
BSON_ASSERT (key);
if (0 != strcmp (key, "keyMaterial")) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "keyMaterial must have field 'keyMaterial'");
}
if (!_mongocrypt_buffer_from_binary_iter (&buffer, &iter)) {
return _mongocrypt_ctx_fail_w_msg (ctx,
"keyMaterial must be binary data");
}
if (buffer.len != MONGOCRYPT_KEY_LEN) {
_mongocrypt_set_error (
ctx->status,
MONGOCRYPT_STATUS_ERROR_CLIENT,
MONGOCRYPT_GENERIC_ERROR_CODE,
"keyMaterial should have length %d, but has length %" PRIu32,
MONGOCRYPT_KEY_LEN,
buffer.len);
return _mongocrypt_ctx_fail (ctx);
}
_mongocrypt_buffer_steal (&ctx->opts.key_material, &buffer);
if (bson_iter_next (&iter)) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "unrecognized field, only keyMaterial expected");
}
return true;
}
bool
mongocrypt_ctx_setopt_algorithm (mongocrypt_ctx_t *ctx,
const char *algorithm,
int len)
{
- size_t calculated_len;
-
if (!ctx) {
return false;
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
- if (ctx->opts.algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE) {
+ if (ctx->opts.algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE ||
+ ctx->opts.index_type.set) {
return _mongocrypt_ctx_fail_w_msg (ctx, "already set algorithm");
}
if (len < -1) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid algorithm length");
}
if (!algorithm) {
return _mongocrypt_ctx_fail_w_msg (ctx, "passed null algorithm");
}
- calculated_len = len == -1 ? strlen (algorithm) : (size_t) len;
+ const size_t calculated_len = len == -1 ? strlen (algorithm) : (size_t) len;
if (ctx->crypt->log.trace_enabled) {
_mongocrypt_log (&ctx->crypt->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%.*s\")",
BSON_FUNC,
"algorithm",
(int) calculated_len,
algorithm);
}
- if (calculated_len == ALGORITHM_DETERMINISTIC_LEN &&
- strncmp (algorithm,
- ALGORITHM_DETERMINISTIC,
- ALGORITHM_DETERMINISTIC_LEN) == 0) {
+ mstr_view algo_str = mstrv_view_data (algorithm, calculated_len);
+ if (mstr_eq (algo_str, mstrv_lit (MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR))) {
ctx->opts.algorithm = MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC;
- return true;
- }
-
- if (calculated_len == ALGORITHM_RANDOM_LEN &&
- strncmp (algorithm, ALGORITHM_RANDOM, ALGORITHM_RANDOM_LEN) == 0) {
+ } else if (mstr_eq (algo_str, mstrv_lit (MONGOCRYPT_ALGORITHM_RANDOM_STR))) {
ctx->opts.algorithm = MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM;
- return true;
+ } else if (mstr_eq (algo_str,
+ mstrv_lit (MONGOCRYPT_ALGORITHM_INDEXED_STR))) {
+ ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_EQUALITY;
+ ctx->opts.index_type.set = true;
+ } else if (mstr_eq (algo_str,
+ mstrv_lit (MONGOCRYPT_ALGORITHM_UNINDEXED_STR))) {
+ ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_NONE;
+ ctx->opts.index_type.set = true;
+ } else {
+ char *error = bson_strdup_printf ("unsupported algorithm string \"%.*s\"",
+ (int) algo_str.len,
+ algo_str.data);
+ _mongocrypt_ctx_fail_w_msg (ctx, error);
+ bson_free (error);
+ return false;
}
- return _mongocrypt_ctx_fail_w_msg (ctx, "unsupported algorithm");
+ return true;
}
mongocrypt_ctx_t *
mongocrypt_ctx_new (mongocrypt_t *crypt)
{
mongocrypt_ctx_t *ctx;
size_t ctx_size;
if (!crypt) {
return NULL;
}
if (!crypt->initialized) {
mongocrypt_status_t *status;
status = crypt->status;
CLIENT_ERR ("cannot create context from uninitialized crypt");
return NULL;
}
ctx_size = sizeof (_mongocrypt_ctx_encrypt_t);
if (sizeof (_mongocrypt_ctx_decrypt_t) > ctx_size) {
ctx_size = sizeof (_mongocrypt_ctx_decrypt_t);
}
if (sizeof (_mongocrypt_ctx_datakey_t) > ctx_size) {
ctx_size = sizeof (_mongocrypt_ctx_datakey_t);
}
ctx = bson_malloc0 (ctx_size);
BSON_ASSERT (ctx);
ctx->crypt = crypt;
ctx->status = mongocrypt_status_new ();
ctx->opts.algorithm = MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE;
ctx->state = MONGOCRYPT_CTX_DONE;
return ctx;
}
#define CHECK_AND_CALL(fn, ...) \
do { \
if (!ctx->vtable.fn) { \
return _mongocrypt_ctx_fail_w_msg (ctx, "not applicable to context"); \
} \
return ctx->vtable.fn (__VA_ARGS__); \
} while (0)
/* Common to both encrypt and decrypt context. */
static bool
_mongo_op_keys (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
{
/* Construct the find filter to fetch keys. */
if (!_mongocrypt_key_broker_filter (&ctx->kb, out)) {
BSON_ASSERT (!_mongocrypt_key_broker_status (&ctx->kb, ctx->status));
return _mongocrypt_ctx_fail (ctx);
}
return true;
}
static bool
_mongo_feed_keys (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
{
_mongocrypt_buffer_t buf;
_mongocrypt_buffer_from_binary (&buf, in);
- if (!_mongocrypt_key_broker_add_doc (&ctx->kb, &buf)) {
+ if (!_mongocrypt_key_broker_add_doc (
+ &ctx->kb, _mongocrypt_ctx_kms_providers (ctx), &buf)) {
BSON_ASSERT (!_mongocrypt_key_broker_status (&ctx->kb, ctx->status));
return _mongocrypt_ctx_fail (ctx);
}
return true;
}
static bool
_mongo_done_keys (mongocrypt_ctx_t *ctx)
{
(void) _mongocrypt_key_broker_docs_done (&ctx->kb);
return _mongocrypt_ctx_state_from_key_broker (ctx);
}
static mongocrypt_kms_ctx_t *
_next_kms_ctx (mongocrypt_ctx_t *ctx)
{
return _mongocrypt_key_broker_next_kms (&ctx->kb);
}
static bool
_kms_done (mongocrypt_ctx_t *ctx)
{
- if (!_mongocrypt_key_broker_kms_done (&ctx->kb)) {
+ _mongocrypt_opts_kms_providers_t *kms_providers =
+ _mongocrypt_ctx_kms_providers (ctx);
+ if (!_mongocrypt_key_broker_kms_done (&ctx->kb, kms_providers)) {
BSON_ASSERT (!_mongocrypt_key_broker_status (&ctx->kb, ctx->status));
return _mongocrypt_ctx_fail (ctx);
}
return _mongocrypt_ctx_state_from_key_broker (ctx);
}
bool
mongocrypt_ctx_mongo_op (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
{
if (!ctx) {
return false;
}
if (!ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
}
if (!out) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid NULL input");
}
switch (ctx->state) {
case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
CHECK_AND_CALL (mongo_op_collinfo, ctx, out);
case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
CHECK_AND_CALL (mongo_op_markings, ctx, out);
case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
CHECK_AND_CALL (mongo_op_keys, ctx, out);
case MONGOCRYPT_CTX_ERROR:
return false;
+ case MONGOCRYPT_CTX_DONE:
+ case MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS:
+ case MONGOCRYPT_CTX_NEED_KMS:
+ case MONGOCRYPT_CTX_READY:
default:
return _mongocrypt_ctx_fail_w_msg (ctx, "wrong state");
}
}
bool
mongocrypt_ctx_mongo_feed (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
{
if (!ctx) {
return false;
}
if (!ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
}
if (!in) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid NULL input");
}
if (ctx->crypt->log.trace_enabled) {
char *in_val;
in_val = _mongocrypt_new_json_string_from_binary (in);
_mongocrypt_log (&ctx->crypt->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%s\")",
BSON_FUNC,
"in",
in_val);
bson_free (in_val);
}
switch (ctx->state) {
case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
CHECK_AND_CALL (mongo_feed_collinfo, ctx, in);
case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
CHECK_AND_CALL (mongo_feed_markings, ctx, in);
case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
CHECK_AND_CALL (mongo_feed_keys, ctx, in);
case MONGOCRYPT_CTX_ERROR:
return false;
+ case MONGOCRYPT_CTX_DONE:
+ case MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS:
+ case MONGOCRYPT_CTX_NEED_KMS:
+ case MONGOCRYPT_CTX_READY:
default:
return _mongocrypt_ctx_fail_w_msg (ctx, "wrong state");
}
}
bool
mongocrypt_ctx_mongo_done (mongocrypt_ctx_t *ctx)
{
if (!ctx) {
return false;
}
if (!ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
}
switch (ctx->state) {
case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
CHECK_AND_CALL (mongo_done_collinfo, ctx);
case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
CHECK_AND_CALL (mongo_done_markings, ctx);
case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
CHECK_AND_CALL (mongo_done_keys, ctx);
case MONGOCRYPT_CTX_ERROR:
return false;
+ case MONGOCRYPT_CTX_DONE:
+ case MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS:
+ case MONGOCRYPT_CTX_NEED_KMS:
+ case MONGOCRYPT_CTX_READY:
default:
return _mongocrypt_ctx_fail_w_msg (ctx, "wrong state");
}
}
mongocrypt_ctx_state_t
mongocrypt_ctx_state (mongocrypt_ctx_t *ctx)
{
if (!ctx) {
return MONGOCRYPT_CTX_ERROR;
}
if (!ctx->initialized) {
_mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
return MONGOCRYPT_CTX_ERROR;
}
return ctx->state;
}
mongocrypt_kms_ctx_t *
mongocrypt_ctx_next_kms_ctx (mongocrypt_ctx_t *ctx)
{
if (!ctx) {
return NULL;
}
if (!ctx->initialized) {
_mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
return NULL;
}
if (!ctx->vtable.next_kms_ctx) {
_mongocrypt_ctx_fail_w_msg (ctx, "not applicable to context");
return NULL;
}
switch (ctx->state) {
case MONGOCRYPT_CTX_NEED_KMS:
return ctx->vtable.next_kms_ctx (ctx);
case MONGOCRYPT_CTX_ERROR:
return NULL;
+ case MONGOCRYPT_CTX_DONE:
+ case MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS:
+ case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
+ case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
+ case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
+ case MONGOCRYPT_CTX_READY:
default:
_mongocrypt_ctx_fail_w_msg (ctx, "wrong state");
return NULL;
}
}
+bool
+mongocrypt_ctx_provide_kms_providers (
+ mongocrypt_ctx_t *ctx, mongocrypt_binary_t *kms_providers_definition)
+{
+ if (!ctx) {
+ return false;
+ }
+
+ if (!ctx->initialized) {
+ _mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
+ return false;
+ }
+
+ if (ctx->state != MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS) {
+ _mongocrypt_ctx_fail_w_msg (ctx, "wrong state");
+ return false;
+ }
+
+ if (!_mongocrypt_parse_kms_providers (kms_providers_definition,
+ &ctx->per_ctx_kms_providers,
+ ctx->status,
+ &ctx->crypt->log)) {
+ return false;
+ }
+
+ if (!_mongocrypt_opts_kms_providers_validate (&ctx->per_ctx_kms_providers,
+ ctx->status)) {
+ /* Remove the parsed KMS providers if they are invalid */
+ _mongocrypt_opts_kms_providers_cleanup (&ctx->per_ctx_kms_providers);
+ memset (
+ &ctx->per_ctx_kms_providers, 0, sizeof (ctx->per_ctx_kms_providers));
+ return false;
+ }
+
+ memcpy (&ctx->kms_providers,
+ &ctx->crypt->opts.kms_providers,
+ sizeof (_mongocrypt_opts_kms_providers_t));
+ _mongocrypt_opts_merge_kms_providers (&ctx->kms_providers,
+ &ctx->per_ctx_kms_providers);
+
+ ctx->state = ctx->kb.state == KB_ADDING_DOCS ? MONGOCRYPT_CTX_NEED_MONGO_KEYS
+ : MONGOCRYPT_CTX_NEED_KMS;
+ if (ctx->vtable.after_kms_credentials_provided) {
+ return ctx->vtable.after_kms_credentials_provided (ctx);
+ }
+ return true;
+}
+
+
bool
mongocrypt_ctx_kms_done (mongocrypt_ctx_t *ctx)
{
if (!ctx) {
return false;
}
if (!ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
}
if (!ctx->vtable.kms_done) {
return _mongocrypt_ctx_fail_w_msg (ctx, "not applicable to context");
}
switch (ctx->state) {
case MONGOCRYPT_CTX_NEED_KMS:
return ctx->vtable.kms_done (ctx);
case MONGOCRYPT_CTX_ERROR:
return false;
+ case MONGOCRYPT_CTX_DONE:
+ case MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS:
+ case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
+ case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
+ case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
+ case MONGOCRYPT_CTX_READY:
default:
return _mongocrypt_ctx_fail_w_msg (ctx, "wrong state");
}
}
bool
mongocrypt_ctx_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out)
{
if (!ctx) {
return false;
}
if (!ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "ctx NULL or uninitialized");
}
if (!out) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid NULL input");
}
if (!ctx->vtable.finalize) {
return _mongocrypt_ctx_fail_w_msg (ctx, "not applicable to context");
}
switch (ctx->state) {
case MONGOCRYPT_CTX_READY:
return ctx->vtable.finalize (ctx, out);
case MONGOCRYPT_CTX_ERROR:
return false;
+ case MONGOCRYPT_CTX_DONE:
+ case MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS:
+ case MONGOCRYPT_CTX_NEED_KMS:
+ case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
+ case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
+ case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
default:
return _mongocrypt_ctx_fail_w_msg (ctx, "wrong state");
}
}
bool
mongocrypt_ctx_status (mongocrypt_ctx_t *ctx, mongocrypt_status_t *out)
{
if (!ctx) {
return false;
}
if (!mongocrypt_status_ok (ctx->status)) {
_mongocrypt_status_copy_to (ctx->status, out);
return false;
}
_mongocrypt_status_reset (out);
return true;
}
void
mongocrypt_ctx_destroy (mongocrypt_ctx_t *ctx)
{
if (!ctx) {
return;
}
if (ctx->vtable.cleanup) {
ctx->vtable.cleanup (ctx);
}
+ _mongocrypt_opts_kms_providers_cleanup (&ctx->per_ctx_kms_providers);
_mongocrypt_kek_cleanup (&ctx->opts.kek);
mongocrypt_status_destroy (ctx->status);
_mongocrypt_key_broker_cleanup (&ctx->kb);
_mongocrypt_buffer_cleanup (&ctx->opts.key_material);
_mongocrypt_key_alt_name_destroy_all (ctx->opts.key_alt_names);
_mongocrypt_buffer_cleanup (&ctx->opts.key_id);
+ _mongocrypt_buffer_cleanup (&ctx->opts.index_key_id);
bson_free (ctx);
return;
}
bool
mongocrypt_ctx_setopt_masterkey_aws (mongocrypt_ctx_t *ctx,
const char *region,
int32_t region_len,
const char *cmk,
int32_t cmk_len)
{
mongocrypt_binary_t *bin;
bson_t as_bson;
bool ret;
char *temp = NULL;
if (!ctx) {
return false;
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
if (ctx->opts.kek.kms_provider != MONGOCRYPT_KMS_PROVIDER_AWS &&
ctx->opts.kek.kms_provider != MONGOCRYPT_KMS_PROVIDER_NONE) {
return _mongocrypt_ctx_fail_w_msg (ctx, "master key already set");
}
if (ctx->opts.kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_AWS &&
ctx->opts.kek.provider.aws.region) {
return _mongocrypt_ctx_fail_w_msg (ctx, "master key already set");
}
if (!_mongocrypt_validate_and_copy_string (region, region_len, &temp) ||
region_len == 0) {
bson_free (temp);
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid region");
}
bson_free (temp);
temp = NULL;
if (!_mongocrypt_validate_and_copy_string (cmk, cmk_len, &temp) ||
cmk_len == 0) {
bson_free (temp);
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid cmk");
}
bson_free (temp);
bson_init (&as_bson);
bson_append_utf8 (&as_bson,
MONGOCRYPT_STR_AND_LEN ("provider"),
MONGOCRYPT_STR_AND_LEN ("aws"));
bson_append_utf8 (
&as_bson, MONGOCRYPT_STR_AND_LEN ("region"), region, region_len);
bson_append_utf8 (&as_bson, MONGOCRYPT_STR_AND_LEN ("key"), cmk, cmk_len);
bin = mongocrypt_binary_new_from_data ((uint8_t *) bson_get_data (&as_bson),
as_bson.len);
ret = mongocrypt_ctx_setopt_key_encryption_key (ctx, bin);
mongocrypt_binary_destroy (bin);
bson_destroy (&as_bson);
if (ctx->crypt->log.trace_enabled) {
_mongocrypt_log (&ctx->crypt->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%s\", %s=%d, %s=\"%s\", %s=%d)",
BSON_FUNC,
"region",
ctx->opts.kek.provider.aws.region,
"region_len",
region_len,
"cmk",
ctx->opts.kek.provider.aws.cmk,
"cmk_len",
cmk_len);
}
return ret;
}
bool
mongocrypt_ctx_setopt_masterkey_local (mongocrypt_ctx_t *ctx)
{
if (!ctx) {
return false;
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
if (ctx->opts.kek.kms_provider) {
return _mongocrypt_ctx_fail_w_msg (ctx, "master key already set");
}
ctx->opts.kek.kms_provider = MONGOCRYPT_KMS_PROVIDER_LOCAL;
return true;
}
bool
_mongocrypt_ctx_init (mongocrypt_ctx_t *ctx,
_mongocrypt_ctx_opts_spec_t *opts_spec)
{
bool has_id = false, has_alt_name = false, has_multiple_alt_names = false;
+ // This condition is guarded in setopt_algorithm:
+ BSON_ASSERT (
+ !(ctx->opts.index_type.set &&
+ ctx->opts.algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE) &&
+ "Both an encryption algorithm and an index_type were set.");
+
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot double initialize");
}
ctx->initialized = true;
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
/* Set some default functions */
ctx->vtable.mongo_op_keys = _mongo_op_keys;
ctx->vtable.mongo_feed_keys = _mongo_feed_keys;
ctx->vtable.mongo_done_keys = _mongo_done_keys;
ctx->vtable.next_kms_ctx = _next_kms_ctx;
ctx->vtable.kms_done = _kms_done;
/* Check that required options are included and prohibited options are
* not.
*/
if (opts_spec->kek == OPT_REQUIRED) {
if (!ctx->opts.kek.kms_provider) {
return _mongocrypt_ctx_fail_w_msg (ctx, "master key required");
}
- if (!(ctx->opts.kek.kms_provider & ctx->crypt->opts.kms_providers)) {
+ if (!ctx->crypt->opts.use_need_kms_credentials_state &&
+ !(ctx->opts.kek.kms_provider &
+ _mongocrypt_ctx_kms_providers (ctx)->configured_providers)) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "requested kms provider not configured");
}
}
if (opts_spec->kek == OPT_PROHIBITED && ctx->opts.kek.kms_provider) {
return _mongocrypt_ctx_fail_w_msg (ctx, "master key prohibited");
}
/* Special case. key_descriptor applies to explicit encryption. It must be
* either a key id or *one* key alt name, but not both.
* key_alt_names applies to creating a data key. It may be one or multiple
* key alt names.
*/
has_id = !_mongocrypt_buffer_empty (&ctx->opts.key_id);
has_alt_name = !!(ctx->opts.key_alt_names);
has_multiple_alt_names = has_alt_name && !!(ctx->opts.key_alt_names->next);
if (opts_spec->key_descriptor == OPT_REQUIRED) {
if (!has_id && !has_alt_name) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "either key id or key alt name required");
}
if (has_id && has_alt_name) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "cannot have both key id and key alt name");
}
if (has_multiple_alt_names) {
return _mongocrypt_ctx_fail_w_msg (
ctx, "must not specify multiple key alt names");
}
}
if (opts_spec->key_descriptor == OPT_PROHIBITED) {
/* still okay if key_alt_names are allowed and only alt names were
* specified. */
if ((opts_spec->key_alt_names == OPT_PROHIBITED && has_alt_name) ||
has_id) {
return _mongocrypt_ctx_fail_w_msg (ctx,
"key id and alt name prohibited");
}
}
if (opts_spec->key_material == OPT_PROHIBITED &&
ctx->opts.key_material.owned) {
return _mongocrypt_ctx_fail_w_msg (ctx, "key material prohibited");
}
if (opts_spec->algorithm == OPT_REQUIRED &&
ctx->opts.algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE) {
return _mongocrypt_ctx_fail_w_msg (ctx, "algorithm required");
}
if (opts_spec->algorithm == OPT_PROHIBITED &&
ctx->opts.algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE) {
return _mongocrypt_ctx_fail_w_msg (ctx, "algorithm prohibited");
}
_mongocrypt_key_broker_init (&ctx->kb, ctx->crypt);
return true;
}
bool
_mongocrypt_ctx_state_from_key_broker (mongocrypt_ctx_t *ctx)
{
_mongocrypt_key_broker_t *kb;
mongocrypt_status_t *status;
mongocrypt_ctx_state_t new_state = MONGOCRYPT_CTX_ERROR;
bool ret = false;
status = ctx->status;
kb = &ctx->kb;
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
switch (kb->state) {
case KB_ERROR:
_mongocrypt_status_copy_to (kb->status, status);
new_state = MONGOCRYPT_CTX_ERROR;
ret = false;
break;
case KB_ADDING_DOCS:
- /* Require key documents from driver. */
+ /* Encrypted keys need KMS, which need to be provided before
+ * adding docs. */
+ if (_mongocrypt_needs_credentials (ctx->crypt)) {
+ new_state = MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS;
+ } else {
+ /* Require key documents from driver. */
+ new_state = MONGOCRYPT_CTX_NEED_MONGO_KEYS;
+ }
+ ret = true;
+ break;
+ case KB_ADDING_DOCS_ANY:
+ /* Assume KMS credentials have been provided. */
new_state = MONGOCRYPT_CTX_NEED_MONGO_KEYS;
ret = true;
break;
case KB_AUTHENTICATING:
case KB_DECRYPTING_KEY_MATERIAL:
- /* Encrypted keys need KMS. */
new_state = MONGOCRYPT_CTX_NEED_KMS;
ret = true;
break;
case KB_DONE:
new_state = MONGOCRYPT_CTX_READY;
if (kb->key_requests == NULL) {
/* No key requests were ever added. */
ctx->nothing_to_do = true; /* nothing to encrypt/decrypt */
}
ret = true;
break;
/* As currently implemented, we do not expect to ever be in KB_REQUESTING
- * state when calling this function. */
+ * or KB_REQUESTING_ANY state when calling this function. */
case KB_REQUESTING:
+ default:
CLIENT_ERR ("key broker in unexpected state");
new_state = MONGOCRYPT_CTX_ERROR;
ret = false;
break;
}
if (new_state != ctx->state) {
ctx->state = new_state;
}
return ret;
}
bool
mongocrypt_ctx_setopt_masterkey_aws_endpoint (mongocrypt_ctx_t *ctx,
const char *endpoint,
int32_t endpoint_len)
{
if (!ctx) {
return false;
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
if (ctx->opts.kek.kms_provider != MONGOCRYPT_KMS_PROVIDER_AWS &&
ctx->opts.kek.kms_provider != MONGOCRYPT_KMS_PROVIDER_NONE) {
return _mongocrypt_ctx_fail_w_msg (ctx, "endpoint prohibited");
}
ctx->opts.kek.kms_provider = MONGOCRYPT_KMS_PROVIDER_AWS;
if (ctx->opts.kek.provider.aws.endpoint) {
return _mongocrypt_ctx_fail_w_msg (ctx, "already set masterkey endpoint");
}
ctx->opts.kek.provider.aws.endpoint = _mongocrypt_endpoint_new (
endpoint, endpoint_len, NULL /* opts */, ctx->status);
if (!ctx->opts.kek.provider.aws.endpoint) {
return _mongocrypt_ctx_fail (ctx);
}
return true;
}
bool
mongocrypt_ctx_setopt_key_encryption_key (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *bin)
{
bson_t as_bson;
if (!ctx) {
return false;
}
if (ctx->initialized) {
return _mongocrypt_ctx_fail_w_msg (ctx, "cannot set options after init");
}
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
return false;
}
if (ctx->opts.kek.kms_provider) {
return _mongocrypt_ctx_fail_w_msg (ctx, "key encryption key already set");
}
if (!_mongocrypt_binary_to_bson (bin, &as_bson)) {
return _mongocrypt_ctx_fail_w_msg (ctx, "invalid BSON");
}
if (!_mongocrypt_kek_parse_owned (&as_bson, &ctx->opts.kek, ctx->status)) {
return _mongocrypt_ctx_fail (ctx);
}
if (ctx->crypt->log.trace_enabled) {
char *bin_str = bson_as_canonical_extended_json (&as_bson, NULL);
_mongocrypt_log (&ctx->crypt->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%s\")",
BSON_FUNC,
"bin",
bin_str);
bson_free (bin_str);
}
return true;
}
+
+_mongocrypt_opts_kms_providers_t *
+_mongocrypt_ctx_kms_providers (mongocrypt_ctx_t *ctx)
+{
+ return ctx->kms_providers.configured_providers
+ ? &ctx->kms_providers
+ : &ctx->crypt->opts.kms_providers;
+}
+
+bool
+mongocrypt_ctx_setopt_contention_factor (mongocrypt_ctx_t *ctx,
+ int64_t contention_factor)
+{
+ if (!ctx) {
+ return false;
+ }
+ ctx->opts.contention_factor.value = contention_factor;
+ ctx->opts.contention_factor.set = true;
+ return true;
+}
+
+bool
+mongocrypt_ctx_setopt_index_key_id (mongocrypt_ctx_t *ctx,
+ mongocrypt_binary_t *key_id)
+{
+ if (!ctx) {
+ return false;
+ }
+
+ return _set_binary_opt (
+ ctx, key_id, &ctx->opts.index_key_id, BSON_SUBTYPE_UUID);
+}
+
+bool
+mongocrypt_ctx_setopt_query_type (mongocrypt_ctx_t *ctx,
+ const char *query_type,
+ int len)
+{
+ if (!ctx) {
+ return false;
+ }
+
+ if (ctx->initialized) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "Cannot set options after init");
+ }
+ if (ctx->state == MONGOCRYPT_CTX_ERROR) {
+ return false;
+ }
+ if (len < -1) {
+ return _mongocrypt_ctx_fail_w_msg (ctx,
+ "Invalid query_type string length");
+ }
+ if (!query_type) {
+ return _mongocrypt_ctx_fail_w_msg (ctx, "Invalid null query_type string");
+ }
+
+ const size_t calc_len = len == -1 ? strlen (query_type) : (size_t) len;
+ mstr_view qt_str = mstrv_view_data (query_type, calc_len);
+ if (mstr_eq (qt_str, mstrv_lit (MONGOCRYPT_QUERY_TYPE_EQUALITY_STR))) {
+ ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_EQUALITY;
+ ctx->opts.query_type.set = true;
+ } else {
+ char *error = bson_strdup_printf (
+ "Unsupported query_type \"%.*s\"", (int) qt_str.len, qt_str.data);
+ _mongocrypt_ctx_fail_w_msg (ctx, error);
+ bson_free (error);
+ return false;
+ }
+ return true;
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-dll-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-dll-private.h
similarity index 81%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-dll-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-dll-private.h
index 1f4f68d0..3bef20a8 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-dll-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-dll-private.h
@@ -1,79 +1,97 @@
#ifndef MONGOCRYPT_DLL_PRIVATE_H
#define MONGOCRYPT_DLL_PRIVATE_H
#include <mlib/str.h>
+#include <mlib/error.h>
#include <stdlib.h>
#if _WIN32
#define MCR_DLL_SUFFIX ".dll"
#elif __APPLE__
#define MCR_DLL_SUFFIX ".dylib"
#else
#define MCR_DLL_SUFFIX ".so"
#endif
#define MCR_DLL_NULL \
((mcr_dll){._native_handle = NULL, .error_string = MSTR_NULL})
/**
* @brief A dynamically-loaded library i.e. returned by LoadLibrary() or
* dlopen()
*/
typedef struct mcr_dll {
// (All supported platforms use a void* as the library handle type)
void *_native_handle;
mstr error_string;
} mcr_dll;
/**
* @brief Open and load a dynamic library
*
* @param lib A path or name of a library, suitable for encoding as a
* filepath on the host system.
*
* @return mcr_dll A newly opened dynamic library, which must be
* released using @ref mcr_dll_close()
*
* If the given `lib` is a qualified path (either relative or absolute) and not
* just a filename, then the system will search for the library on the system's
* default library search paths. If `lib` is a qualified relative path (not just
* a filename), it will be resolved relative to the application's working
* directory.
*/
mcr_dll
mcr_dll_open (const char *lib);
/**
* @brief Close a dynamic library opened with @ref mcr_dll_open
*
* @param dll A dynamic library handle
*/
static inline void
mcr_dll_close (mcr_dll dll)
{
extern void mcr_dll_close_handle (mcr_dll);
mcr_dll_close_handle (dll);
mstr_free (dll.error_string);
}
/**
* @brief Obtain a pointer to an exported entity from the given dynamic library.
*
* @param dll A library opened with @ref mcr_dll_open
* @param symbol The name of a symbol to open
* @return void* A pointer to that symbol, or NULL if not found
*/
void *
mcr_dll_sym (mcr_dll dll, const char *symbol);
/**
* @brief Determine whether the given DLL is a handle to an open library
*/
static inline bool
mcr_dll_is_open (mcr_dll dll)
{
return dll._native_handle != NULL;
}
+typedef struct mcr_dll_path_result {
+ mstr path;
+ mstr error_string;
+} mcr_dll_path_result;
+
+/**
+ * @brief Obtain a filepath to the given loaded DLL
+ *
+ * @param dll The library loaded to inspect
+ * @return mcr_dll_path_result A result containing the absolute path to a
+ * library, or an error string.
+ *
+ * @note Caller must free both `retval.path` and `retval.error_string`.
+ */
+mcr_dll_path_result
+mcr_dll_path (mcr_dll dll);
+
#endif // MONGOCRYPT_DLL_PRIVATE_H
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-endian-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-endian-private.h
new file mode 100644
index 00000000..b6ab87ed
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-endian-private.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2022-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file is copied and modified from kms_message kms_endian.h. */
+
+#ifndef MONGOCRYPT_ENDIAN_PRIVATE_H
+#define MONGOCRYPT_ENDIAN_PRIVATE_H
+
+#include <stdint.h>
+#include <string.h>
+
+/* Define a fallback for __has_builtin for compatibility with non-clang
+ * compilers. */
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#if defined(__clang__) && __has_builtin(__builtin_bswap16) && \
+ __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)
+#define MONGOCRYPT_UINT16_SWAP_LE_BE(v) __builtin_bswap16 (v)
+#define MONGOCRYPT_UINT32_SWAP_LE_BE(v) __builtin_bswap32 (v)
+#define MONGOCRYPT_UINT64_SWAP_LE_BE(v) __builtin_bswap64 (v)
+#elif defined(__GNUC__) && (__GNUC__ >= 4)
+#if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 3)
+#define MONGOCRYPT_UINT32_SWAP_LE_BE(v) __builtin_bswap32 ((uint32_t) v)
+#define MONGOCRYPT_UINT64_SWAP_LE_BE(v) __builtin_bswap64 ((uint64_t) v)
+#endif
+#if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 8)
+#define MONGOCRYPT_UINT16_SWAP_LE_BE(v) __builtin_bswap16 ((uint32_t) v)
+#endif
+#endif
+
+#ifndef MONGOCRYPT_UINT16_SWAP_LE_BE
+#define MONGOCRYPT_UINT16_SWAP_LE_BE(v) \
+ __mongocrypt_uint16_swap_slow ((uint16_t) v)
+#endif
+
+#ifndef MONGOCRYPT_UINT32_SWAP_LE_BE
+#define MONGOCRYPT_UINT32_SWAP_LE_BE(v) \
+ __mongocrypt_uint32_swap_slow ((uint32_t) v)
+#endif
+
+#ifndef MONGOCRYPT_UINT64_SWAP_LE_BE
+#define MONGOCRYPT_UINT64_SWAP_LE_BE(v) \
+ __mongocrypt_uint64_swap_slow ((uint64_t) v)
+#endif
+
+#if defined(MONGOCRYPT_LITTLE_ENDIAN)
+#define MONGOCRYPT_UINT16_FROM_LE(v) ((uint16_t) v)
+#define MONGOCRYPT_UINT16_TO_LE(v) ((uint16_t) v)
+#define MONGOCRYPT_UINT16_FROM_BE(v) MONGOCRYPT_UINT16_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT16_TO_BE(v) MONGOCRYPT_UINT16_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT32_FROM_LE(v) ((uint32_t) v)
+#define MONGOCRYPT_UINT32_TO_LE(v) ((uint32_t) v)
+#define MONGOCRYPT_UINT32_FROM_BE(v) MONGOCRYPT_UINT32_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT32_TO_BE(v) MONGOCRYPT_UINT32_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT64_FROM_LE(v) ((uint64_t) v)
+#define MONGOCRYPT_UINT64_TO_LE(v) ((uint64_t) v)
+#define MONGOCRYPT_UINT64_FROM_BE(v) MONGOCRYPT_UINT64_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT64_TO_BE(v) MONGOCRYPT_UINT64_SWAP_LE_BE (v)
+#elif defined(MONGOCRYPT_BIG_ENDIAN)
+#define MONGOCRYPT_UINT16_FROM_LE(v) MONGOCRYPT_UINT16_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT16_TO_LE(v) MONGOCRYPT_UINT16_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT16_FROM_BE(v) ((uint16_t) v)
+#define MONGOCRYPT_UINT16_TO_BE(v) ((uint16_t) v)
+#define MONGOCRYPT_UINT32_FROM_LE(v) MONGOCRYPT_UINT32_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT32_TO_LE(v) MONGOCRYPT_UINT32_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT32_FROM_BE(v) ((uint32_t) v)
+#define MONGOCRYPT_UINT32_TO_BE(v) ((uint32_t) v)
+#define MONGOCRYPT_UINT64_FROM_LE(v) MONGOCRYPT_UINT64_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT64_TO_LE(v) MONGOCRYPT_UINT64_SWAP_LE_BE (v)
+#define MONGOCRYPT_UINT64_FROM_BE(v) ((uint64_t) v)
+#define MONGOCRYPT_UINT64_TO_BE(v) ((uint64_t) v)
+#else
+#error "The endianness of target architecture is unknown."
+#endif
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * __mongocrypt_uint16_swap_slow --
+ *
+ * Fallback endianness conversion for 16-bit integers.
+ *
+ * Returns:
+ * The endian swapped version.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static inline uint16_t
+__mongocrypt_uint16_swap_slow (uint16_t v) /* IN */
+{
+ return ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * __mongocrypt_uint32_swap_slow --
+ *
+ * Fallback endianness conversion for 32-bit integers.
+ *
+ * Returns:
+ * The endian swapped version.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static inline uint32_t
+__mongocrypt_uint32_swap_slow (uint32_t v) /* IN */
+{
+ return ((v & 0x000000FFU) << 24) | ((v & 0x0000FF00U) << 8) |
+ ((v & 0x00FF0000U) >> 8) | ((v & 0xFF000000U) >> 24);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * __mongocrypt_uint64_swap_slow --
+ *
+ * Fallback endianness conversion for 64-bit integers.
+ *
+ * Returns:
+ * The endian swapped version.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static inline uint64_t
+__mongocrypt_uint64_swap_slow (uint64_t v) /* IN */
+{
+ return ((v & 0x00000000000000FFULL) << 56) |
+ ((v & 0x000000000000FF00ULL) << 40) |
+ ((v & 0x0000000000FF0000ULL) << 24) |
+ ((v & 0x00000000FF000000ULL) << 8) |
+ ((v & 0x000000FF00000000ULL) >> 8) |
+ ((v & 0x0000FF0000000000ULL) >> 24) |
+ ((v & 0x00FF000000000000ULL) >> 40) |
+ ((v & 0xFF00000000000000ULL) >> 56);
+}
+
+
+#endif /* MONGOCRYPT_ENDIAN_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-endpoint-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-endpoint-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-endpoint-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-endpoint-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-endpoint.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-endpoint.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-endpoint.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-endpoint.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kek-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kek-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kek-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kek-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kek.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kek.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kek.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kek.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-broker-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-broker-private.h
similarity index 90%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-broker-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-broker-private.h
index 8703e604..5653401f 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-broker-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-broker-private.h
@@ -1,194 +1,209 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_KEY_BROKER_PRIVATE_H
#define MONGOCRYPT_KEY_BROKER_PRIVATE_H
#include <bson/bson.h>
#include "kms_message/kms_message.h"
#include "mongocrypt.h"
#include "mongocrypt-cache-private.h"
#include "mongocrypt-kms-ctx-private.h"
#include "mongocrypt-cache-key-private.h"
#include "mongocrypt-binary-private.h"
#include "mongocrypt-opts-private.h"
#include "mongocrypt-cache-private.h"
/* The key broker acts as a middle-man between an encrypt/decrypt request and
* the key cache.
* Each encrypt/decrypt request has one key broker. Key brokers are not shared.
* It is responsible for:
* - keeping track of requested keys (either by id or keyAltName)
* - copying keys from the cache to satisfy those requests
* - generating find cmd filters to fetch keys that aren't cached or are expired
* - generating KMS decrypt requests on newly fetched keys
* - adding newly fetched keys back to the cache
*
* Notes:
* - any key request that is satisfied stays satisfied.
* - keys returned from the driver are validated to not have intersecting key
* alt names (or duplicate ids).
* - keys fetched from the cache are not validated, because the cache is shared
* and locking only occurs on a single fetch (so it is possible to have two keys
* fetched from the cache that have intersecting keyAltNames but a different
* _id, and that is not an error)
*/
-/* The state of the key broker. Transitions are only forward. */
+/* The state of the key broker. */
typedef enum {
/* Starting state. Accept requests for keys to be added (either by id or
name) */
KB_REQUESTING,
/* Accept key documents fetched from the key vault collection. */
KB_ADDING_DOCS,
+ /* Accept any key document fetched from the key vault collection. */
+ KB_ADDING_DOCS_ANY,
/* Getting oauth token(s) from KMS providers. */
KB_AUTHENTICATING,
/* Accept KMS replies to decrypt key material in each key document. */
KB_DECRYPTING_KEY_MATERIAL,
KB_DONE,
KB_ERROR
} key_broker_state_t;
/* Represents a single request for a key, as indicated from a response
* from mongocryptd. */
typedef struct _key_request_t {
/* only one of id or alt_name are set. */
_mongocrypt_buffer_t id;
_mongocrypt_key_alt_name_t *alt_name;
bool satisfied; /* true if satisfied by a cache entry or a key returned. */
struct _key_request_t *next;
} key_request_t;
/* Represents a single key supplied from the driver or cache. */
typedef struct _key_returned_t {
_mongocrypt_key_doc_t *doc;
_mongocrypt_buffer_t decrypted_key_material;
mongocrypt_kms_ctx_t kms;
bool decrypted;
bool needs_auth;
struct _key_returned_t *next;
} key_returned_t;
typedef struct _auth_request_t {
mongocrypt_kms_ctx_t kms;
bool returned;
bool initialized;
} auth_request_t;
typedef struct {
key_broker_state_t state;
mongocrypt_status_t *status;
key_request_t *key_requests;
/* Keep keys returned from driver separate from keys returned from cache.
* Keys returned from driver MUST not have conflicts (e.g. intersecting key
* alt names)
* But keys from cache MAY have conflicts since the cache is only locked for
* a single get operation.
*/
key_returned_t *keys_returned;
key_returned_t *keys_cached;
_mongocrypt_buffer_t filter;
mongocrypt_t *crypt;
key_returned_t *decryptor_iter;
auth_request_t auth_request_azure;
auth_request_t auth_request_gcp;
} _mongocrypt_key_broker_t;
void
_mongocrypt_key_broker_init (_mongocrypt_key_broker_t *kb, mongocrypt_t *crypt);
/* Add a request for a key by UUID. */
bool
_mongocrypt_key_broker_request_id (_mongocrypt_key_broker_t *kb,
const _mongocrypt_buffer_t *key_id)
MONGOCRYPT_WARN_UNUSED_RESULT;
/* Add keyAltName into the key broker.
Key is added as KEY_EMPTY. */
bool
_mongocrypt_key_broker_request_name (_mongocrypt_key_broker_t *kb,
const bson_value_t *key_alt_name)
MONGOCRYPT_WARN_UNUSED_RESULT;
+/* Switch mode to permit adding documents without prior requests. */
+bool
+_mongocrypt_key_broker_request_any (_mongocrypt_key_broker_t *kb)
+ MONGOCRYPT_WARN_UNUSED_RESULT;
+
bool
_mongocrypt_key_broker_requests_done (_mongocrypt_key_broker_t *kb);
/* Get the find command filter. */
bool
_mongocrypt_key_broker_filter (_mongocrypt_key_broker_t *kb,
mongocrypt_binary_t *out)
MONGOCRYPT_WARN_UNUSED_RESULT;
/* Add a key document. */
bool
_mongocrypt_key_broker_add_doc (_mongocrypt_key_broker_t *kb,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
const _mongocrypt_buffer_t *doc)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_key_broker_docs_done (_mongocrypt_key_broker_t *kb);
/* Iterate the keys needing KMS decryption. */
mongocrypt_kms_ctx_t *
_mongocrypt_key_broker_next_kms (_mongocrypt_key_broker_t *kb)
MONGOCRYPT_WARN_UNUSED_RESULT;
/* Indicate that all KMS requests are complete. */
bool
-_mongocrypt_key_broker_kms_done (_mongocrypt_key_broker_t *kb);
+_mongocrypt_key_broker_kms_done (
+ _mongocrypt_key_broker_t *kb,
+ _mongocrypt_opts_kms_providers_t *kms_providers);
/* Get the final decrypted key material from a key by looking up with a key_id.
* @out is always initialized, even on error. */
bool
_mongocrypt_key_broker_decrypted_key_by_id (_mongocrypt_key_broker_t *kb,
const _mongocrypt_buffer_t *key_id,
_mongocrypt_buffer_t *out)
MONGOCRYPT_WARN_UNUSED_RESULT;
/* Get the final decrypted key material from a key, and optionally its key_id.
* @key_id_out may be NULL. @out and @key_id_out (if not NULL) are always
* initialized, even on error. */
bool
_mongocrypt_key_broker_decrypted_key_by_name (_mongocrypt_key_broker_t *kb,
const bson_value_t *key_alt_name,
_mongocrypt_buffer_t *out,
_mongocrypt_buffer_t *key_id_out)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_key_broker_status (_mongocrypt_key_broker_t *kb,
mongocrypt_status_t *out);
void
_mongocrypt_key_broker_cleanup (_mongocrypt_key_broker_t *kb);
/* For testing only, add a decrypted key */
void
_mongocrypt_key_broker_add_test_key (_mongocrypt_key_broker_t *kb,
const _mongocrypt_buffer_t *key_id);
+/* _mongocrypt_key_broker_restart is used to request additional keys. It must
+ * only be called in the KB_DONE state. */
+bool
+_mongocrypt_key_broker_restart (_mongocrypt_key_broker_t *kb);
+
#endif /* MONGOCRYPT_KEY_BROKER_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-broker.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-broker.c
similarity index 91%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-broker.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-broker.c
index 2b1a1d0e..508e773a 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-broker.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-broker.c
@@ -1,1040 +1,1099 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongocrypt-key-broker-private.h"
#include "mongocrypt-private.h"
void
_mongocrypt_key_broker_init (_mongocrypt_key_broker_t *kb, mongocrypt_t *crypt)
{
memset (kb, 0, sizeof (*kb));
kb->crypt = crypt;
kb->state = KB_REQUESTING;
kb->status = mongocrypt_status_new ();
}
/*
* Creates a new key_returned_t and prepends it to a list.
*
* Side effects:
* - updates *list to point to a new head.
*/
static key_returned_t *
_key_returned_prepend (_mongocrypt_key_broker_t *kb,
key_returned_t **list,
_mongocrypt_key_doc_t *key_doc)
{
key_returned_t *key_returned;
BSON_ASSERT (key_doc);
key_returned = bson_malloc0 (sizeof (*key_returned));
BSON_ASSERT (key_returned);
key_returned->doc = _mongocrypt_key_new ();
_mongocrypt_key_doc_copy_to (key_doc, key_returned->doc);
/* Prepend and update the head of the list. */
key_returned->next = *list;
*list = key_returned;
/* Update the head of the decrypting iter. */
kb->decryptor_iter = kb->keys_returned;
return key_returned;
}
/* Find the first (if any) key_returned_t matching either a key_id or a list of
* key_alt_names (both are NULLable) */
static key_returned_t *
_key_returned_find_one (key_returned_t *list,
_mongocrypt_buffer_t *key_id,
_mongocrypt_key_alt_name_t *key_alt_names)
{
key_returned_t *key_returned;
for (key_returned = list; NULL != key_returned;
key_returned = key_returned->next) {
if (key_id) {
if (0 == _mongocrypt_buffer_cmp (key_id, &key_returned->doc->id)) {
return key_returned;
}
}
if (key_alt_names) {
if (_mongocrypt_key_alt_name_intersects (
key_alt_names, key_returned->doc->key_alt_names)) {
return key_returned;
}
}
}
return NULL;
}
/* Find the first (if any) key_request_t in the key broker matching either a
* key_id or a list of key_alt_names (both are NULLable) */
static key_request_t *
_key_request_find_one (_mongocrypt_key_broker_t *kb,
const _mongocrypt_buffer_t *key_id,
_mongocrypt_key_alt_name_t *key_alt_names)
{
key_request_t *key_request;
for (key_request = kb->key_requests; NULL != key_request;
key_request = key_request->next) {
if (key_id) {
if (0 == _mongocrypt_buffer_cmp (key_id, &key_request->id)) {
return key_request;
}
}
if (key_alt_names) {
if (_mongocrypt_key_alt_name_intersects (key_alt_names,
key_request->alt_name)) {
return key_request;
}
}
}
return NULL;
}
static bool
_all_key_requests_satisfied (_mongocrypt_key_broker_t *kb)
{
key_request_t *key_request;
for (key_request = kb->key_requests; NULL != key_request;
key_request = key_request->next) {
if (!key_request->satisfied) {
return false;
}
}
return true;
}
static bool
_key_broker_fail_w_msg (_mongocrypt_key_broker_t *kb, const char *msg)
{
mongocrypt_status_t *status;
kb->state = KB_ERROR;
status = kb->status;
CLIENT_ERR (msg);
return false;
}
static bool
_key_broker_fail (_mongocrypt_key_broker_t *kb)
{
if (mongocrypt_status_ok (kb->status)) {
return _key_broker_fail_w_msg (
kb, "unexpected, failing but no error status set");
}
kb->state = KB_ERROR;
return false;
}
static bool
_try_satisfying_from_cache (_mongocrypt_key_broker_t *kb, key_request_t *req)
{
_mongocrypt_cache_key_attr_t *attr = NULL;
_mongocrypt_cache_key_value_t *value = NULL;
bool ret = false;
- if (kb->state != KB_REQUESTING) {
+ if (kb->state != KB_REQUESTING && kb->state != KB_ADDING_DOCS_ANY) {
_key_broker_fail_w_msg (
kb, "trying to retrieve key from cache in invalid state");
goto cleanup;
}
attr = _mongocrypt_cache_key_attr_new (&req->id, req->alt_name);
if (!_mongocrypt_cache_get (&kb->crypt->cache_key, attr, (void **) &value)) {
_key_broker_fail_w_msg (kb, "failed to retrieve from cache");
goto cleanup;
}
if (value) {
key_returned_t *key_returned;
req->satisfied = true;
if (_mongocrypt_buffer_empty (&value->decrypted_key_material)) {
_key_broker_fail_w_msg (
kb, "cache entry does not have decrypted key material");
goto cleanup;
}
/* Add the cached key to our locally copied list.
* Note, we deduplicate requests, but *not* keys from the cache,
* because the state of the cache may change between each call to
* _mongocrypt_cache_get.
*/
key_returned =
_key_returned_prepend (kb, &kb->keys_cached, value->key_doc);
_mongocrypt_buffer_init (&key_returned->decrypted_key_material);
_mongocrypt_buffer_copy_to (&value->decrypted_key_material,
&key_returned->decrypted_key_material);
key_returned->decrypted = true;
}
ret = true;
cleanup:
_mongocrypt_cache_key_value_destroy (value);
_mongocrypt_cache_key_attr_destroy (attr);
return ret;
}
static bool
_store_to_cache (_mongocrypt_key_broker_t *kb, key_returned_t *key_returned)
{
_mongocrypt_cache_key_value_t *value;
_mongocrypt_cache_key_attr_t *attr;
bool ret;
if (!key_returned->decrypted) {
return _key_broker_fail_w_msg (kb, "cannot cache non-decrypted key");
}
attr = _mongocrypt_cache_key_attr_new (&key_returned->doc->id,
key_returned->doc->key_alt_names);
if (!attr) {
return _key_broker_fail_w_msg (kb,
"could not create key cache attribute");
}
value = _mongocrypt_cache_key_value_new (
key_returned->doc, &key_returned->decrypted_key_material);
ret = _mongocrypt_cache_add_stolen (
&kb->crypt->cache_key, attr, value, kb->status);
_mongocrypt_cache_key_attr_destroy (attr);
if (!ret) {
return _key_broker_fail (kb);
}
return true;
}
bool
_mongocrypt_key_broker_request_id (_mongocrypt_key_broker_t *kb,
const _mongocrypt_buffer_t *key_id)
{
key_request_t *req;
if (kb->state != KB_REQUESTING) {
return _key_broker_fail_w_msg (
kb, "attempting to request a key id, but in wrong state");
}
if (!_mongocrypt_buffer_is_uuid ((_mongocrypt_buffer_t *) key_id)) {
return _key_broker_fail_w_msg (kb, "expected UUID for key id");
}
if (_key_request_find_one (kb, key_id, NULL)) {
return true;
}
req = bson_malloc0 (sizeof *req);
BSON_ASSERT (req);
_mongocrypt_buffer_copy_to (key_id, &req->id);
req->next = kb->key_requests;
kb->key_requests = req;
if (!_try_satisfying_from_cache (kb, req)) {
return false;
}
return true;
}
bool
_mongocrypt_key_broker_request_name (_mongocrypt_key_broker_t *kb,
const bson_value_t *key_alt_name_value)
{
key_request_t *req;
_mongocrypt_key_alt_name_t *key_alt_name;
if (kb->state != KB_REQUESTING) {
return _key_broker_fail_w_msg (
kb, "attempting to request a key name, but in wrong state");
}
key_alt_name = _mongocrypt_key_alt_name_new (key_alt_name_value);
/* Check if we already have a request for this key alt name. */
if (_key_request_find_one (kb, NULL /* key id */, key_alt_name)) {
_mongocrypt_key_alt_name_destroy_all (key_alt_name);
return true;
}
req = bson_malloc0 (sizeof *req);
BSON_ASSERT (req);
req->alt_name = key_alt_name /* takes ownership */;
req->next = kb->key_requests;
kb->key_requests = req;
if (!_try_satisfying_from_cache (kb, req)) {
return false;
}
return true;
}
+bool
+_mongocrypt_key_broker_request_any (_mongocrypt_key_broker_t *kb)
+{
+ if (kb->state != KB_REQUESTING) {
+ return _key_broker_fail_w_msg (
+ kb, "attempting to request any keys, but in wrong state");
+ }
+
+ if (kb->key_requests) {
+ return _key_broker_fail_w_msg (
+ kb, "attempting to request any keys, but requests already made");
+ }
+
+ kb->state = KB_ADDING_DOCS_ANY;
+
+ return true;
+}
+
bool
_mongocrypt_key_broker_requests_done (_mongocrypt_key_broker_t *kb)
{
if (kb->state != KB_REQUESTING) {
return _key_broker_fail_w_msg (
kb, "attempting to finish adding requests, but in wrong state");
}
if (kb->key_requests) {
- /* If all were satisfied from the cache, then we're done since those all
- * have decrypted material */
if (_all_key_requests_satisfied (kb)) {
kb->state = KB_DONE;
} else {
kb->state = KB_ADDING_DOCS;
}
} else {
kb->state = KB_DONE;
}
return true;
}
bool
_mongocrypt_key_broker_filter (_mongocrypt_key_broker_t *kb,
mongocrypt_binary_t *out)
{
key_request_t *req;
_mongocrypt_key_alt_name_t *key_alt_name;
int name_index = 0;
int id_index = 0;
bson_t ids, names;
bson_t *filter;
BSON_ASSERT (kb);
if (kb->state != KB_ADDING_DOCS) {
return _key_broker_fail_w_msg (
kb, "attempting to retrieve filter, but in wrong state");
}
if (!_mongocrypt_buffer_empty (&kb->filter)) {
_mongocrypt_buffer_to_binary (&kb->filter, out);
return true;
}
bson_init (&names);
bson_init (&ids);
for (req = kb->key_requests; NULL != req; req = req->next) {
if (req->satisfied) {
continue;
}
if (!_mongocrypt_buffer_empty (&req->id)) {
/* Collect key_ids in "ids" */
char *key_str;
key_str = bson_strdup_printf ("%d", id_index++);
if (!key_str ||
!_mongocrypt_buffer_append (
&req->id, &ids, key_str, (uint32_t) strlen (key_str))) {
bson_destroy (&ids);
bson_destroy (&names);
bson_free (key_str);
return _key_broker_fail_w_msg (kb, "could not construct id list");
}
bson_free (key_str);
}
/* Collect key alt names in "names" */
for (key_alt_name = req->alt_name; NULL != key_alt_name;
key_alt_name = key_alt_name->next) {
char *key_str;
key_str = bson_strdup_printf ("%d", name_index++);
BSON_ASSERT (key_str);
if (!bson_append_value (&names,
key_str,
(uint32_t) strlen (key_str),
&key_alt_name->value)) {
bson_destroy (&ids);
bson_destroy (&names);
bson_free (key_str);
return _key_broker_fail_w_msg (
kb, "could not construct keyAltName list");
}
bson_free (key_str);
}
}
/*
* This is our final query:
* { $or: [ { _id: { $in : [ids] }},
* { keyAltName : { $in : [names] }} ] }
*/
filter = BCON_NEW ("$or",
"[",
"{",
"_id",
"{",
"$in",
BCON_ARRAY (&ids),
"}",
"}",
"{",
"keyAltNames",
"{",
"$in",
BCON_ARRAY (&names),
"}",
"}",
"]");
_mongocrypt_buffer_steal_from_bson (&kb->filter, filter);
_mongocrypt_buffer_to_binary (&kb->filter, out);
bson_destroy (&ids);
bson_destroy (&names);
return true;
}
bool
_mongocrypt_key_broker_add_doc (_mongocrypt_key_broker_t *kb,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
const _mongocrypt_buffer_t *doc)
{
bool ret = false;
bson_t doc_bson;
_mongocrypt_key_doc_t *key_doc = NULL;
key_request_t *key_request;
key_returned_t *key_returned;
_mongocrypt_kms_provider_t kek_provider;
char *access_token = NULL;
- if (kb->state != KB_ADDING_DOCS) {
+ if (kb->state != KB_ADDING_DOCS && kb->state != KB_ADDING_DOCS_ANY) {
_key_broker_fail_w_msg (
kb, "attempting to add a key doc, but in wrong state");
goto done;
}
if (!doc) {
_key_broker_fail_w_msg (kb, "invalid key");
goto done;
}
/* First, parse the key document. */
key_doc = _mongocrypt_key_new ();
if (!_mongocrypt_buffer_to_bson (doc, &doc_bson)) {
_key_broker_fail_w_msg (kb, "malformed BSON for key document");
goto done;
}
if (!_mongocrypt_key_parse_owned (&doc_bson, key_doc, kb->status)) {
goto done;
}
- /* Ensure that this document matches at least one request. */
if (!_key_request_find_one (kb, &key_doc->id, key_doc->key_alt_names)) {
- _key_broker_fail_w_msg (
- kb, "unexpected key returned, does not match any requests");
- goto done;
+ /* If in normal mode, ensure that this document matches at least one
+ * existing request. */
+ if (kb->state == KB_ADDING_DOCS) {
+ _key_broker_fail_w_msg (
+ kb, "unexpected key returned, does not match any requests");
+ goto done;
+ }
+
+ /* If in any mode, add request for provided document now. */
+ if (kb->state == KB_ADDING_DOCS_ANY) {
+ key_request_t *const req = bson_malloc0 (sizeof (key_request_t));
+
+ BSON_ASSERT (req);
+
+ _mongocrypt_buffer_copy_to (&key_doc->id, &req->id);
+ req->alt_name =
+ _mongocrypt_key_alt_name_copy_all (key_doc->key_alt_names);
+ req->next = kb->key_requests;
+ kb->key_requests = req;
+
+ if (!_try_satisfying_from_cache (kb, req)) {
+ goto done;
+ }
+
+ /* Key is already cached; no work to be done. */
+ if (req->satisfied) {
+ ret = true;
+ goto done;
+ }
+ }
}
/* Check if there are other keys_returned with intersecting altnames or
* equal id. This is an error. Do *not* check cached keys. */
if (_key_returned_find_one (
kb->keys_returned, &key_doc->id, key_doc->key_alt_names)) {
_key_broker_fail_w_msg (
kb, "keys returned have duplicate keyAltNames or _id");
goto done;
}
key_returned = _key_returned_prepend (kb, &kb->keys_returned, key_doc);
/* Check that the returned key doc's provider matches. */
kek_provider = key_doc->kek.kms_provider;
- if (0 == (kek_provider & kb->crypt->opts.kms_providers)) {
+ if (0 == (kek_provider & kms_providers->configured_providers)) {
_key_broker_fail_w_msg (
kb, "client not configured with KMS provider necessary to decrypt");
goto done;
}
/* If the KMS provider is local, decrypt immediately. Otherwise, create the
* HTTP KMS request. */
if (kek_provider == MONGOCRYPT_KMS_PROVIDER_LOCAL) {
if (!_mongocrypt_unwrap_key (kb->crypt->crypto,
- &kb->crypt->opts.kms_provider_local.key,
+ &kms_providers->local.key,
&key_returned->doc->key_material,
&key_returned->decrypted_key_material,
kb->status)) {
_key_broker_fail (kb);
goto done;
}
key_returned->decrypted = true;
if (!_store_to_cache (kb, key_returned)) {
goto done;
}
} else if (kek_provider == MONGOCRYPT_KMS_PROVIDER_AWS) {
if (!_mongocrypt_kms_ctx_init_aws_decrypt (&key_returned->kms,
- &kb->crypt->opts,
+ kms_providers,
key_doc,
&kb->crypt->log,
kb->crypt->crypto)) {
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
_key_broker_fail (kb);
goto done;
}
} else if (kek_provider == MONGOCRYPT_KMS_PROVIDER_AZURE) {
access_token = _mongocrypt_cache_oauth_get (kb->crypt->cache_oauth_azure);
if (!access_token) {
key_returned->needs_auth = true;
/* Create an oauth request if one does not exist. */
if (!kb->auth_request_azure.initialized) {
if (!_mongocrypt_kms_ctx_init_azure_auth (
&kb->auth_request_azure.kms,
&kb->crypt->log,
- &kb->crypt->opts,
+ kms_providers,
/* The key vault endpoint is used to determine the scope. */
key_doc->kek.provider.azure.key_vault_endpoint)) {
mongocrypt_kms_ctx_status (&kb->auth_request_azure.kms,
kb->status);
_key_broker_fail (kb);
goto done;
}
kb->auth_request_azure.initialized = true;
}
} else {
if (!_mongocrypt_kms_ctx_init_azure_unwrapkey (&key_returned->kms,
- &kb->crypt->opts,
+ kms_providers,
access_token,
key_doc,
&kb->crypt->log)) {
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
_key_broker_fail (kb);
goto done;
}
}
} else if (kek_provider == MONGOCRYPT_KMS_PROVIDER_GCP) {
access_token = _mongocrypt_cache_oauth_get (kb->crypt->cache_oauth_gcp);
if (!access_token) {
key_returned->needs_auth = true;
/* Create an oauth request if one does not exist. */
if (!kb->auth_request_gcp.initialized) {
if (!_mongocrypt_kms_ctx_init_gcp_auth (
&kb->auth_request_gcp.kms,
&kb->crypt->log,
&kb->crypt->opts,
+ kms_providers,
key_doc->kek.provider.gcp.endpoint)) {
mongocrypt_kms_ctx_status (&kb->auth_request_gcp.kms,
kb->status);
_key_broker_fail (kb);
goto done;
}
kb->auth_request_gcp.initialized = true;
}
} else {
if (!_mongocrypt_kms_ctx_init_gcp_decrypt (&key_returned->kms,
- &kb->crypt->opts,
+ kms_providers,
access_token,
key_doc,
&kb->crypt->log)) {
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
_key_broker_fail (kb);
goto done;
}
}
} else if (kek_provider == MONGOCRYPT_KMS_PROVIDER_KMIP) {
char *unique_identifier;
_mongocrypt_endpoint_t *endpoint;
if (!key_returned->doc->kek.provider.kmip.key_id) {
_key_broker_fail_w_msg (kb, "KMIP key malformed, no keyId present");
goto done;
}
unique_identifier = key_returned->doc->kek.provider.kmip.key_id;
if (key_returned->doc->kek.provider.kmip.endpoint) {
endpoint = key_returned->doc->kek.provider.kmip.endpoint;
- } else if (kb->crypt->opts.kms_provider_kmip.endpoint) {
- endpoint = kb->crypt->opts.kms_provider_kmip.endpoint;
+ } else if (kms_providers->kmip.endpoint) {
+ endpoint = kms_providers->kmip.endpoint;
} else {
_key_broker_fail_w_msg (kb, "endpoint not set for KMIP request");
goto done;
}
if (!_mongocrypt_kms_ctx_init_kmip_get (&key_returned->kms,
endpoint,
unique_identifier,
&kb->crypt->log)) {
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
_key_broker_fail (kb);
goto done;
}
} else {
_key_broker_fail_w_msg (kb, "unrecognized kms provider");
goto done;
}
/* Mark all matching key requests as satisfied. */
for (key_request = kb->key_requests; NULL != key_request;
key_request = key_request->next) {
if (0 == _mongocrypt_buffer_cmp (&key_doc->id, &key_request->id)) {
key_request->satisfied = true;
}
if (_mongocrypt_key_alt_name_intersects (key_doc->key_alt_names,
key_request->alt_name)) {
key_request->satisfied = true;
}
}
ret = true;
done:
bson_free (access_token);
_mongocrypt_key_destroy (key_doc);
return ret;
}
bool
_mongocrypt_key_broker_docs_done (_mongocrypt_key_broker_t *kb)
{
key_returned_t *key_returned;
bool needs_decryption;
bool needs_auth;
- if (kb->state != KB_ADDING_DOCS) {
+ if (kb->state != KB_ADDING_DOCS && kb->state != KB_ADDING_DOCS_ANY) {
return _key_broker_fail_w_msg (
kb, "attempting to finish adding docs, but in wrong state");
}
/* If there are any requests left unsatisfied, error. */
if (!_all_key_requests_satisfied (kb)) {
return _key_broker_fail_w_msg (kb,
"not all keys requested were satisfied");
}
/* Transition to the next state.
* - If there are any Azure or GCP backed keys, and no oauth token is
* cached, transition to KB_AUTHENTICATING.
* - Otherwise, if there are keys that need to be decrypted, transition to
* KB_DECRYPTING_KEY_MATERIAL.
* - Otherwise, all keys were retrieved from the cache or decrypted locally,
* skip the decrypting state and go right to KB_DONE.
*/
needs_decryption = false;
needs_auth = false;
for (key_returned = kb->keys_returned; NULL != key_returned;
key_returned = key_returned->next) {
if (key_returned->needs_auth) {
needs_auth = true;
break;
}
if (!key_returned->decrypted) {
needs_decryption = true;
}
}
if (needs_auth) {
kb->state = KB_AUTHENTICATING;
} else if (needs_decryption) {
kb->state = KB_DECRYPTING_KEY_MATERIAL;
} else {
kb->state = KB_DONE;
}
return true;
}
mongocrypt_kms_ctx_t *
_mongocrypt_key_broker_next_kms (_mongocrypt_key_broker_t *kb)
{
if (kb->state != KB_DECRYPTING_KEY_MATERIAL &&
kb->state != KB_AUTHENTICATING) {
_key_broker_fail_w_msg (
kb, "attempting to get KMS request, but in wrong state");
/* TODO (CDRIVER-3327) this breaks other expectations. If the caller only
* checks the return value they may mistake this NULL as indicating all
* KMS requests have been iterated. */
return NULL;
}
if (kb->state == KB_AUTHENTICATING) {
if (!kb->auth_request_azure.initialized &&
!kb->auth_request_gcp.initialized) {
_key_broker_fail_w_msg (kb,
"unexpected, attempting to authenticate but "
"KMS request not initialized");
return NULL;
}
if (kb->auth_request_azure.initialized &&
!kb->auth_request_azure.returned) {
kb->auth_request_azure.returned = true;
return &kb->auth_request_azure.kms;
}
if (kb->auth_request_gcp.initialized && !kb->auth_request_gcp.returned) {
kb->auth_request_gcp.returned = true;
return &kb->auth_request_gcp.kms;
}
return NULL;
}
while (kb->decryptor_iter) {
if (!kb->decryptor_iter->decrypted) {
key_returned_t *key_returned;
key_returned = kb->decryptor_iter;
/* iterate before returning, so next call starts at next entry */
kb->decryptor_iter = kb->decryptor_iter->next;
return &key_returned->kms;
}
kb->decryptor_iter = kb->decryptor_iter->next;
}
return NULL;
}
bool
-_mongocrypt_key_broker_kms_done (_mongocrypt_key_broker_t *kb)
+_mongocrypt_key_broker_kms_done (
+ _mongocrypt_key_broker_t *kb,
+ _mongocrypt_opts_kms_providers_t *kms_providers)
{
key_returned_t *key_returned;
if (kb->state != KB_DECRYPTING_KEY_MATERIAL &&
kb->state != KB_AUTHENTICATING) {
return _key_broker_fail_w_msg (
kb, "attempting to complete KMS requests, but in wrong state");
}
if (kb->state == KB_AUTHENTICATING) {
bson_t oauth_response;
_mongocrypt_buffer_t oauth_response_buf;
if (kb->auth_request_azure.initialized) {
if (!_mongocrypt_kms_ctx_result (&kb->auth_request_azure.kms,
&oauth_response_buf)) {
mongocrypt_kms_ctx_status (&kb->auth_request_azure.kms, kb->status);
return _key_broker_fail (kb);
}
/* Cache returned tokens. */
BSON_ASSERT (
_mongocrypt_buffer_to_bson (&oauth_response_buf, &oauth_response));
if (!_mongocrypt_cache_oauth_add (
kb->crypt->cache_oauth_azure, &oauth_response, kb->status)) {
return false;
}
}
if (kb->auth_request_gcp.initialized) {
if (!_mongocrypt_kms_ctx_result (&kb->auth_request_gcp.kms,
&oauth_response_buf)) {
mongocrypt_kms_ctx_status (&kb->auth_request_gcp.kms, kb->status);
return _key_broker_fail (kb);
}
/* Cache returned tokens. */
BSON_ASSERT (
_mongocrypt_buffer_to_bson (&oauth_response_buf, &oauth_response));
if (!_mongocrypt_cache_oauth_add (
kb->crypt->cache_oauth_gcp, &oauth_response, kb->status)) {
return false;
}
}
/* Auth should be finished, create any remaining KMS requests. */
for (key_returned = kb->keys_returned; NULL != key_returned;
key_returned = key_returned->next) {
char *access_token;
if (!key_returned->needs_auth) {
continue;
}
if (key_returned->doc->kek.kms_provider ==
MONGOCRYPT_KMS_PROVIDER_AZURE) {
access_token =
_mongocrypt_cache_oauth_get (kb->crypt->cache_oauth_azure);
if (!access_token) {
return _key_broker_fail_w_msg (
kb, "authentication failed, no oauth token");
}
if (!_mongocrypt_kms_ctx_init_azure_unwrapkey (&key_returned->kms,
- &kb->crypt->opts,
+ kms_providers,
access_token,
key_returned->doc,
&kb->crypt->log)) {
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
bson_free (access_token);
return _key_broker_fail (kb);
}
key_returned->needs_auth = false;
bson_free (access_token);
} else if (key_returned->doc->kek.kms_provider ==
MONGOCRYPT_KMS_PROVIDER_GCP) {
access_token =
_mongocrypt_cache_oauth_get (kb->crypt->cache_oauth_gcp);
if (!access_token) {
return _key_broker_fail_w_msg (
kb, "authentication failed, no oauth token");
}
if (!_mongocrypt_kms_ctx_init_gcp_decrypt (&key_returned->kms,
- &kb->crypt->opts,
+ kms_providers,
access_token,
key_returned->doc,
&kb->crypt->log)) {
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
bson_free (access_token);
return _key_broker_fail (kb);
}
key_returned->needs_auth = false;
bson_free (access_token);
} else {
return _key_broker_fail_w_msg (kb,
"unexpected, authenticating but "
"no requests require "
"authentication");
}
}
kb->state = KB_DECRYPTING_KEY_MATERIAL;
return true;
}
for (key_returned = kb->keys_returned; NULL != key_returned;
key_returned = key_returned->next) {
/* Local keys were already decrypted. */
if (key_returned->doc->kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_AWS ||
key_returned->doc->kek.kms_provider ==
MONGOCRYPT_KMS_PROVIDER_AZURE ||
key_returned->doc->kek.kms_provider == MONGOCRYPT_KMS_PROVIDER_GCP) {
if (key_returned->decrypted) {
- return _key_broker_fail_w_msg (
- kb,
- "unexpected, returned keys should not be "
- "decrypted before KMS completion");
+ /* Non-local keys may have been decrypted previously if the key
+ * broker has been restarted. */
+ continue;
}
if (!key_returned->kms.req) {
return _key_broker_fail_w_msg (
kb, "unexpected, KMS not set on key returned");
}
if (!_mongocrypt_kms_ctx_result (
&key_returned->kms, &key_returned->decrypted_key_material)) {
/* Always fatal. Key attempted to decrypt but failed. */
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
return _key_broker_fail (kb);
}
} else if (key_returned->doc->kek.kms_provider ==
MONGOCRYPT_KMS_PROVIDER_KMIP) {
_mongocrypt_buffer_t kek;
if (!_mongocrypt_kms_ctx_result (&key_returned->kms, &kek)) {
mongocrypt_kms_ctx_status (&key_returned->kms, kb->status);
return _key_broker_fail (kb);
}
if (!_mongocrypt_unwrap_key (kb->crypt->crypto,
&kek,
&key_returned->doc->key_material,
&key_returned->decrypted_key_material,
kb->status)) {
_key_broker_fail (kb);
_mongocrypt_buffer_cleanup (&kek);
return false;
}
_mongocrypt_buffer_cleanup (&kek);
} else if (key_returned->doc->kek.kms_provider !=
MONGOCRYPT_KMS_PROVIDER_LOCAL) {
return _key_broker_fail_w_msg (kb, "unrecognized kms provider");
}
if (key_returned->decrypted_key_material.len != MONGOCRYPT_KEY_LEN) {
return _key_broker_fail_w_msg (kb,
"decrypted key is incorrect length");
}
key_returned->decrypted = true;
if (!_store_to_cache (kb, key_returned)) {
return false;
}
}
kb->state = KB_DONE;
return true;
}
bool
_get_decrypted_key_material (_mongocrypt_key_broker_t *kb,
_mongocrypt_buffer_t *key_id,
_mongocrypt_key_alt_name_t *key_alt_name,
_mongocrypt_buffer_t *out,
_mongocrypt_buffer_t *key_id_out)
{
key_returned_t *key_returned;
_mongocrypt_buffer_init (out);
if (key_id_out) {
_mongocrypt_buffer_init (key_id_out);
}
/* Search both keys_returned and keys_cached. */
key_returned =
_key_returned_find_one (kb->keys_returned, key_id, key_alt_name);
if (!key_returned) {
/* Try the keys retrieved from the cache. */
key_returned =
_key_returned_find_one (kb->keys_cached, key_id, key_alt_name);
}
if (!key_returned) {
return _key_broker_fail_w_msg (kb, "could not find key");
}
if (!key_returned->decrypted) {
return _key_broker_fail_w_msg (kb, "unexpected, key not decrypted");
}
_mongocrypt_buffer_copy_to (&key_returned->decrypted_key_material, out);
if (key_id_out) {
_mongocrypt_buffer_copy_to (&key_returned->doc->id, key_id_out);
}
return true;
}
bool
_mongocrypt_key_broker_decrypted_key_by_id (_mongocrypt_key_broker_t *kb,
const _mongocrypt_buffer_t *key_id,
_mongocrypt_buffer_t *out)
{
- if (kb->state != KB_DONE) {
+ if (kb->state != KB_DONE && kb->state != KB_REQUESTING) {
return _key_broker_fail_w_msg (
kb, "attempting retrieve decrypted key material, but in wrong state");
}
return _get_decrypted_key_material (kb,
(_mongocrypt_buffer_t *) key_id,
NULL /* key alt name */,
out,
NULL /* key id out */);
}
bool
_mongocrypt_key_broker_decrypted_key_by_name (
_mongocrypt_key_broker_t *kb,
const bson_value_t *key_alt_name_value,
_mongocrypt_buffer_t *out,
_mongocrypt_buffer_t *key_id_out)
{
bool ret;
_mongocrypt_key_alt_name_t *key_alt_name;
if (kb->state != KB_DONE) {
return _key_broker_fail_w_msg (
kb, "attempting retrieve decrypted key material, but in wrong state");
}
key_alt_name = _mongocrypt_key_alt_name_new (key_alt_name_value);
ret = _get_decrypted_key_material (kb, NULL, key_alt_name, out, key_id_out);
_mongocrypt_key_alt_name_destroy_all (key_alt_name);
return ret;
}
bool
_mongocrypt_key_broker_status (_mongocrypt_key_broker_t *kb,
mongocrypt_status_t *out)
{
BSON_ASSERT (kb);
if (!mongocrypt_status_ok (kb->status)) {
_mongocrypt_status_copy_to (kb->status, out);
return false;
}
return true;
}
static void
_destroy_key_requests (key_request_t *head)
{
key_request_t *tmp;
while (head) {
tmp = head->next;
_mongocrypt_buffer_cleanup (&head->id);
_mongocrypt_key_alt_name_destroy_all (head->alt_name);
bson_free (head);
head = tmp;
}
}
static void
_destroy_keys_returned (key_returned_t *head)
{
key_returned_t *tmp;
while (head) {
tmp = head->next;
_mongocrypt_key_destroy (head->doc);
_mongocrypt_buffer_cleanup (&head->decrypted_key_material);
_mongocrypt_kms_ctx_cleanup (&head->kms);
bson_free (head);
head = tmp;
}
}
void
_mongocrypt_key_broker_cleanup (_mongocrypt_key_broker_t *kb)
{
mongocrypt_status_destroy (kb->status);
_mongocrypt_buffer_cleanup (&kb->filter);
/* Delete all linked lists */
_destroy_keys_returned (kb->keys_returned);
_destroy_keys_returned (kb->keys_cached);
_destroy_key_requests (kb->key_requests);
_mongocrypt_kms_ctx_cleanup (&kb->auth_request_azure.kms);
_mongocrypt_kms_ctx_cleanup (&kb->auth_request_gcp.kms);
}
void
_mongocrypt_key_broker_add_test_key (_mongocrypt_key_broker_t *kb,
const _mongocrypt_buffer_t *key_id)
{
key_returned_t *key_returned;
_mongocrypt_key_doc_t *key_doc;
BSON_ASSERT (kb);
key_doc = _mongocrypt_key_new ();
_mongocrypt_buffer_copy_to (key_id, &key_doc->id);
key_returned = _key_returned_prepend (kb, &kb->keys_returned, key_doc);
key_returned->decrypted = true;
_mongocrypt_buffer_init (&key_returned->decrypted_key_material);
_mongocrypt_buffer_resize (&key_returned->decrypted_key_material,
MONGOCRYPT_KEY_LEN);
memset (key_returned->decrypted_key_material.data, 0, MONGOCRYPT_KEY_LEN);
_mongocrypt_key_destroy (key_doc);
/* Hijack state and move directly to DONE. */
kb->state = KB_DONE;
-}
\ No newline at end of file
+}
+
+
+bool
+_mongocrypt_key_broker_restart (_mongocrypt_key_broker_t *kb)
+{
+ if (kb->state != KB_DONE) {
+ return _key_broker_fail_w_msg (
+ kb, "_mongocrypt_key_broker_restart called in wrong state");
+ }
+ kb->state = KB_REQUESTING;
+ _mongocrypt_buffer_cleanup (&kb->filter);
+ _mongocrypt_buffer_init (&kb->filter);
+ return true;
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key.c
similarity index 99%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key.c
index c02d7f3d..cef53382 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-key.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-key.c
@@ -1,457 +1,459 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongocrypt-private.h"
#include "mongocrypt-key-private.h"
/* Check if two single entries are equal (i.e. ignore the 'next' pointer). */
static bool
_one_key_alt_name_equal (_mongocrypt_key_alt_name_t *ptr_a,
_mongocrypt_key_alt_name_t *ptr_b)
{
BSON_ASSERT (ptr_a->value.value_type == BSON_TYPE_UTF8);
BSON_ASSERT (ptr_b->value.value_type == BSON_TYPE_UTF8);
return 0 == strcmp (_mongocrypt_key_alt_name_get_string (ptr_a),
_mongocrypt_key_alt_name_get_string (ptr_b));
}
static bool
_find (_mongocrypt_key_alt_name_t *list, _mongocrypt_key_alt_name_t *entry)
{
for (; NULL != list; list = list->next) {
if (_one_key_alt_name_equal (list, entry)) {
return true;
}
}
return false;
}
static uint32_t
_list_len (_mongocrypt_key_alt_name_t *list)
{
uint32_t count = 0;
while (NULL != list) {
count++;
list = list->next;
}
return count;
}
static bool
_check_unique (_mongocrypt_key_alt_name_t *list)
{
for (; NULL != list; list = list->next) {
/* Check if we can find the current entry in the remaining. */
if (_find (list->next, list)) {
return false;
}
}
return true;
}
static bool
_parse_masterkey (bson_iter_t *iter,
_mongocrypt_key_doc_t *out,
mongocrypt_status_t *status)
{
const uint8_t *data;
uint32_t len;
bson_t kek_doc;
if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
CLIENT_ERR ("invalid 'masterKey', expected document");
return false;
}
bson_iter_document (iter, &len, &data);
bson_init_static (&kek_doc, data, len);
if (!_mongocrypt_kek_parse_owned (&kek_doc, &out->kek, status)) {
return false;
}
return true;
}
bool
_mongocrypt_key_alt_name_from_iter (const bson_iter_t *iter_in,
_mongocrypt_key_alt_name_t **out,
mongocrypt_status_t *status)
{
_mongocrypt_key_alt_name_t *key_alt_names = NULL, *tmp;
bson_iter_t iter;
memcpy (&iter, iter_in, sizeof (iter));
*out = NULL;
/* A key parsed with no keyAltNames will have a zero'ed out bson value. Not
* an error. */
if (!BSON_ITER_HOLDS_ARRAY (&iter)) {
CLIENT_ERR ("malformed keyAltNames, expected array");
return false;
}
if (!bson_iter_recurse (&iter, &iter)) {
CLIENT_ERR ("malformed keyAltNames, could not recurse into array");
return false;
}
while (bson_iter_next (&iter)) {
if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
_mongocrypt_key_alt_name_destroy_all (key_alt_names);
CLIENT_ERR ("unexpected non-UTF8 keyAltName");
return false;
}
tmp = _mongocrypt_key_alt_name_new (bson_iter_value (&iter));
tmp->next = key_alt_names;
key_alt_names = tmp;
}
if (!_check_unique (key_alt_names)) {
_mongocrypt_key_alt_name_destroy_all (key_alt_names);
CLIENT_ERR ("unexpected duplicate keyAltNames");
return false;
}
*out = key_alt_names;
return true;
}
/* Takes ownership of all fields. */
bool
_mongocrypt_key_parse_owned (const bson_t *bson,
_mongocrypt_key_doc_t *out,
mongocrypt_status_t *status)
{
bson_iter_t iter;
bool has_id = false, has_key_material = false, has_status = false,
has_creation_date = false, has_update_date = false,
has_master_key = false;
if (!bson_validate (bson, BSON_VALIDATE_NONE, NULL) ||
!bson_iter_init (&iter, bson)) {
CLIENT_ERR ("invalid BSON");
return false;
}
bson_destroy (&out->bson);
bson_copy_to (bson, &out->bson);
while (bson_iter_next (&iter)) {
const char *field;
field = bson_iter_key (&iter);
if (!field) {
CLIENT_ERR ("invalid BSON, could not retrieve field name");
return false;
}
if (0 == strcmp ("_id", field)) {
has_id = true;
if (!_mongocrypt_buffer_copy_from_uuid_iter (&out->id, &iter)) {
CLIENT_ERR ("invalid key, '_id' is not a UUID");
return false;
}
continue;
}
/* keyAltNames (optional) */
if (0 == strcmp ("keyAltNames", field)) {
if (!_mongocrypt_key_alt_name_from_iter (
&iter, &out->key_alt_names, status)) {
return false;
}
continue;
}
if (0 == strcmp ("keyMaterial", field)) {
has_key_material = true;
if (!_mongocrypt_buffer_copy_from_binary_iter (&out->key_material,
&iter)) {
CLIENT_ERR ("invalid 'keyMaterial', expected binary");
return false;
}
if (out->key_material.subtype != BSON_SUBTYPE_BINARY) {
CLIENT_ERR ("invalid 'keyMaterial', expected subtype 0");
return false;
}
continue;
}
if (0 == strcmp ("masterKey", field)) {
has_master_key = true;
if (!_parse_masterkey (&iter, out, status)) {
return false;
}
continue;
}
if (0 == strcmp ("version", field)) {
if (!BSON_ITER_HOLDS_INT (&iter)) {
CLIENT_ERR ("invalid 'version', expect int");
return false;
}
if (bson_iter_as_int64 (&iter) != 0) {
CLIENT_ERR (
"unsupported key document version, only supports version=0");
return false;
}
continue;
}
if (0 == strcmp ("status", field)) {
/* Don't need status. Check that it's present and ignore it. */
has_status = true;
continue;
}
if (0 == strcmp ("creationDate", field)) {
has_creation_date = true;
if (!BSON_ITER_HOLDS_DATE_TIME (&iter)) {
CLIENT_ERR ("invalid 'creationDate', expect datetime");
return false;
}
out->creation_date = bson_iter_date_time (&iter);
continue;
}
if (0 == strcmp ("updateDate", field)) {
has_update_date = true;
if (!BSON_ITER_HOLDS_DATE_TIME (&iter)) {
CLIENT_ERR ("invalid 'updateDate', expect datetime");
return false;
}
out->update_date = bson_iter_date_time (&iter);
continue;
}
CLIENT_ERR ("unrecognized field '%s'", field);
return false;
}
/* Check that required fields were set. */
if (!has_id) {
CLIENT_ERR ("invalid key, no '_id'");
return false;
}
if (!has_master_key) {
CLIENT_ERR ("invalid key, no 'masterKey'");
return false;
}
if (!has_key_material) {
CLIENT_ERR ("invalid key, no 'keyMaterial'");
return false;
}
if (!has_status) {
CLIENT_ERR ("invalid key, no 'status'");
return false;
}
if (!has_creation_date) {
CLIENT_ERR ("invalid key, no 'creationDate'");
return false;
}
if (!has_update_date) {
CLIENT_ERR ("invalid key, no 'updateDate'");
return false;
}
return true;
}
_mongocrypt_key_doc_t *
_mongocrypt_key_new ()
{
_mongocrypt_key_doc_t *key_doc;
key_doc = (_mongocrypt_key_doc_t *) bson_malloc0 (sizeof *key_doc);
bson_init (&key_doc->bson);
return key_doc;
}
bool
_mongocrypt_key_equal (const _mongocrypt_key_doc_t *a,
const _mongocrypt_key_doc_t *b)
{
return bson_equal (&a->bson, &b->bson);
}
void
_mongocrypt_key_destroy (_mongocrypt_key_doc_t *key)
{
if (!key) {
return;
}
_mongocrypt_buffer_cleanup (&key->id);
_mongocrypt_key_alt_name_destroy_all (key->key_alt_names);
_mongocrypt_buffer_cleanup (&key->key_material);
_mongocrypt_kek_cleanup (&key->kek);
bson_destroy (&key->bson);
bson_free (key);
}
void
_mongocrypt_key_doc_copy_to (_mongocrypt_key_doc_t *src,
_mongocrypt_key_doc_t *dst)
{
BSON_ASSERT (src);
BSON_ASSERT (dst);
_mongocrypt_buffer_copy_to (&src->id, &dst->id);
_mongocrypt_buffer_copy_to (&src->key_material, &dst->key_material);
dst->key_alt_names = _mongocrypt_key_alt_name_copy_all (src->key_alt_names);
bson_destroy (&dst->bson);
bson_copy_to (&src->bson, &dst->bson);
_mongocrypt_kek_copy_to (&src->kek, &dst->kek);
+ dst->creation_date = src->creation_date;
+ dst->update_date = src->update_date;
}
_mongocrypt_key_alt_name_t *
_mongocrypt_key_alt_name_copy_all (_mongocrypt_key_alt_name_t *ptr)
{
_mongocrypt_key_alt_name_t *ptr_copy = NULL, *head = NULL;
while (ptr) {
_mongocrypt_key_alt_name_t *copied;
copied = bson_malloc0 (sizeof (*copied));
BSON_ASSERT (copied);
bson_value_copy (&ptr->value, &copied->value);
if (!ptr_copy) {
ptr_copy = copied;
head = ptr_copy;
} else {
ptr_copy->next = copied;
ptr_copy = ptr_copy->next;
}
ptr = ptr->next;
}
return head;
}
void
_mongocrypt_key_alt_name_destroy_all (_mongocrypt_key_alt_name_t *ptr)
{
_mongocrypt_key_alt_name_t *next;
while (ptr) {
next = ptr->next;
bson_value_destroy (&ptr->value);
bson_free (ptr);
ptr = next;
}
}
bool
_mongocrypt_key_alt_name_intersects (_mongocrypt_key_alt_name_t *ptr_a,
_mongocrypt_key_alt_name_t *ptr_b)
{
_mongocrypt_key_alt_name_t *orig_ptr_b = ptr_b;
for (; ptr_a; ptr_a = ptr_a->next) {
for (ptr_b = orig_ptr_b; ptr_b; ptr_b = ptr_b->next) {
if (_one_key_alt_name_equal (ptr_a, ptr_b)) {
return true;
}
}
}
return false;
}
_mongocrypt_key_alt_name_t *
_mongocrypt_key_alt_name_create (const char *name, ...)
{
va_list args;
const char *arg_ptr;
_mongocrypt_key_alt_name_t *head, *prev;
head = NULL;
prev = NULL;
va_start (args, name);
arg_ptr = name;
while (arg_ptr) {
_mongocrypt_key_alt_name_t *curr;
curr = bson_malloc0 (sizeof (*curr));
BSON_ASSERT (curr);
curr->value.value_type = BSON_TYPE_UTF8;
curr->value.value.v_utf8.str = bson_strdup (arg_ptr);
curr->value.value.v_utf8.len = (uint32_t) strlen (arg_ptr);
if (!prev) {
head = curr;
} else {
prev->next = curr;
}
arg_ptr = va_arg (args, const char *);
prev = curr;
}
va_end (args);
return head;
}
_mongocrypt_key_alt_name_t *
_mongocrypt_key_alt_name_new (const bson_value_t *value)
{
_mongocrypt_key_alt_name_t *name = bson_malloc0 (sizeof (*name));
BSON_ASSERT (name);
bson_value_copy (value, &name->value);
return name;
}
bool
_mongocrypt_key_alt_name_unique_list_equal (_mongocrypt_key_alt_name_t *list_a,
_mongocrypt_key_alt_name_t *list_b)
{
_mongocrypt_key_alt_name_t *ptr;
BSON_ASSERT (_check_unique (list_a));
BSON_ASSERT (_check_unique (list_b));
if (_list_len (list_a) != _list_len (list_b)) {
return false;
}
for (ptr = list_a; NULL != ptr; ptr = ptr->next) {
if (!_find (list_b, ptr)) {
return false;
}
}
return true;
}
const char *
_mongocrypt_key_alt_name_get_string (_mongocrypt_key_alt_name_t *key_alt_name)
{
return key_alt_name->value.value.v_utf8.str;
-}
\ No newline at end of file
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
similarity index 67%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
index e26fbf1e..1e370ce4 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kms-ctx-private.h
@@ -1,153 +1,154 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_KMX_CTX_PRIVATE_H
#define MONGOCRYPT_KMX_CTX_PRIVATE_H
#include "mongocrypt.h"
#include "mongocrypt-compat.h"
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-cache-key-private.h"
#include "mongocrypt-endpoint-private.h"
#include "mongocrypt-opts-private.h"
#include "kms_message/kms_message.h"
#include "mongocrypt-crypto-private.h"
struct __mongocrypt_ctx_opts_t;
typedef enum {
MONGOCRYPT_KMS_AWS_ENCRYPT,
MONGOCRYPT_KMS_AWS_DECRYPT,
MONGOCRYPT_KMS_AZURE_OAUTH,
MONGOCRYPT_KMS_AZURE_WRAPKEY,
MONGOCRYPT_KMS_AZURE_UNWRAPKEY,
MONGOCRYPT_KMS_GCP_OAUTH,
MONGOCRYPT_KMS_GCP_ENCRYPT,
MONGOCRYPT_KMS_GCP_DECRYPT,
MONGOCRYPT_KMS_KMIP_REGISTER,
MONGOCRYPT_KMS_KMIP_ACTIVATE,
MONGOCRYPT_KMS_KMIP_GET
} _kms_request_type_t;
struct _mongocrypt_kms_ctx_t {
kms_request_t *req;
_kms_request_type_t req_type;
kms_response_parser_t *parser;
mongocrypt_status_t *status;
_mongocrypt_buffer_t msg;
_mongocrypt_buffer_t result;
char *endpoint;
_mongocrypt_log_t *log;
};
bool
-_mongocrypt_kms_ctx_init_aws_decrypt (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
- _mongocrypt_key_doc_t *key,
- _mongocrypt_log_t *log,
- _mongocrypt_crypto_t *crypto)
- MONGOCRYPT_WARN_UNUSED_RESULT;
+_mongocrypt_kms_ctx_init_aws_decrypt (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ _mongocrypt_key_doc_t *key,
+ _mongocrypt_log_t *log,
+ _mongocrypt_crypto_t *crypto) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_kms_ctx_init_aws_encrypt (
mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
struct __mongocrypt_ctx_opts_t *ctx_opts,
_mongocrypt_buffer_t *decrypted_key_material,
_mongocrypt_log_t *log,
_mongocrypt_crypto_t *crypto) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_kms_ctx_result (mongocrypt_kms_ctx_t *kms,
_mongocrypt_buffer_t *out)
MONGOCRYPT_WARN_UNUSED_RESULT;
void
_mongocrypt_kms_ctx_cleanup (mongocrypt_kms_ctx_t *kms);
bool
-_mongocrypt_kms_ctx_init_azure_auth (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
- _mongocrypt_endpoint_t *key_vault_endpoint)
- MONGOCRYPT_WARN_UNUSED_RESULT;
+_mongocrypt_kms_ctx_init_azure_auth (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_log_t *log,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ _mongocrypt_endpoint_t *key_vault_endpoint) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_kms_ctx_init_azure_wrapkey (
mongocrypt_kms_ctx_t *kms,
_mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
struct __mongocrypt_ctx_opts_t *ctx_opts,
const char *access_token,
_mongocrypt_buffer_t *plaintext_key_material) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
-_mongocrypt_kms_ctx_init_azure_unwrapkey (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
- const char *access_token,
- _mongocrypt_key_doc_t *key,
- _mongocrypt_log_t *log)
- MONGOCRYPT_WARN_UNUSED_RESULT;
+_mongocrypt_kms_ctx_init_azure_unwrapkey (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ const char *access_token,
+ _mongocrypt_key_doc_t *key,
+ _mongocrypt_log_t *log) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
-_mongocrypt_kms_ctx_init_gcp_auth (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
- _mongocrypt_endpoint_t *kms_endpoint)
- MONGOCRYPT_WARN_UNUSED_RESULT;
+_mongocrypt_kms_ctx_init_gcp_auth (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_log_t *log,
+ _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ _mongocrypt_endpoint_t *kms_endpoint) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_kms_ctx_init_gcp_encrypt (
mongocrypt_kms_ctx_t *kms,
_mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
struct __mongocrypt_ctx_opts_t *ctx_opts,
const char *access_token,
_mongocrypt_buffer_t *plaintext_key_material) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
-_mongocrypt_kms_ctx_init_gcp_decrypt (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
- const char *access_token,
- _mongocrypt_key_doc_t *key,
- _mongocrypt_log_t *log)
- MONGOCRYPT_WARN_UNUSED_RESULT;
+_mongocrypt_kms_ctx_init_gcp_decrypt (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ const char *access_token,
+ _mongocrypt_key_doc_t *key,
+ _mongocrypt_log_t *log) MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_kms_ctx_init_kmip_register (mongocrypt_kms_ctx_t *kms,
const _mongocrypt_endpoint_t *endpoint,
const uint8_t *secretdata,
uint32_t secretdata_len,
_mongocrypt_log_t *log)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_kms_ctx_init_kmip_activate (mongocrypt_kms_ctx_t *kms,
const _mongocrypt_endpoint_t *endpoint,
const char *unique_identifier,
_mongocrypt_log_t *log)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_kms_ctx_init_kmip_get (mongocrypt_kms_ctx_t *kms,
const _mongocrypt_endpoint_t *endpoint,
const char *unique_identifier,
_mongocrypt_log_t *log)
MONGOCRYPT_WARN_UNUSED_RESULT;
#endif /* MONGOCRYPT_KMX_CTX_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kms-ctx.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kms-ctx.c
similarity index 94%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kms-ctx.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kms-ctx.c
index 412187ab..e6b88f26 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-kms-ctx.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-kms-ctx.c
@@ -1,1642 +1,1649 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongocrypt-private.h"
#include "mongocrypt-binary-private.h"
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-ctx-private.h"
#include "mongocrypt-kms-ctx-private.h"
#include "mongocrypt-opts-private.h"
#include "mongocrypt-status-private.h"
#include "mongocrypt-util-private.h"
#include <kms_message/kms_b64.h>
#include <kms_message/kms_azure_request.h>
#include <kms_message/kms_gcp_request.h>
#include "mongocrypt.h"
typedef struct {
mongocrypt_status_t *status;
void *ctx;
} ctx_with_status_t;
/* Before we've read the Content-Length header in an HTTP response,
* we don't know how many bytes we'll need. So return this value
* in kms_ctx_bytes_needed until we are fed the Content-Length.
*/
#define DEFAULT_MAX_KMS_BYTE_REQUEST 1024
#define SHA256_LEN 32
#define DEFAULT_HTTPS_PORT "443"
#define DEFAULT_KMIP_PORT "5696"
static bool
_sha256 (void *ctx, const char *input, size_t len, unsigned char *hash_out)
{
bool ret;
ctx_with_status_t *ctx_with_status = (ctx_with_status_t *) ctx;
_mongocrypt_crypto_t *crypto = (_mongocrypt_crypto_t *) ctx_with_status->ctx;
mongocrypt_binary_t *plaintext, *out;
plaintext =
mongocrypt_binary_new_from_data ((uint8_t *) input, (uint32_t) len);
out = mongocrypt_binary_new ();
out->data = hash_out;
out->len = SHA256_LEN;
ret = crypto->sha_256 (crypto->ctx, plaintext, out, ctx_with_status->status);
mongocrypt_binary_destroy (plaintext);
mongocrypt_binary_destroy (out);
return ret;
}
static bool
_sha256_hmac (void *ctx,
const char *key_input,
size_t key_len,
const char *input,
size_t len,
unsigned char *hash_out)
{
ctx_with_status_t *ctx_with_status = (ctx_with_status_t *) ctx;
_mongocrypt_crypto_t *crypto = (_mongocrypt_crypto_t *) ctx_with_status->ctx;
mongocrypt_binary_t *key, *plaintext, *out;
bool ret;
(void) crypto;
key = mongocrypt_binary_new_from_data ((uint8_t *) key_input,
(uint32_t) key_len);
plaintext =
mongocrypt_binary_new_from_data ((uint8_t *) input, (uint32_t) len);
out = mongocrypt_binary_new ();
out->data = hash_out;
out->len = SHA256_LEN;
ret = crypto->hmac_sha_256 (
crypto->ctx, key, plaintext, out, ctx_with_status->status);
mongocrypt_binary_destroy (key);
mongocrypt_binary_destroy (plaintext);
mongocrypt_binary_destroy (out);
return ret;
}
static void
_set_kms_crypto_hooks (_mongocrypt_crypto_t *crypto,
ctx_with_status_t *ctx_with_status,
kms_request_opt_t *opts)
{
if (crypto->hooks_enabled) {
kms_request_opt_set_crypto_hooks (
opts, _sha256, _sha256_hmac, ctx_with_status);
}
}
static bool
is_kms (_kms_request_type_t kms_type)
{
return kms_type == MONGOCRYPT_KMS_KMIP_REGISTER ||
kms_type == MONGOCRYPT_KMS_KMIP_ACTIVATE ||
kms_type == MONGOCRYPT_KMS_KMIP_GET;
}
static void
_init_common (mongocrypt_kms_ctx_t *kms,
_mongocrypt_log_t *log,
_kms_request_type_t kms_type)
{
if (is_kms (kms_type)) {
kms->parser = kms_kmip_response_parser_new (NULL /* reserved */);
} else {
kms->parser = kms_response_parser_new ();
}
kms->log = log;
kms->status = mongocrypt_status_new ();
kms->req_type = kms_type;
_mongocrypt_buffer_init (&kms->result);
}
bool
-_mongocrypt_kms_ctx_init_aws_decrypt (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
- _mongocrypt_key_doc_t *key,
- _mongocrypt_log_t *log,
- _mongocrypt_crypto_t *crypto)
+_mongocrypt_kms_ctx_init_aws_decrypt (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ _mongocrypt_key_doc_t *key,
+ _mongocrypt_log_t *log,
+ _mongocrypt_crypto_t *crypto)
{
kms_request_opt_t *opt;
mongocrypt_status_t *status;
ctx_with_status_t ctx_with_status;
bool ret = false;
_init_common (kms, log, MONGOCRYPT_KMS_AWS_DECRYPT);
status = kms->status;
ctx_with_status.ctx = crypto;
ctx_with_status.status = mongocrypt_status_new ();
if (!key->kek.kms_provider) {
CLIENT_ERR ("no kms provider specified on key");
goto done;
}
if (MONGOCRYPT_KMS_PROVIDER_AWS != key->kek.kms_provider) {
CLIENT_ERR ("expected aws kms provider");
goto done;
}
if (!key->kek.provider.aws.region) {
CLIENT_ERR ("no key region provided");
goto done;
}
- if (0 == (crypt_opts->kms_providers & MONGOCRYPT_KMS_PROVIDER_AWS)) {
+ if (0 ==
+ (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_AWS)) {
CLIENT_ERR ("aws kms not configured");
goto done;
}
- if (!crypt_opts->kms_provider_aws.access_key_id) {
+ if (!kms_providers->aws.access_key_id) {
CLIENT_ERR ("aws access key id not provided");
goto done;
}
- if (!crypt_opts->kms_provider_aws.secret_access_key) {
+ if (!kms_providers->aws.secret_access_key) {
CLIENT_ERR ("aws secret access key not provided");
goto done;
}
/* create the KMS request. */
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
_set_kms_crypto_hooks (crypto, &ctx_with_status, opt);
kms_request_opt_set_connection_close (opt, true);
kms->req = kms_decrypt_request_new (
key->key_material.data, key->key_material.len, opt);
kms_request_opt_destroy (opt);
kms_request_set_service (kms->req, "kms");
- if (crypt_opts->kms_provider_aws.session_token) {
+ if (kms_providers->aws.session_token) {
kms_request_add_header_field (kms->req,
"X-Amz-Security-Token",
- crypt_opts->kms_provider_aws.session_token);
+ kms_providers->aws.session_token);
}
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing KMS message: %s",
kms_request_get_error (kms->req));
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
/* If an endpoint was set, override the default Host header. */
if (key->kek.provider.aws.endpoint) {
if (!kms_request_add_header_field (
kms->req, "Host", key->kek.provider.aws.endpoint->host_and_port)) {
CLIENT_ERR ("error constructing KMS message: %s",
kms_request_get_error (kms->req));
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
}
if (!kms_request_set_region (kms->req, key->kek.provider.aws.region)) {
CLIENT_ERR ("failed to set region");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
if (!kms_request_set_access_key_id (
- kms->req, crypt_opts->kms_provider_aws.access_key_id)) {
+ kms->req, kms_providers->aws.access_key_id)) {
CLIENT_ERR ("failed to set aws access key id");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
if (!kms_request_set_secret_key (
- kms->req, crypt_opts->kms_provider_aws.secret_access_key)) {
+ kms->req, kms_providers->aws.secret_access_key)) {
CLIENT_ERR ("failed to set aws secret access key");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) kms_request_get_signed (kms->req);
if (!kms->msg.data) {
CLIENT_ERR ("failed to create KMS message");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
kms->msg.len = (uint32_t) strlen ((char *) kms->msg.data);
kms->msg.owned = true;
if (key->kek.provider.aws.endpoint) {
kms->endpoint =
bson_strdup (key->kek.provider.aws.endpoint->host_and_port);
} else {
/* construct the endpoint from AWS region. */
kms->endpoint = bson_strdup_printf ("kms.%s.amazonaws.com",
key->kek.provider.aws.region);
}
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
ret = true;
done:
mongocrypt_status_destroy (ctx_with_status.status);
return ret;
}
bool
_mongocrypt_kms_ctx_init_aws_encrypt (
mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
_mongocrypt_ctx_opts_t *ctx_opts,
_mongocrypt_buffer_t *plaintext_key_material,
_mongocrypt_log_t *log,
_mongocrypt_crypto_t *crypto)
{
kms_request_opt_t *opt;
mongocrypt_status_t *status;
ctx_with_status_t ctx_with_status;
bool ret = false;
_init_common (kms, log, MONGOCRYPT_KMS_AWS_ENCRYPT);
status = kms->status;
ctx_with_status.ctx = crypto;
ctx_with_status.status = mongocrypt_status_new ();
if (MONGOCRYPT_KMS_PROVIDER_AWS != ctx_opts->kek.kms_provider) {
CLIENT_ERR ("expected aws kms provider");
goto done;
}
if (!ctx_opts->kek.provider.aws.region) {
CLIENT_ERR ("no key region provided");
goto done;
}
if (!ctx_opts->kek.provider.aws.cmk) {
CLIENT_ERR ("no aws cmk provided");
goto done;
}
- if (0 == (crypt_opts->kms_providers & MONGOCRYPT_KMS_PROVIDER_AWS)) {
+ if (0 ==
+ (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_AWS)) {
CLIENT_ERR ("aws kms not configured");
goto done;
}
- if (!crypt_opts->kms_provider_aws.access_key_id) {
+ if (!kms_providers->aws.access_key_id) {
CLIENT_ERR ("aws access key id not provided");
goto done;
}
- if (!crypt_opts->kms_provider_aws.secret_access_key) {
+ if (!kms_providers->aws.secret_access_key) {
CLIENT_ERR ("aws secret access key not provided");
goto done;
}
/* create the KMS request. */
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
_set_kms_crypto_hooks (crypto, &ctx_with_status, opt);
kms_request_opt_set_connection_close (opt, true);
kms->req = kms_encrypt_request_new (plaintext_key_material->data,
plaintext_key_material->len,
ctx_opts->kek.provider.aws.cmk,
opt);
kms_request_opt_destroy (opt);
kms_request_set_service (kms->req, "kms");
- if (crypt_opts->kms_provider_aws.session_token) {
+ if (kms_providers->aws.session_token) {
kms_request_add_header_field (kms->req,
"X-Amz-Security-Token",
- crypt_opts->kms_provider_aws.session_token);
+ kms_providers->aws.session_token);
}
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing KMS message: %s",
kms_request_get_error (kms->req));
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
/* If an endpoint was set, override the default Host header. */
if (ctx_opts->kek.provider.aws.endpoint) {
if (!kms_request_add_header_field (
kms->req, "Host", ctx_opts->kek.provider.aws.endpoint->host)) {
CLIENT_ERR ("error constructing KMS message: %s",
kms_request_get_error (kms->req));
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
}
if (!kms_request_set_region (kms->req, ctx_opts->kek.provider.aws.region)) {
CLIENT_ERR ("failed to set region");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
if (!kms_request_set_access_key_id (
- kms->req, crypt_opts->kms_provider_aws.access_key_id)) {
+ kms->req, kms_providers->aws.access_key_id)) {
CLIENT_ERR ("failed to set aws access key id");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
if (!kms_request_set_secret_key (
- kms->req, crypt_opts->kms_provider_aws.secret_access_key)) {
+ kms->req, kms_providers->aws.secret_access_key)) {
CLIENT_ERR ("failed to set aws secret access key");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) kms_request_get_signed (kms->req);
if (!kms->msg.data) {
CLIENT_ERR ("failed to create KMS message");
_mongocrypt_status_append (status, ctx_with_status.status);
goto done;
}
kms->msg.len = (uint32_t) strlen ((char *) kms->msg.data);
kms->msg.owned = true;
/* construct the endpoint */
if (ctx_opts->kek.provider.aws.endpoint) {
kms->endpoint =
bson_strdup (ctx_opts->kek.provider.aws.endpoint->host_and_port);
} else {
kms->endpoint = bson_strdup_printf ("kms.%s.amazonaws.com",
ctx_opts->kek.provider.aws.region);
}
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
ret = true;
done:
mongocrypt_status_destroy (ctx_with_status.status);
return ret;
}
uint32_t
mongocrypt_kms_ctx_bytes_needed (mongocrypt_kms_ctx_t *kms)
{
if (!kms) {
return 0;
}
/* TODO: an oddity of kms-message. After retrieving the result, it
* resets the parser. */
if (!mongocrypt_status_ok (kms->status) ||
!_mongocrypt_buffer_empty (&kms->result)) {
return 0;
}
return kms_response_parser_wants_bytes (kms->parser,
DEFAULT_MAX_KMS_BYTE_REQUEST);
}
/* An AWS KMS context has received full response. Parse out the result or error.
*/
static bool
_ctx_done_aws (mongocrypt_kms_ctx_t *kms, const char *json_field)
{
kms_response_t *response = NULL;
const char *body;
bson_t body_bson = BSON_INITIALIZER;
bool ret;
bson_error_t bson_error;
bson_iter_t iter;
uint32_t b64_strlen;
char *b64_str;
int http_status;
size_t body_len;
mongocrypt_status_t *status;
status = kms->status;
ret = false;
/* Parse out the {en|de}crypted result. */
http_status = kms_response_parser_status (kms->parser);
response = kms_response_parser_get_response (kms->parser);
body = kms_response_get_body (response, &body_len);
if (http_status != 200) {
/* 1xx, 2xx, and 3xx HTTP status codes are not errors, but we only
* support handling 200 response. */
if (http_status < 400) {
CLIENT_ERR ("Unsupported HTTP code in KMS response. HTTP status=%d",
http_status);
goto fail;
}
/* Either empty body or body containing JSON with error message. */
if (body_len == 0) {
CLIENT_ERR ("Error in KMS response. HTTP status=%d", http_status);
goto fail;
}
/* AWS error responses include a JSON message, like { "message":
* "error" } */
bson_destroy (&body_bson);
if (!bson_init_from_json (&body_bson, body, body_len, &bson_error)) {
bson_init (&body_bson);
} else if (bson_iter_init_find (&iter, &body_bson, "message") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
CLIENT_ERR ("Error in KMS response '%s'. "
"HTTP status=%d",
bson_iter_utf8 (&iter, NULL),
http_status);
goto fail;
}
/* If we couldn't parse JSON, return the body unchanged as an error. */
CLIENT_ERR ("Error parsing JSON in KMS response '%s'. HTTP status=%d",
body,
http_status);
goto fail;
}
/* If HTTP response succeeded (status 200) then body should contain JSON.
*/
bson_destroy (&body_bson);
if (!bson_init_from_json (&body_bson, body, body_len, &bson_error)) {
CLIENT_ERR ("Error parsing JSON in KMS response '%s'. "
"HTTP status=%d",
bson_error.message,
http_status);
bson_init (&body_bson);
goto fail;
}
if (!bson_iter_init_find (&iter, &body_bson, json_field) ||
!BSON_ITER_HOLDS_UTF8 (&iter)) {
CLIENT_ERR (
"KMS JSON response does not include string '%s'. HTTP status=%d",
json_field,
http_status);
goto fail;
}
b64_str = (char *) bson_iter_utf8 (&iter, &b64_strlen);
BSON_ASSERT (b64_str);
kms->result.data = bson_malloc (b64_strlen + 1);
BSON_ASSERT (kms->result.data);
kms->result.len =
kms_message_b64_pton (b64_str, kms->result.data, b64_strlen);
kms->result.owned = true;
ret = true;
fail:
bson_destroy (&body_bson);
kms_response_destroy (response);
return ret;
}
/* A Azure/GCP oauth KMS context has received full response. Parse out the
* bearer token or error. */
static bool
_ctx_done_oauth (mongocrypt_kms_ctx_t *kms)
{
kms_response_t *response = NULL;
const char *body;
bson_t *bson_body = NULL;
bool ret;
bson_error_t bson_error;
bson_iter_t iter;
int http_status;
size_t body_len;
mongocrypt_status_t *status;
status = kms->status;
ret = false;
/* Parse out the oauth token result (or error). */
http_status = kms_response_parser_status (kms->parser);
response = kms_response_parser_get_response (kms->parser);
body = kms_response_get_body (response, &body_len);
if (body_len == 0) {
CLIENT_ERR ("Empty KMS response. HTTP status=%d", http_status);
goto fail;
}
bson_body =
bson_new_from_json ((const uint8_t *) body, body_len, &bson_error);
if (!bson_body) {
CLIENT_ERR ("Invalid JSON in KMS response. HTTP status=%d. Error: %s",
http_status,
bson_error.message);
goto fail;
}
if (http_status != 200) {
const char *error = "";
const char *error_description = "";
/* Check for oauth errors.
* https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes#handling-error-codes-in-your-application.
* 'error' provides a short error classification
* 'error_description' is a long error description
*/
if (bson_iter_init_find (&iter, bson_body, "error") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
error = bson_iter_utf8 (&iter, NULL);
}
if (bson_iter_init_find (&iter, bson_body, "error_description") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
error_description = bson_iter_utf8 (&iter, NULL);
}
CLIENT_ERR ("Error in KMS response: '%s', '%s'. HTTP status=%d",
error,
error_description,
http_status);
goto fail;
}
if (!bson_iter_init_find (&iter, bson_body, "access_token") ||
!BSON_ITER_HOLDS_UTF8 (&iter)) {
CLIENT_ERR (
"Invalid KMS response, no access_token returned. HTTP status=%d",
http_status);
goto fail;
}
/* Store the full response, to include the expiration time. */
_mongocrypt_buffer_steal_from_bson (&kms->result, bson_body);
bson_body = NULL;
ret = true;
fail:
bson_destroy (bson_body);
kms_response_destroy (response);
return ret;
}
/* An Azure oauth KMS context has received full response. Parse out the bearer
* token or error. */
static bool
_ctx_done_azure_wrapkey_unwrapkey (mongocrypt_kms_ctx_t *kms)
{
kms_response_t *response = NULL;
const char *body;
bson_t *bson_body = NULL;
bool ret;
bson_error_t bson_error;
bson_iter_t iter;
int http_status;
size_t body_len;
mongocrypt_status_t *status;
const char *b64url_data = NULL;
uint32_t b64url_len;
char *b64_data = NULL;
uint32_t b64_len;
status = kms->status;
ret = false;
/* Parse out the oauth token result (or error). */
http_status = kms_response_parser_status (kms->parser);
response = kms_response_parser_get_response (kms->parser);
body = kms_response_get_body (response, &body_len);
if (body_len == 0) {
CLIENT_ERR ("Empty KMS response. HTTP status=%d", http_status);
goto fail;
}
bson_body =
bson_new_from_json ((const uint8_t *) body, body_len, &bson_error);
if (!bson_body) {
CLIENT_ERR ("Invalid JSON in KMS response. HTTP status=%d", http_status);
goto fail;
}
if (http_status != 200) {
const char *message = "";
/* Check for errors.
* https://docs.microsoft.com/en-us/rest/api/keyvault/wrapkey/wrapkey#error
*/
if (bson_iter_init (&iter, bson_body) &&
bson_iter_find_descendant (&iter, "error.message", &iter) &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
message = bson_iter_utf8 (&iter, NULL);
}
CLIENT_ERR (
"Error in KMS response: '%s'. HTTP status=%d", message, http_status);
goto fail;
}
if (!bson_iter_init_find (&iter, bson_body, "value") ||
!BSON_ITER_HOLDS_UTF8 (&iter)) {
CLIENT_ERR ("Invalid KMS response, no value returned. HTTP status=%d",
http_status);
goto fail;
}
b64url_data = bson_iter_utf8 (&iter, &b64url_len);
/* add four for padding. */
b64_len = b64url_len + 4;
b64_data = bson_malloc0 (b64_len);
if (kms_message_b64url_to_b64 (b64url_data, b64url_len, b64_data, b64_len) ==
-1) {
CLIENT_ERR ("Error converting base64url to base64");
goto fail;
}
kms->result.data = bson_malloc0 (b64_len);
kms->result.len = kms_message_b64_pton (b64_data, kms->result.data, b64_len);
kms->result.owned = true;
ret = true;
fail:
bson_destroy (bson_body);
kms_response_destroy (response);
bson_free (b64_data);
return ret;
}
/* A GCP KMS context has received full response. Parse out the result or error.
*/
static bool
_ctx_done_gcp (mongocrypt_kms_ctx_t *kms, const char *json_field)
{
kms_response_t *response = NULL;
const char *body;
bson_t body_bson = BSON_INITIALIZER;
bool ret;
bson_error_t bson_error;
bson_iter_t iter;
size_t outlen;
char *b64_str;
int http_status;
size_t body_len;
mongocrypt_status_t *status;
status = kms->status;
ret = false;
/* Parse out the {en|de}crypted result. */
http_status = kms_response_parser_status (kms->parser);
response = kms_response_parser_get_response (kms->parser);
body = kms_response_get_body (response, &body_len);
if (http_status != 200) {
/* 1xx, 2xx, and 3xx HTTP status codes are not errors, but we only
* support handling 200 response. */
if (http_status < 400) {
CLIENT_ERR ("Unsupported HTTP code in KMS response. HTTP status=%d",
http_status);
goto fail;
}
/* Either empty body or body containing JSON with error message. */
if (body_len == 0) {
CLIENT_ERR ("Error in KMS response. HTTP status=%d", http_status);
goto fail;
}
/* GCP error responses include a JSON message, like { "message":
* "error", "code": <num> } */
bson_destroy (&body_bson);
if (!bson_init_from_json (&body_bson, body, body_len, &bson_error)) {
bson_init (&body_bson);
} else {
const char *msg = "";
int32_t code = 0;
if (bson_iter_init_find (&iter, &body_bson, "message") &&
BSON_ITER_HOLDS_UTF8 (&iter)) {
msg = bson_iter_utf8 (&iter, NULL);
}
if (bson_iter_init_find (&iter, &body_bson, "code") &&
BSON_ITER_HOLDS_INT32 (&iter)) {
code = bson_iter_int32 (&iter);
}
CLIENT_ERR ("Error in KMS response '%s', code: '%d'. "
"HTTP status=%d",
msg,
code,
http_status);
goto fail;
}
/* If we couldn't parse JSON, return the body unchanged as an error. */
CLIENT_ERR ("Error parsing JSON in KMS response '%s'. HTTP status=%d",
body,
http_status);
goto fail;
}
/* If HTTP response succeeded (status 200) then body should contain JSON.
*/
bson_destroy (&body_bson);
if (!bson_init_from_json (&body_bson, body, body_len, &bson_error)) {
CLIENT_ERR ("Error parsing JSON in KMS response '%s'. "
"HTTP status=%d",
bson_error.message,
http_status);
bson_init (&body_bson);
goto fail;
}
if (!bson_iter_init_find (&iter, &body_bson, json_field) ||
!BSON_ITER_HOLDS_UTF8 (&iter)) {
CLIENT_ERR (
"KMS JSON response does not include string '%s'. HTTP status=%d",
json_field,
http_status);
goto fail;
}
b64_str = (char *) bson_iter_utf8 (&iter, NULL);
BSON_ASSERT (b64_str);
kms->result.data = kms_message_b64_to_raw (b64_str, &outlen);
kms->result.len = (uint32_t) outlen;
kms->result.owned = true;
ret = true;
fail:
bson_destroy (&body_bson);
kms_response_destroy (response);
return ret;
}
static bool
_ctx_done_kmip_register (mongocrypt_kms_ctx_t *kms_ctx)
{
kms_response_t *res = NULL;
mongocrypt_status_t *status = kms_ctx->status;
bool ret = false;
char *uid;
res = kms_response_parser_get_response (kms_ctx->parser);
if (!res) {
CLIENT_ERR ("Error getting KMIP response: %s",
kms_response_parser_error (kms_ctx->parser));
goto done;
}
uid = kms_kmip_response_get_unique_identifier (res);
if (!uid) {
CLIENT_ERR (
"Error getting UniqueIdentifer from KMIP Register response: %s",
kms_response_get_error (res));
goto done;
}
if (!_mongocrypt_buffer_steal_from_string (&kms_ctx->result, uid)) {
CLIENT_ERR ("Error storing KMS UniqueIdentifer result");
bson_free (uid);
goto done;
}
ret = true;
done:
kms_response_destroy (res);
return ret;
}
static bool
_ctx_done_kmip_activate (mongocrypt_kms_ctx_t *kms_ctx)
{
return _ctx_done_kmip_register (kms_ctx);
}
static bool
_ctx_done_kmip_get (mongocrypt_kms_ctx_t *kms_ctx)
{
kms_response_t *res = NULL;
mongocrypt_status_t *status = kms_ctx->status;
bool ret = false;
uint8_t *secretdata;
size_t secretdata_len;
res = kms_response_parser_get_response (kms_ctx->parser);
if (!res) {
CLIENT_ERR ("Error getting KMIP response: %s",
kms_response_parser_error (kms_ctx->parser));
goto done;
}
secretdata = kms_kmip_response_get_secretdata (res, &secretdata_len);
if (!secretdata) {
CLIENT_ERR ("Error getting SecretData from KMIP Get response: %s",
kms_response_get_error (res));
goto done;
}
if (!_mongocrypt_buffer_steal_from_data_and_size (
&kms_ctx->result, secretdata, secretdata_len)) {
CLIENT_ERR ("Error storing KMS SecretData result");
bson_free (secretdata);
goto done;
}
ret = true;
done:
kms_response_destroy (res);
return ret;
}
bool
mongocrypt_kms_ctx_feed (mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes)
{
mongocrypt_status_t *status;
if (!kms) {
return false;
}
status = kms->status;
if (!mongocrypt_status_ok (status)) {
return false;
}
if (!bytes) {
CLIENT_ERR ("argument 'bytes' is required");
return false;
}
if (bytes->len > mongocrypt_kms_ctx_bytes_needed (kms)) {
CLIENT_ERR ("KMS response fed too much data");
return false;
}
if (kms->log->trace_enabled) {
_mongocrypt_log (kms->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%.*s\")",
BSON_FUNC,
"bytes",
mongocrypt_binary_len (bytes),
mongocrypt_binary_data (bytes));
}
if (!kms_response_parser_feed (kms->parser, bytes->data, bytes->len)) {
if (is_kms (kms->req_type)) {
/* The KMIP response parser does not suport kms_response_parser_status.
* Only report the error string. */
CLIENT_ERR ("KMS response parser error with error: '%s'",
kms_response_parser_error (kms->parser));
} else {
CLIENT_ERR ("KMS response parser error with status %d, error: '%s'",
kms_response_parser_status (kms->parser),
kms_response_parser_error (kms->parser));
}
return false;
}
if (0 == mongocrypt_kms_ctx_bytes_needed (kms)) {
switch (kms->req_type) {
default:
CLIENT_ERR ("Unknown request type");
return false;
case MONGOCRYPT_KMS_AWS_ENCRYPT:
return _ctx_done_aws (kms, "CiphertextBlob");
case MONGOCRYPT_KMS_AWS_DECRYPT:
return _ctx_done_aws (kms, "Plaintext");
case MONGOCRYPT_KMS_AZURE_OAUTH:
return _ctx_done_oauth (kms);
case MONGOCRYPT_KMS_AZURE_WRAPKEY:
return _ctx_done_azure_wrapkey_unwrapkey (kms);
case MONGOCRYPT_KMS_AZURE_UNWRAPKEY:
return _ctx_done_azure_wrapkey_unwrapkey (kms);
case MONGOCRYPT_KMS_GCP_OAUTH:
return _ctx_done_oauth (kms);
case MONGOCRYPT_KMS_GCP_ENCRYPT:
return _ctx_done_gcp (kms, "ciphertext");
case MONGOCRYPT_KMS_GCP_DECRYPT:
return _ctx_done_gcp (kms, "plaintext");
case MONGOCRYPT_KMS_KMIP_REGISTER:
return _ctx_done_kmip_register (kms);
case MONGOCRYPT_KMS_KMIP_ACTIVATE:
return _ctx_done_kmip_activate (kms);
case MONGOCRYPT_KMS_KMIP_GET:
return _ctx_done_kmip_get (kms);
}
}
return true;
}
bool
_mongocrypt_kms_ctx_result (mongocrypt_kms_ctx_t *kms,
_mongocrypt_buffer_t *out)
{
mongocrypt_status_t *status;
status = kms->status;
/* If we have no status, we were never initialized */
if (!status) {
return false;
}
if (!mongocrypt_status_ok (status)) {
return false;
}
if (mongocrypt_kms_ctx_bytes_needed (kms) > 0) {
CLIENT_ERR ("KMS response unfinished");
return false;
}
_mongocrypt_buffer_init (out);
out->data = kms->result.data;
out->len = kms->result.len;
return true;
}
bool
mongocrypt_kms_ctx_status (mongocrypt_kms_ctx_t *kms,
mongocrypt_status_t *status_out)
{
if (!kms) {
return false;
}
if (!status_out) {
mongocrypt_status_t *status = kms->status;
CLIENT_ERR ("argument 'status' is required");
return false;
}
_mongocrypt_status_copy_to (kms->status, status_out);
return mongocrypt_status_ok (status_out);
}
void
_mongocrypt_kms_ctx_cleanup (mongocrypt_kms_ctx_t *kms)
{
if (!kms) {
return;
}
if (kms->req) {
kms_request_destroy (kms->req);
}
if (kms->parser) {
kms_response_parser_destroy (kms->parser);
}
mongocrypt_status_destroy (kms->status);
_mongocrypt_buffer_cleanup (&kms->msg);
_mongocrypt_buffer_cleanup (&kms->result);
bson_free (kms->endpoint);
}
bool
mongocrypt_kms_ctx_message (mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *msg)
{
if (!kms) {
return false;
}
if (!msg) {
mongocrypt_status_t *status = kms->status;
CLIENT_ERR ("argument 'msg' is required");
return false;
}
msg->data = kms->msg.data;
msg->len = kms->msg.len;
return true;
}
bool
mongocrypt_kms_ctx_endpoint (mongocrypt_kms_ctx_t *kms, const char **endpoint)
{
if (!kms) {
return false;
}
if (!endpoint) {
mongocrypt_status_t *status = kms->status;
CLIENT_ERR ("argument 'endpoint' is required");
return false;
}
*endpoint = kms->endpoint;
return true;
}
bool
-_mongocrypt_kms_ctx_init_azure_auth (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
- _mongocrypt_endpoint_t *key_vault_endpoint)
+_mongocrypt_kms_ctx_init_azure_auth (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_log_t *log,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ _mongocrypt_endpoint_t *key_vault_endpoint)
{
kms_request_opt_t *opt = NULL;
mongocrypt_status_t *status;
_mongocrypt_endpoint_t *identity_platform_endpoint;
char *scope = NULL;
const char *hostname;
char *request_string;
bool ret = false;
_init_common (kms, log, MONGOCRYPT_KMS_AZURE_OAUTH);
status = kms->status;
- identity_platform_endpoint =
- crypt_opts->kms_provider_azure.identity_platform_endpoint;
+ identity_platform_endpoint = kms_providers->azure.identity_platform_endpoint;
if (identity_platform_endpoint) {
kms->endpoint = bson_strdup (identity_platform_endpoint->host_and_port);
hostname = identity_platform_endpoint->host;
} else {
kms->endpoint = bson_strdup ("login.microsoftonline.com");
hostname = "login.microsoftonline.com";
}
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
if (key_vault_endpoint) {
/* Request a custom scope. It is URL encoded, like
* https%3A%2F%2Fvault.azure.net%2F.default */
scope = bson_strdup_printf (
"%s%s%s", "https%3A%2F%2F", key_vault_endpoint->domain, "%2F.default");
} else {
/* Default to commercial Azure endpoint. */
scope = bson_strdup ("https%3A%2F%2Fvault.azure.net%2F.default");
}
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
kms_request_opt_set_connection_close (opt, true);
kms_request_opt_set_provider (opt, KMS_REQUEST_PROVIDER_AZURE);
kms->req =
kms_azure_request_oauth_new (hostname,
scope,
- crypt_opts->kms_provider_azure.tenant_id,
- crypt_opts->kms_provider_azure.client_id,
- crypt_opts->kms_provider_azure.client_secret,
+ kms_providers->azure.tenant_id,
+ kms_providers->azure.client_id,
+ kms_providers->azure.client_secret,
opt);
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing KMS message: %s",
kms_request_get_error (kms->req));
goto fail;
}
request_string = kms_request_to_string (kms->req);
if (!request_string) {
CLIENT_ERR ("error getting Azure OAuth KMS message: %s",
kms_request_get_error (kms->req));
goto fail;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) request_string;
kms->msg.len = (uint32_t) strlen (request_string);
kms->msg.owned = true;
ret = true;
fail:
bson_free (scope);
kms_request_opt_destroy (opt);
return ret;
}
bool
_mongocrypt_kms_ctx_init_azure_wrapkey (
mongocrypt_kms_ctx_t *kms,
_mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
struct __mongocrypt_ctx_opts_t *ctx_opts,
const char *access_token,
_mongocrypt_buffer_t *plaintext_key_material)
{
kms_request_opt_t *opt = NULL;
mongocrypt_status_t *status;
char *path_and_query = NULL;
char *payload = NULL;
const char *host;
char *request_string;
bool ret = false;
char *bearer_token_value = NULL;
_init_common (kms, log, MONGOCRYPT_KMS_AZURE_WRAPKEY);
status = kms->status;
kms->endpoint = bson_strdup (
ctx_opts->kek.provider.azure.key_vault_endpoint->host_and_port);
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
host = ctx_opts->kek.provider.azure.key_vault_endpoint->host;
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
kms_request_opt_set_connection_close (opt, true);
kms_request_opt_set_provider (opt, KMS_REQUEST_PROVIDER_AZURE);
kms->req =
kms_azure_request_wrapkey_new (host,
access_token,
ctx_opts->kek.provider.azure.key_name,
ctx_opts->kek.provider.azure.key_version,
plaintext_key_material->data,
plaintext_key_material->len,
opt);
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing KMS wrapkey message: %s",
kms_request_get_error (kms->req));
goto fail;
}
request_string = kms_request_to_string (kms->req);
if (!request_string) {
CLIENT_ERR ("error getting Azure wrapkey KMS message: %s",
kms_request_get_error (kms->req));
goto fail;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) request_string;
kms->msg.len = (uint32_t) strlen (request_string);
kms->msg.owned = true;
ret = true;
fail:
kms_request_opt_destroy (opt);
bson_free (path_and_query);
bson_free (payload);
bson_free (bearer_token_value);
return ret;
}
bool
-_mongocrypt_kms_ctx_init_azure_unwrapkey (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
- const char *access_token,
- _mongocrypt_key_doc_t *key,
- _mongocrypt_log_t *log)
+_mongocrypt_kms_ctx_init_azure_unwrapkey (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ const char *access_token,
+ _mongocrypt_key_doc_t *key,
+ _mongocrypt_log_t *log)
{
kms_request_opt_t *opt = NULL;
mongocrypt_status_t *status;
char *path_and_query = NULL;
char *payload = NULL;
const char *host;
char *request_string;
bool ret = false;
char *bearer_token_value = NULL;
_init_common (kms, log, MONGOCRYPT_KMS_AZURE_UNWRAPKEY);
status = kms->status;
kms->endpoint =
bson_strdup (key->kek.provider.azure.key_vault_endpoint->host_and_port);
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
host = key->kek.provider.azure.key_vault_endpoint->host;
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
kms_request_opt_set_connection_close (opt, true);
kms_request_opt_set_provider (opt, KMS_REQUEST_PROVIDER_AZURE);
kms->req =
kms_azure_request_unwrapkey_new (host,
access_token,
key->kek.provider.azure.key_name,
key->kek.provider.azure.key_version,
key->key_material.data,
key->key_material.len,
opt);
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing KMS unwrapkey message: %s",
kms_request_get_error (kms->req));
goto fail;
}
request_string = kms_request_to_string (kms->req);
if (!request_string) {
CLIENT_ERR ("error getting Azure unwrapkey KMS message: %s",
kms_request_get_error (kms->req));
goto fail;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) request_string;
kms->msg.len = (uint32_t) strlen (request_string);
kms->msg.owned = true;
ret = true;
fail:
kms_request_opt_destroy (opt);
bson_free (path_and_query);
bson_free (payload);
bson_free (bearer_token_value);
return ret;
}
#define RSAES_PKCS1_V1_5_SIGNATURE_LEN 256
/* This is the form of the callback that KMS message calls. */
bool
_sign_rsaes_pkcs1_v1_5_trampoline (void *ctx,
const char *private_key,
size_t private_key_len,
const char *input,
size_t input_len,
unsigned char *signature_out)
{
ctx_with_status_t *ctx_with_status;
_mongocrypt_opts_t *crypt_opts;
mongocrypt_binary_t private_key_bin;
mongocrypt_binary_t input_bin;
mongocrypt_binary_t output_bin;
bool ret;
ctx_with_status = (ctx_with_status_t *) ctx;
crypt_opts = (_mongocrypt_opts_t *) ctx_with_status->ctx;
private_key_bin.data = (uint8_t *) private_key;
private_key_bin.len = (uint32_t) private_key_len;
input_bin.data = (uint8_t *) input;
input_bin.len = (uint32_t) input_len;
output_bin.data = (uint8_t *) signature_out;
output_bin.len = RSAES_PKCS1_V1_5_SIGNATURE_LEN;
ret = crypt_opts->sign_rsaes_pkcs1_v1_5 (crypt_opts->sign_ctx,
&private_key_bin,
&input_bin,
&output_bin,
ctx_with_status->status);
return ret;
}
bool
-_mongocrypt_kms_ctx_init_gcp_auth (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
- _mongocrypt_endpoint_t *kms_endpoint)
+_mongocrypt_kms_ctx_init_gcp_auth (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_log_t *log,
+ _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ _mongocrypt_endpoint_t *kms_endpoint)
{
kms_request_opt_t *opt = NULL;
mongocrypt_status_t *status;
_mongocrypt_endpoint_t *auth_endpoint;
char *scope = NULL;
char *audience = NULL;
const char *hostname;
char *request_string;
bool ret = false;
ctx_with_status_t ctx_with_status;
_init_common (kms, log, MONGOCRYPT_KMS_GCP_OAUTH);
status = kms->status;
- auth_endpoint = crypt_opts->kms_provider_gcp.endpoint;
+ auth_endpoint = kms_providers->gcp.endpoint;
ctx_with_status.ctx = crypt_opts;
ctx_with_status.status = mongocrypt_status_new ();
if (auth_endpoint) {
kms->endpoint = bson_strdup (auth_endpoint->host_and_port);
hostname = auth_endpoint->host;
audience = bson_strdup_printf ("https://%s/token", auth_endpoint->host);
} else {
kms->endpoint = bson_strdup ("oauth2.googleapis.com");
hostname = "oauth2.googleapis.com";
audience = bson_strdup_printf ("https://oauth2.googleapis.com/token");
}
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
if (kms_endpoint) {
/* Request a custom scope. */
scope = bson_strdup_printf ("https://www.%s/auth/cloudkms",
kms_endpoint->domain);
} else {
scope = bson_strdup ("https://www.googleapis.com/auth/cloudkms");
}
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
kms_request_opt_set_connection_close (opt, true);
kms_request_opt_set_provider (opt, KMS_REQUEST_PROVIDER_GCP);
if (crypt_opts->sign_rsaes_pkcs1_v1_5) {
kms_request_opt_set_crypto_hook_sign_rsaes_pkcs1_v1_5 (
opt, _sign_rsaes_pkcs1_v1_5_trampoline, &ctx_with_status);
}
kms->req = kms_gcp_request_oauth_new (
hostname,
- crypt_opts->kms_provider_gcp.email,
+ kms_providers->gcp.email,
audience,
scope,
- (const char *) crypt_opts->kms_provider_gcp.private_key.data,
- crypt_opts->kms_provider_gcp.private_key.len,
+ (const char *) kms_providers->gcp.private_key.data,
+ kms_providers->gcp.private_key.len,
opt);
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing KMS message: %s",
kms_request_get_error (kms->req));
_mongocrypt_status_append (status, ctx_with_status.status);
goto fail;
}
request_string = kms_request_to_string (kms->req);
if (!request_string) {
CLIENT_ERR ("error getting GCP OAuth KMS message: %s",
kms_request_get_error (kms->req));
_mongocrypt_status_append (status, ctx_with_status.status);
goto fail;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) request_string;
kms->msg.len = (uint32_t) strlen (request_string);
kms->msg.owned = true;
ret = true;
fail:
bson_free (scope);
bson_free (audience);
kms_request_opt_destroy (opt);
mongocrypt_status_destroy (ctx_with_status.status);
return ret;
}
bool
_mongocrypt_kms_ctx_init_gcp_encrypt (
mongocrypt_kms_ctx_t *kms,
_mongocrypt_log_t *log,
- _mongocrypt_opts_t *crypt_opts,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
struct __mongocrypt_ctx_opts_t *ctx_opts,
const char *access_token,
_mongocrypt_buffer_t *plaintext_key_material)
{
kms_request_opt_t *opt = NULL;
mongocrypt_status_t *status;
char *path_and_query = NULL;
char *payload = NULL;
const char *hostname;
char *request_string;
bool ret = false;
char *bearer_token_value = NULL;
_init_common (kms, log, MONGOCRYPT_KMS_GCP_ENCRYPT);
status = kms->status;
if (ctx_opts->kek.provider.gcp.endpoint) {
kms->endpoint =
bson_strdup (ctx_opts->kek.provider.gcp.endpoint->host_and_port);
hostname = ctx_opts->kek.provider.gcp.endpoint->host;
} else {
kms->endpoint = bson_strdup ("cloudkms.googleapis.com");
hostname = "cloudkms.googleapis.com";
}
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
kms_request_opt_set_connection_close (opt, true);
kms_request_opt_set_provider (opt, KMS_REQUEST_PROVIDER_GCP);
kms->req =
kms_gcp_request_encrypt_new (hostname,
access_token,
ctx_opts->kek.provider.gcp.project_id,
ctx_opts->kek.provider.gcp.location,
ctx_opts->kek.provider.gcp.key_ring,
ctx_opts->kek.provider.gcp.key_name,
ctx_opts->kek.provider.gcp.key_version,
plaintext_key_material->data,
plaintext_key_material->len,
opt);
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing GCP KMS encrypt message: %s",
kms_request_get_error (kms->req));
goto fail;
}
request_string = kms_request_to_string (kms->req);
if (!request_string) {
CLIENT_ERR ("error getting GCP KMS encrypt KMS message: %s",
kms_request_get_error (kms->req));
goto fail;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) request_string;
kms->msg.len = (uint32_t) strlen (request_string);
kms->msg.owned = true;
ret = true;
fail:
kms_request_opt_destroy (opt);
bson_free (path_and_query);
bson_free (payload);
bson_free (bearer_token_value);
return ret;
}
bool
-_mongocrypt_kms_ctx_init_gcp_decrypt (mongocrypt_kms_ctx_t *kms,
- _mongocrypt_opts_t *crypt_opts,
- const char *access_token,
- _mongocrypt_key_doc_t *key,
- _mongocrypt_log_t *log)
+_mongocrypt_kms_ctx_init_gcp_decrypt (
+ mongocrypt_kms_ctx_t *kms,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ const char *access_token,
+ _mongocrypt_key_doc_t *key,
+ _mongocrypt_log_t *log)
{
kms_request_opt_t *opt = NULL;
mongocrypt_status_t *status;
char *path_and_query = NULL;
char *payload = NULL;
const char *hostname;
char *request_string;
bool ret = false;
char *bearer_token_value = NULL;
_init_common (kms, log, MONGOCRYPT_KMS_GCP_DECRYPT);
status = kms->status;
if (key->kek.provider.gcp.endpoint) {
kms->endpoint =
bson_strdup (key->kek.provider.gcp.endpoint->host_and_port);
hostname = key->kek.provider.gcp.endpoint->host;
} else {
kms->endpoint = bson_strdup ("cloudkms.googleapis.com");
hostname = "cloudkms.googleapis.com";
}
_mongocrypt_apply_default_port (&kms->endpoint, DEFAULT_HTTPS_PORT);
opt = kms_request_opt_new ();
BSON_ASSERT (opt);
kms_request_opt_set_connection_close (opt, true);
kms_request_opt_set_provider (opt, KMS_REQUEST_PROVIDER_GCP);
kms->req = kms_gcp_request_decrypt_new (hostname,
access_token,
key->kek.provider.gcp.project_id,
key->kek.provider.gcp.location,
key->kek.provider.gcp.key_ring,
key->kek.provider.gcp.key_name,
key->key_material.data,
key->key_material.len,
opt);
if (kms_request_get_error (kms->req)) {
CLIENT_ERR ("error constructing GCP KMS decrypt message: %s",
kms_request_get_error (kms->req));
goto fail;
}
request_string = kms_request_to_string (kms->req);
if (!request_string) {
CLIENT_ERR ("error getting GCP KMS decrypt KMS message: %s",
kms_request_get_error (kms->req));
goto fail;
}
_mongocrypt_buffer_init (&kms->msg);
kms->msg.data = (uint8_t *) request_string;
kms->msg.len = (uint32_t) strlen (request_string);
kms->msg.owned = true;
ret = true;
fail:
kms_request_opt_destroy (opt);
bson_free (path_and_query);
bson_free (payload);
bson_free (bearer_token_value);
return ret;
}
bool
_mongocrypt_kms_ctx_init_kmip_register (mongocrypt_kms_ctx_t *kms_ctx,
const _mongocrypt_endpoint_t *endpoint,
const uint8_t *secretdata,
uint32_t secretdata_len,
_mongocrypt_log_t *log)
{
mongocrypt_status_t *status;
bool ret = false;
const uint8_t *reqdata;
size_t reqlen;
_init_common (kms_ctx, log, MONGOCRYPT_KMS_KMIP_REGISTER);
status = kms_ctx->status;
kms_ctx->endpoint = bson_strdup (endpoint->host_and_port);
_mongocrypt_apply_default_port (&kms_ctx->endpoint, DEFAULT_KMIP_PORT);
kms_ctx->req = kms_kmip_request_register_secretdata_new (
NULL /* reserved */, secretdata, secretdata_len);
if (!kms_ctx->req) {
CLIENT_ERR ("Error creating KMIP register request: %s",
kms_request_get_error (kms_ctx->req));
goto done;
}
reqdata = kms_request_to_bytes (kms_ctx->req, &reqlen);
if (!_mongocrypt_buffer_copy_from_data_and_size (
&kms_ctx->msg, reqdata, reqlen)) {
CLIENT_ERR ("Error storing KMS request payload");
goto done;
}
ret = true;
done:
return ret;
}
bool
_mongocrypt_kms_ctx_init_kmip_activate (mongocrypt_kms_ctx_t *kms_ctx,
const _mongocrypt_endpoint_t *endpoint,
const char *unique_identifier,
_mongocrypt_log_t *log)
{
mongocrypt_status_t *status;
bool ret = false;
size_t reqlen;
const uint8_t *reqdata;
_init_common (kms_ctx, log, MONGOCRYPT_KMS_KMIP_ACTIVATE);
status = kms_ctx->status;
kms_ctx->endpoint = bson_strdup (endpoint->host_and_port);
_mongocrypt_apply_default_port (&kms_ctx->endpoint, DEFAULT_KMIP_PORT);
kms_ctx->req =
kms_kmip_request_activate_new (NULL /* reserved */, unique_identifier);
if (!kms_ctx->req) {
CLIENT_ERR ("Error creating KMIP activate request: %s",
kms_request_get_error (kms_ctx->req));
goto done;
}
reqdata = kms_request_to_bytes (kms_ctx->req, &reqlen);
if (!_mongocrypt_buffer_copy_from_data_and_size (
&kms_ctx->msg, reqdata, reqlen)) {
CLIENT_ERR ("Error storing KMS request payload");
goto done;
}
ret = true;
done:
return ret;
}
bool
_mongocrypt_kms_ctx_init_kmip_get (mongocrypt_kms_ctx_t *kms_ctx,
const _mongocrypt_endpoint_t *endpoint,
const char *unique_identifier,
_mongocrypt_log_t *log)
{
mongocrypt_status_t *status;
bool ret = false;
size_t reqlen;
const uint8_t *reqdata;
_init_common (kms_ctx, log, MONGOCRYPT_KMS_KMIP_GET);
status = kms_ctx->status;
kms_ctx->endpoint = bson_strdup (endpoint->host_and_port);
_mongocrypt_apply_default_port (&kms_ctx->endpoint, DEFAULT_KMIP_PORT);
kms_ctx->req =
kms_kmip_request_get_new (NULL /* reserved */, unique_identifier);
if (!kms_ctx->req) {
CLIENT_ERR ("Error creating KMIP get request: %s",
kms_request_get_error (kms_ctx->req));
goto done;
}
reqdata = kms_request_to_bytes (kms_ctx->req, &reqlen);
if (!_mongocrypt_buffer_copy_from_data_and_size (
&kms_ctx->msg, reqdata, reqlen)) {
CLIENT_ERR ("Error storing KMS request payload");
goto done;
}
ret = true;
done:
return ret;
}
const char *
set_and_ret (const char *what, uint32_t *len)
{
if (len) {
BSON_ASSERT (size_to_uint32 (strlen (what), len));
}
return what;
}
const char *
mongocrypt_kms_ctx_get_kms_provider (mongocrypt_kms_ctx_t *kms, uint32_t *len)
{
switch (kms->req_type) {
default:
BSON_ASSERT ("unknown KMS request type");
case MONGOCRYPT_KMS_AWS_ENCRYPT:
case MONGOCRYPT_KMS_AWS_DECRYPT:
return set_and_ret ("aws", len);
case MONGOCRYPT_KMS_AZURE_OAUTH:
case MONGOCRYPT_KMS_AZURE_WRAPKEY:
case MONGOCRYPT_KMS_AZURE_UNWRAPKEY:
return set_and_ret ("azure", len);
case MONGOCRYPT_KMS_GCP_OAUTH:
case MONGOCRYPT_KMS_GCP_ENCRYPT:
case MONGOCRYPT_KMS_GCP_DECRYPT:
return set_and_ret ("gcp", len);
case MONGOCRYPT_KMS_KMIP_REGISTER:
case MONGOCRYPT_KMS_KMIP_ACTIVATE:
case MONGOCRYPT_KMS_KMIP_GET:
return set_and_ret ("kmip", len);
}
}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-log-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-log-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-log-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-log-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-log.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-log.c
similarity index 98%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-log.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-log.c
index 00553ff5..aac4b300 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-log.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-log.c
@@ -1,108 +1,111 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mongocrypt-config.h"
#include "mongocrypt-log-private.h"
#include "mongocrypt-opts-private.h"
#include <bson/bson.h>
void
_mongocrypt_log_init (_mongocrypt_log_t *log)
{
_mongocrypt_mutex_init (&log->mutex);
/* Initially, no log function is set. */
_mongocrypt_log_set_fn (log, NULL, NULL);
#ifdef MONGOCRYPT_ENABLE_TRACE
log->trace_enabled = (getenv ("MONGOCRYPT_TRACE") != NULL);
#endif
}
void
_mongocrypt_log_cleanup (_mongocrypt_log_t *log)
{
_mongocrypt_mutex_cleanup (&log->mutex);
memset (log, 0, sizeof (*log));
}
void
_mongocrypt_stdout_log_fn (mongocrypt_log_level_t level,
const char *message,
uint32_t message_len,
void *ctx)
{
switch (level) {
case MONGOCRYPT_LOG_LEVEL_FATAL:
printf ("FATAL");
break;
case MONGOCRYPT_LOG_LEVEL_ERROR:
printf ("ERROR");
break;
case MONGOCRYPT_LOG_LEVEL_WARNING:
printf ("WARNING");
break;
case MONGOCRYPT_LOG_LEVEL_INFO:
printf ("INFO");
break;
case MONGOCRYPT_LOG_LEVEL_TRACE:
printf ("TRACE");
break;
+ default:
+ printf ("UNKNOWN");
+ break;
}
printf (" %s\n", message);
}
void
_mongocrypt_log_set_fn (_mongocrypt_log_t *log,
mongocrypt_log_fn_t fn,
void *ctx)
{
_mongocrypt_mutex_lock (&log->mutex);
log->fn = fn;
log->ctx = ctx;
_mongocrypt_mutex_unlock (&log->mutex);
}
void
_mongocrypt_log (_mongocrypt_log_t *log,
mongocrypt_log_level_t level,
const char *format,
...)
{
va_list args;
char *message;
if (level == MONGOCRYPT_LOG_LEVEL_TRACE && !log->trace_enabled) {
return;
}
BSON_ASSERT (format);
va_start (args, format);
message = bson_strdupv_printf (format, args);
va_end (args);
BSON_ASSERT (message);
_mongocrypt_mutex_lock (&log->mutex);
if (log->fn) {
log->fn (level, message, (uint32_t) strlen (message), log->ctx);
}
_mongocrypt_mutex_unlock (&log->mutex);
bson_free (message);
}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-marking-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-marking-private.h
similarity index 74%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-marking-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-marking-private.h
index 1e43ad76..bf1b4756 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-marking-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-marking-private.h
@@ -1,53 +1,68 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_MARKING_PRIVATE_H
#define MONGOCRYPT_MARKING_PRIVATE_H
+#include "mc-fle2-encryption-placeholder-private.h"
#include "mongocrypt-private.h"
#include "mongocrypt-ciphertext-private.h"
+typedef enum {
+ MONGOCRYPT_MARKING_FLE1_BY_ID,
+ MONGOCRYPT_MARKING_FLE1_BY_ALTNAME,
+ MONGOCRYPT_MARKING_FLE2_ENCRYPTION,
+} mongocrypt_marking_type_t;
+
typedef struct {
- mongocrypt_encryption_algorithm_t algorithm;
- bson_iter_t v_iter;
- /* one of the following is zeroed, and the other is set. */
- _mongocrypt_buffer_t key_id;
- bson_value_t key_alt_name;
- bool has_alt_name;
+ mongocrypt_marking_type_t type;
+
+ union {
+ struct {
+ // Markings used by FLE1
+ mongocrypt_encryption_algorithm_t algorithm;
+ bson_iter_t v_iter;
+
+ _mongocrypt_buffer_t key_id;
+ bson_value_t key_alt_name;
+ };
+
+ mc_FLE2EncryptionPlaceholder_t fle2;
+ };
} _mongocrypt_marking_t;
void
_mongocrypt_marking_init (_mongocrypt_marking_t *marking);
void
_mongocrypt_marking_cleanup (_mongocrypt_marking_t *marking);
bool
_mongocrypt_marking_parse_unowned (const _mongocrypt_buffer_t *in,
_mongocrypt_marking_t *out,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_marking_to_ciphertext (void *ctx,
_mongocrypt_marking_t *marking,
_mongocrypt_ciphertext_t *ciphertext,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
#endif /* MONGOCRYPT_MARKING_PRIVATE_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-marking.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-marking.c
new file mode 100644
index 00000000..21192533
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-marking.c
@@ -0,0 +1,847 @@
+/*
+ * Copyright 2019-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mc-fle-blob-subtype-private.h"
+#include "mc-fle2-encryption-placeholder-private.h"
+#include "mc-fle2-find-equality-payload-private.h"
+#include "mc-fle2-insert-update-payload-private.h"
+#include "mc-fle2-payload-uev-private.h"
+#include "mc-tokens-private.h"
+#include "mongocrypt.h"
+#include "mongocrypt-buffer-private.h"
+#include "mongocrypt-ciphertext-private.h"
+#include "mongocrypt-crypto-private.h"
+#include "mongocrypt-key-broker-private.h"
+#include "mongocrypt-marking-private.h"
+
+static bool
+_mongocrypt_marking_parse_fle1_placeholder (const bson_t *in,
+ _mongocrypt_marking_t *out,
+ mongocrypt_status_t *status)
+{
+ bson_iter_t iter;
+ bool has_ki = false, has_ka = false, has_a = false, has_v = false;
+
+ out->type = MONGOCRYPT_MARKING_FLE1_BY_ID;
+
+ if (!bson_iter_init (&iter, in)) {
+ CLIENT_ERR ("invalid BSON");
+ return false;
+ }
+
+ while (bson_iter_next (&iter)) {
+ const char *field;
+
+ field = bson_iter_key (&iter);
+ BSON_ASSERT (field);
+ if (0 == strcmp ("ki", field)) {
+ has_ki = true;
+ if (!_mongocrypt_buffer_from_uuid_iter (&out->key_id, &iter)) {
+ CLIENT_ERR ("key id must be a UUID");
+ return false;
+ }
+ continue;
+ }
+
+ if (0 == strcmp ("ka", field)) {
+ has_ka = true;
+ /* Some bson_value types are not allowed to be key alt names */
+ const bson_value_t *value;
+
+ value = bson_iter_value (&iter);
+
+ if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
+ CLIENT_ERR ("key alt name must be a UTF8");
+ return false;
+ }
+ /* CDRIVER-3100 We must make a copy of this value; the result of
+ * bson_iter_value is ephemeral. */
+ bson_value_copy (value, &out->key_alt_name);
+ out->type = MONGOCRYPT_MARKING_FLE1_BY_ALTNAME;
+ continue;
+ }
+
+ if (0 == strcmp ("v", field)) {
+ has_v = true;
+ memcpy (&out->v_iter, &iter, sizeof (bson_iter_t));
+ continue;
+ }
+
+
+ if (0 == strcmp ("a", field)) {
+ int32_t algorithm;
+
+ has_a = true;
+ if (!BSON_ITER_HOLDS_INT32 (&iter)) {
+ CLIENT_ERR ("invalid marking, 'a' must be an int32");
+ return false;
+ }
+ algorithm = bson_iter_int32 (&iter);
+ if (algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC &&
+ algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM) {
+ CLIENT_ERR ("invalid algorithm value: %d", algorithm);
+ return false;
+ }
+ out->algorithm = (mongocrypt_encryption_algorithm_t) algorithm;
+ continue;
+ }
+
+ CLIENT_ERR ("unrecognized field '%s'", field);
+ return false;
+ }
+
+ if (!has_v) {
+ CLIENT_ERR ("no 'v' specified");
+ return false;
+ }
+
+ if (!has_ki && !has_ka) {
+ CLIENT_ERR ("neither 'ki' nor 'ka' specified");
+ return false;
+ }
+
+ if (has_ki && has_ka) {
+ CLIENT_ERR ("both 'ki' and 'ka' specified");
+ return false;
+ }
+
+ if (!has_a) {
+ CLIENT_ERR ("no 'a' specified");
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+_mongocrypt_marking_parse_fle2_placeholder (const bson_t *in,
+ _mongocrypt_marking_t *out,
+ mongocrypt_status_t *status)
+{
+ out->type = MONGOCRYPT_MARKING_FLE2_ENCRYPTION;
+ return mc_FLE2EncryptionPlaceholder_parse (&out->fle2, in, status);
+}
+
+bool
+_mongocrypt_marking_parse_unowned (const _mongocrypt_buffer_t *in,
+ _mongocrypt_marking_t *out,
+ mongocrypt_status_t *status)
+{
+ bson_t bson;
+
+ _mongocrypt_marking_init (out);
+ /* 5 for minimal BSON object, plus one for blob subtype */
+ if (in->len < 6) {
+ CLIENT_ERR ("invalid marking, length < 6");
+ return false;
+ }
+
+ if (!bson_init_static (&bson, in->data + 1, in->len - 1) ||
+ !bson_validate (&bson, BSON_VALIDATE_NONE, NULL)) {
+ CLIENT_ERR ("invalid BSON");
+ return false;
+ }
+
+ if (in->data[0] == MC_SUBTYPE_FLE1EncryptionPlaceholder) {
+ return _mongocrypt_marking_parse_fle1_placeholder (&bson, out, status);
+ } else if (in->data[0] == MC_SUBTYPE_FLE2EncryptionPlaceholder) {
+ return _mongocrypt_marking_parse_fle2_placeholder (&bson, out, status);
+ } else {
+ CLIENT_ERR ("invalid marking, first byte must be 0 or 3");
+ return false;
+ }
+}
+
+
+void
+_mongocrypt_marking_init (_mongocrypt_marking_t *marking)
+{
+ memset (marking, 0, sizeof (*marking));
+}
+
+
+void
+_mongocrypt_marking_cleanup (_mongocrypt_marking_t *marking)
+{
+ if (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION) {
+ mc_FLE2EncryptionPlaceholder_cleanup (&marking->fle2);
+ return;
+ }
+
+ // else FLE1
+ _mongocrypt_buffer_cleanup (&marking->key_id);
+ bson_value_destroy (&marking->key_alt_name);
+}
+
+
+/**
+ * Calculates:
+ * E?CToken = HMAC(collectionLevel1Token, n)
+ * E?CDerivedFromDataToken = HMAC(E?CToken, value)
+ * E?CDerivedFromDataTokenAndCounter = HMAC(E?CDerivedFromDataToken, c)
+ *
+ * E?C = EDC|ESC|ECC
+ * n = 1 for EDC, 2 for ESC, 3 for ECC
+ * c = maxContentionCounter
+ *
+ * E?CDerivedFromDataTokenAndCounter is saved to out,
+ * which is initialized even on failure.
+ */
+#define DERIVE_TOKEN_IMPL(Name) \
+ static bool _fle2_derive_##Name##_token ( \
+ _mongocrypt_crypto_t *crypto, \
+ _mongocrypt_buffer_t *out, \
+ const mc_CollectionsLevel1Token_t *level1Token, \
+ const _mongocrypt_buffer_t *value, \
+ bool useCounter, \
+ int64_t counter, \
+ mongocrypt_status_t *status) \
+ { \
+ _mongocrypt_buffer_init (out); \
+ \
+ mc_##Name##Token_t *token = \
+ mc_##Name##Token_new (crypto, level1Token, status); \
+ if (!token) { \
+ return false; \
+ } \
+ \
+ mc_##Name##DerivedFromDataToken_t *fromDataToken = \
+ mc_##Name##DerivedFromDataToken_new (crypto, token, value, status); \
+ mc_##Name##Token_destroy (token); \
+ if (!fromDataToken) { \
+ return false; \
+ } \
+ \
+ if (!useCounter) { \
+ /* FindEqualityPayload uses *fromDataToken */ \
+ _mongocrypt_buffer_copy_to ( \
+ mc_##Name##DerivedFromDataToken_get (fromDataToken), \
+ out); \
+ mc_##Name##DerivedFromDataToken_destroy (fromDataToken); \
+ return true; \
+ } \
+ \
+ /* InsertUpdatePayload continues through *fromDataTokenAndCounter */ \
+ mc_##Name##DerivedFromDataTokenAndCounter_t *fromTokenAndCounter = \
+ mc_##Name##DerivedFromDataTokenAndCounter_new ( \
+ crypto, fromDataToken, counter, status); \
+ mc_##Name##DerivedFromDataToken_destroy (fromDataToken); \
+ if (!fromTokenAndCounter) { \
+ return false; \
+ } \
+ \
+ _mongocrypt_buffer_copy_to ( \
+ mc_##Name##DerivedFromDataTokenAndCounter_get (fromTokenAndCounter), \
+ out); \
+ mc_##Name##DerivedFromDataTokenAndCounter_destroy (fromTokenAndCounter); \
+ \
+ return true; \
+ }
+
+DERIVE_TOKEN_IMPL (EDC)
+DERIVE_TOKEN_IMPL (ESC)
+DERIVE_TOKEN_IMPL (ECC)
+
+#undef DERIVE_TOKEN_IMPL
+
+static bool
+_fle2_placeholder_aes_ctr_encrypt (_mongocrypt_key_broker_t *kb,
+ const _mongocrypt_buffer_t *key,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
+ _mongocrypt_buffer_t iv;
+ const uint32_t cipherlen =
+ _mongocrypt_fle2_calculate_ciphertext_len (in->len);
+ uint32_t written = 0;
+
+ _mongocrypt_buffer_init_size (out, cipherlen);
+
+ BSON_ASSERT (
+ _mongocrypt_buffer_from_subrange (&iv, out, 0, MONGOCRYPT_IV_LEN));
+ if (!_mongocrypt_random (crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
+ return false;
+ }
+
+ if (!_mongocrypt_fle2_do_encryption (
+ crypto, &iv, key, in, out, &written, status)) {
+ _mongocrypt_buffer_cleanup (out);
+ _mongocrypt_buffer_init (out);
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool
+_fle2_placeholder_aead_encrypt (_mongocrypt_key_broker_t *kb,
+ const _mongocrypt_buffer_t *keyId,
+ const _mongocrypt_buffer_t *in,
+ _mongocrypt_buffer_t *out,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
+ _mongocrypt_buffer_t iv, key;
+ const uint32_t cipherlen =
+ _mongocrypt_fle2aead_calculate_ciphertext_len (in->len);
+ uint32_t written = 0;
+ bool res;
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, keyId, &key)) {
+ CLIENT_ERR ("unable to retrieve key");
+ return false;
+ }
+
+ _mongocrypt_buffer_init_size (&iv, MONGOCRYPT_IV_LEN);
+ if (!_mongocrypt_random (crypto, &iv, iv.len, status)) {
+ _mongocrypt_buffer_cleanup (&key);
+ return false;
+ }
+
+ _mongocrypt_buffer_init_size (out, cipherlen);
+ res = _mongocrypt_fle2aead_do_encryption (
+ crypto, &iv, keyId, &key, in, out, &written, status);
+ _mongocrypt_buffer_cleanup (&key);
+ _mongocrypt_buffer_cleanup (&iv);
+
+ if (!res) {
+ _mongocrypt_buffer_cleanup (out);
+ _mongocrypt_buffer_init (out);
+ return false;
+ }
+
+ return true;
+}
+
+
+// Field derivations shared by both INSERT and FIND payloads.
+typedef struct {
+ _mongocrypt_buffer_t tokenKey;
+ mc_CollectionsLevel1Token_t *collectionsLevel1Token;
+ _mongocrypt_buffer_t edcDerivedToken;
+ _mongocrypt_buffer_t escDerivedToken;
+ _mongocrypt_buffer_t eccDerivedToken;
+} _FLE2EncryptedPayloadCommon_t;
+
+static void
+_FLE2EncryptedPayloadCommon_cleanup (_FLE2EncryptedPayloadCommon_t *common)
+{
+ _mongocrypt_buffer_cleanup (&common->tokenKey);
+ mc_CollectionsLevel1Token_destroy (common->collectionsLevel1Token);
+ _mongocrypt_buffer_cleanup (&common->edcDerivedToken);
+ _mongocrypt_buffer_cleanup (&common->escDerivedToken);
+ _mongocrypt_buffer_cleanup (&common->eccDerivedToken);
+ memset (common, 0, sizeof (*common));
+}
+
+
+static bool
+_mongocrypt_fle2_placeholder_common (_mongocrypt_key_broker_t *kb,
+ _FLE2EncryptedPayloadCommon_t *ret,
+ const _mongocrypt_buffer_t *indexKeyId,
+ const _mongocrypt_buffer_t *value,
+ bool useCounter,
+ int64_t maxContentionCounter,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
+ _mongocrypt_buffer_t indexKey = {0};
+ memset (ret, 0, sizeof (*ret));
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (
+ kb, indexKeyId, &indexKey)) {
+ CLIENT_ERR ("unable to retreive key");
+ goto fail;
+ }
+
+ if (indexKey.len != MONGOCRYPT_KEY_LEN) {
+ CLIENT_ERR ("invalid indexKey, expected len=%" PRIu32
+ ", got len=%" PRIu32,
+ MONGOCRYPT_KEY_LEN,
+ indexKey.len);
+ goto fail;
+ }
+
+ // indexKey is 3 equal sized keys: [Ke][Km][TokenKey]
+ BSON_ASSERT (MONGOCRYPT_KEY_LEN == (3 * MONGOCRYPT_TOKEN_KEY_LEN));
+ if (!_mongocrypt_buffer_copy_from_data_and_size (
+ &ret->tokenKey,
+ indexKey.data + (2 * MONGOCRYPT_TOKEN_KEY_LEN),
+ MONGOCRYPT_TOKEN_KEY_LEN)) {
+ CLIENT_ERR ("failed allocating memory for token key");
+ goto fail;
+ }
+
+ ret->collectionsLevel1Token =
+ mc_CollectionsLevel1Token_new (crypto, &ret->tokenKey, status);
+ if (!ret->collectionsLevel1Token) {
+ CLIENT_ERR ("unable to derive collectionLevel1Token");
+ goto fail;
+ }
+
+ if (!_fle2_derive_EDC_token (crypto,
+ &ret->edcDerivedToken,
+ ret->collectionsLevel1Token,
+ value,
+ useCounter,
+ maxContentionCounter,
+ status)) {
+ goto fail;
+ }
+
+ if (!_fle2_derive_ESC_token (crypto,
+ &ret->escDerivedToken,
+ ret->collectionsLevel1Token,
+ value,
+ useCounter,
+ maxContentionCounter,
+ status)) {
+ goto fail;
+ }
+
+ if (!_fle2_derive_ECC_token (crypto,
+ &ret->eccDerivedToken,
+ ret->collectionsLevel1Token,
+ value,
+ useCounter,
+ maxContentionCounter,
+ status)) {
+ goto fail;
+ }
+
+ _mongocrypt_buffer_cleanup (&indexKey);
+ return true;
+
+fail:
+ _FLE2EncryptedPayloadCommon_cleanup (ret);
+ _mongocrypt_buffer_cleanup (&indexKey);
+ return false;
+}
+
+
+static bool
+_mongocrypt_fle2_placeholder_to_insert_update_ciphertext (
+ _mongocrypt_key_broker_t *kb,
+ _mongocrypt_marking_t *marking,
+ _mongocrypt_ciphertext_t *ciphertext,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
+ _mongocrypt_buffer_t value = {0};
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
+ mc_FLE2InsertUpdatePayload_t payload;
+ bool res = false;
+
+ BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
+ BSON_ASSERT (placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT);
+ _mongocrypt_ciphertext_init (ciphertext);
+ _mongocrypt_buffer_init (&value);
+ mc_FLE2InsertUpdatePayload_init (&payload);
+
+ _mongocrypt_buffer_from_iter (&value, &placeholder->v_iter);
+
+ int64_t contentionFactor = 0;
+ if (placeholder->maxContentionCounter > 0) {
+ /* Choose a random contentionFactor in the inclusive range [0,
+ * placeholder->maxContentionCounter] */
+ if (!_mongocrypt_random_int64 (crypto,
+ placeholder->maxContentionCounter + 1,
+ &contentionFactor,
+ status)) {
+ goto fail;
+ }
+ }
+
+ if (!_mongocrypt_fle2_placeholder_common (
+ kb,
+ &common,
+ &placeholder->index_key_id,
+ &value,
+ true, /* derive tokens using counter */
+ contentionFactor,
+ status)) {
+ goto fail;
+ }
+
+ // d := EDCDerivedToken
+ _mongocrypt_buffer_steal (&payload.edcDerivedToken, &common.edcDerivedToken);
+ // s := ESCDerivedToken
+ _mongocrypt_buffer_steal (&payload.escDerivedToken, &common.escDerivedToken);
+ // c := ECCDerivedToken
+ _mongocrypt_buffer_steal (&payload.eccDerivedToken, &common.eccDerivedToken);
+
+ // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndCounter ||
+ // ECCDerivedFromDataTokenAndCounter)
+ {
+ _mongocrypt_buffer_t tokens[] = {payload.escDerivedToken,
+ payload.eccDerivedToken};
+ _mongocrypt_buffer_t p;
+ _mongocrypt_buffer_concat (&p, tokens, 2);
+ mc_ECOCToken_t *ecocToken =
+ mc_ECOCToken_new (crypto, common.collectionsLevel1Token, status);
+ if (!ecocToken) {
+ _mongocrypt_buffer_cleanup (&p);
+ goto fail;
+ }
+ res = _fle2_placeholder_aes_ctr_encrypt (kb,
+ mc_ECOCToken_get (ecocToken),
+ &p,
+ &payload.encryptedTokens,
+ status);
+ _mongocrypt_buffer_cleanup (&p);
+ mc_ECOCToken_destroy (ecocToken);
+ if (!res) {
+ goto fail;
+ }
+ }
+
+ _mongocrypt_buffer_copy_to (&placeholder->index_key_id,
+ &payload.indexKeyId); // u
+ payload.valueType = bson_iter_type (&placeholder->v_iter); // t
+
+ // v := UserKeyId + EncryptAEAD(UserKey, value)
+ {
+ _mongocrypt_buffer_t tmp[2] = {placeholder->user_key_id, {0}};
+ if (!_fle2_placeholder_aead_encrypt (
+ kb, &placeholder->user_key_id, &value, &tmp[1], status)) {
+ goto fail;
+ }
+ res = _mongocrypt_buffer_concat (&payload.value, tmp, 2);
+ _mongocrypt_buffer_cleanup (&tmp[1]);
+ if (!res) {
+ goto fail;
+ }
+ }
+
+ // e := ServerDataEncryptionLevel1Token
+ {
+ mc_ServerDataEncryptionLevel1Token_t *serverToken =
+ mc_ServerDataEncryptionLevel1Token_new (
+ crypto, &common.tokenKey, status);
+ if (!serverToken) {
+ goto fail;
+ }
+ _mongocrypt_buffer_copy_to (
+ mc_ServerDataEncryptionLevel1Token_get (serverToken),
+ &payload.serverEncryptionToken);
+ mc_ServerDataEncryptionLevel1Token_destroy (serverToken);
+ }
+
+ {
+ bson_t out;
+ bson_init (&out);
+ mc_FLE2InsertUpdatePayload_serialize (&out, &payload);
+ _mongocrypt_buffer_steal_from_bson (&ciphertext->data, &out);
+ }
+ _mongocrypt_buffer_steal (&ciphertext->key_id, &payload.indexKeyId);
+ ciphertext->original_bson_type =
+ (uint8_t) bson_iter_type (&placeholder->v_iter);
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2InsertUpdatePayload;
+
+ res = true;
+fail:
+ mc_FLE2InsertUpdatePayload_cleanup (&payload);
+ _mongocrypt_buffer_cleanup (&value);
+ _FLE2EncryptedPayloadCommon_cleanup (&common);
+
+ return res;
+}
+
+
+static bool
+_mongocrypt_fle2_placeholder_to_find_ciphertext (
+ _mongocrypt_key_broker_t *kb,
+ _mongocrypt_marking_t *marking,
+ _mongocrypt_ciphertext_t *ciphertext,
+ mongocrypt_status_t *status)
+{
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
+ _mongocrypt_buffer_t value = {0};
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
+ mc_FLE2FindEqualityPayload_t payload;
+ bool res = false;
+
+ BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
+ BSON_ASSERT (placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
+ _mongocrypt_ciphertext_init (ciphertext);
+ _mongocrypt_buffer_init (&value);
+ mc_FLE2FindEqualityPayload_init (&payload);
+
+ _mongocrypt_buffer_from_iter (&value, &placeholder->v_iter);
+
+ if (!_mongocrypt_fle2_placeholder_common (kb,
+ &common,
+ &placeholder->index_key_id,
+ &value,
+ false, /* derive tokens without counter */
+ placeholder->maxContentionCounter,
+ status)) {
+ goto fail;
+ }
+
+ // d := EDCDerivedToken
+ _mongocrypt_buffer_steal (&payload.edcDerivedToken, &common.edcDerivedToken);
+ // s := ESCDerivedToken
+ _mongocrypt_buffer_steal (&payload.escDerivedToken, &common.escDerivedToken);
+ // c := ECCDerivedToken
+ _mongocrypt_buffer_steal (&payload.eccDerivedToken, &common.eccDerivedToken);
+
+ // e := ServerDataEncryptionLevel1Token
+ {
+ mc_ServerDataEncryptionLevel1Token_t *serverToken =
+ mc_ServerDataEncryptionLevel1Token_new (
+ kb->crypt->crypto, &common.tokenKey, status);
+ if (!serverToken) {
+ goto fail;
+ }
+ _mongocrypt_buffer_copy_to (
+ mc_ServerDataEncryptionLevel1Token_get (serverToken),
+ &payload.serverEncryptionToken);
+ mc_ServerDataEncryptionLevel1Token_destroy (serverToken);
+ }
+
+ payload.maxContentionCounter = placeholder->maxContentionCounter;
+
+ {
+ bson_t out;
+ bson_init (&out);
+ mc_FLE2FindEqualityPayload_serialize (&out, &payload);
+ _mongocrypt_buffer_steal_from_bson (&ciphertext->data, &out);
+ }
+ _mongocrypt_buffer_steal (&ciphertext->key_id, &placeholder->index_key_id);
+ ciphertext->original_bson_type =
+ (uint8_t) bson_iter_type (&placeholder->v_iter);
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindEqualityPayload;
+
+ res = true;
+fail:
+ mc_FLE2FindEqualityPayload_cleanup (&payload);
+ _mongocrypt_buffer_cleanup (&value);
+ _FLE2EncryptedPayloadCommon_cleanup (&common);
+
+ return res;
+}
+
+static bool
+_mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue (
+ _mongocrypt_key_broker_t *kb,
+ _mongocrypt_marking_t *marking,
+ _mongocrypt_ciphertext_t *ciphertext,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_buffer_t plaintext = {0};
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
+ _mongocrypt_buffer_t user_key = {0};
+ bool res = false;
+
+ BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
+ BSON_ASSERT (placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED);
+ _mongocrypt_ciphertext_init (ciphertext);
+ _mongocrypt_buffer_from_iter (&plaintext, &placeholder->v_iter);
+
+ if (!_mongocrypt_key_broker_decrypted_key_by_id (
+ kb, &placeholder->user_key_id, &user_key)) {
+ CLIENT_ERR ("unable to retreive key");
+ goto fail;
+ }
+
+ if (!mc_FLE2UnindexedEncryptedValue_encrypt (
+ kb->crypt->crypto,
+ &placeholder->user_key_id,
+ bson_iter_type (&placeholder->v_iter),
+ &plaintext,
+ &user_key,
+ &ciphertext->data,
+ status)) {
+ goto fail;
+ }
+
+ _mongocrypt_buffer_steal (&ciphertext->key_id, &placeholder->user_key_id);
+ ciphertext->original_bson_type =
+ (uint8_t) bson_iter_type (&placeholder->v_iter);
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2UnindexedEncryptedValue;
+ res = true;
+fail:
+ _mongocrypt_buffer_cleanup (&plaintext);
+ _mongocrypt_buffer_cleanup (&user_key);
+
+ return res;
+}
+
+static bool
+_mongocrypt_fle1_marking_to_ciphertext (_mongocrypt_key_broker_t *kb,
+ _mongocrypt_marking_t *marking,
+ _mongocrypt_ciphertext_t *ciphertext,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_buffer_t plaintext;
+ _mongocrypt_buffer_t iv;
+ _mongocrypt_buffer_t associated_data;
+ _mongocrypt_buffer_t key_material;
+ _mongocrypt_buffer_t key_id;
+ bool ret = false;
+ bool key_found;
+ uint32_t bytes_written;
+
+ BSON_ASSERT ((marking->type == MONGOCRYPT_MARKING_FLE1_BY_ID) ||
+ (marking->type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME));
+
+ _mongocrypt_buffer_init (&plaintext);
+ _mongocrypt_buffer_init (&associated_data);
+ _mongocrypt_buffer_init (&iv);
+ _mongocrypt_buffer_init (&key_id);
+ _mongocrypt_buffer_init (&key_material);
+
+ /* Get the decrypted key for this marking. */
+ if (marking->type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME) {
+ key_found = _mongocrypt_key_broker_decrypted_key_by_name (
+ kb, &marking->key_alt_name, &key_material, &key_id);
+ } else if (!_mongocrypt_buffer_empty (&marking->key_id)) {
+ key_found = _mongocrypt_key_broker_decrypted_key_by_id (
+ kb, &marking->key_id, &key_material);
+ _mongocrypt_buffer_copy_to (&marking->key_id, &key_id);
+ } else {
+ CLIENT_ERR ("marking must have either key_id or key_alt_name");
+ goto fail;
+ }
+
+ if (!key_found) {
+ _mongocrypt_status_copy_to (kb->status, status);
+ goto fail;
+ }
+
+ _mongocrypt_ciphertext_init (ciphertext);
+ ciphertext->original_bson_type = (uint8_t) bson_iter_type (&marking->v_iter);
+ if (marking->algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC) {
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE1DeterministicEncryptedValue;
+ } else {
+ BSON_ASSERT (marking->algorithm ==
+ MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM);
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE1RandomEncryptedValue;
+ }
+ _mongocrypt_buffer_copy_to (&key_id, &ciphertext->key_id);
+ if (!_mongocrypt_ciphertext_serialize_associated_data (ciphertext,
+ &associated_data)) {
+ CLIENT_ERR ("could not serialize associated data");
+ goto fail;
+ }
+
+ _mongocrypt_buffer_from_iter (&plaintext, &marking->v_iter);
+ ciphertext->data.len = _mongocrypt_calculate_ciphertext_len (plaintext.len);
+ ciphertext->data.data = bson_malloc (ciphertext->data.len);
+ BSON_ASSERT (ciphertext->data.data);
+
+ ciphertext->data.owned = true;
+
+ switch (marking->algorithm) {
+ case MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC:
+ /* Use deterministic encryption. */
+ _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
+ ret = _mongocrypt_calculate_deterministic_iv (kb->crypt->crypto,
+ &key_material,
+ &plaintext,
+ &associated_data,
+ &iv,
+ status);
+ if (!ret) {
+ goto fail;
+ }
+
+ ret = _mongocrypt_do_encryption (kb->crypt->crypto,
+ &iv,
+ &associated_data,
+ &key_material,
+ &plaintext,
+ &ciphertext->data,
+ &bytes_written,
+ status);
+ break;
+ case MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM:
+ /* Use randomized encryption.
+ * In this case, we must generate a new, random iv. */
+ _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
+ if (!_mongocrypt_random (
+ kb->crypt->crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
+ goto fail;
+ }
+ ret = _mongocrypt_do_encryption (kb->crypt->crypto,
+ &iv,
+ &associated_data,
+ &key_material,
+ &plaintext,
+ &ciphertext->data,
+ &bytes_written,
+ status);
+ break;
+ case MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE:
+ default:
+ /* Error. */
+ CLIENT_ERR ("Unsupported value for encryption algorithm");
+ goto fail;
+ }
+
+ if (!ret) {
+ goto fail;
+ }
+
+ BSON_ASSERT (bytes_written == ciphertext->data.len);
+
+ ret = true;
+
+fail:
+ _mongocrypt_buffer_cleanup (&iv);
+ _mongocrypt_buffer_cleanup (&key_id);
+ _mongocrypt_buffer_cleanup (&plaintext);
+ _mongocrypt_buffer_cleanup (&associated_data);
+ _mongocrypt_buffer_cleanup (&key_material);
+ return ret;
+}
+
+bool
+_mongocrypt_marking_to_ciphertext (void *ctx,
+ _mongocrypt_marking_t *marking,
+ _mongocrypt_ciphertext_t *ciphertext,
+ mongocrypt_status_t *status)
+{
+ _mongocrypt_key_broker_t *kb = (_mongocrypt_key_broker_t *) ctx;
+ BSON_ASSERT (marking);
+ BSON_ASSERT (ciphertext);
+ BSON_ASSERT (status);
+ BSON_ASSERT (ctx);
+
+ if (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION) {
+ if (marking->fle2.algorithm == MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED) {
+ return _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue (
+ kb, marking, ciphertext, status);
+ } else if (marking->fle2.type ==
+ MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT) {
+ return _mongocrypt_fle2_placeholder_to_insert_update_ciphertext (
+ kb, marking, ciphertext, status);
+ } else {
+ BSON_ASSERT (marking->fle2.type ==
+ MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
+ return _mongocrypt_fle2_placeholder_to_find_ciphertext (
+ kb, marking, ciphertext, status);
+ }
+ } else {
+ return _mongocrypt_fle1_marking_to_ciphertext (
+ kb, marking, ciphertext, status);
+ }
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-mutex-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-mutex-private.h
similarity index 80%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-mutex-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-mutex-private.h
index 4d1d7fc3..9ef4fc9d 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-mutex-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-mutex-private.h
@@ -1,41 +1,46 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_MUTEX_PRIVATE_H
#define MONGOCRYPT_MUTEX_PRIVATE_H
#include <bson/bson.h>
#if defined(BSON_OS_UNIX)
#include <pthread.h>
#define mongocrypt_mutex_t pthread_mutex_t
#else
#define mongocrypt_mutex_t CRITICAL_SECTION
#endif
void
_mongocrypt_mutex_init (mongocrypt_mutex_t *mutex);
void
_mongocrypt_mutex_cleanup (mongocrypt_mutex_t *mutex);
void
_mongocrypt_mutex_lock (mongocrypt_mutex_t *mutex);
void
_mongocrypt_mutex_unlock (mongocrypt_mutex_t *mutex);
+#define MONGOCRYPT_WITH_MUTEX(Mutex) \
+ for (int only_once = (_mongocrypt_mutex_lock (&(Mutex)), 1); only_once; \
+ _mongocrypt_mutex_unlock (&(Mutex))) \
+ for (; only_once; only_once = 0)
+
#endif /* MONGOCRYPT_MUTEX_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-opts-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-opts-private.h
similarity index 79%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-opts-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-opts-private.h
index e7a99719..c891bb47 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-opts-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-opts-private.h
@@ -1,200 +1,228 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_OPTS_PRIVATE_H
#define MONGOCRYPT_OPTS_PRIVATE_H
#include <bson/bson.h>
#include "mlib/str.h"
#include "mongocrypt.h"
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-log-private.h"
#include "mongocrypt-endpoint-private.h"
#include "mongocrypt-kek-private.h"
typedef struct {
char *tenant_id;
char *client_id;
char *client_secret;
_mongocrypt_endpoint_t *identity_platform_endpoint;
} _mongocrypt_opts_kms_provider_azure_t;
typedef struct {
char *email;
_mongocrypt_buffer_t private_key;
_mongocrypt_endpoint_t *endpoint;
} _mongocrypt_opts_kms_provider_gcp_t;
typedef struct {
char *secret_access_key;
char *access_key_id;
char *session_token;
} _mongocrypt_opts_kms_provider_aws_t;
typedef struct {
_mongocrypt_buffer_t key;
} _mongocrypt_opts_kms_provider_local_t;
typedef struct {
_mongocrypt_endpoint_t *endpoint;
} _mongocrypt_opts_kms_provider_kmip_t;
+typedef struct {
+ int configured_providers; /* A bit set of _mongocrypt_kms_provider_t */
+ int need_credentials; /* A bit set of _mongocrypt_kms_provider_t */
+ _mongocrypt_opts_kms_provider_local_t local;
+ _mongocrypt_opts_kms_provider_aws_t aws;
+ _mongocrypt_opts_kms_provider_azure_t azure;
+ _mongocrypt_opts_kms_provider_gcp_t gcp;
+ _mongocrypt_opts_kms_provider_kmip_t kmip;
+} _mongocrypt_opts_kms_providers_t;
+
typedef struct {
mongocrypt_log_fn_t log_fn;
void *log_ctx;
_mongocrypt_buffer_t schema_map;
+ _mongocrypt_buffer_t encrypted_field_config_map;
- int kms_providers; /* A bit set of _mongocrypt_kms_provider_t */
- _mongocrypt_opts_kms_provider_local_t kms_provider_local;
- _mongocrypt_opts_kms_provider_aws_t kms_provider_aws;
- _mongocrypt_opts_kms_provider_azure_t kms_provider_azure;
- _mongocrypt_opts_kms_provider_gcp_t kms_provider_gcp;
- _mongocrypt_opts_kms_provider_kmip_t kms_provider_kmip;
+ _mongocrypt_opts_kms_providers_t kms_providers;
mongocrypt_hmac_fn sign_rsaes_pkcs1_v1_5;
void *sign_ctx;
- /// Keep an array of search paths for finding the CSFLE dynamic library
+ /// Keep an array of search paths for finding the crypt_shared library
/// during mongocrypt_init()
- int n_cselib_search_paths;
- mstr *cselib_search_paths;
+ int n_crypt_shared_lib_search_paths;
+ mstr *crypt_shared_lib_search_paths;
/// Optionally, a user may override the default search behavior by specifying
/// a specifiy path to the library. If this is set, this suppresses the
/// search behavior.
- mstr csfle_lib_override_path;
+ mstr crypt_shared_lib_override_path;
+
+ bool use_need_kms_credentials_state;
+ bool bypass_query_analysis;
} _mongocrypt_opts_t;
+void
+_mongocrypt_opts_kms_providers_cleanup (
+ _mongocrypt_opts_kms_providers_t *kms_providers);
+
+
+/* Merge `source` into `dest`. Does not perform any memory ownership management;
+ * values in `dest` will be overwritten with values from `source` without
+ * being released. */
+void
+_mongocrypt_opts_merge_kms_providers (
+ _mongocrypt_opts_kms_providers_t *dest,
+ const _mongocrypt_opts_kms_providers_t *source);
+
void
_mongocrypt_opts_init (_mongocrypt_opts_t *opts);
void
_mongocrypt_opts_cleanup (_mongocrypt_opts_t *opts);
bool
_mongocrypt_opts_validate (_mongocrypt_opts_t *opts,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
+
+bool
+_mongocrypt_opts_kms_providers_validate (
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT;
+
/*
* Parse an optional UTF-8 value from BSON.
* @dotkey may be a dot separated key like: "a.b.c".
* @*out is set to a copy of the string if found, NULL otherwise. Caller must
* clean up with bson_free (*out).
* Returns true if no error occured.
*/
bool
_mongocrypt_parse_optional_utf8 (const bson_t *bson,
const char *dotkey,
char **out,
mongocrypt_status_t *status);
/*
* Parse a required UTF-8 value from BSON.
* @dotkey may be a dot separated key like: "a.b.c".
* @*out is set to a copy of the string if found, NULL otherwise. Caller must
* clean up with bson_free (*out).
* Returns true if no error occured.
*/
bool
_mongocrypt_parse_required_utf8 (const bson_t *bson,
const char *dotkey,
char **out,
mongocrypt_status_t *status);
/*
* Parse an optional endpoint UTF-8 from BSON.
* @dotkey may be a dot separated key like: "a.b.c".
* @*out is set to a new _mongocrypt_endpoint_t of the if found, NULL otherwise.
- * @*opts may be set to configure endpoint parsing. It is optional and may be NULL.
- * Caller must clean up with _mongocrypt_endpoint_destroy (*out).
- * Returns true if no error occured.
+ * @*opts may be set to configure endpoint parsing. It is optional and may be
+ * NULL. Caller must clean up with _mongocrypt_endpoint_destroy (*out). Returns
+ * true if no error occured.
*/
bool
_mongocrypt_parse_optional_endpoint (const bson_t *bson,
const char *dotkey,
_mongocrypt_endpoint_t **out,
_mongocrypt_endpoint_parse_opts_t *opts,
mongocrypt_status_t *status);
/*
* Parse a required endpoint UTF-8 from BSON.
* @dotkey may be a dot separated key like: "a.b.c".
* @*out is set to a new _mongocrypt_endpoint_t of the if found, NULL otherwise.
- * @*opts may be set to configure endpoint parsing. It is optional and may be NULL.
- * Caller must clean up with _mongocrypt_endpoint_destroy (*out).
- * Returns true if no error occured.
+ * @*opts may be set to configure endpoint parsing. It is optional and may be
+ * NULL. Caller must clean up with _mongocrypt_endpoint_destroy (*out). Returns
+ * true if no error occured.
*/
bool
_mongocrypt_parse_required_endpoint (const bson_t *bson,
const char *dotkey,
_mongocrypt_endpoint_t **out,
_mongocrypt_endpoint_parse_opts_t *opts,
mongocrypt_status_t *status);
/*
* Parse an optional binary type from BSON.
* The field parsed is accepted as:
* - A BSON binary value (of any subtype).
* - A BSON UTF-8 value, set to base64 encoded data.
*
* @dotkey may be a dot separated key like: "a.b.c"
* @out is initialized with the parsed data, or initialized to empty on error.
* Caller must clean up with _mongocrypt_buffer_cleanup (out).
* Returns true if no error occurred.
*/
bool
_mongocrypt_parse_optional_binary (const bson_t *bson,
const char *dotkey,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status);
/*
* Parse a required binary type from BSON.
* The field parsed is accepted as:
* - A BSON binary value (of any subtype).
* - A BSON UTF-8 value, set to base64 encoded data.
*
* @dotkey may be a dot separated key like: "a.b.c"
* @out is initialized with the parsed data, or initialized to empty on error.
* Caller must clean up with _mongocrypt_buffer_cleanup (out).
* Returns true if no error occurred.
*/
bool
_mongocrypt_parse_required_binary (const bson_t *bson,
const char *dotkey,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status);
/*
* Checks for unrecognized fields in parsing @bson.
* @dotkey is a dot separated path to a document field, like "a.b.c" or NULL.
* Pass a list of allowed fields.
* Returns true if no error occurred.
*/
bool
_mongocrypt_check_allowed_fields_va (const bson_t *bson,
const char *dotkey,
mongocrypt_status_t *status,
...);
#define _mongocrypt_check_allowed_fields(bson, path, status, ...) \
_mongocrypt_check_allowed_fields_va (bson, path, status, __VA_ARGS__, NULL)
#endif /* MONGOCRYPT_OPTS_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-opts.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-opts.c
similarity index 56%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-opts.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-opts.c
index 8bf30a8c..c78a6f83 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-opts.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-opts.c
@@ -1,296 +1,429 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongocrypt-opts-private.h"
#include "mongocrypt-log-private.h"
#include "mongocrypt-private.h"
#include <kms_message/kms_b64.h>
void
_mongocrypt_opts_init (_mongocrypt_opts_t *opts)
{
memset (opts, 0, sizeof (*opts));
}
static void
_mongocrypt_opts_kms_provider_azure_cleanup (
_mongocrypt_opts_kms_provider_azure_t *kms_provider_azure)
{
bson_free (kms_provider_azure->client_id);
bson_free (kms_provider_azure->client_secret);
bson_free (kms_provider_azure->tenant_id);
_mongocrypt_endpoint_destroy (
kms_provider_azure->identity_platform_endpoint);
}
static void
_mongocrypt_opts_kms_provider_gcp_cleanup (
_mongocrypt_opts_kms_provider_gcp_t *kms_provider_gcp)
{
bson_free (kms_provider_gcp->email);
_mongocrypt_endpoint_destroy (kms_provider_gcp->endpoint);
_mongocrypt_buffer_cleanup (&kms_provider_gcp->private_key);
}
+void
+_mongocrypt_opts_kms_providers_cleanup (
+ _mongocrypt_opts_kms_providers_t *kms_providers)
+{
+ bson_free (kms_providers->aws.secret_access_key);
+ bson_free (kms_providers->aws.access_key_id);
+ bson_free (kms_providers->aws.session_token);
+ _mongocrypt_buffer_cleanup (&kms_providers->local.key);
+ _mongocrypt_opts_kms_provider_azure_cleanup (&kms_providers->azure);
+ _mongocrypt_opts_kms_provider_gcp_cleanup (&kms_providers->gcp);
+ _mongocrypt_endpoint_destroy (kms_providers->kmip.endpoint);
+}
+
+
+void
+_mongocrypt_opts_merge_kms_providers (
+ _mongocrypt_opts_kms_providers_t *dest,
+ const _mongocrypt_opts_kms_providers_t *source)
+{
+ if (source->configured_providers & MONGOCRYPT_KMS_PROVIDER_AWS) {
+ memcpy (&dest->aws, &source->aws, sizeof (source->aws));
+ dest->configured_providers |= MONGOCRYPT_KMS_PROVIDER_AWS;
+ }
+ if (source->configured_providers & MONGOCRYPT_KMS_PROVIDER_LOCAL) {
+ memcpy (&dest->local, &source->local, sizeof (source->local));
+ dest->configured_providers |= MONGOCRYPT_KMS_PROVIDER_LOCAL;
+ }
+ if (source->configured_providers & MONGOCRYPT_KMS_PROVIDER_AZURE) {
+ memcpy (&dest->azure, &source->azure, sizeof (source->azure));
+ dest->configured_providers |= MONGOCRYPT_KMS_PROVIDER_AZURE;
+ }
+ if (source->configured_providers & MONGOCRYPT_KMS_PROVIDER_GCP) {
+ memcpy (&dest->gcp, &source->gcp, sizeof (source->gcp));
+ dest->configured_providers |= MONGOCRYPT_KMS_PROVIDER_GCP;
+ }
+ if (source->configured_providers & MONGOCRYPT_KMS_PROVIDER_KMIP) {
+ memcpy (&dest->kmip, &source->kmip, sizeof (source->kmip));
+ dest->configured_providers |= MONGOCRYPT_KMS_PROVIDER_KMIP;
+ }
+ /* ensure all providers were copied */
+ BSON_ASSERT (!(source->configured_providers & ~dest->configured_providers));
+}
+
+
void
_mongocrypt_opts_cleanup (_mongocrypt_opts_t *opts)
{
- bson_free (opts->kms_provider_aws.secret_access_key);
- bson_free (opts->kms_provider_aws.access_key_id);
- bson_free (opts->kms_provider_aws.session_token);
- _mongocrypt_buffer_cleanup (&opts->kms_provider_local.key);
+ _mongocrypt_opts_kms_providers_cleanup (&opts->kms_providers);
_mongocrypt_buffer_cleanup (&opts->schema_map);
- _mongocrypt_opts_kms_provider_azure_cleanup (&opts->kms_provider_azure);
- _mongocrypt_opts_kms_provider_gcp_cleanup (&opts->kms_provider_gcp);
- _mongocrypt_endpoint_destroy (opts->kms_provider_kmip.endpoint);
+ _mongocrypt_buffer_cleanup (&opts->encrypted_field_config_map);
// Free any lib search paths added by the caller
- for (int i = 0; i < opts->n_cselib_search_paths; ++i) {
- mstr_free (opts->cselib_search_paths[i]);
+ for (int i = 0; i < opts->n_crypt_shared_lib_search_paths; ++i) {
+ mstr_free (opts->crypt_shared_lib_search_paths[i]);
}
- bson_free (opts->cselib_search_paths);
- mstr_free (opts->csfle_lib_override_path);
+ bson_free (opts->crypt_shared_lib_search_paths);
+ mstr_free (opts->crypt_shared_lib_override_path);
}
bool
-_mongocrypt_opts_validate (_mongocrypt_opts_t *opts,
- mongocrypt_status_t *status)
+_mongocrypt_opts_kms_providers_validate (
+ _mongocrypt_opts_kms_providers_t *kms_providers, mongocrypt_status_t *status)
{
- if (!opts->kms_providers) {
+ if (!kms_providers->configured_providers &&
+ !kms_providers->need_credentials) {
CLIENT_ERR ("no kms provider set");
return false;
}
- if (opts->kms_providers & MONGOCRYPT_KMS_PROVIDER_AWS) {
- if (!opts->kms_provider_aws.access_key_id ||
- !opts->kms_provider_aws.secret_access_key) {
+ if (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_AWS) {
+ if (!kms_providers->aws.access_key_id ||
+ !kms_providers->aws.secret_access_key) {
CLIENT_ERR ("aws credentials unset");
return false;
}
}
- if (opts->kms_providers & MONGOCRYPT_KMS_PROVIDER_LOCAL) {
- if (_mongocrypt_buffer_empty (&opts->kms_provider_local.key)) {
+ if (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_LOCAL) {
+ if (_mongocrypt_buffer_empty (&kms_providers->local.key)) {
CLIENT_ERR ("local data key unset");
return false;
}
}
return true;
}
+/* _shares_bson_fields checks if @one or @two share any top-level field names.
+ * Returns false on error and sets @status. Returns true if no error
+ * occurred. Sets @found to the first shared field name found.
+ * If no shared field names are found, @found is set to NULL.
+ */
+static bool
+_shares_bson_fields (bson_t *one,
+ bson_t *two,
+ const char **found,
+ mongocrypt_status_t *status)
+{
+ bson_iter_t iter1;
+ bson_iter_t iter2;
+
+ *found = NULL;
+ if (!bson_iter_init (&iter1, one)) {
+ CLIENT_ERR ("error iterating one BSON in _shares_bson_fields");
+ return false;
+ }
+ while (bson_iter_next (&iter1)) {
+ const char *key1 = bson_iter_key (&iter1);
+
+ if (!bson_iter_init (&iter2, two)) {
+ CLIENT_ERR ("error iterating two BSON in _shares_bson_fields");
+ return false;
+ }
+ while (bson_iter_next (&iter2)) {
+ const char *key2 = bson_iter_key (&iter2);
+ if (0 == strcmp (key1, key2)) {
+ *found = key1;
+ return true;
+ }
+ }
+ }
+ return true;
+}
+
+/* _validate_encrypted_field_config_map_and_schema_map validates that the same
+ * namespace is not both in encrypted_field_config_map and schema_map. */
+bool
+_validate_encrypted_field_config_map_and_schema_map (
+ _mongocrypt_buffer_t *encrypted_field_config_map,
+ _mongocrypt_buffer_t *schema_map,
+ mongocrypt_status_t *status)
+{
+ const char *found;
+ bson_t schema_map_bson;
+ bson_t encrypted_field_config_map_bson;
+
+ /* If either map is unset, there is nothing to validate. Return true to
+ * signal no error. */
+ if (_mongocrypt_buffer_empty (encrypted_field_config_map)) {
+ return true;
+ }
+ if (_mongocrypt_buffer_empty (schema_map)) {
+ return true;
+ }
+
+ if (!_mongocrypt_buffer_to_bson (schema_map, &schema_map_bson)) {
+ CLIENT_ERR ("error converting schema_map to BSON");
+ return false;
+ }
+ if (!_mongocrypt_buffer_to_bson (encrypted_field_config_map,
+ &encrypted_field_config_map_bson)) {
+ CLIENT_ERR ("error converting encrypted_field_config_map to BSON");
+ return false;
+ }
+ if (!_shares_bson_fields (
+ &schema_map_bson, &encrypted_field_config_map_bson, &found, status)) {
+ return false;
+ }
+ if (found != NULL) {
+ CLIENT_ERR (
+ "%s is present in both schema_map and encrypted_field_config_map",
+ found);
+ return false;
+ }
+ return true;
+}
+
+
+bool
+_mongocrypt_opts_validate (_mongocrypt_opts_t *opts,
+ mongocrypt_status_t *status)
+{
+ if (!_validate_encrypted_field_config_map_and_schema_map (
+ &opts->encrypted_field_config_map, &opts->schema_map, status)) {
+ return false;
+ }
+ return _mongocrypt_opts_kms_providers_validate (&opts->kms_providers,
+ status);
+}
+
bool
_mongocrypt_parse_optional_utf8 (const bson_t *bson,
const char *dotkey,
char **out,
mongocrypt_status_t *status)
{
bson_iter_t iter;
bson_iter_t child;
*out = NULL;
if (!bson_iter_init (&iter, bson)) {
CLIENT_ERR ("invalid BSON");
return false;
}
if (!bson_iter_find_descendant (&iter, dotkey, &child)) {
/* Not found. Not an error. */
return true;
}
if (!BSON_ITER_HOLDS_UTF8 (&child)) {
CLIENT_ERR ("expected UTF-8 %s", dotkey);
return false;
}
*out = bson_strdup (bson_iter_utf8 (&child, NULL));
return true;
}
bool
_mongocrypt_parse_required_utf8 (const bson_t *bson,
const char *dotkey,
char **out,
mongocrypt_status_t *status)
{
if (!_mongocrypt_parse_optional_utf8 (bson, dotkey, out, status)) {
return false;
}
if (!*out) {
CLIENT_ERR ("expected UTF-8 %s", dotkey);
return false;
}
return true;
}
bool
_mongocrypt_parse_optional_endpoint (const bson_t *bson,
const char *dotkey,
_mongocrypt_endpoint_t **out,
_mongocrypt_endpoint_parse_opts_t *opts,
mongocrypt_status_t *status)
{
char *endpoint_raw;
*out = NULL;
if (!_mongocrypt_parse_optional_utf8 (bson, dotkey, &endpoint_raw, status)) {
return false;
}
/* Not found. Not an error. */
if (!endpoint_raw) {
return true;
}
*out = _mongocrypt_endpoint_new (endpoint_raw, -1, opts, status);
bson_free (endpoint_raw);
return (*out) != NULL;
}
bool
_mongocrypt_parse_required_endpoint (const bson_t *bson,
const char *dotkey,
_mongocrypt_endpoint_t **out,
_mongocrypt_endpoint_parse_opts_t *opts,
mongocrypt_status_t *status)
{
if (!_mongocrypt_parse_optional_endpoint (bson, dotkey, out, opts, status)) {
return false;
}
if (!*out) {
CLIENT_ERR ("expected endpoint %s", dotkey);
return false;
}
return true;
}
bool
_mongocrypt_parse_optional_binary (const bson_t *bson,
const char *dotkey,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status)
{
bson_iter_t iter;
bson_iter_t child;
_mongocrypt_buffer_init (out);
if (!bson_iter_init (&iter, bson)) {
CLIENT_ERR ("invalid BSON");
return false;
}
if (!bson_iter_find_descendant (&iter, dotkey, &child)) {
/* Not found. Not an error. */
return true;
}
if (BSON_ITER_HOLDS_UTF8 (&child)) {
size_t out_len;
/* Attempt to base64 decode. */
out->data =
kms_message_b64_to_raw (bson_iter_utf8 (&child, NULL), &out_len);
if (!out->data) {
CLIENT_ERR ("unable to parse base64 from UTF-8 field %s", dotkey);
return false;
}
out->len = (uint32_t) out_len;
out->owned = true;
} else if (BSON_ITER_HOLDS_BINARY (&child)) {
if (!_mongocrypt_buffer_copy_from_binary_iter (out, &child)) {
CLIENT_ERR ("unable to parse binary from field %s", dotkey);
return false;
}
} else {
CLIENT_ERR ("expected UTF-8 or binary %s", dotkey);
return false;
}
return true;
}
bool
_mongocrypt_parse_required_binary (const bson_t *bson,
const char *dotkey,
_mongocrypt_buffer_t *out,
mongocrypt_status_t *status)
{
if (!_mongocrypt_parse_optional_binary (bson, dotkey, out, status)) {
return false;
}
if (out->len == 0) {
CLIENT_ERR ("expected UTF-8 or binary %s", dotkey);
return false;
}
return true;
}
bool
_mongocrypt_check_allowed_fields_va (const bson_t *bson,
const char *dotkey,
mongocrypt_status_t *status,
...)
{
va_list args;
const char *field;
bson_iter_t iter;
if (dotkey) {
bson_iter_t parent;
bson_iter_init (&parent, bson);
if (!bson_iter_find_descendant (&parent, dotkey, &iter) ||
!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
CLIENT_ERR ("invalid BSON, expected %s", dotkey);
return false;
}
bson_iter_recurse (&iter, &iter);
} else {
bson_iter_init (&iter, bson);
}
while (bson_iter_next (&iter)) {
bool found = false;
va_start (args, status);
field = va_arg (args, const char *);
while (field) {
if (0 == strcmp (field, bson_iter_key (&iter))) {
found = true;
break;
}
field = va_arg (args, const char *);
}
va_end (args);
if (!found) {
CLIENT_ERR ("Unexpected field: '%s'", bson_iter_key (&iter));
return false;
}
}
return true;
-}
\ No newline at end of file
+}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-private.h
similarity index 68%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-private.h
index 97916000..58484da6 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-private.h
@@ -1,158 +1,185 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_PRIVATE_H
#define MONGOCRYPT_PRIVATE_H
#include "mongocrypt.h"
#include "mongocrypt-config.h"
#include "bson/bson.h"
#include "mongocrypt-dll-private.h"
#include "mongocrypt-log-private.h"
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-cache-private.h"
#include "mongocrypt-cache-key-private.h"
#include "mongocrypt-mutex-private.h"
#include "mongocrypt-opts-private.h"
#include "mongocrypt-crypto-private.h"
#include "mongocrypt-cache-oauth-private.h"
-#include "mongo_csfle-v1.h"
+#include "mongo_crypt-v1.h"
#define MONGOCRYPT_GENERIC_ERROR_CODE 1
#define CLIENT_ERR_W_CODE(code, ...) \
_mongocrypt_set_error ( \
status, MONGOCRYPT_STATUS_ERROR_CLIENT, code, __VA_ARGS__)
#define CLIENT_ERR(...) \
CLIENT_ERR_W_CODE (MONGOCRYPT_GENERIC_ERROR_CODE, __VA_ARGS__)
#define KMS_ERR_W_CODE(code, ...) \
_mongocrypt_set_error ( \
status, MONGOCRYPT_STATUS_ERROR_KMS, code, __VA_ARGS__)
#define KMS_ERR(...) KMS_ERR_W_CODE (MONGOCRYPT_GENERIC_ERROR_CODE, __VA_ARGS__)
#define MONGOCRYPT_STR_AND_LEN(x) (x), (sizeof (x) / sizeof ((x)[0]) - 1)
#define MONGOCRYPT_DATA_AND_LEN(x) \
((uint8_t *) x), (sizeof (x) / sizeof ((x)[0]) - 1)
/* TODO: remove after integrating into libmongoc */
#define BSON_SUBTYPE_ENCRYPTED 6
/* TODO: Move these to mongocrypt-log-private.h? */
const char *
tmp_json (const bson_t *bson);
const char *
tmp_buf (const _mongocrypt_buffer_t *buf);
void
_mongocrypt_set_error (mongocrypt_status_t *status,
mongocrypt_status_type_t type,
uint32_t code,
const char *format,
...);
-typedef struct _mcr_csfle_v1_vtable {
+typedef struct _mongo_crypt_v1_vtable {
#define MONGOC_CSFLE_FUNCTIONS_X \
/* status methods */ \
- X_FUNC (status_create, mongo_csfle_v1_status *, void) \
- X_FUNC (status_destroy, void, mongo_csfle_v1_status *status) \
- X_FUNC (status_get_error, int, const mongo_csfle_v1_status *status) \
+ X_FUNC (status_create, mongo_crypt_v1_status *, void) \
+ X_FUNC (status_destroy, void, mongo_crypt_v1_status *status) \
+ X_FUNC (status_get_error, int, const mongo_crypt_v1_status *status) \
X_FUNC (status_get_explanation, \
const char *, \
- const mongo_csfle_v1_status *status) \
- X_FUNC (status_get_code, int, const mongo_csfle_v1_status *status) \
+ const mongo_crypt_v1_status *status) \
+ X_FUNC (status_get_code, int, const mongo_crypt_v1_status *status) \
/* lib methods */ \
- X_FUNC (lib_create, mongo_csfle_v1_lib *, mongo_csfle_v1_status *status) \
+ X_FUNC (lib_create, mongo_crypt_v1_lib *, mongo_crypt_v1_status *status) \
X_FUNC (lib_destroy, \
int, \
- mongo_csfle_v1_lib *lib, \
- mongo_csfle_v1_status *status) \
+ mongo_crypt_v1_lib *lib, \
+ mongo_crypt_v1_status *status) \
/* query_analyzer methods */ \
X_FUNC (query_analyzer_create, \
- mongo_csfle_v1_query_analyzer *, \
- mongo_csfle_v1_lib *lib, \
- mongo_csfle_v1_status *status) \
+ mongo_crypt_v1_query_analyzer *, \
+ mongo_crypt_v1_lib *lib, \
+ mongo_crypt_v1_status *status) \
X_FUNC ( \
- query_analyzer_destroy, void, mongo_csfle_v1_query_analyzer *analyzer) \
+ query_analyzer_destroy, void, mongo_crypt_v1_query_analyzer *analyzer) \
X_FUNC (analyze_query, \
uint8_t *, \
- mongo_csfle_v1_query_analyzer *analyer, \
+ mongo_crypt_v1_query_analyzer *analyer, \
const uint8_t *documentBSON, \
const char *ns_str, \
uint32_t ns_len, \
uint32_t *bson_len, \
- mongo_csfle_v1_status *status) \
+ mongo_crypt_v1_status *status) \
+ X_FUNC (get_version, uint64_t, void) \
+ X_FUNC (get_version_str, const char *, void) \
/* Free bson data created by csfle */ \
X_FUNC (bson_free, void, uint8_t *bson)
- /// At time of writing, these two symbols seem to be missing from the CSFLE
- /// build, despite documentation in the csfle header (Refer: SERVER-63680):
- // X_FUNC (get_version, uint64_t, void)
- // X_FUNC (get_version_str, const char *, void)
-
#define X_FUNC(Name, RetType, ...) RetType (*Name) (__VA_ARGS__);
MONGOC_CSFLE_FUNCTIONS_X
#undef X_FUNC
-} _mcr_csfle_v1_vtable;
-
+ /// Whether the vtable is valid and complete
+ bool okay;
+} _mongo_crypt_v1_vtable;
struct _mongocrypt_t {
bool initialized;
_mongocrypt_opts_t opts;
mongocrypt_mutex_t mutex;
/* The collinfo and key cache are protected with an internal mutex. */
_mongocrypt_cache_t cache_collinfo;
_mongocrypt_cache_t cache_key;
_mongocrypt_log_t log;
mongocrypt_status_t *status;
_mongocrypt_crypto_t *crypto;
/* A counter, protected by mutex, for generating unique context ids */
uint32_t ctx_counter;
_mongocrypt_cache_oauth_t *cache_oauth_azure;
_mongocrypt_cache_oauth_t *cache_oauth_gcp;
- /// A CSFLE DLL, initialized by mongocrypt_init
- mcr_dll csfle_lib;
- _mcr_csfle_v1_vtable csfle_vtable;
+ /// A CSFLE DLL vtable, initialized by mongocrypt_init
+ _mongo_crypt_v1_vtable csfle;
+ /// Pointer to the global csfle_lib object. Should not be freed directly.
+ mongo_crypt_v1_lib *csfle_lib;
};
typedef enum {
MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE = 0,
MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC = 1,
MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM = 2
} mongocrypt_encryption_algorithm_t;
+typedef enum {
+ MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT = 1,
+ MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND = 2
+} mongocrypt_fle2_placeholder_type_t;
+
+typedef enum {
+ MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED = 1,
+ MONGOCRYPT_FLE2_ALGORITHM_EQUALITY = 2
+} mongocrypt_fle2_encryption_algorithm_t;
bool
_mongocrypt_validate_and_copy_string (const char *in,
int32_t in_len,
char **out) MONGOCRYPT_WARN_UNUSED_RESULT;
char *
_mongocrypt_new_string_from_bytes (const void *in, int len);
char *
_mongocrypt_new_json_string_from_binary (mongocrypt_binary_t *binary);
+
+bool
+_mongocrypt_parse_kms_providers (
+ mongocrypt_binary_t *kms_providers_definition,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ mongocrypt_status_t *status,
+ _mongocrypt_log_t *log);
+
+/* _mongocrypt_needs_credentials returns true if @crypt was configured to
+ * request credentials for any KMS provider. */
+bool
+_mongocrypt_needs_credentials (mongocrypt_t *crypt);
+
+/* _mongocrypt_needs_credentials returns true if @crypt was configured to
+ * request credentials for @provider. */
+bool
+_mongocrypt_needs_credentials_for_provider (
+ mongocrypt_t *crypt, _mongocrypt_kms_provider_t provider);
+
#endif /* MONGOCRYPT_PRIVATE_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-status-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-status-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-status-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-status-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-status.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-status.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-status.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-status.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-traverse-util-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
similarity index 97%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
index 84b99b33..c14a2eab 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-traverse-util-private.h
@@ -1,58 +1,59 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_TRAVERSE_UTIL_H
#define MONGOCRYPT_TRAVERSE_UTIL_H
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-status-private.h"
typedef enum {
TRAVERSE_MATCH_CIPHERTEXT,
- TRAVERSE_MATCH_MARKING
+ TRAVERSE_MATCH_MARKING,
+ TRAVERSE_MATCH_SUBTYPE6,
} traversal_match_t;
typedef bool (*_mongocrypt_traverse_callback_t) (void *ctx,
_mongocrypt_buffer_t *in,
mongocrypt_status_t *status);
typedef bool (*_mongocrypt_transform_callback_t) (void *ctx,
_mongocrypt_buffer_t *in,
bson_value_t *out,
mongocrypt_status_t *status);
bool
_mongocrypt_traverse_binary_in_bson (_mongocrypt_traverse_callback_t cb,
void *ctx,
traversal_match_t match,
bson_iter_t *iter,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
bool
_mongocrypt_transform_binary_in_bson (_mongocrypt_transform_callback_t cb,
void *ctx,
traversal_match_t match,
bson_iter_t *iter,
bson_t *out,
mongocrypt_status_t *status)
MONGOCRYPT_WARN_UNUSED_RESULT;
#endif /* MONGOCRYPT_TRAVERSE_UTIL_H */
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-traverse-util.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-traverse-util.c
similarity index 92%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-traverse-util.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-traverse-util.c
index a4470077..d9442257 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-traverse-util.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-traverse-util.c
@@ -1,216 +1,222 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bson/bson.h>
#include "mongocrypt-buffer-private.h"
#include "mongocrypt-log-private.h"
#include "mongocrypt-private.h"
#include "mongocrypt-status-private.h"
#include "mongocrypt-traverse-util-private.h"
+#include "mc-fle-blob-subtype-private.h"
typedef struct {
void *ctx;
bson_iter_t iter;
bson_t *copy; /* implies transform */
char *path; /* only enabled during tracing. */
_mongocrypt_traverse_callback_t traverse_cb;
_mongocrypt_transform_callback_t transform_cb;
mongocrypt_status_t *status;
traversal_match_t match;
bson_t child;
} _recurse_state_t;
static bool
_check_first_byte (uint8_t byte, traversal_match_t match)
{
-#define FIRST_BYTE_MARKING 0
-#define FIRST_BYTE_DETERMINISTIC 1
-#define FIRST_BYTE_RANDOMIZED 2
-
switch (match) {
case TRAVERSE_MATCH_MARKING:
- return byte == FIRST_BYTE_MARKING;
+ return byte == MC_SUBTYPE_FLE1EncryptionPlaceholder ||
+ byte == MC_SUBTYPE_FLE2EncryptionPlaceholder;
case TRAVERSE_MATCH_CIPHERTEXT:
- return byte == FIRST_BYTE_DETERMINISTIC || byte == FIRST_BYTE_RANDOMIZED;
+ return byte == MC_SUBTYPE_FLE1DeterministicEncryptedValue ||
+ byte == MC_SUBTYPE_FLE1RandomEncryptedValue ||
+ byte == MC_SUBTYPE_FLE2IndexedEqualityEncryptedValue ||
+ byte == MC_SUBTYPE_FLE2UnindexedEncryptedValue ||
+ byte == MC_SUBTYPE_FLE2InsertUpdatePayload;
+ case TRAVERSE_MATCH_SUBTYPE6:
+ return true;
+ default:
+ break;
}
return false;
}
static bool
_recurse (_recurse_state_t *state)
{
mongocrypt_status_t *status;
status = state->status;
while (bson_iter_next (&state->iter)) {
if (BSON_ITER_HOLDS_BINARY (&state->iter)) {
_mongocrypt_buffer_t value;
BSON_ASSERT (
_mongocrypt_buffer_from_binary_iter (&value, &state->iter));
if (value.subtype == 6 && value.len > 0 &&
_check_first_byte (value.data[0], state->match)) {
bool ret;
/* call the right callback. */
if (state->copy) {
bson_value_t value_out;
ret =
state->transform_cb (state->ctx, &value, &value_out, status);
if (ret) {
bson_append_value (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
&value_out);
bson_value_destroy (&value_out);
}
} else {
ret = state->traverse_cb (state->ctx, &value, status);
}
if (!ret) {
return false;
}
continue;
}
/* fall through and copy */
}
if (BSON_ITER_HOLDS_ARRAY (&state->iter)) {
_recurse_state_t child_state;
bool ret;
memcpy (&child_state, state, sizeof (_recurse_state_t));
if (!bson_iter_recurse (&state->iter, &child_state.iter)) {
CLIENT_ERR ("error recursing into array");
return false;
}
if (state->copy) {
bson_append_array_begin (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
&state->child);
child_state.copy = &state->child;
}
ret = _recurse (&child_state);
if (state->copy) {
bson_append_array_end (state->copy, &state->child);
}
if (!ret) {
return false;
}
continue;
}
if (BSON_ITER_HOLDS_DOCUMENT (&state->iter)) {
_recurse_state_t child_state;
bool ret;
memcpy (&child_state, state, sizeof (_recurse_state_t));
if (!bson_iter_recurse (&state->iter, &child_state.iter)) {
CLIENT_ERR ("error recursing into document");
return false;
}
/* TODO: check for errors everywhere. */
if (state->copy) {
bson_append_document_begin (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
&state->child);
child_state.copy = &state->child;
}
ret = _recurse (&child_state);
if (state->copy) {
if (!bson_append_document_end (state->copy, &state->child)) {
CLIENT_ERR ("error appending document");
return false;
}
}
if (!ret) {
return false;
}
continue;
}
if (state->copy) {
bson_append_value (state->copy,
bson_iter_key (&state->iter),
bson_iter_key_len (&state->iter),
bson_iter_value (&state->iter));
}
}
return true;
}
bool
_mongocrypt_transform_binary_in_bson (_mongocrypt_transform_callback_t cb,
void *ctx,
traversal_match_t match,
bson_iter_t *iter,
bson_t *out,
mongocrypt_status_t *status)
{
_recurse_state_t starting_state = {ctx,
*iter,
out /* copy */,
NULL /* path */,
NULL /* traverse callback */,
cb,
status,
match,
{0}};
return _recurse (&starting_state);
}
/*-----------------------------------------------------------------------------
*
* _mongocrypt_traverse_binary_in_bson
*
* Traverse the BSON being iterated with iter, and call cb for every binary
* subtype 06 value where the first byte corresponds to 'match'.
*
* Return:
* True on success. Returns false on failure and sets error.
*
*-----------------------------------------------------------------------------
*/
bool
_mongocrypt_traverse_binary_in_bson (_mongocrypt_traverse_callback_t cb,
void *ctx,
traversal_match_t match,
bson_iter_t *iter,
mongocrypt_status_t *status)
{
_recurse_state_t starting_state = {ctx,
*iter,
NULL /* copy */,
NULL /* path */,
cb,
NULL /* transform callback */,
status,
match,
{0}};
return _recurse (&starting_state);
}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-util-private.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-util-private.h
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-util-private.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-util-private.h
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-util.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-util.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt-util.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt-util.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.c b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt.c
similarity index 51%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.c
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt.c
index 7292e287..2360958d 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt.c
@@ -1,1008 +1,1545 @@
/*
* Copyright 2018-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mlib/thread.h"
#include "mlib/path.h"
#include "mlib/error.h"
#include <kms_message/kms_message.h>
#include <bson/bson.h>
#include "mongocrypt-private.h"
#include "mongocrypt-binary-private.h"
#include "mongocrypt-cache-collinfo-private.h"
#include "mongocrypt-cache-key-private.h"
#include "mongocrypt-config.h"
#include "mongocrypt-crypto-private.h"
#include "mongocrypt-log-private.h"
+#include "mongocrypt-mutex-private.h"
#include "mongocrypt-opts-private.h"
#include "mongocrypt-status-private.h"
#include "mongocrypt-util-private.h"
/* Assert size for interop with wrapper purposes */
BSON_STATIC_ASSERT (sizeof (mongocrypt_log_level_t) == 4);
const char *
mongocrypt_version (uint32_t *len)
{
if (len) {
*len = (uint32_t) strlen (MONGOCRYPT_VERSION);
}
return MONGOCRYPT_VERSION;
}
void
_mongocrypt_set_error (mongocrypt_status_t *status,
mongocrypt_status_type_t type,
uint32_t code,
const char *format,
...)
{
va_list args;
char *prepared_message;
if (status) {
va_start (args, format);
prepared_message = bson_strdupv_printf (format, args);
if (!prepared_message) {
mongocrypt_status_set (status, type, code, "Out of memory", -1);
} else {
mongocrypt_status_set (status, type, code, prepared_message, -1);
bson_free (prepared_message);
}
va_end (args);
}
}
const char *
tmp_json (const bson_t *bson)
{
static char storage[1024];
char *json;
memset (storage, 0, 1024);
json = bson_as_canonical_extended_json (bson, NULL);
bson_snprintf (storage, sizeof (storage), "%s", json);
bson_free (json);
return (const char *) storage;
}
const char *
tmp_buf (const _mongocrypt_buffer_t *buf)
{
static char storage[1024];
uint32_t i, n;
memset (storage, 0, 1024);
/* capped at two characters per byte, minus 1 for trailing \0 */
n = sizeof (storage) / 2 - 1;
if (buf->len < n) {
n = buf->len;
}
for (i = 0; i < n; i++) {
bson_snprintf (storage + (i * 2), 3, "%02x", buf->data[i]);
}
return (const char *) storage;
}
void
_mongocrypt_do_init (void)
{
(void) kms_message_init ();
_native_crypto_init ();
}
mongocrypt_t *
mongocrypt_new (void)
{
mongocrypt_t *crypt;
crypt = bson_malloc0 (sizeof (mongocrypt_t));
BSON_ASSERT (crypt);
+ crypt->crypto = bson_malloc0 (sizeof (*crypt->crypto));
+ BSON_ASSERT (crypt->crypto);
_mongocrypt_mutex_init (&crypt->mutex);
_mongocrypt_cache_collinfo_init (&crypt->cache_collinfo);
_mongocrypt_cache_key_init (&crypt->cache_key);
crypt->status = mongocrypt_status_new ();
_mongocrypt_opts_init (&crypt->opts);
_mongocrypt_log_init (&crypt->log);
crypt->ctx_counter = 1;
crypt->cache_oauth_azure = _mongocrypt_cache_oauth_new ();
crypt->cache_oauth_gcp = _mongocrypt_cache_oauth_new ();
- crypt->csfle_lib = MCR_DLL_NULL;
+ crypt->csfle = (_mongo_crypt_v1_vtable){.okay = false};
static mlib_once_flag init_flag = MLIB_ONCE_INITIALIZER;
if (!mlib_call_once (&init_flag, _mongocrypt_do_init) ||
!_native_crypto_initialized) {
mongocrypt_status_t *status = crypt->status;
CLIENT_ERR ("failed to initialize");
/* Return crypt with failure status so caller can obtain error when
* calling mongocrypt_init */
}
return crypt;
}
bool
mongocrypt_setopt_log_handler (mongocrypt_t *crypt,
mongocrypt_log_fn_t log_fn,
void *log_ctx)
{
if (!crypt) {
return false;
}
if (crypt->initialized) {
mongocrypt_status_t *status = crypt->status;
CLIENT_ERR ("options cannot be set after initialization");
return false;
}
crypt->opts.log_fn = log_fn;
crypt->opts.log_ctx = log_ctx;
return true;
}
bool
mongocrypt_setopt_kms_provider_aws (mongocrypt_t *crypt,
const char *aws_access_key_id,
int32_t aws_access_key_id_len,
const char *aws_secret_access_key,
int32_t aws_secret_access_key_len)
{
mongocrypt_status_t *status;
+ _mongocrypt_opts_kms_providers_t *const kms_providers =
+ &crypt->opts.kms_providers;
if (!crypt) {
return false;
}
status = crypt->status;
if (crypt->initialized) {
CLIENT_ERR ("options cannot be set after initialization");
return false;
}
- if (0 != (crypt->opts.kms_providers & MONGOCRYPT_KMS_PROVIDER_AWS)) {
+ if (0 !=
+ (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_AWS)) {
CLIENT_ERR ("aws kms provider already set");
return false;
}
if (!_mongocrypt_validate_and_copy_string (
aws_access_key_id,
aws_access_key_id_len,
- &crypt->opts.kms_provider_aws.access_key_id)) {
+ &kms_providers->aws.access_key_id)) {
CLIENT_ERR ("invalid aws access key id");
return false;
}
if (!_mongocrypt_validate_and_copy_string (
aws_secret_access_key,
aws_secret_access_key_len,
- &crypt->opts.kms_provider_aws.secret_access_key)) {
+ &kms_providers->aws.secret_access_key)) {
CLIENT_ERR ("invalid aws secret access key");
return false;
}
if (crypt->log.trace_enabled) {
_mongocrypt_log (&crypt->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%s\", %s=%d, %s=\"%s\", %s=%d)",
BSON_FUNC,
"aws_access_key_id",
- crypt->opts.kms_provider_aws.access_key_id,
+ kms_providers->aws.access_key_id,
"aws_access_key_id_len",
aws_access_key_id_len,
"aws_secret_access_key",
- crypt->opts.kms_provider_aws.secret_access_key,
+ kms_providers->aws.secret_access_key,
"aws_secret_access_key_len",
aws_secret_access_key_len);
}
- crypt->opts.kms_providers |= MONGOCRYPT_KMS_PROVIDER_AWS;
+ kms_providers->configured_providers |= MONGOCRYPT_KMS_PROVIDER_AWS;
return true;
}
char *
_mongocrypt_new_string_from_bytes (const void *in, int len)
{
const int max_bytes = 100;
const int chars_per_byte = 2;
int out_size = max_bytes * chars_per_byte;
const unsigned char *src = in;
char *out;
char *ret;
out_size += len > max_bytes ? sizeof ("...") : 1 /* for null */;
out = bson_malloc0 (out_size);
BSON_ASSERT (out);
ret = out;
for (int i = 0; i < len && i < max_bytes; i++, out += chars_per_byte) {
sprintf (out, "%02X", src[i]);
}
sprintf (out, (len > max_bytes) ? "..." : "");
return ret;
}
char *
_mongocrypt_new_json_string_from_binary (mongocrypt_binary_t *binary)
{
bson_t bson;
uint32_t len;
if (!_mongocrypt_binary_to_bson (binary, &bson) ||
!bson_validate (&bson, BSON_VALIDATE_NONE, NULL)) {
char *hex;
char *full_str;
hex = _mongocrypt_new_string_from_bytes (binary->data, binary->len);
full_str = bson_strdup_printf ("(malformed) %s", hex);
bson_free (hex);
return full_str;
}
return bson_as_canonical_extended_json (&bson, (size_t *) &len);
}
bool
mongocrypt_setopt_schema_map (mongocrypt_t *crypt,
mongocrypt_binary_t *schema_map)
{
bson_t tmp;
bson_error_t bson_err;
mongocrypt_status_t *status;
if (!crypt) {
return false;
}
status = crypt->status;
if (crypt->initialized) {
CLIENT_ERR ("options cannot be set after initialization");
return false;
}
if (!schema_map || !mongocrypt_binary_data (schema_map)) {
CLIENT_ERR ("passed null schema map");
return false;
}
if (!_mongocrypt_buffer_empty (&crypt->opts.schema_map)) {
CLIENT_ERR ("already set schema map");
return false;
}
_mongocrypt_buffer_copy_from_binary (&crypt->opts.schema_map, schema_map);
/* validate bson */
if (!_mongocrypt_buffer_to_bson (&crypt->opts.schema_map, &tmp)) {
CLIENT_ERR ("invalid bson");
return false;
}
if (!bson_validate_with_error (&tmp, BSON_VALIDATE_NONE, &bson_err)) {
CLIENT_ERR (bson_err.message);
return false;
}
return true;
}
+bool
+mongocrypt_setopt_encrypted_field_config_map (mongocrypt_t *crypt,
+ mongocrypt_binary_t *efc_map)
+{
+ mongocrypt_status_t *status;
+ bson_t as_bson;
+ bson_error_t bson_err;
+
+ if (!crypt) {
+ return false;
+ }
+ status = crypt->status;
+
+ if (crypt->initialized) {
+ CLIENT_ERR ("options cannot be set after initialization");
+ return false;
+ }
+
+ if (!efc_map || !mongocrypt_binary_data (efc_map)) {
+ CLIENT_ERR ("passed null encrypted_field_config_map");
+ return false;
+ }
+
+ if (!_mongocrypt_buffer_empty (&crypt->opts.encrypted_field_config_map)) {
+ CLIENT_ERR ("already set encrypted_field_config_map");
+ return false;
+ }
+
+ _mongocrypt_buffer_copy_from_binary (&crypt->opts.encrypted_field_config_map,
+ efc_map);
+
+ /* validate bson */
+ if (!_mongocrypt_buffer_to_bson (&crypt->opts.encrypted_field_config_map,
+ &as_bson)) {
+ CLIENT_ERR ("invalid bson");
+ return false;
+ }
+
+ if (!bson_validate_with_error (&as_bson, BSON_VALIDATE_NONE, &bson_err)) {
+ CLIENT_ERR (bson_err.message);
+ return false;
+ }
+
+ return true;
+}
bool
mongocrypt_setopt_kms_provider_local (mongocrypt_t *crypt,
mongocrypt_binary_t *key)
{
mongocrypt_status_t *status;
+ _mongocrypt_opts_kms_providers_t *const kms_providers =
+ &crypt->opts.kms_providers;
if (!crypt) {
return false;
}
status = crypt->status;
if (crypt->initialized) {
CLIENT_ERR ("options cannot be set after initialization");
return false;
}
- if (0 != (crypt->opts.kms_providers & MONGOCRYPT_KMS_PROVIDER_LOCAL)) {
+ if (0 !=
+ (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_LOCAL)) {
CLIENT_ERR ("local kms provider already set");
return false;
}
if (!key) {
CLIENT_ERR ("passed null key");
return false;
}
if (mongocrypt_binary_len (key) != MONGOCRYPT_KEY_LEN) {
CLIENT_ERR ("local key must be %d bytes", MONGOCRYPT_KEY_LEN);
return false;
}
if (crypt->log.trace_enabled) {
char *key_val;
key_val = _mongocrypt_new_string_from_bytes (key->data, key->len);
_mongocrypt_log (&crypt->log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%s\")",
BSON_FUNC,
"key",
key_val);
bson_free (key_val);
}
- _mongocrypt_buffer_copy_from_binary (&crypt->opts.kms_provider_local.key,
- key);
- crypt->opts.kms_providers |= MONGOCRYPT_KMS_PROVIDER_LOCAL;
+ _mongocrypt_buffer_copy_from_binary (&kms_providers->local.key, key);
+ kms_providers->configured_providers |= MONGOCRYPT_KMS_PROVIDER_LOCAL;
return true;
}
typedef struct {
/// Whether the load is successful
bool okay;
/// The DLL handle to the opened library.
mcr_dll lib;
/// A vtable for the functions in the DLL
- _mcr_csfle_v1_vtable vtable;
+ _mongo_crypt_v1_vtable vtable;
} _loaded_csfle;
/**
* @brief Attempt to open the CSFLE dynamic library and initialize a vtable for
* it.
*/
static _loaded_csfle
_try_load_csfle (const char *filepath, _mongocrypt_log_t *log)
{
// Try to open the dynamic lib
mcr_dll lib = mcr_dll_open (filepath);
// Check for errors, which are represented by strings
if (lib.error_string.data) {
// Error opening candidate
_mongocrypt_log (
log,
MONGOCRYPT_LOG_LEVEL_WARNING,
"Error while opening candidate for CSFLE dynamic library [%s]: %s",
filepath,
lib.error_string.data);
// Free resources, which will include the error string
mcr_dll_close (lib);
// Bad:
return (_loaded_csfle){.okay = false};
}
// Successfully opened DLL
_mongocrypt_log (log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"Loading CSFLE dynamic library [%s]",
filepath);
// Construct the library vtable
- bool vtable_okay = true;
- _mcr_csfle_v1_vtable vtable;
+ _mongo_crypt_v1_vtable vtable = {.okay = true};
#define X_FUNC(Name, RetType, ...) \
{ \
/* Symbol names are qualified by the lib name and version: */ \
- const char *symname = "mongo_csfle_v1_" #Name; \
+ const char *symname = "mongo_crypt_v1_" #Name; \
vtable.Name = mcr_dll_sym (lib, symname); \
if (vtable.Name == NULL) { \
/* The requested symbol is not present */ \
_mongocrypt_log ( \
log, \
MONGOCRYPT_LOG_LEVEL_ERROR, \
"Missing required symbol '%s' from CSFLE dynamic library [%s]", \
symname, \
filepath); \
/* Mark the vtable as broken, but keep trying to load more symbols to \
* produce error messages for all missing symbols */ \
- vtable_okay = false; \
+ vtable.okay = false; \
} \
}
MONGOC_CSFLE_FUNCTIONS_X
#undef X_FUNC
- if (!vtable_okay) {
+ if (!vtable.okay) {
mcr_dll_close (lib);
_mongocrypt_log (
log,
MONGOCRYPT_LOG_LEVEL_ERROR,
"One or more required symbols are missing from CSFLE dynamic library "
"[%s], so this dynamic library will not be used.",
filepath);
return (_loaded_csfle){.okay = false};
}
// Success!
_mongocrypt_log (log,
MONGOCRYPT_LOG_LEVEL_INFO,
"Opened CSFLE dynamic library [%s]",
filepath);
return (_loaded_csfle){.okay = true, .lib = lib, .vtable = vtable};
}
/**
* @brief If the leading path element in `filepath` is $ORIGIN, replace that
* with the directory containing the current executing module.
*
* @return true If no error occurred and the path is valid
* @return false If there was an error and `filepath` cannot be processed
*/
bool
_try_replace_dollar_origin (mstr *filepath, _mongocrypt_log_t *log)
{
const mstr_view dollar_origin = mstrv_lit ("$ORIGIN");
if (!mstr_starts_with (filepath->view, dollar_origin)) {
// Nothing to replace
return true;
}
// Check that the next char is a path separator or end-of-string:
char peek = filepath->data[dollar_origin.len];
if (peek != 0 && !mpath_is_sep (peek, MPATH_NATIVE)) {
// Not a single path element
return true;
}
// Replace $ORIGIN with the directory of the current module
const current_module_result self_exe_r = current_module_path ();
if (self_exe_r.error) {
// Failed to get the current module to load replace $ORIGIN
mstr error = merror_system_error_string (self_exe_r.error);
_mongocrypt_log (log,
MONGOCRYPT_LOG_LEVEL_WARNING,
"Error while loading the executable module path for "
"substitution of $ORIGIN in CSFLE search path [%s]: %s",
filepath->data,
error.data);
mstr_free (error);
return false;
}
const mstr_view self_dir = mpath_parent (self_exe_r.path.view, MPATH_NATIVE);
mstr_inplace_splice (filepath, 0, dollar_origin.len, self_dir);
mstr_free (self_exe_r.path);
return true;
}
+_loaded_csfle
+_try_find_csfle (mongocrypt_t *crypt)
+{
+ _loaded_csfle candidate_csfle = {0};
+ mstr csfle_cand_filepath = MSTR_NULL;
+ if (crypt->opts.crypt_shared_lib_override_path.data) {
+ // If an override path was specified, skip the library searching behavior
+ csfle_cand_filepath =
+ mstr_copy (crypt->opts.crypt_shared_lib_override_path.view);
+ if (_try_replace_dollar_origin (&csfle_cand_filepath, &crypt->log)) {
+ // Succesfully substituted $ORIGIN
+ // Do not allow a plain filename to go through, as that will cause the
+ // DLL load to search the system.
+ mstr_assign (&csfle_cand_filepath,
+ mpath_absolute (csfle_cand_filepath.view, MPATH_NATIVE));
+ candidate_csfle =
+ _try_load_csfle (csfle_cand_filepath.data, &crypt->log);
+ }
+ } else {
+ // No override path was specified, so try to find it on the provided
+ // search paths.
+ for (int i = 0; i < crypt->opts.n_crypt_shared_lib_search_paths; ++i) {
+ mstr_view cand_dir = crypt->opts.crypt_shared_lib_search_paths[i].view;
+ mstr_view csfle_filename = mstrv_lit ("mongo_crypt_v1" MCR_DLL_SUFFIX);
+ if (mstr_eq (cand_dir, mstrv_lit ("$SYSTEM"))) {
+ // Caller wants us to search for the library on the system's default
+ // library paths. Pass only the library's filename to cause dll_open
+ // to search on the library paths.
+ mstr_assign (&csfle_cand_filepath, mstr_copy (csfle_filename));
+ } else {
+ // Compose the candidate filepath:
+ mstr_assign (&csfle_cand_filepath,
+ mpath_join (cand_dir, csfle_filename, MPATH_NATIVE));
+ if (!_try_replace_dollar_origin (&csfle_cand_filepath,
+ &crypt->log)) {
+ // Error while substituting $ORIGIN
+ continue;
+ }
+ }
+ // Try to load the file:
+ candidate_csfle =
+ _try_load_csfle (csfle_cand_filepath.data, &crypt->log);
+ if (candidate_csfle.okay) {
+ // Stop searching:
+ break;
+ }
+ }
+ }
+
+ mstr_free (csfle_cand_filepath);
+ return candidate_csfle;
+}
+
+
+/// Global state for the application's csfle library
+typedef struct csfle_global_lib_state {
+ /// Synchronization around the reference count:
+ mongocrypt_mutex_t mtx;
+ int refcount;
+ /// The open library handle:
+ mcr_dll dll;
+ /// vtable for the APIs:
+ _mongo_crypt_v1_vtable vtable;
+ /// The global library state managed by the csfle library:
+ mongo_crypt_v1_lib *csfle_lib;
+} csfle_global_lib_state;
+
+csfle_global_lib_state g_csfle_state;
+
+static void
+init_csfle_state (void)
+{
+ _mongocrypt_mutex_init (&g_csfle_state.mtx);
+}
+mlib_once_flag g_csfle_init_flag = MLIB_ONCE_INITIALIZER;
+
+/**
+ * @brief Verify that `found` refers to the same library that is globally loaded
+ * for the application.
+ *
+ * @param crypt The requesting mongocrypt_t. Error information may be set
+ * through here.
+ * @param found The result of _try_load_csfle()
+ * @return true If `found` matches the global state
+ * @return false Otherwise
+ *
+ * @note This function assumes that the global csfle state is valid and will not
+ * be destroyed by any other thread. (One must hold the reference count >= 1)
+ */
+static bool
+_validate_csfle_singleton (mongocrypt_t *crypt, _loaded_csfle found)
+{
+ mongocrypt_status_t *status = crypt->status;
+ // Path to the existing loaded csfle:
+ mcr_dll_path_result existing_path_ = mcr_dll_path (g_csfle_state.dll);
+ assert (existing_path_.path.data &&
+ "Failed to get path to already-loaded csfle library");
+ mstr_view existing_path = existing_path_.path.view;
+ bool okay = true;
+ if (!found.okay) {
+ // There is one loaded, but we failed to find that same library. Error:
+ CLIENT_ERR ("An existing CSFLE libary is loaded by the application at "
+ "[%s], but the current call to mongocrypt_init() failed to "
+ "find that same library.",
+ existing_path.data);
+ okay = false;
+ } else {
+ // Get the path to what we found:
+ mcr_dll_path_result found_path = mcr_dll_path (found.lib);
+ assert (found_path.path.data &&
+ "Failed to get the dynamic library filepath of the library that "
+ "was loaded for csfle");
+ if (!mstr_eq (found_path.path.view, existing_path)) {
+ // Our find-result should only ever find the existing same library.
+ // Error:
+ CLIENT_ERR (
+ "An existing CSFLE library is loaded by the application at [%s], "
+ "but the current call to mongocrypt_init() attempted to load a "
+ "second CSFLE library from [%s]. This is not allowed.",
+ existing_path.data,
+ found_path.path.data);
+ okay = false;
+ }
+ mstr_free (found_path.path);
+ mstr_free (found_path.error_string);
+ }
+
+ mstr_free (existing_path_.path);
+ mstr_free (existing_path_.error_string);
+ return okay;
+}
+
+/**
+ * @brief Drop a reference count to the global csfle loaded library.
+ *
+ * This should be called as part of mongocrypt_t destruction following a
+ * successful loading of csfle.
+ */
+static void
+_csfle_drop_global_ref ()
+{
+ mlib_call_once (&g_csfle_init_flag, init_csfle_state);
+
+ bool dropped_last_ref = false;
+ csfle_global_lib_state old_state = {.refcount = 0};
+ MONGOCRYPT_WITH_MUTEX (g_csfle_state.mtx)
+ {
+ assert (g_csfle_state.refcount > 0);
+ int new_rc = --g_csfle_state.refcount;
+ if (new_rc == 0) {
+ old_state = g_csfle_state;
+ dropped_last_ref = true;
+ }
+ }
+
+ if (dropped_last_ref) {
+ mongo_crypt_v1_status *status = old_state.vtable.status_create ();
+ const int destroy_rc =
+ old_state.vtable.lib_destroy (old_state.csfle_lib, status);
+ if (destroy_rc != MONGO_CRYPT_V1_SUCCESS && status) {
+ fprintf (stderr,
+ "csfle lib_destroy() failed: %s [Error %d, code %d]\n",
+ old_state.vtable.status_get_explanation (status),
+ old_state.vtable.status_get_error (status),
+ old_state.vtable.status_get_code (status));
+ }
+ old_state.vtable.status_destroy (status);
+
+#ifndef __linux__
+ mcr_dll_close (old_state.dll);
+#endif
+ /// NOTE: On Linux, skip closing the CSFLE library itself, since a bug in
+ /// the way ld-linux and GCC interact causes static destructors to not run
+ /// during dlclose(). Still, free the error string:
+ mstr_free (old_state.dll.error_string);
+ }
+}
+
+/**
+ * @brief Following a call to _try_find_csfle, reconcile the result with the
+ * current application-global csfle status.
+ *
+ * csfle contains global state that can only be loaded once for the entire
+ * application. For this reason, there is a global object that manages the
+ * loaded library. Attempts to create more than one mongocrypt_t that all
+ * request csfle requires that all instances attempt to open the same csfle
+ * library.
+ *
+ * This function checks if there is already a csfle loaded for the process. If
+ * there is, we validate that the given find-result found the same library
+ * that is already loaded. If not, then this function sets an error and returns
+ * `false`.
+ *
+ * If there was no prior loaded csfle and the find-result indicates that it
+ * found the library, this function will store the find-result in the global
+ * state for later calls to mongocrypt_init() that request csfle.
+ *
+ * This function performs reference counting on the global state. Following a
+ * successful call to this function (i.e. it returns `true`), one must have a
+ * corresponding call to _csfle_drop_global_ref(), which will release the
+ * resources acquired by this function.
+ *
+ * @param crypt The requesting mongocrypt_t instance. An error may be set
+ * through this object.
+ * @param found The result of _try_find_csfle().
+ * @return true Upon success AND `found->okay`
+ * @return false Otherwise.
+ *
+ * @note If there was no prior global state loaded, this function will steal
+ * the library referenced by `found`. The caller should release `found->lib`
+ * regardless.
+ */
+static bool
+_csfle_replace_or_take_validate_singleton (mongocrypt_t *crypt,
+ _loaded_csfle *found)
+{
+ mlib_call_once (&g_csfle_init_flag, init_csfle_state);
+
+ // If we have a loaded library, create a csfle_status object to use with
+ // lib_create
+ mongo_crypt_v1_status *csfle_status = NULL;
+ if (found->okay) {
+ // Create the status. Note that this may fail, so do not assume
+ // csfle_status is non-null.
+ csfle_status = found->vtable.status_create ();
+ }
+
+ /**
+ * Atomically:
+ *
+ * 1. If there is an existing global library, increment its reference count.
+ * 2. Otherwise, if we have successfully loaded a new csfle, replace the
+ * global library and set its reference count to 1.
+ * 3. Otherwise, do nothing.
+ */
+ enum {
+ TOOK_REFERENCE,
+ DID_NOTHING,
+ REPLACED_GLOBAL,
+ LIB_CREATE_FAILED,
+ } action;
+ MONGOCRYPT_WITH_MUTEX (g_csfle_state.mtx)
+ {
+ if (g_csfle_state.refcount) {
+ // Increment the refcount to prevent the global csfle library from
+ // disappearing
+ ++g_csfle_state.refcount;
+ action = TOOK_REFERENCE;
+ } else if (found->okay) {
+ // We have found csfle, and no one else is holding one. Our result will
+ // now become the global result.
+ // Create the single csfle_lib object for the application:
+ mongo_crypt_v1_lib *csfle_lib =
+ found->vtable.lib_create (csfle_status);
+ if (csfle_lib == NULL) {
+ // Creation failed:
+ action = LIB_CREATE_FAILED;
+ } else {
+ // Creation succeeded: Store the result:
+ g_csfle_state.dll = found->lib;
+ g_csfle_state.vtable = found->vtable;
+ g_csfle_state.csfle_lib = csfle_lib;
+ g_csfle_state.refcount = 1;
+ action = REPLACED_GLOBAL;
+ }
+ } else {
+ // We failed to load the library, and no one else has one either.
+ // Nothing to do.
+ action = DID_NOTHING;
+ }
+ }
+
+ // Get the possible failure status information.
+ mstr message = MSTR_NULL;
+ int err = 0;
+ int code = 0;
+ if (csfle_status) {
+ assert (found->okay);
+ message =
+ mstr_copy_cstr (found->vtable.status_get_explanation (csfle_status));
+ err = found->vtable.status_get_error (csfle_status);
+ code = found->vtable.status_get_code (csfle_status);
+ found->vtable.status_destroy (csfle_status);
+ }
+
+ bool have_csfle = true;
+ switch (action) {
+ case TOOK_REFERENCE: {
+ const bool is_valid = _validate_csfle_singleton (crypt, *found);
+ if (!is_valid) {
+ // We've failed validation, so we're not going to continue to
+ // reference the global instance it. Drop it now:
+ _csfle_drop_global_ref ();
+ }
+ have_csfle = is_valid;
+ break;
+ }
+ case REPLACED_GLOBAL:
+ // Reset the library in the caller so they can't unload the DLL. The DLL
+ // is now managed in the global variable.
+ found->lib = MCR_DLL_NULL;
+ _mongocrypt_log (&crypt->log,
+ MONGOCRYPT_LOG_LEVEL_TRACE,
+ "Loading new csfle library for the application.");
+ have_csfle = true;
+ break;
+ case LIB_CREATE_FAILED:
+ if (!message.data) {
+ // We failed to obtain a message about the failure
+ _mongocrypt_set_error (crypt->status,
+ MONGOCRYPT_STATUS_ERROR_CRYPT_SHARED,
+ MONGOCRYPT_GENERIC_ERROR_CODE,
+ "csfle lib_create() failed");
+ } else {
+ // Record the message, error, and code from csfle about the failure
+ _mongocrypt_set_error (
+ crypt->status,
+ MONGOCRYPT_STATUS_ERROR_CRYPT_SHARED,
+ MONGOCRYPT_GENERIC_ERROR_CODE,
+ "csfle lib_create() failed: %s [Error %d, code %d]",
+ message.data,
+ err,
+ code);
+ }
+ have_csfle = false;
+ break;
+ case DID_NOTHING:
+ default:
+ have_csfle = false;
+ break;
+ }
+
+ mstr_free (message);
+ return have_csfle;
+}
+
+/**
+ * @return true If the given mongocrypt wants csfle
+ * @return false Otherwise
+ *
+ * @note "Requesting csfle" means that it has set at least one search path OR
+ * has set the override path
+ */
+static bool
+_wants_csfle (mongocrypt_t *c)
+{
+ if (c->opts.bypass_query_analysis) {
+ return false;
+ }
+ return c->opts.n_crypt_shared_lib_search_paths != 0 ||
+ c->opts.crypt_shared_lib_override_path.data != NULL;
+}
+
+/**
+ * @brief Try to enable csfle for the given mongocrypt
+ *
+ * @param crypt The crypt object for which we should enable csfle
+ * @return true If no errors occurred
+ * @return false Otherwise
+ *
+ * @note Returns `true` even if loading fails to find the csfle library on the
+ * requested paths. `false` is only for hard-errors, which includes failure to
+ * load from the override path.
+ */
+static bool
+_try_enable_csfle (mongocrypt_t *crypt)
+{
+ mongocrypt_status_t *status = crypt->status;
+
+ _loaded_csfle found = _try_find_csfle (crypt);
+
+ // If a crypt_shared override path was specified, but we did not succeed in
+ // loading crypt_shared, that is a hard-error.
+ if (crypt->opts.crypt_shared_lib_override_path.data && !found.okay) {
+ CLIENT_ERR (
+ "A crypt_shared override path was specified [%s], but we failed to "
+ "open a dynamic library at that location",
+ crypt->opts.crypt_shared_lib_override_path.data);
+ return false;
+ }
+
+ // Attempt to validate the try-find result against the global state:
+ const bool got_csfle =
+ _csfle_replace_or_take_validate_singleton (crypt, &found);
+ // Close the lib we found (may have been stolen in validate_singleton())
+ mcr_dll_close (found.lib);
+
+ if (got_csfle) {
+ crypt->csfle = g_csfle_state.vtable;
+ crypt->csfle_lib = g_csfle_state.csfle_lib;
+ }
+ // In cast of failure, validate_singleton() will set a non-ok status.
+ return mongocrypt_status_type (status) == MONGOCRYPT_STATUS_OK;
+}
+
bool
mongocrypt_init (mongocrypt_t *crypt)
{
mongocrypt_status_t *status;
if (!crypt) {
return false;
}
status = crypt->status;
if (crypt->initialized) {
CLIENT_ERR ("already initialized");
return false;
}
crypt->initialized = true;
if (!mongocrypt_status_ok (crypt->status)) {
return false;
}
if (!_mongocrypt_opts_validate (&crypt->opts, status)) {
return false;
}
if (crypt->opts.log_fn) {
_mongocrypt_log_set_fn (
&crypt->log, crypt->opts.log_fn, crypt->opts.log_ctx);
}
if (!crypt->crypto) {
#ifndef MONGOCRYPT_ENABLE_CRYPTO
CLIENT_ERR ("libmongocrypt built with native crypto disabled. crypto "
"hooks required");
return false;
#else
/* set default hooks. */
crypt->crypto = bson_malloc0 (sizeof (*crypt->crypto));
BSON_ASSERT (crypt->crypto);
#endif
}
- mcr_dll_close (crypt->csfle_lib);
-
- mstr csfle_cand_filepath = MSTR_NULL;
- if (crypt->opts.csfle_lib_override_path.data) {
- // If an override path was specified, skip the library searching behavior
- csfle_cand_filepath =
- mstr_copy (crypt->opts.csfle_lib_override_path.view);
- if (_try_replace_dollar_origin (&csfle_cand_filepath, &crypt->log)) {
- // Succesfully substituted $ORIGIN
- // Do not allow a plain filename to go through, as that will cause the
- // DLL load to search the system.
- mstr_assign (&csfle_cand_filepath,
- mpath_absolute (csfle_cand_filepath.view, MPATH_NATIVE));
- _loaded_csfle candidate =
- _try_load_csfle (csfle_cand_filepath.data, &crypt->log);
- if (candidate.okay) {
- // Successfully loaded
- crypt->csfle_vtable = candidate.vtable;
- crypt->csfle_lib = candidate.lib;
- }
- }
- } else {
- // No override path was specified, so try to find it on the provided
- // search paths.
- for (int i = 0; i < crypt->opts.n_cselib_search_paths; ++i) {
- mstr_view cand_dir = crypt->opts.cselib_search_paths[i].view;
- mstr_view csfle_filename = mstrv_lit ("mongo_csfle_v1" MCR_DLL_SUFFIX);
- if (mstr_eq (cand_dir, mstrv_lit ("$SYSTEM"))) {
- // Caller wants us to search for the library on the system's default
- // library paths. Pass only the library's filename to cause dll_open
- // to search on the library paths.
- mstr_assign (&csfle_cand_filepath, mstr_copy (csfle_filename));
- } else {
- // Compose the candidate filepath:
- mstr_assign (&csfle_cand_filepath,
- mpath_join (cand_dir, csfle_filename, MPATH_NATIVE));
- if (!_try_replace_dollar_origin (&csfle_cand_filepath,
- &crypt->log)) {
- // Error while substituting $ORIGIN
- continue;
- }
- }
- // Try to load the file:
- _loaded_csfle candidate =
- _try_load_csfle (csfle_cand_filepath.data, &crypt->log);
- if (candidate.okay) {
- // We got one:
- crypt->csfle_vtable = candidate.vtable;
- crypt->csfle_lib = candidate.lib;
- // Stop searching:
- break;
- }
- }
- }
- mstr_free (csfle_cand_filepath);
-
- // If a CSFLE override path was specified, but we did not succeed in loading
- // CSFLE, that is a hard-error.
- if (crypt->opts.csfle_lib_override_path.data &&
- !mcr_dll_is_open (crypt->csfle_lib)) {
- CLIENT_ERR ("A CSFLE override path was specified [%s], but we failed to "
- "open a dynamic library at that location",
- crypt->opts.csfle_lib_override_path.data);
- return false;
+ if (!_wants_csfle (crypt)) {
+ // User does not want csfle. Just succeed.
+ return true;
}
- return true;
+ return _try_enable_csfle (crypt);
}
bool
mongocrypt_status (mongocrypt_t *crypt, mongocrypt_status_t *out)
{
if (!crypt) {
return false;
}
if (!out) {
mongocrypt_status_t *status = crypt->status;
CLIENT_ERR ("argument 'out' is required");
return false;
}
if (!mongocrypt_status_ok (crypt->status)) {
_mongocrypt_status_copy_to (crypt->status, out);
return false;
}
_mongocrypt_status_reset (out);
return true;
}
void
mongocrypt_destroy (mongocrypt_t *crypt)
{
if (!crypt) {
return;
}
_mongocrypt_opts_cleanup (&crypt->opts);
_mongocrypt_cache_cleanup (&crypt->cache_collinfo);
_mongocrypt_cache_cleanup (&crypt->cache_key);
_mongocrypt_mutex_cleanup (&crypt->mutex);
_mongocrypt_log_cleanup (&crypt->log);
mongocrypt_status_destroy (crypt->status);
bson_free (crypt->crypto);
_mongocrypt_cache_oauth_destroy (crypt->cache_oauth_azure);
_mongocrypt_cache_oauth_destroy (crypt->cache_oauth_gcp);
-#ifndef __linux__
- mcr_dll_close (crypt->csfle_lib);
-#else
- /// NOTE: On Linux, skip closing the CSFLE library itself, since a bug in the
- /// way ld-linux and GCC interact causes static destructors to not run during
- /// dlclose(). Still, free the error string that may be non-null:
- mstr_free (crypt->csfle_lib.error_string);
-#endif
+ if (crypt->csfle.okay) {
+ _csfle_drop_global_ref ();
+ crypt->csfle.okay = false;
+ }
+
bson_free (crypt);
}
+const char *
+mongocrypt_crypt_shared_lib_version_string (const mongocrypt_t *crypt,
+ uint32_t *len)
+{
+ if (!crypt->csfle.okay) {
+ if (len) {
+ *len = 0;
+ }
+ return NULL;
+ }
+ const char *version = crypt->csfle.get_version_str ();
+ if (len) {
+ *len = (uint32_t) (strlen (version));
+ }
+ return version;
+}
+
+uint64_t
+mongocrypt_crypt_shared_lib_version (const mongocrypt_t *crypt)
+{
+ if (!crypt->csfle.okay) {
+ return 0;
+ }
+ return crypt->csfle.get_version ();
+}
+
+
bool
_mongocrypt_validate_and_copy_string (const char *in,
int32_t in_len,
char **out)
{
if (!in) {
return false;
}
if (in_len < -1) {
return false;
}
if (in_len == -1) {
in_len = (uint32_t) strlen (in);
}
if (!bson_utf8_validate (in, in_len, false)) {
return false;
}
*out = bson_strndup (in, in_len);
return true;
}
bool
mongocrypt_setopt_crypto_hooks (mongocrypt_t *crypt,
mongocrypt_crypto_fn aes_256_cbc_encrypt,
mongocrypt_crypto_fn aes_256_cbc_decrypt,
mongocrypt_random_fn random,
mongocrypt_hmac_fn hmac_sha_512,
mongocrypt_hmac_fn hmac_sha_256,
mongocrypt_hash_fn sha_256,
void *ctx)
{
mongocrypt_status_t *status;
if (!crypt) {
return false;
}
status = crypt->status;
if (crypt->initialized) {
CLIENT_ERR ("options cannot be set after initialization");
return false;
}
- if (crypt->crypto) {
- CLIENT_ERR ("crypto_hooks already set");
- return false;
+ if (!crypt->crypto) {
+ crypt->crypto = bson_malloc0 (sizeof (*crypt->crypto));
+ BSON_ASSERT (crypt->crypto);
}
- crypt->crypto = bson_malloc0 (sizeof (*crypt->crypto));
- BSON_ASSERT (crypt->crypto);
-
crypt->crypto->hooks_enabled = true;
crypt->crypto->ctx = ctx;
if (!aes_256_cbc_encrypt) {
CLIENT_ERR ("aes_256_cbc_encrypt not set");
return false;
}
crypt->crypto->aes_256_cbc_encrypt = aes_256_cbc_encrypt;
if (!aes_256_cbc_decrypt) {
CLIENT_ERR ("aes_256_cbc_decrypt not set");
return false;
}
crypt->crypto->aes_256_cbc_decrypt = aes_256_cbc_decrypt;
if (!random) {
CLIENT_ERR ("random not set");
return false;
}
crypt->crypto->random = random;
if (!hmac_sha_512) {
CLIENT_ERR ("hmac_sha_512 not set");
return false;
}
crypt->crypto->hmac_sha_512 = hmac_sha_512;
if (!hmac_sha_256) {
CLIENT_ERR ("hmac_sha_256 not set");
return false;
}
crypt->crypto->hmac_sha_256 = hmac_sha_256;
if (!sha_256) {
CLIENT_ERR ("sha_256 not set");
return false;
}
crypt->crypto->sha_256 = sha_256;
return true;
}
bool
mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 (
mongocrypt_t *crypt,
mongocrypt_hmac_fn sign_rsaes_pkcs1_v1_5,
void *sign_ctx)
{
mongocrypt_status_t *status;
if (!crypt) {
return false;
}
status = crypt->status;
if (crypt->initialized) {
CLIENT_ERR ("options cannot be set after initialization");
return false;
}
if (crypt->opts.sign_rsaes_pkcs1_v1_5) {
CLIENT_ERR ("signature hook already set");
return false;
}
crypt->opts.sign_rsaes_pkcs1_v1_5 = sign_rsaes_pkcs1_v1_5;
crypt->opts.sign_ctx = sign_ctx;
return true;
}
bool
-mongocrypt_setopt_kms_providers (mongocrypt_t *crypt,
- mongocrypt_binary_t *kms_providers)
+mongocrypt_setopt_aes_256_ctr (mongocrypt_t *crypt,
+ mongocrypt_crypto_fn aes_256_ctr_encrypt,
+ mongocrypt_crypto_fn aes_256_ctr_decrypt,
+ void *ctx)
{
mongocrypt_status_t *status;
- bson_t as_bson;
- bson_iter_t iter;
if (!crypt) {
return false;
}
+
+ if (!crypt->crypto) {
+ crypt->crypto = bson_malloc0 (sizeof (*crypt->crypto));
+ BSON_ASSERT (crypt->crypto);
+ }
+
+ status = crypt->status;
+
+ if (crypt->initialized) {
+ CLIENT_ERR ("options cannot be set after initialization");
+ return false;
+ }
+
+ if (!aes_256_ctr_encrypt) {
+ CLIENT_ERR ("aes_256_ctr_encrypt not set");
+ return false;
+ }
+
+ if (!aes_256_ctr_decrypt) {
+ CLIENT_ERR ("aes_256_ctr_decrypt not set");
+ return false;
+ }
+
+ crypt->crypto->aes_256_ctr_encrypt = aes_256_ctr_encrypt;
+ crypt->crypto->aes_256_ctr_decrypt = aes_256_ctr_decrypt;
+
+ return true;
+}
+
+bool
+mongocrypt_setopt_aes_256_ecb (mongocrypt_t *crypt,
+ mongocrypt_crypto_fn aes_256_ecb_encrypt,
+ void *ctx)
+{
+ mongocrypt_status_t *status;
+
+ if (!crypt) {
+ return false;
+ }
+
+ if (!crypt->crypto) {
+ crypt->crypto = bson_malloc0 (sizeof (*crypt->crypto));
+ BSON_ASSERT (crypt->crypto);
+ }
+
status = crypt->status;
if (crypt->initialized) {
CLIENT_ERR ("options cannot be set after initialization");
return false;
}
- if (!_mongocrypt_binary_to_bson (kms_providers, &as_bson) ||
+ if (!aes_256_ecb_encrypt) {
+ CLIENT_ERR ("aes_256_ecb_encrypt not set");
+ return false;
+ }
+
+ crypt->crypto->aes_256_ecb_encrypt = aes_256_ecb_encrypt;
+
+ return true;
+}
+
+bool
+mongocrypt_setopt_kms_providers (mongocrypt_t *crypt,
+ mongocrypt_binary_t *kms_providers_definition)
+{
+ mongocrypt_status_t *const status = crypt->status;
+ if (!crypt) {
+ return false;
+ }
+
+ if (crypt->initialized) {
+ CLIENT_ERR ("options cannot be set after initialization");
+ return false;
+ }
+
+ return _mongocrypt_parse_kms_providers (kms_providers_definition,
+ &crypt->opts.kms_providers,
+ crypt->status,
+ &crypt->log);
+}
+
+bool
+_mongocrypt_parse_kms_providers (
+ mongocrypt_binary_t *kms_providers_definition,
+ _mongocrypt_opts_kms_providers_t *kms_providers,
+ mongocrypt_status_t *status,
+ _mongocrypt_log_t *log)
+{
+ bson_t as_bson;
+ bson_iter_t iter;
+
+ if (!_mongocrypt_binary_to_bson (kms_providers_definition, &as_bson) ||
!bson_iter_init (&iter, &as_bson)) {
CLIENT_ERR ("invalid BSON");
return false;
}
while (bson_iter_next (&iter)) {
const char *field_name;
+ bson_t field_bson;
field_name = bson_iter_key (&iter);
+ if (BSON_ITER_HOLDS_DOCUMENT (&iter)) {
+ uint32_t len;
+ const uint8_t *data = NULL;
+ bson_iter_document (&iter, &len, &data);
+ bson_init_static (&field_bson, data, len);
+ } else {
+ CLIENT_ERR ("'%s' value must be a BSON document", field_name);
+ return false;
+ }
- if (0 == strcmp (field_name, "azure")) {
- if (0 != (crypt->opts.kms_providers & MONGOCRYPT_KMS_PROVIDER_AZURE)) {
+ if (0 == strcmp (field_name, "azure") && bson_empty (&field_bson)) {
+ kms_providers->need_credentials |= MONGOCRYPT_KMS_PROVIDER_AZURE;
+ } else if (0 == strcmp (field_name, "azure")) {
+ if (0 != (kms_providers->configured_providers &
+ MONGOCRYPT_KMS_PROVIDER_AZURE)) {
CLIENT_ERR ("azure KMS provider already set");
return false;
}
- if (!_mongocrypt_parse_required_utf8 (
- &as_bson,
- "azure.tenantId",
- &crypt->opts.kms_provider_azure.tenant_id,
- crypt->status)) {
+ if (!_mongocrypt_parse_required_utf8 (&as_bson,
+ "azure.tenantId",
+ &kms_providers->azure.tenant_id,
+ status)) {
return false;
}
- if (!_mongocrypt_parse_required_utf8 (
- &as_bson,
- "azure.clientId",
- &crypt->opts.kms_provider_azure.client_id,
- crypt->status)) {
+ if (!_mongocrypt_parse_required_utf8 (&as_bson,
+ "azure.clientId",
+ &kms_providers->azure.client_id,
+ status)) {
return false;
}
if (!_mongocrypt_parse_required_utf8 (
&as_bson,
"azure.clientSecret",
- &crypt->opts.kms_provider_azure.client_secret,
- crypt->status)) {
+ &kms_providers->azure.client_secret,
+ status)) {
return false;
}
if (!_mongocrypt_parse_optional_endpoint (
&as_bson,
"azure.identityPlatformEndpoint",
- &crypt->opts.kms_provider_azure.identity_platform_endpoint,
+ &kms_providers->azure.identity_platform_endpoint,
NULL /* opts */,
- crypt->status)) {
+ status)) {
return false;
}
if (!_mongocrypt_check_allowed_fields (&as_bson,
"azure",
- crypt->status,
+ status,
"tenantId",
"clientId",
"clientSecret",
"identityPlatformEndpoint")) {
return false;
}
- crypt->opts.kms_providers |= MONGOCRYPT_KMS_PROVIDER_AZURE;
+ kms_providers->configured_providers |= MONGOCRYPT_KMS_PROVIDER_AZURE;
+ } else if (0 == strcmp (field_name, "gcp") && bson_empty (&field_bson)) {
+ kms_providers->need_credentials |= MONGOCRYPT_KMS_PROVIDER_GCP;
} else if (0 == strcmp (field_name, "gcp")) {
- if (0 != (crypt->opts.kms_providers & MONGOCRYPT_KMS_PROVIDER_GCP)) {
+ if (0 != (kms_providers->configured_providers &
+ MONGOCRYPT_KMS_PROVIDER_GCP)) {
CLIENT_ERR ("gcp KMS provider already set");
return false;
}
if (!_mongocrypt_parse_required_utf8 (
- &as_bson,
- "gcp.email",
- &crypt->opts.kms_provider_gcp.email,
- crypt->status)) {
+ &as_bson, "gcp.email", &kms_providers->gcp.email, status)) {
return false;
}
if (!_mongocrypt_parse_required_binary (
&as_bson,
"gcp.privateKey",
- &crypt->opts.kms_provider_gcp.private_key,
- crypt->status)) {
+ &kms_providers->gcp.private_key,
+ status)) {
return false;
}
- if (!_mongocrypt_parse_optional_endpoint (
- &as_bson,
- "gcp.endpoint",
- &crypt->opts.kms_provider_gcp.endpoint,
- NULL /* opts */,
- crypt->status)) {
+ if (!_mongocrypt_parse_optional_endpoint (&as_bson,
+ "gcp.endpoint",
+ &kms_providers->gcp.endpoint,
+ NULL /* opts */,
+ status)) {
return false;
}
- if (!_mongocrypt_check_allowed_fields (&as_bson,
- "gcp",
- crypt->status,
- "email",
- "privateKey",
- "endpoint")) {
+ if (!_mongocrypt_check_allowed_fields (
+ &as_bson, "gcp", status, "email", "privateKey", "endpoint")) {
return false;
}
- crypt->opts.kms_providers |= MONGOCRYPT_KMS_PROVIDER_GCP;
+ kms_providers->configured_providers |= MONGOCRYPT_KMS_PROVIDER_GCP;
+ } else if (0 == strcmp (field_name, "local") &&
+ bson_empty (&field_bson)) {
+ kms_providers->need_credentials |= MONGOCRYPT_KMS_PROVIDER_LOCAL;
} else if (0 == strcmp (field_name, "local")) {
if (!_mongocrypt_parse_required_binary (
- &as_bson,
- "local.key",
- &crypt->opts.kms_provider_local.key,
- crypt->status)) {
+ &as_bson, "local.key", &kms_providers->local.key, status)) {
return false;
}
- if (crypt->opts.kms_provider_local.key.len != MONGOCRYPT_KEY_LEN) {
+ if (kms_providers->local.key.len != MONGOCRYPT_KEY_LEN) {
CLIENT_ERR ("local key must be %d bytes", MONGOCRYPT_KEY_LEN);
return false;
}
if (!_mongocrypt_check_allowed_fields (
- &as_bson, "local", crypt->status, "key")) {
+ &as_bson, "local", status, "key")) {
return false;
}
- crypt->opts.kms_providers |= MONGOCRYPT_KMS_PROVIDER_LOCAL;
+ kms_providers->configured_providers |= MONGOCRYPT_KMS_PROVIDER_LOCAL;
+ } else if (0 == strcmp (field_name, "aws") && bson_empty (&field_bson)) {
+ kms_providers->need_credentials |= MONGOCRYPT_KMS_PROVIDER_AWS;
} else if (0 == strcmp (field_name, "aws")) {
if (!_mongocrypt_parse_required_utf8 (
&as_bson,
"aws.accessKeyId",
- &crypt->opts.kms_provider_aws.access_key_id,
- crypt->status)) {
+ &kms_providers->aws.access_key_id,
+ status)) {
return false;
}
if (!_mongocrypt_parse_required_utf8 (
&as_bson,
"aws.secretAccessKey",
- &crypt->opts.kms_provider_aws.secret_access_key,
- crypt->status)) {
+ &kms_providers->aws.secret_access_key,
+ status)) {
return false;
}
if (!_mongocrypt_parse_optional_utf8 (
&as_bson,
"aws.sessionToken",
- &crypt->opts.kms_provider_aws.session_token,
- crypt->status)) {
+ &kms_providers->aws.session_token,
+ status)) {
return false;
}
if (!_mongocrypt_check_allowed_fields (&as_bson,
"aws",
- crypt->status,
+ status,
"accessKeyId",
"secretAccessKey",
"sessionToken")) {
return false;
}
- crypt->opts.kms_providers |= MONGOCRYPT_KMS_PROVIDER_AWS;
+ kms_providers->configured_providers |= MONGOCRYPT_KMS_PROVIDER_AWS;
+ } else if (0 == strcmp (field_name, "kmip") && bson_empty (&field_bson)) {
+ kms_providers->need_credentials |= MONGOCRYPT_KMS_PROVIDER_KMIP;
} else if (0 == strcmp (field_name, "kmip")) {
_mongocrypt_endpoint_parse_opts_t opts = {0};
opts.allow_empty_subdomain = true;
if (!_mongocrypt_parse_required_endpoint (
&as_bson,
"kmip.endpoint",
- &crypt->opts.kms_provider_kmip.endpoint,
+ &kms_providers->kmip.endpoint,
&opts,
- crypt->status)) {
+ status)) {
return false;
}
if (!_mongocrypt_check_allowed_fields (
- &as_bson, "kmip", crypt->status, "endpoint")) {
+ &as_bson, "kmip", status, "endpoint")) {
return false;
}
- crypt->opts.kms_providers |= MONGOCRYPT_KMS_PROVIDER_KMIP;
+ kms_providers->configured_providers |= MONGOCRYPT_KMS_PROVIDER_KMIP;
} else {
CLIENT_ERR ("unsupported KMS provider: %s", field_name);
return false;
}
}
- if (crypt->log.trace_enabled) {
+ if (log->trace_enabled) {
char *as_str = bson_as_json (&as_bson, NULL);
- _mongocrypt_log (&crypt->log,
+ _mongocrypt_log (log,
MONGOCRYPT_LOG_LEVEL_TRACE,
"%s (%s=\"%s\")",
BSON_FUNC,
"kms_providers",
as_str);
bson_free (as_str);
}
return true;
}
void
-mongocrypt_setopt_append_csfle_search_path (mongocrypt_t *crypt,
- const char *path)
+mongocrypt_setopt_append_crypt_shared_lib_search_path (mongocrypt_t *crypt,
+ const char *path)
{
// Dup the path string for us to manage
mstr pathdup = mstr_copy_cstr (path);
// Increase array len
- const int new_len = crypt->opts.n_cselib_search_paths + 1;
- mstr *const new_array =
- bson_realloc (crypt->opts.cselib_search_paths, sizeof (mstr) * new_len);
+ const int new_len = crypt->opts.n_crypt_shared_lib_search_paths + 1;
+ mstr *const new_array = bson_realloc (
+ crypt->opts.crypt_shared_lib_search_paths, sizeof (mstr) * new_len);
// Store the path
new_array[new_len - 1] = pathdup;
// Write back opts
- crypt->opts.cselib_search_paths = new_array;
- crypt->opts.n_cselib_search_paths = new_len;
+ crypt->opts.crypt_shared_lib_search_paths = new_array;
+ crypt->opts.n_crypt_shared_lib_search_paths = new_len;
}
void
-mongocrypt_setopt_set_csfle_lib_path_override (mongocrypt_t *crypt,
- const char *path)
+mongocrypt_setopt_use_need_kms_credentials_state (mongocrypt_t *crypt)
+{
+ crypt->opts.use_need_kms_credentials_state = true;
+}
+
+
+void
+mongocrypt_setopt_set_crypt_shared_lib_path_override (mongocrypt_t *crypt,
+ const char *path)
+{
+ mstr_assign (&crypt->opts.crypt_shared_lib_override_path,
+ mstr_copy_cstr (path));
+}
+
+bool
+_mongocrypt_needs_credentials (mongocrypt_t *crypt)
+{
+ if (!crypt->opts.use_need_kms_credentials_state) {
+ return false;
+ }
+
+ return crypt->opts.kms_providers.need_credentials != 0;
+}
+
+bool
+_mongocrypt_needs_credentials_for_provider (mongocrypt_t *crypt,
+ _mongocrypt_kms_provider_t provider)
+{
+ if (!crypt->opts.use_need_kms_credentials_state) {
+ return false;
+ }
+
+ return (crypt->opts.kms_providers.need_credentials & provider) != 0;
+}
+
+void
+mongocrypt_setopt_bypass_query_analysis (mongocrypt_t *crypt)
{
- mstr_assign (&crypt->opts.csfle_lib_override_path, mstr_copy_cstr (path));
+ crypt->opts.bypass_query_analysis = true;
}
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.h b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt.h
similarity index 77%
rename from mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.h
rename to mongodb-1.14.0/src/libmongocrypt/src/mongocrypt.h
index 8bc49bc7..f37fad24 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/mongocrypt.h
+++ b/mongodb-1.14.0/src/libmongocrypt/src/mongocrypt.h
@@ -1,1255 +1,1524 @@
/*
* Copyright 2019-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MONGOCRYPT_H
#define MONGOCRYPT_H
/** @file mongocrypt.h The top-level handle to libmongocrypt. */
/**
* @mainpage libmongocrypt
* See all public API documentation in: @ref mongocrypt.h
*/
#include "mongocrypt-export.h"
#include "mongocrypt-compat.h"
-#include "mongocrypt-config.h"
-/**
- * @def MONGOCRYPT_VERSION
- * The version string describing libmongocrypt.
- * Has the form x.y.z-<pre>+<date>+git<sha>.
- */
-#define MONGOCRYPT_VERSION "1.3.2"
+/* clang-format off */
+#ifndef __has_include
+ #include "mongocrypt-config.h"
+#else
+ #if __has_include("mongocrypt-config.h")
+ #include "mongocrypt-config.h"
+ #else
+ #error No "mongocrypt-config.h" header is available. That file must \
+ be generated in order to use libmongocrypt.
+ #endif
+#endif
+/* clang-format on */
/**
* Returns the version string for libmongocrypt.
*
* @param[out] len An optional length of the returned string. May be NULL.
* @returns a NULL terminated version string for libmongocrypt.
*/
MONGOCRYPT_EXPORT
const char *
mongocrypt_version (uint32_t *len);
/**
* A non-owning view of a byte buffer.
*
* When constructing a mongocrypt_binary_t it is the responsibility of the
* caller to maintain the lifetime of the viewed data. However, all public
* functions that take a mongocrypt_binary_t as an argument will make a copy of
* the viewed data. For example, the following is valid:
*
* @code{.c}
* mongocrypt_binary_t bin = mongocrypt_binary_new_from_data(mydata, mylen);
* assert (mongocrypt_setopt_kms_provider_local (crypt), bin);
* // The viewed data of bin has been copied. Ok to free the view and the data.
* mongocrypt_binary_destroy (bin);
* my_free_fn (mydata);
* @endcode
*
* Functions with a mongocrypt_binary_t* out guarantee the lifetime of the
* viewed data to live as long as the parent object. For example, @ref
* mongocrypt_ctx_mongo_op guarantees that the viewed data of
* mongocrypt_binary_t is valid until the parent ctx is destroyed with @ref
* mongocrypt_ctx_destroy.
*/
typedef struct _mongocrypt_binary_t mongocrypt_binary_t;
/**
* Create a new non-owning view of a buffer (data + length).
*
* Use this to create a mongocrypt_binary_t used for output parameters.
*
* @returns A new mongocrypt_binary_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_binary_t *
mongocrypt_binary_new (void);
/**
* Create a new non-owning view of a buffer (data + length).
*
* @param[in] data A pointer to an array of bytes. This data is not copied. @p
* data must outlive the binary object.
* @param[in] len The length of the @p data byte array.
*
* @returns A new @ref mongocrypt_binary_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_binary_t *
mongocrypt_binary_new_from_data (uint8_t *data, uint32_t len);
/**
* Get a pointer to the viewed data.
*
* @param[in] binary The @ref mongocrypt_binary_t.
*
* @returns A pointer to the viewed data.
*/
MONGOCRYPT_EXPORT
uint8_t *
mongocrypt_binary_data (const mongocrypt_binary_t *binary);
/**
* Get the length of the viewed data.
*
* @param[in] binary The @ref mongocrypt_binary_t.
*
* @returns The length of the viewed data.
*/
MONGOCRYPT_EXPORT
uint32_t
mongocrypt_binary_len (const mongocrypt_binary_t *binary);
/**
* Free the @ref mongocrypt_binary_t.
*
* This does not free the viewed data.
*
* @param[in] binary The mongocrypt_binary_t destroy.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_binary_destroy (mongocrypt_binary_t *binary);
/**
* Indicates success or contains error information.
*
* Functions like @ref mongocrypt_ctx_encrypt_init follow a pattern to expose a
* status. A boolean is returned. True indicates success, and false indicates
* failure. On failure a status on the handle is set, and is accessible with a
* corresponding (handle)_status function. E.g. @ref mongocrypt_ctx_status.
*/
typedef struct _mongocrypt_status_t mongocrypt_status_t;
/**
* Indicates the type of error.
*/
typedef enum {
MONGOCRYPT_STATUS_OK = 0,
MONGOCRYPT_STATUS_ERROR_CLIENT = 1,
- MONGOCRYPT_STATUS_ERROR_KMS = 2
+ MONGOCRYPT_STATUS_ERROR_KMS = 2,
+ MONGOCRYPT_STATUS_ERROR_CRYPT_SHARED = 3,
} mongocrypt_status_type_t;
/**
* Create a new status object.
*
* Use a new status object to retrieve the status from a handle by passing
* this as an out-parameter to functions like @ref mongocrypt_ctx_status.
* When done, destroy it with @ref mongocrypt_status_destroy.
*
* @returns A new status object.
*/
MONGOCRYPT_EXPORT
mongocrypt_status_t *
mongocrypt_status_new (void);
/**
* Set a status object with message, type, and code.
*
* Use this to set the @ref mongocrypt_status_t given in the crypto hooks.
*
* @param[in] type The status type.
* @param[in] code The status code.
* @param[in] message The message.
* @param[in] message_len Due to historical behavior, pass 1 + the string length
* of @p message (which differs from other functions accepting string
* arguments).
* Alternatively, if message is NULL terminated this may be -1 to tell
* mongocrypt
* to determine the string's length with strlen.
*
*/
MONGOCRYPT_EXPORT
void
mongocrypt_status_set (mongocrypt_status_t *status,
mongocrypt_status_type_t type,
uint32_t code,
const char *message,
int32_t message_len);
/**
* Indicates success or the type of error.
*
* @param[in] status The status object.
*
* @returns A @ref mongocrypt_status_type_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_status_type_t
mongocrypt_status_type (mongocrypt_status_t *status);
/**
* Get an error code or 0.
*
* @param[in] status The status object.
*
* @returns An error code.
*/
MONGOCRYPT_EXPORT
uint32_t
mongocrypt_status_code (mongocrypt_status_t *status);
/**
* Get the error message associated with a status or NULL.
*
* @param[in] status The status object.
* @param[out] len An optional length of the returned string (excluding the
* trailing NULL byte). May be NULL.
*
* @returns A NULL terminated error message or NULL.
*/
MONGOCRYPT_EXPORT
const char *
mongocrypt_status_message (mongocrypt_status_t *status, uint32_t *len);
/**
* Returns true if the status indicates success.
*
* @param[in] status The status to check.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_status_ok (mongocrypt_status_t *status);
/**
* Free the memory for a status object.
*
* @param[in] status The status to destroy.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_status_destroy (mongocrypt_status_t *status);
/**
* Indicates the type of log message.
*/
typedef enum {
MONGOCRYPT_LOG_LEVEL_FATAL = 0,
MONGOCRYPT_LOG_LEVEL_ERROR = 1,
MONGOCRYPT_LOG_LEVEL_WARNING = 2,
MONGOCRYPT_LOG_LEVEL_INFO = 3,
MONGOCRYPT_LOG_LEVEL_TRACE = 4
} mongocrypt_log_level_t;
/**
* A log callback function. Set a custom log callback with @ref
* mongocrypt_setopt_log_handler.
*
* @param[in] message A NULL terminated message.
* @param[in] message_len The length of message.
* @param[in] ctx A context provided by the caller of @ref
* mongocrypt_setopt_log_handler.
*/
typedef void (*mongocrypt_log_fn_t) (mongocrypt_log_level_t level,
const char *message,
uint32_t message_len,
void *ctx);
/**
* The top-level handle to libmongocrypt.
*
* Create a mongocrypt_t handle to perform operations within libmongocrypt:
* encryption, decryption, registering log callbacks, etc.
*
* Functions on a mongocrypt_t are thread safe, though functions on derived
* handles (e.g. mongocrypt_ctx_t) are not and must be owned by a single
* thread. See each handle's documentation for thread-safety considerations.
*
* Multiple mongocrypt_t handles may be created.
*/
typedef struct _mongocrypt_t mongocrypt_t;
/**
* Allocate a new @ref mongocrypt_t object.
*
* Set options using mongocrypt_setopt_* functions, then initialize with @ref
* mongocrypt_init. When done with the @ref mongocrypt_t, free with @ref
* mongocrypt_destroy.
*
* @returns A new @ref mongocrypt_t object.
*/
MONGOCRYPT_EXPORT
mongocrypt_t *
mongocrypt_new (void);
/**
* Set a handler on the @ref mongocrypt_t object to get called on every log
* message.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] log_fn The log callback.
* @param[in] log_ctx A context passed as an argument to the log callback every
* invocation.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_log_handler (mongocrypt_t *crypt,
mongocrypt_log_fn_t log_fn,
void *log_ctx);
/**
* Configure an AWS KMS provider on the @ref mongocrypt_t object.
*
* This has been superseded by the more flexible:
* @ref mongocrypt_setopt_kms_providers
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] aws_access_key_id The AWS access key ID used to generate KMS
* messages.
* @param[in] aws_access_key_id_len The string length (in bytes) of @p
* aws_access_key_id. Pass -1 to determine the string length with strlen (must
* be NULL terminated).
* @param[in] aws_secret_access_key The AWS secret access key used to generate
* KMS messages.
* @param[in] aws_secret_access_key_len The string length (in bytes) of @p
* aws_secret_access_key. Pass -1 to determine the string length with strlen
* (must be NULL terminated).
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_kms_provider_aws (mongocrypt_t *crypt,
const char *aws_access_key_id,
int32_t aws_access_key_id_len,
const char *aws_secret_access_key,
int32_t aws_secret_access_key_len);
/**
* Configure a local KMS provider on the @ref mongocrypt_t object.
*
* This has been superseded by the more flexible:
* @ref mongocrypt_setopt_kms_providers
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] key A 96 byte master key used to encrypt and decrypt key vault
* keys. The viewed data is copied. It is valid to destroy @p key with @ref
* mongocrypt_binary_destroy immediately after.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_kms_provider_local (mongocrypt_t *crypt,
mongocrypt_binary_t *key);
/**
* Configure KMS providers with a BSON document.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] kms_providers A BSON document mapping the KMS provider names
- * to credentials.
+ * to credentials. Set a KMS provider value to an empty document to supply
+ * credentials on-demand with @ref mongocrypt_ctx_provide_kms_providers.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_kms_providers (mongocrypt_t *crypt,
mongocrypt_binary_t *kms_providers);
/**
* Set a local schema map for encryption.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] schema_map A BSON document representing the schema map supplied by
* the user. The keys are collection namespaces and values are JSON schemas. The
* viewed data copied. It is valid to destroy @p schema_map with @ref
* mongocrypt_binary_destroy immediately after.
* @pre @p crypt has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_schema_map (mongocrypt_t *crypt,
mongocrypt_binary_t *schema_map);
+/**
+ * Set a local EncryptedFieldConfigMap for encryption.
+ *
+ * @param[in] crypt The @ref mongocrypt_t object.
+ * @param[in] efc_map A BSON document representing the EncryptedFieldConfigMap
+ * supplied by the user. The keys are collection namespaces and values are
+ * EncryptedFieldConfigMap documents. The viewed data copied. It is valid to
+ * destroy @p efc_map with @ref mongocrypt_binary_destroy immediately after.
+ * @pre @p crypt has not been initialized.
+ * @returns A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_status
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_setopt_encrypted_field_config_map (mongocrypt_t *crypt,
+ mongocrypt_binary_t *efc_map);
+
/**
* @brief Append an additional search directory to the search path for loading
- * the CSFLE dynamic library.
+ * the crypt_shared dynamic library.
*
* @param[in] crypt The @ref mongocrypt_t object to update
* @param[in] path A null-terminated sequence of bytes for the search path. On
* some filesystems, this may be arbitrary bytes. On other filesystems, this may
* be required to be a valid UTF-8 code unit sequence. If the leading element of
* the path is the literal string "$ORIGIN", that substring will be replaced
* with the directory path containing the executable libmongocrypt module. If
* the path string is literal "$SYSTEM", then libmongocrypt will defer to the
- * system's library resolution mechanism to find the CSFLE library.
+ * system's library resolution mechanism to find the crypt_shared library.
*
- * @note If no CSFLE dynamic library is found in any of the directories
+ * @note If no crypt_shared dynamic library is found in any of the directories
* specified by the search paths loaded here, @ref mongocrypt_init() will still
- * succeed and continue to operate without CSFLE.
+ * succeed and continue to operate without crypt_shared.
*
* @note The search paths are searched in the order that they are appended. This
* allows one to provide a precedence in how the library will be discovered. For
* example, appending known directories before appending "$SYSTEM" will allow
* one to supersede the system's installed library, but still fall-back to it if
* the library wasn't found otherwise. If one does not ever append "$SYSTEM",
* then the system's library-search mechanism will never be consulted.
*
* @note If an absolute path to the library is specified using
- * @ref mongocrypt_setopt_set_csfle_lib_path_override, then paths appended here
- * will have no effect.
+ * @ref mongocrypt_setopt_set_crypt_shared_lib_path_override, then paths
+ * appended here will have no effect.
*/
MONGOCRYPT_EXPORT
void
-mongocrypt_setopt_append_csfle_search_path (mongocrypt_t *crypt,
- const char *path);
+mongocrypt_setopt_append_crypt_shared_lib_search_path (mongocrypt_t *crypt,
+ const char *path);
/**
- * @brief Set a single override path for loading the CSFLE dynamic library.
+ * @brief Set a single override path for loading the crypt_shared dynamic
+ * library.
*
* @param[in] crypt The @ref mongocrypt_t object to update
- * @param[in] path A null-terminated sequence of bytes for a path to the CSFLE
- * dynamic library. On some filesystems, this may be arbitrary bytes. On other
- * filesystems, this may be required to be a valid UTF-8 code unit sequence. If
- * the leading element of the path is the literal string `$ORIGIN`, that
- * substring will be replaced with the directory path containing the executable
- * libmongocrypt module.
+ * @param[in] path A null-terminated sequence of bytes for a path to the
+ * crypt_shared dynamic library. On some filesystems, this may be arbitrary
+ * bytes. On other filesystems, this may be required to be a valid UTF-8 code
+ * unit sequence. If the leading element of the path is the literal string
+ * `$ORIGIN`, that substring will be replaced with the directory path containing
+ * the executable libmongocrypt module.
*
* @note This function will do no IO nor path validation. All validation will
* occur during the call to @ref mongocrypt_init.
*
- * @note If a CSFLE library path override is specified here, then no paths given
- * to @ref mongocrypt_setopt_append_csfle_search_path will be consulted when
- * opening the CSFLE library.
+ * @note If a crypt_shared library path override is specified here, then no
+ * paths given to @ref mongocrypt_setopt_append_crypt_shared_lib_search_path
+ * will be consulted when opening the crypt_shared library.
*
* @note If a path is provided via this API and @ref mongocrypt_init fails to
- * initialize a valid CSFLE library instance for the path specified, then
+ * initialize a valid crypt_shared library instance for the path specified, then
* the initialization of mongocrypt_t will fail with an error.
*/
MONGOCRYPT_EXPORT
void
-mongocrypt_setopt_set_csfle_lib_path_override (mongocrypt_t *crypt,
- const char *path);
+mongocrypt_setopt_set_crypt_shared_lib_path_override (mongocrypt_t *crypt,
+ const char *path);
+
+
+/**
+ * @brief Opt-into handling the MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS state.
+ *
+ * If set, before entering the MONGOCRYPT_CTX_NEED_KMS state,
+ * contexts may enter the MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS state
+ * and then wait for credentials to be supplied through
+ * @ref mongocrypt_ctx_provide_kms_providers.
+ *
+ * A context will only enter MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS
+ * if an empty document was set for a KMS provider in @ref
+ * mongocrypt_setopt_kms_providers.
+ *
+ * @param[in] crypt The @ref mongocrypt_t object to update
+ */
+MONGOCRYPT_EXPORT
+void
+mongocrypt_setopt_use_need_kms_credentials_state (mongocrypt_t *crypt);
/**
* Initialize new @ref mongocrypt_t object.
*
* Set options before using @ref mongocrypt_setopt_kms_provider_local, @ref
* mongocrypt_setopt_kms_provider_aws, or @ref mongocrypt_setopt_log_handler.
*
* @param[in] crypt The @ref mongocrypt_t object.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status Failure may occur if previously
* set
* options are invalid.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_init (mongocrypt_t *crypt);
/**
* Get the status associated with a @ref mongocrypt_t object.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[out] status Receives the status.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_status (mongocrypt_t *crypt, mongocrypt_status_t *status);
/**
* Destroy the @ref mongocrypt_t object.
*
* @param[in] crypt The @ref mongocrypt_t object to destroy.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_destroy (mongocrypt_t *crypt);
+/**
+ * Obtain a nul-terminated version string of the loaded crypt_shared dynamic
+ * library, if available.
+ *
+ * If no crypt_shared was successfully loaded, this function returns NULL.
+ *
+ * @param[in] crypt The mongocrypt_t object after a successful call to
+ * mongocrypt_init.
+ * @param[out] len An optional output parameter to which the length of the
+ * returned string is written. If provided and no crypt_shared library was
+ * loaded, zero is written to *len.
+ *
+ * @return A nul-terminated string of the dynamically loaded crypt_shared
+ * library.
+ *
+ * @note For a numeric value that can be compared against, use
+ * @ref mongocrypt_crypt_shared_lib_version.
+ */
+MONGOCRYPT_EXPORT
+const char *
+mongocrypt_crypt_shared_lib_version_string (const mongocrypt_t *crypt,
+ uint32_t *len);
+
+
+/**
+ * @brief Obtain a 64-bit constant encoding the version of the loaded
+ * crypt_shared library, if available.
+ *
+ * @param[in] crypt The mongocrypt_t object after a successul call to
+ * mongocrypt_init.
+ *
+ * @return A 64-bit encoded version number, with the version encoded as four
+ * sixteen-bit integers, or zero if no crypt_shared library was loaded.
+ *
+ * The version is encoded as four 16-bit numbers, from high to low:
+ *
+ * - Major version
+ * - Minor version
+ * - Revision
+ * - Reserved
+ *
+ * For example, version 6.2.1 would be encoded as: 0x0006'0002'0001'0000
+ */
+MONGOCRYPT_EXPORT
+uint64_t
+mongocrypt_crypt_shared_lib_version (const mongocrypt_t *crypt);
+
/**
* Manages the state machine for encryption or decryption.
*/
typedef struct _mongocrypt_ctx_t mongocrypt_ctx_t;
/**
* Create a new uninitialized @ref mongocrypt_ctx_t.
*
* Initialize the context with functions like @ref mongocrypt_ctx_encrypt_init.
* When done, destroy it with @ref mongocrypt_ctx_destroy.
*
* @param[in] crypt The @ref mongocrypt_t object.
* @returns A new context.
*/
MONGOCRYPT_EXPORT
mongocrypt_ctx_t *
mongocrypt_ctx_new (mongocrypt_t *crypt);
/**
* Get the status associated with a @ref mongocrypt_ctx_t object.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[out] status Receives the status.
*
* @returns True if the output is an ok status, false if it is an error
* status.
*
* @see mongocrypt_status_ok
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_status (mongocrypt_ctx_t *ctx, mongocrypt_status_t *status);
/**
* Set the key id to use for explicit encryption.
*
* It is an error to set both this and the key alt name.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] key_id The binary corresponding to the _id (a UUID) of the data
* key to use from the key vault collection. Note, the UUID must be encoded with
* RFC-4122 byte order. The viewed data is copied. It is valid to destroy
* @p key_id with @ref mongocrypt_binary_destroy immediately after.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_key_id (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_id);
/**
* Set the keyAltName to use for explicit encryption or
* data key creation.
*
* Pass the binary encoding a BSON document like the following:
*
* { "keyAltName" : (BSON UTF8 value) }
*
* For explicit encryption, it is an error to set both the keyAltName
* and the key id.
*
* For creating data keys, call this function repeatedly to set
* multiple keyAltNames.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] key_alt_name The name to use. The viewed data is copied. It is
* valid to destroy @p key_alt_name with @ref mongocrypt_binary_destroy
* immediately after.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_key_alt_name (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_alt_name);
/**
* Set the keyMaterial to use for encrypting data.
*
* Pass the binary encoding of a BSON document like the following:
*
* { "keyMaterial" : (BSON BINARY value) }
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] key_material The data encryption key to use. The viewed data is
* copied. It is valid to destroy @p key_material with @ref
* mongocrypt_binary_destroy immediately after.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_key_material (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *key_material);
/**
* Set the algorithm used for encryption to either
* deterministic or random encryption. This value
* should only be set when using explicit encryption.
*
* If -1 is passed in for "len", then "algorithm" is
* assumed to be a null-terminated string.
*
* Valid values for algorithm are:
* "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
* "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] algorithm A string specifying the algorithm to
* use for encryption.
* @param[in] len The length of the algorithm string.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_algorithm (mongocrypt_ctx_t *ctx,
const char *algorithm,
int len);
+/// String constant for setopt_algorithm "Deterministic" encryption
+#define MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR \
+ "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+/// String constant for setopt_algorithm "Random" encryption
+#define MONGOCRYPT_ALGORITHM_RANDOM_STR "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+/// String constant for setopt_algorithm "Indexed" explicit encryption
+#define MONGOCRYPT_ALGORITHM_INDEXED_STR "Indexed"
+/// String constant for setopt_algorithm "Unindexed" explicit encryption
+#define MONGOCRYPT_ALGORITHM_UNINDEXED_STR "Unindexed"
+
/**
* Identify the AWS KMS master key to use for creating a data key.
*
* This has been superseded by the more flexible:
* @ref mongocrypt_ctx_setopt_key_encryption_key
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] region The AWS region.
* @param[in] region_len The string length of @p region. Pass -1 to determine
* the string length with strlen (must be NULL terminated).
* @param[in] cmk The Amazon Resource Name (ARN) of the customer master key
* (CMK).
* @param[in] cmk_len The string length of @p cmk_len. Pass -1 to determine the
* string length with strlen (must be NULL terminated).
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_masterkey_aws (mongocrypt_ctx_t *ctx,
const char *region,
int32_t region_len,
const char *cmk,
int32_t cmk_len);
/**
* Identify a custom AWS endpoint when creating a data key.
* This is used internally to construct the correct HTTP request
* (with the Host header set to this endpoint). This endpoint
* is persisted in the new data key, and will be returned via
* @ref mongocrypt_kms_ctx_endpoint.
*
* This has been superseded by the more flexible:
* @ref mongocrypt_ctx_setopt_key_encryption_key
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] endpoint The endpoint.
* @param[in] endpoint_len The string length of @p endpoint. Pass -1 to
* determine the string length with strlen (must be NULL terminated).
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_masterkey_aws_endpoint (mongocrypt_ctx_t *ctx,
const char *endpoint,
int32_t endpoint_len);
/**
* Set the master key to "local" for creating a data key.
* This has been superseded by the more flexible:
* @ref mongocrypt_ctx_setopt_key_encryption_key
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_masterkey_local (mongocrypt_ctx_t *ctx);
/**
- * Set key encryption key document for creating a data key.
+ * Set key encryption key document for creating a data key or for rewrapping
+ * datakeys.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] bin BSON representing the key encryption key document with
* an additional "provider" field. The following forms are accepted:
*
* AWS
* {
* provider: "aws",
* region: <string>,
* key: <string>,
* endpoint: <optional string>
* }
*
* Azure
* {
* provider: "azure",
* keyVaultEndpoint: <string>,
* keyName: <string>,
* keyVersion: <optional string>
* }
*
* GCP
* {
* provider: "gcp",
* projectId: <string>,
* location: <string>,
* keyRing: <string>,
* keyName: <string>,
* keyVersion: <string>,
* endpoint: <optional string>
* }
*
* Local
* {
* provider: "local"
* }
*
* KMIP
* {
* provider: "kmip",
* keyId: <optional string>
* endpoint: <string>
* }
*
* @pre @p ctx has not been initialized.
* @returns A boolean indicating success. If false, and error status is set.
* Retrieve it with @ref mongocrypt_ctx_status.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_setopt_key_encryption_key (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *bin);
/**
* Initialize a context to create a data key.
*
* Associated options:
* - @ref mongocrypt_ctx_setopt_masterkey_aws
* - @ref mongocrypt_ctx_setopt_masterkey_aws_endpoint
* - @ref mongocrypt_ctx_setopt_masterkey_local
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
* @pre A master key option has been set, and an associated KMS provider
* has been set on the parent @ref mongocrypt_t.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_datakey_init (mongocrypt_ctx_t *ctx);
/**
* Initialize a context for encryption.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] db The database name.
* @param[in] db_len The byte length of @p db. Pass -1 to determine the string
* length with strlen (must
* be NULL terminated).
* @param[in] cmd The BSON command to be encrypted. The viewed data is copied.
* It is valid to destroy @p cmd with @ref mongocrypt_binary_destroy immediately
* after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_encrypt_init (mongocrypt_ctx_t *ctx,
const char *db,
int32_t db_len,
mongocrypt_binary_t *cmd);
/**
* Explicit helper method to encrypt a single BSON object. Contexts
* created for explicit encryption will not go through mongocryptd.
*
* To specify a key_id, algorithm, or iv to use, please use the
* corresponding mongocrypt_setopt methods before calling this.
*
* This method expects the passed-in BSON to be of the form:
* { "v" : BSON value to encrypt }
*
- * Associated options:
+ * Associated options for FLE 1:
* - @ref mongocrypt_ctx_setopt_key_id
* - @ref mongocrypt_ctx_setopt_key_alt_name
* - @ref mongocrypt_ctx_setopt_algorithm
*
+ * Associated options for Queryable Encryption:
+ * - @ref mongocrypt_ctx_setopt_key_id
+ * - @ref mongocrypt_ctx_setopt_index_key_id
+ * - @ref mongocrypt_ctx_setopt_contention_factor
+ * - @ref mongocrypt_ctx_setopt_query_type
+ *
+ * An error is returned if FLE 1 and Queryable Encryption incompatible options
+ * are set.
+ *
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @param[in] msg A @ref mongocrypt_binary_t the plaintext BSON value. The
* viewed data is copied. It is valid to destroy @p msg with @ref
* mongocrypt_binary_destroy immediately after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *msg);
/**
* Initialize a context for decryption.
*
* This method expects the passed-in BSON to be of the form:
* { "v" : BSON value to encrypt }
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] doc The document to be decrypted. The viewed data is copied. It is
* valid to destroy @p doc with @ref mongocrypt_binary_destroy immediately
* after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_decrypt_init (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *doc);
/**
* Explicit helper method to decrypt a single BSON object.
*
+ * Pass the binary encoding of a BSON document containing the BSON value to
+ * encrypt like the following:
+ *
+ * { "v" : (BSON BINARY value of subtype 6) }
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @param[in] msg A @ref mongocrypt_binary_t the encrypted BSON. The viewed data
* is copied. It is valid to destroy @p msg with @ref mongocrypt_binary_destroy
* immediately after.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_explicit_decrypt_init (mongocrypt_ctx_t *ctx,
mongocrypt_binary_t *msg);
+/**
+ * @brief Initialize a context to rewrap datakeys.
+ *
+ * Associated options:
+ * - @ref mongocrypt_ctx_setopt_key_encryption_key
+ *
+ * @param[in] ctx The @ref mongocrypt_ctx_t object.
+ * @param[in] filter The filter to use for the find command on the key vault
+ * collection to retrieve datakeys to rewrap.
+ * @return A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_ctx_status.
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_ctx_rewrap_many_datakey_init (mongocrypt_ctx_t *ctx,
+ mongocrypt_binary_t *filter);
+
+
/**
* Indicates the state of the @ref mongocrypt_ctx_t. Each state requires
* different handling. See [the integration
* guide](https://github.com/mongodb/libmongocrypt/blob/master/integrating.md#state-machine)
* for information on what to do for each state.
*/
typedef enum {
MONGOCRYPT_CTX_ERROR = 0,
MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1, /* run on main MongoClient */
MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2, /* run on mongocryptd. */
MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3, /* run on key vault */
MONGOCRYPT_CTX_NEED_KMS = 4,
+ MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS = 7, /* fetch/renew KMS credentials */
MONGOCRYPT_CTX_READY = 5, /* ready for encryption/decryption */
- MONGOCRYPT_CTX_DONE = 6
+ MONGOCRYPT_CTX_DONE = 6,
} mongocrypt_ctx_state_t;
/**
* Get the current state of a context.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @returns A @ref mongocrypt_ctx_state_t.
*/
MONGOCRYPT_EXPORT
mongocrypt_ctx_state_t
mongocrypt_ctx_state (mongocrypt_ctx_t *ctx);
/**
* Get BSON necessary to run the mongo operation when mongocrypt_ctx_t
* is in MONGOCRYPT_CTX_NEED_MONGO_* states.
*
* @p op_bson is a BSON document to be used for the operation.
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a listCollections filter.
* - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a find filter.
* - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a command to send to
* mongocryptd.
*
* The lifetime of @p op_bson is tied to the lifetime of @p ctx. It is valid
* until @ref mongocrypt_ctx_destroy is called.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[out] op_bson A BSON document for the MongoDB operation. The data
* viewed by @p op_bson is guaranteed to be valid until @p ctx is destroyed with
* @ref mongocrypt_ctx_destroy.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_mongo_op (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *op_bson);
/**
* Feed a BSON reply or result when mongocrypt_ctx_t is in
* MONGOCRYPT_CTX_NEED_MONGO_* states. This may be called multiple times
* depending on the operation.
*
* reply is a BSON document result being fed back for this operation.
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a doc from a listCollections
* cursor. (Note, if listCollections returned no result, do not call this
* function.)
* - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a doc from a find cursor.
* (Note, if find returned no results, do not call this function. reply must
* not
* be NULL.)
* - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a reply from mongocryptd.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @param[in] reply A BSON document for the MongoDB operation. The viewed data
* is copied. It is valid to destroy @p reply with @ref
* mongocrypt_binary_destroy immediately after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_mongo_feed (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *reply);
/**
* Call when done feeding the reply (or replies) back to the context.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_mongo_done (mongocrypt_ctx_t *ctx);
/**
* Manages a single KMS HTTP request/response.
*/
typedef struct _mongocrypt_kms_ctx_t mongocrypt_kms_ctx_t;
/**
* Get the next KMS handle.
*
* Multiple KMS handles may be retrieved at once. Drivers may do this to fan
* out multiple concurrent KMS HTTP requests. Feeding multiple KMS requests
* is thread-safe.
*
* If KMS handles are being handled synchronously, the driver can reuse the same
* TLS socket to send HTTP requests and receive responses.
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @returns a new @ref mongocrypt_kms_ctx_t or NULL.
*/
MONGOCRYPT_EXPORT
mongocrypt_kms_ctx_t *
mongocrypt_ctx_next_kms_ctx (mongocrypt_ctx_t *ctx);
/**
* Get the HTTP request message for a KMS handle.
*
* The lifetime of @p msg is tied to the lifetime of @p kms. It is valid
* until @ref mongocrypt_ctx_kms_done is called.
*
* @param[in] kms A @ref mongocrypt_kms_ctx_t.
* @param[out] msg The HTTP request to send to KMS. The data viewed by @p msg is
* guaranteed to be valid until the call of @ref mongocrypt_ctx_kms_done of the
* parent @ref mongocrypt_ctx_t.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_kms_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_message (mongocrypt_kms_ctx_t *kms,
mongocrypt_binary_t *msg);
/**
* Get the hostname from which to connect over TLS.
*
* The storage for @p endpoint is not owned by the caller, but
* is valid until calling @ref mongocrypt_ctx_kms_done.
*
* @param[in] kms A @ref mongocrypt_kms_ctx_t.
* @param[out] endpoint The output endpoint as a NULL terminated string.
* The endpoint consists of a hostname and port separated by a colon.
* E.g. "example.com:123". A port is always present.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_kms_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_endpoint (mongocrypt_kms_ctx_t *kms, const char **endpoint);
/**
* Indicates how many bytes to feed into @ref mongocrypt_kms_ctx_feed.
*
* @param[in] kms The @ref mongocrypt_kms_ctx_t.
* @returns The number of requested bytes.
*/
MONGOCRYPT_EXPORT
uint32_t
mongocrypt_kms_ctx_bytes_needed (mongocrypt_kms_ctx_t *kms);
/**
* Feed bytes from the HTTP response.
*
* Feeding more bytes than what has been returned in @ref
* mongocrypt_kms_ctx_bytes_needed is an error.
*
* @param[in] kms The @ref mongocrypt_kms_ctx_t.
* @param[in] bytes The bytes to feed. The viewed data is copied. It is valid to
* destroy @p bytes with @ref mongocrypt_binary_destroy immediately after.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_kms_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_feed (mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes);
/**
* Get the status associated with a @ref mongocrypt_kms_ctx_t object.
*
* @param[in] kms The @ref mongocrypt_kms_ctx_t object.
* @param[out] status Receives the status.
*
* @returns A boolean indicating success. If false, an error status is set.
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_kms_ctx_status (mongocrypt_kms_ctx_t *kms,
mongocrypt_status_t *status);
/**
* Get the KMS provider identifier associated with this KMS request.
*
* This is used to conditionally configure TLS connections based on the KMS
* request. It is useful for KMIP, which authenticates with a client
* certificate.
*
* @param[in] kms The @ref mongocrypt_kms_ctx_t object.
* @param[out] len Receives the length of the returned string. It may be NULL.
* If it is not NULL, it is set to the length of the returned string without
* the NULL terminator.
*
* @returns One of the NULL terminated static strings: "aws", "azure", "gcp", or
* "kmip".
*/
MONGOCRYPT_EXPORT
const char *
mongocrypt_kms_ctx_get_kms_provider (mongocrypt_kms_ctx_t *kms, uint32_t *len);
/**
* Call when done handling all KMS contexts.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_kms_done (mongocrypt_ctx_t *ctx);
+/**
+ * Call in response to the MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS state
+ * to set per-context KMS provider settings. These follow the same format
+ * as @ref mongocrypt_setopt_kms_providers. If no keys are present in the
+ * BSON input, the KMS provider settings configured for the @ref mongocrypt_t
+ * at initialization are used.
+ *
+ * @param[in] ctx The @ref mongocrypt_ctx_t object.
+ * @param[in] kms_providers A BSON document mapping the KMS provider names
+ * to credentials.
+ *
+ * @returns A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_ctx_status.
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_ctx_provide_kms_providers (
+ mongocrypt_ctx_t *ctx, mongocrypt_binary_t *kms_providers_definition);
+
/**
* Perform the final encryption or decryption.
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
* @param[out] out The final BSON. The data viewed by @p out is guaranteed
* to be valid until @p ctx is destroyed with @ref mongocrypt_ctx_destroy.
* The meaning of this BSON depends on the type of @p ctx.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_encrypt_init, then
* this BSON is the (possibly) encrypted command to send to the server.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_decrypt_init, then
* this BSON is the decrypted result to return to the user.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_explicit_encrypt_init,
* then this BSON has the form { "v": (BSON binary) } where the BSON binary
* is the resulting encrypted value.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_explicit_decrypt_init,
* then this BSON has the form { "v": (BSON value) } where the BSON value
* is the resulting decrypted value.
*
* If @p ctx was initialized with @ref mongocrypt_ctx_datakey_init, then
* this BSON is the document containing the new data key to be inserted into
* the key vault collection.
*
+ * If @p ctx was initialized with @ref mongocrypt_ctx_rewrap_many_datakey_init,
+ * then this BSON has the form { "v": [(BSON document), ...] } where each BSON
+ * document in the array is a document containing a rewrapped datakey to be
+ * bulk-updated into the key vault collection.
+ *
* @returns a bool indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_ctx_status
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_ctx_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);
/**
* Destroy and free all memory associated with a @ref mongocrypt_ctx_t.
*
* @param[in] ctx A @ref mongocrypt_ctx_t.
*/
MONGOCRYPT_EXPORT
void
mongocrypt_ctx_destroy (mongocrypt_ctx_t *ctx);
/**
* An crypto AES-256-CBC encrypt or decrypt function.
*
* Note, @p in is already padded. Encrypt with padding disabled.
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[in] key An encryption key (32 bytes for AES_256).
* @param[in] iv An initialization vector (16 bytes for AES_256);
* @param[in] in The input.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[out] bytes_written Set this to the number of bytes written to @p out.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_crypto_fn) (void *ctx,
mongocrypt_binary_t *key,
mongocrypt_binary_t *iv,
mongocrypt_binary_t *in,
mongocrypt_binary_t *out,
uint32_t *bytes_written,
mongocrypt_status_t *status);
/**
* A crypto signature or HMAC function.
*
* Currently used in callbacks for HMAC SHA-512, HMAC SHA-256, and RSA SHA-256
* signature.
*
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[in] key An encryption key (32 bytes for HMAC_SHA512).
* @param[in] in The input.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_hmac_fn) (void *ctx,
mongocrypt_binary_t *key,
mongocrypt_binary_t *in,
mongocrypt_binary_t *out,
mongocrypt_status_t *status);
/**
* A crypto hash (SHA-256) function.
*
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[in] in The input.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_hash_fn) (void *ctx,
mongocrypt_binary_t *in,
mongocrypt_binary_t *out,
mongocrypt_status_t *status);
/**
* A crypto secure random function.
*
* @param[in] ctx An optional context object that may have been set when hooks
* were enabled.
* @param[out] out A preallocated byte array for the output. See @ref
* mongocrypt_binary_data.
* @param[in] count The number of random bytes requested.
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_random_fn) (void *ctx,
mongocrypt_binary_t *out,
uint32_t count,
mongocrypt_status_t *status);
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_crypto_hooks (mongocrypt_t *crypt,
mongocrypt_crypto_fn aes_256_cbc_encrypt,
mongocrypt_crypto_fn aes_256_cbc_decrypt,
mongocrypt_random_fn random,
mongocrypt_hmac_fn hmac_sha_512,
mongocrypt_hmac_fn hmac_sha_256,
mongocrypt_hash_fn sha_256,
void *ctx);
+/**
+ * Set a crypto hook for the AES256-CTR operations.
+ *
+ * @param[in] crypt The @ref mongocrypt_t object.
+ * @param[in] aes_256_ctr_encrypt The crypto callback function for encrypt
+ * operation.
+ * @param[in] aes_256_ctr_decrypt The crypto callback function for decrypt
+ * operation.
+ * @param[in] ctx A context passed as an argument to the crypto callback
+ * every invocation.
+ * @pre @ref mongocrypt_init has not been called on @p crypt.
+ * @returns A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_status
+ *
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_setopt_aes_256_ctr (mongocrypt_t *crypt,
+ mongocrypt_crypto_fn aes_256_ctr_encrypt,
+ mongocrypt_crypto_fn aes_256_ctr_decrypt,
+ void *ctx);
+
+/**
+ * Set an AES256-ECB crypto hook for the AES256-CTR operations. If CTR hook was
+ * configured using @ref mongocrypt_setopt_aes_256_ctr, ECB hook will be
+ * ignored.
+ *
+ * @param[in] crypt The @ref mongocrypt_t object.
+ * @param[in] aes_256_ecb_encrypt The crypto callback function for encrypt
+ * operation.
+ * @param[in] ctx A context passed as an argument to the crypto callback
+ * every invocation.
+ * @pre @ref mongocrypt_init has not been called on @p crypt.
+ * @returns A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_status
+ *
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_setopt_aes_256_ecb (mongocrypt_t *crypt,
+ mongocrypt_crypto_fn aes_256_ecb_encrypt,
+ void *ctx);
+
/**
* Set a crypto hook for the RSASSA-PKCS1-v1_5 algorithm with a SHA-256 hash.
*
* See: https://tools.ietf.org/html/rfc3447#section-8.2
*
* Note: this function has the wrong name. It should be:
* mongocrypt_setopt_crypto_hook_sign_rsassa_pkcs1_v1_5
*
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] sign_rsaes_pkcs1_v1_5 The crypto callback function.
* @param[in] sign_ctx A context passed as an argument to the crypto callback
* every invocation.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_status
*
*/
MONGOCRYPT_EXPORT
bool
mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 (
mongocrypt_t *crypt,
mongocrypt_hmac_fn sign_rsaes_pkcs1_v1_5,
void *sign_ctx);
+/**
+ * @brief Opt-into skipping query analysis.
+ *
+ * If opted in:
+ * - The crypt_shared library will not attempt to be loaded.
+ * - A mongocrypt_ctx_t will never enter the MONGOCRYPT_CTX_NEED_MARKINGS state.
+ *
+ * @param[in] crypt The @ref mongocrypt_t object to update
+ */
+MONGOCRYPT_EXPORT
+void
+mongocrypt_setopt_bypass_query_analysis (mongocrypt_t *crypt);
+
+/**
+ * Set the contention factor used for explicit encryption.
+ * The contention factor is only used for indexed Queryable Encryption.
+ *
+ * @param[in] ctx The @ref mongocrypt_ctx_t object.
+ * @param[in] contention_factor
+ * @pre @p ctx has not been initialized.
+ * @returns A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_ctx_status.
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_ctx_setopt_contention_factor (mongocrypt_ctx_t *ctx,
+ int64_t contention_factor);
+
+/**
+ * Set the index key id to use for explicit Queryable Encryption.
+ *
+ * If the index key id not set, the key id from @ref
+ * mongocrypt_ctx_setopt_key_id is used.
+ *
+ * @param[in] ctx The @ref mongocrypt_ctx_t object.
+ * @param[in] key_id The binary corresponding to the _id (a UUID) of the data
+ * key to use from the key vault collection. Note, the UUID must be encoded with
+ * RFC-4122 byte order. The viewed data is copied. It is valid to destroy
+ * @p key_id with @ref mongocrypt_binary_destroy immediately after.
+ * @pre @p ctx has not been initialized.
+ * @returns A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_ctx_status
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_ctx_setopt_index_key_id (mongocrypt_ctx_t *ctx,
+ mongocrypt_binary_t *key_id);
+
+
+/**
+ * Set the query type to use for explicit Queryable Encryption.
+ *
+ * @param[in] ctx The @ref mongocrypt_ctx_t object.
+ * @param[in] query_type The query type string
+ * @param[in] len The length of query_type, or -1 for automatic
+ * @pre @p ctx has not been initialized.
+ * @returns A boolean indicating success. If false, an error status is set.
+ * Retrieve it with @ref mongocrypt_ctx_status
+ */
+MONGOCRYPT_EXPORT
+bool
+mongocrypt_ctx_setopt_query_type (mongocrypt_ctx_t *ctx,
+ const char *query_type,
+ int len);
+
+/// String constant for setopt_query_type_v2, "equality" query type
+#define MONGOCRYPT_QUERY_TYPE_EQUALITY_STR "equality"
+
#endif /* MONGOCRYPT_H */
diff --git a/mongodb-1.14.0/src/libmongocrypt/src/os_posix/os_dll.c b/mongodb-1.14.0/src/libmongocrypt/src/os_posix/os_dll.c
new file mode 100644
index 00000000..52b4db6d
--- /dev/null
+++ b/mongodb-1.14.0/src/libmongocrypt/src/os_posix/os_dll.c
@@ -0,0 +1,132 @@
+// Turn on libc extensions so that we can use dladdr() on Unix-like systems
+#if defined(__has_include) && \
+ !(defined(_GNU_SOURCE) || defined(_DARWIN_C_SOURCE))
+#if __has_include(<features.h>)
+// We're using a glibc-compatible library
+#define _GNU_SOURCE
+#elif __has_include(<Availability.h>)
+// We're on Apple/Darwin
+#define _DARWIN_C_SOURCE
+#endif
+#else // No __has_include
+#if __GNUC__ < 5
+// Best guess on older GCC is that we are using glibc
+#define _GNU_SOURCE
+#endif
+#endif
+
+#include "../mongocrypt-dll-private.h"
+
+#ifndef _WIN32
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <dlfcn.h>
+
+mcr_dll
+mcr_dll_open (const char *filepath)
+{
+ void *handle = dlopen (filepath, RTLD_LAZY | RTLD_LOCAL);
+ if (handle == NULL) {
+ // Failed to open. Return NULL and copy the error message
+ return (mcr_dll){
+ ._native_handle = NULL,
+ .error_string = mstr_copy_cstr (dlerror ()),
+ };
+ } else {
+ // Okay
+ return (mcr_dll){
+ ._native_handle = handle,
+ .error_string = MSTR_NULL,
+ };
+ }
+}
+
+void
+mcr_dll_close_handle (mcr_dll dll)
+{
+ if (dll._native_handle) {
+ dlclose (dll._native_handle);
+ }
+}
+
+void *
+mcr_dll_sym (mcr_dll dll, const char *sym)
+{
+ return dlsym (dll._native_handle, sym);
+}
+
+#endif
+
+#ifdef __APPLE__
+
+#include <mach-o/dyld.h>
+#include <mach-o/nlist.h>
+
+mcr_dll_path_result
+mcr_dll_path (mcr_dll dll)
+{
+ // Clear the three low bits of the module handle:
+ uintptr_t needle = ((uintptr_t) dll._native_handle & ~UINT64_C (0x3));
+ // Iterate each loaded dyld image
+ /// NOTE: Not thread safe. Is there a thread-safe way to do this?
+ for (size_t idx = 0; idx < _dyld_image_count (); ++idx) {
+ // Get the filepath:
+ /// NOTE: Between here and `dlopen`, `dyld_name` could be invalidated by
+ /// a concurrent call to `dlclose()`. Is there a better way?
+ const char *dyld_name = _dyld_get_image_name (idx);
+ // Try and open it. This will return an equivalent pointer to the original
+ // handle to the loaded image since they are deduplicated and reference
+ // counted.
+ void *try_handle = dlopen (dyld_name, RTLD_LAZY);
+ if (!dyld_name) {
+ // Ouch: `idx` was invalidated before we called _dyld_get_image_name.
+ // This will have caused `dlopen()` to return the default handle:
+ assert (try_handle == RTLD_DEFAULT);
+ continue;
+ }
+ // Copy the string before closing, to shrink the chance of `dyld_name`
+ // being used-after-freed.
+ mstr ret_name = mstr_copy_cstr (dyld_name);
+ // Mask off the mode bits:
+ uintptr_t cur = (uintptr_t) try_handle & ~UINT64_C (0x3);
+ // Close our reference to the image. We only care about the handle value.
+ dlclose (try_handle);
+ if (needle == cur) {
+ // We've found the handle
+ return (mcr_dll_path_result){.path = ret_name};
+ }
+ // Not this name.
+ mstr_free (ret_name);
+ }
+ return (mcr_dll_path_result){
+ .error_string = mstr_copy_cstr ("Handle not found in loaded modules")};
+}
+
+#elif defined(__linux__)
+
+#include <link.h>
+
+mcr_dll_path_result
+mcr_dll_path (mcr_dll dll)
+{
+ struct link_map *map;
+ int rc = dlinfo (dll._native_handle, RTLD_DI_LINKMAP, &map);
+ if (rc == 0) {
+ return (mcr_dll_path_result){.path = mstr_copy_cstr (map->l_name)};
+ } else {
+ return (mcr_dll_path_result){.error_string = mstr_copy_cstr (dlerror ())};
+ }
+}
+
+#elif defined(_WIN32)
+
+// Handled in os_win/os_dll.c
+
+#else
+
+#error "Don't know how to do mcr_dll_path() on this platform"
+
+#endif
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/os_posix/os_mutex.c b/mongodb-1.14.0/src/libmongocrypt/src/os_posix/os_mutex.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/os_posix/os_mutex.c
rename to mongodb-1.14.0/src/libmongocrypt/src/os_posix/os_mutex.c
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/os_win/os_dll.c b/mongodb-1.14.0/src/libmongocrypt/src/os_win/os_dll.c
similarity index 64%
rename from mongodb-1.13.0/src/libmongocrypt/src/os_win/os_dll.c
rename to mongodb-1.14.0/src/libmongocrypt/src/os_win/os_dll.c
index 26920d64..3eeb9d2b 100644
--- a/mongodb-1.13.0/src/libmongocrypt/src/os_win/os_dll.c
+++ b/mongodb-1.14.0/src/libmongocrypt/src/os_win/os_dll.c
@@ -1,60 +1,90 @@
#include "../mongocrypt-dll-private.h"
#ifdef _WIN32
#include <mlib/str.h>
#include <mlib/path.h>
#include <mlib/error.h>
#include <string.h>
#include <stdio.h>
#include <windows.h>
mcr_dll
mcr_dll_open (const char *filepath_)
{
// Convert all slashes to the native Windows separator
mstr filepath =
mpath_to_format (MPATH_WIN32, mstrv_view_cstr (filepath_), MPATH_WIN32);
// Check if the path is just a filename.
bool is_just_filename =
mstr_eq (mpath_filename (filepath.view, MPATH_WIN32), filepath.view);
if (!is_just_filename) {
// If the path is only a filename, we'll allow LoadLibrary() to do a
// proper full DLL search. If the path is NOT just a filename, resolve the
// given path to a single unambiguous absolute path to suppress
// LoadLibrary()'s DLL search behavior.
mstr_assign (&filepath, mpath_absolute (filepath.view, MPATH_WIN32));
}
mstr_widen_result wide = mstr_win32_widen (filepath.view);
mstr_free (filepath);
if (wide.error) {
return (mcr_dll){._native_handle = NULL,
.error_string = merror_system_error_string (wide.error)};
}
HMODULE lib = LoadLibraryW (wide.wstring);
if (lib == NULL) {
return (mcr_dll){._native_handle = NULL,
.error_string =
merror_system_error_string (GetLastError ())};
}
free (wide.wstring);
return (mcr_dll){.error_string = NULL, ._native_handle = lib};
}
void
mcr_dll_close_handle (mcr_dll dll)
{
if (dll._native_handle) {
FreeLibrary (dll._native_handle);
}
}
void *
mcr_dll_sym (mcr_dll dll, const char *sym)
{
return GetProcAddress (dll._native_handle, sym);
}
+mcr_dll_path_result
+mcr_dll_path (mcr_dll dll)
+{
+ mstr ret_str = MSTR_NULL;
+ int ret_error = 0;
+ DWORD acc_size = 512;
+ while (!ret_str.data && !ret_error) {
+ // Loop until we allocate a large enough buffer or get an error
+ wchar_t *path = calloc (acc_size + 1, sizeof (wchar_t));
+ SetLastError (0);
+ GetModuleFileNameW (dll._native_handle, path, acc_size);
+ if (GetLastError () == ERROR_INSUFFICIENT_BUFFER) {
+ // Try again with more buffer
+ acc_size *= 2;
+ } else if (GetLastError () != 0) {
+ ret_error = GetLastError ();
+ } else {
+ mstr_narrow_result narrow = mstr_win32_narrow (path);
+ // GetModuleFileNameW should never return invalid Unicode:
+ assert (narrow.error == 0);
+ ret_str = narrow.string;
+ }
+ free (path);
+ }
+ return (mcr_dll_path_result){
+ .path = ret_str,
+ .error_string = merror_system_error_string (ret_error),
+ };
+}
+
#endif
diff --git a/mongodb-1.13.0/src/libmongocrypt/src/os_win/os_mutex.c b/mongodb-1.14.0/src/libmongocrypt/src/os_win/os_mutex.c
similarity index 100%
rename from mongodb-1.13.0/src/libmongocrypt/src/os_win/os_mutex.c
rename to mongodb-1.14.0/src/libmongocrypt/src/os_win/os_mutex.c
diff --git a/mongodb-1.13.0/src/phongo_apm.c b/mongodb-1.14.0/src/phongo_apm.c
similarity index 91%
rename from mongodb-1.13.0/src/phongo_apm.c
rename to mongodb-1.14.0/src/phongo_apm.c
index 36f49546..e87d15e9 100644
--- a/mongodb-1.13.0/src/phongo_apm.c
+++ b/mongodb-1.14.0/src/phongo_apm.c
@@ -1,636 +1,639 @@
/*
* Copyright 2021-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <Zend/zend_exceptions.h>
#include <Zend/zend_interfaces.h>
#include <Zend/zend_operators.h>
#include "php_phongo.h"
#include "phongo_apm.h"
#include "phongo_error.h"
ZEND_EXTERN_MODULE_GLOBALS(mongodb)
/* Ensures that instances of @subscriber_ce in @from (those registered with a
* Manager or globally) are added to the set @to. This is used to build the list
* of subscribers notify for an event. */
static void phongo_apm_add_subscribers_to_notify(zend_class_entry* subscriber_ce, HashTable* from, HashTable* to)
{
zval* subscriber;
ZEND_HASH_FOREACH_VAL_IND(from, subscriber)
{
if (Z_TYPE_P(subscriber) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(subscriber), subscriber_ce)) {
continue;
}
if (zend_hash_index_exists(to, Z_OBJ_HANDLE_P(subscriber))) {
continue;
}
zend_hash_index_update(to, Z_OBJ_HANDLE_P(subscriber), subscriber);
Z_ADDREF_P(subscriber);
}
ZEND_HASH_FOREACH_END();
}
/* Returns a newly allocated HashTable, which will contain all subscribers of a
* certain type that should be notified for an event on the specified client. */
static HashTable* phongo_apm_get_subscribers_to_notify(zend_class_entry* subscriber_ce, mongoc_client_t* client)
{
HashTable* subscribers = NULL;
ALLOC_HASHTABLE(subscribers);
zend_hash_init(subscribers, 0, NULL, ZVAL_PTR_DTOR, 0);
if (MONGODB_G(subscribers)) {
phongo_apm_add_subscribers_to_notify(subscriber_ce, MONGODB_G(subscribers), subscribers);
}
if (MONGODB_G(managers)) {
php_phongo_manager_t* manager;
ZEND_HASH_FOREACH_PTR(MONGODB_G(managers), manager)
{
if (manager->client == client && manager->subscribers) {
phongo_apm_add_subscribers_to_notify(subscriber_ce, manager->subscribers, subscribers);
}
}
ZEND_HASH_FOREACH_END();
}
return subscribers;
}
/* Search for a Manager associated with the given client in the request-scoped
* registry. If any Manager is found, copy it to @out, increment its ref-count,
* and return true; otherwise, set @out to undefined and return false. */
static bool phongo_apm_copy_manager_for_client(mongoc_client_t* client, zval* out)
{
php_phongo_manager_t* manager;
ZVAL_UNDEF(out);
if (!MONGODB_G(managers) || zend_hash_num_elements(MONGODB_G(managers)) == 0) {
return false;
}
ZEND_HASH_FOREACH_PTR(MONGODB_G(managers), manager)
{
if (manager->client == client) {
ZVAL_OBJ(out, &manager->std);
Z_ADDREF_P(out);
return true;
}
}
ZEND_HASH_FOREACH_END();
return false;
}
/* Dispatch an event to all subscribers in a HashTable. The caller is
* responsible for ensuring that subscribers implement the correct interface. */
static void phongo_apm_dispatch_event(HashTable* subscribers, const char* function_name, zval* event)
{
zval* subscriber;
ZEND_HASH_FOREACH_VAL_IND(subscribers, subscriber)
{
if (EG(exception)) {
break;
}
/* We can't use the zend_call_method_with_1_params macro here, as it
* assumes the function name is a string literal. */
zend_call_method(PHONGO_COMPAT_OBJ_P(subscriber), NULL, NULL, function_name, strlen(function_name), NULL, 1, event, NULL);
}
ZEND_HASH_FOREACH_END();
}
static void phongo_apm_command_started(const mongoc_apm_command_started_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_commandstartedevent_t* p_event;
zval z_event;
client = mongoc_apm_command_started_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_commandsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_commandstartedevent_ce);
p_event = Z_COMMANDSTARTEDEVENT_OBJ_P(&z_event);
- p_event->command_name = estrdup(mongoc_apm_command_started_get_command_name(event));
- p_event->server_id = mongoc_apm_command_started_get_server_id(event);
- p_event->operation_id = mongoc_apm_command_started_get_operation_id(event);
- p_event->request_id = mongoc_apm_command_started_get_request_id(event);
- p_event->command = bson_copy(mongoc_apm_command_started_get_command(event));
- p_event->database_name = estrdup(mongoc_apm_command_started_get_database_name(event));
- p_event->has_service_id = mongoc_apm_command_started_get_service_id(event) != NULL;
+ p_event->command_name = estrdup(mongoc_apm_command_started_get_command_name(event));
+ p_event->server_id = mongoc_apm_command_started_get_server_id(event);
+ p_event->operation_id = mongoc_apm_command_started_get_operation_id(event);
+ p_event->request_id = mongoc_apm_command_started_get_request_id(event);
+ p_event->command = bson_copy(mongoc_apm_command_started_get_command(event));
+ p_event->database_name = estrdup(mongoc_apm_command_started_get_database_name(event));
+ p_event->server_connection_id = mongoc_apm_command_started_get_server_connection_id(event);
+ p_event->has_service_id = mongoc_apm_command_started_get_service_id(event) != NULL;
if (p_event->has_service_id) {
bson_oid_copy(mongoc_apm_command_started_get_service_id(event), &p_event->service_id);
}
if (!phongo_apm_copy_manager_for_client(client, &p_event->manager)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Found no Manager for client in APM event context");
zval_ptr_dtor(&z_event);
goto cleanup;
}
phongo_apm_dispatch_event(subscribers, "commandStarted", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_command_succeeded(const mongoc_apm_command_succeeded_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_commandsucceededevent_t* p_event;
zval z_event;
client = mongoc_apm_command_succeeded_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_commandsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_commandsucceededevent_ce);
p_event = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(&z_event);
- p_event->command_name = estrdup(mongoc_apm_command_succeeded_get_command_name(event));
- p_event->server_id = mongoc_apm_command_succeeded_get_server_id(event);
- p_event->operation_id = mongoc_apm_command_succeeded_get_operation_id(event);
- p_event->request_id = mongoc_apm_command_succeeded_get_request_id(event);
- p_event->duration_micros = mongoc_apm_command_succeeded_get_duration(event);
- p_event->reply = bson_copy(mongoc_apm_command_succeeded_get_reply(event));
- p_event->has_service_id = mongoc_apm_command_succeeded_get_service_id(event) != NULL;
+ p_event->command_name = estrdup(mongoc_apm_command_succeeded_get_command_name(event));
+ p_event->server_id = mongoc_apm_command_succeeded_get_server_id(event);
+ p_event->operation_id = mongoc_apm_command_succeeded_get_operation_id(event);
+ p_event->request_id = mongoc_apm_command_succeeded_get_request_id(event);
+ p_event->duration_micros = mongoc_apm_command_succeeded_get_duration(event);
+ p_event->reply = bson_copy(mongoc_apm_command_succeeded_get_reply(event));
+ p_event->server_connection_id = mongoc_apm_command_succeeded_get_server_connection_id(event);
+ p_event->has_service_id = mongoc_apm_command_succeeded_get_service_id(event) != NULL;
if (p_event->has_service_id) {
bson_oid_copy(mongoc_apm_command_succeeded_get_service_id(event), &p_event->service_id);
}
if (!phongo_apm_copy_manager_for_client(client, &p_event->manager)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Found no Manager for client in APM event context");
zval_ptr_dtor(&z_event);
goto cleanup;
}
phongo_apm_dispatch_event(subscribers, "commandSucceeded", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_command_failed(const mongoc_apm_command_failed_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_commandfailedevent_t* p_event;
zval z_event;
bson_error_t tmp_error = { 0 };
client = mongoc_apm_command_failed_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_commandsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_commandfailedevent_ce);
p_event = Z_COMMANDFAILEDEVENT_OBJ_P(&z_event);
- p_event->command_name = estrdup(mongoc_apm_command_failed_get_command_name(event));
- p_event->server_id = mongoc_apm_command_failed_get_server_id(event);
- p_event->operation_id = mongoc_apm_command_failed_get_operation_id(event);
- p_event->request_id = mongoc_apm_command_failed_get_request_id(event);
- p_event->duration_micros = mongoc_apm_command_failed_get_duration(event);
- p_event->reply = bson_copy(mongoc_apm_command_failed_get_reply(event));
- p_event->has_service_id = mongoc_apm_command_failed_get_service_id(event) != NULL;
+ p_event->command_name = estrdup(mongoc_apm_command_failed_get_command_name(event));
+ p_event->server_id = mongoc_apm_command_failed_get_server_id(event);
+ p_event->operation_id = mongoc_apm_command_failed_get_operation_id(event);
+ p_event->request_id = mongoc_apm_command_failed_get_request_id(event);
+ p_event->duration_micros = mongoc_apm_command_failed_get_duration(event);
+ p_event->reply = bson_copy(mongoc_apm_command_failed_get_reply(event));
+ p_event->server_connection_id = mongoc_apm_command_failed_get_server_connection_id(event);
+ p_event->has_service_id = mongoc_apm_command_failed_get_service_id(event) != NULL;
if (p_event->has_service_id) {
bson_oid_copy(mongoc_apm_command_failed_get_service_id(event), &p_event->service_id);
}
if (!phongo_apm_copy_manager_for_client(client, &p_event->manager)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Found no Manager for client in APM event context");
zval_ptr_dtor(&z_event);
goto cleanup;
}
/* We need to process and convert the error right here, otherwise
* debug_info will turn into a recursive loop, and with the wrong trace
* locations */
mongoc_apm_command_failed_get_error(event, &tmp_error);
object_init_ex(&p_event->z_error, phongo_exception_from_mongoc_domain(tmp_error.domain, tmp_error.code));
zend_update_property_string(zend_ce_exception, PHONGO_COMPAT_OBJ_P(&p_event->z_error), ZEND_STRL("message"), tmp_error.message);
zend_update_property_long(zend_ce_exception, PHONGO_COMPAT_OBJ_P(&p_event->z_error), ZEND_STRL("code"), tmp_error.code);
phongo_apm_dispatch_event(subscribers, "commandFailed", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_server_changed(const mongoc_apm_server_changed_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_serverchangedevent_t* p_event;
zval z_event;
client = mongoc_apm_server_changed_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_serverchangedevent_ce);
p_event = Z_SERVERCHANGEDEVENT_OBJ_P(&z_event);
memcpy(&p_event->host, mongoc_apm_server_changed_get_host(event), sizeof(mongoc_host_list_t));
mongoc_apm_server_changed_get_topology_id(event, &p_event->topology_id);
p_event->new_server_description = mongoc_server_description_new_copy(mongoc_apm_server_changed_get_new_description(event));
p_event->old_server_description = mongoc_server_description_new_copy(mongoc_apm_server_changed_get_previous_description(event));
phongo_apm_dispatch_event(subscribers, "serverChanged", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_server_closed(const mongoc_apm_server_closed_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_serverclosedevent_t* p_event;
zval z_event;
client = mongoc_apm_server_closed_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_serverclosedevent_ce);
p_event = Z_SERVERCLOSEDEVENT_OBJ_P(&z_event);
memcpy(&p_event->host, mongoc_apm_server_closed_get_host(event), sizeof(mongoc_host_list_t));
mongoc_apm_server_closed_get_topology_id(event, &p_event->topology_id);
phongo_apm_dispatch_event(subscribers, "serverClosed", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_server_heartbeat_failed(const mongoc_apm_server_heartbeat_failed_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_serverheartbeatfailedevent_t* p_event;
zval z_event;
bson_error_t tmp_error = { 0 };
client = mongoc_apm_server_heartbeat_failed_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_serverheartbeatfailedevent_ce);
p_event = Z_SERVERHEARTBEATFAILEDEVENT_OBJ_P(&z_event);
memcpy(&p_event->host, mongoc_apm_server_heartbeat_failed_get_host(event), sizeof(mongoc_host_list_t));
p_event->awaited = mongoc_apm_server_heartbeat_failed_get_awaited(event);
p_event->duration_micros = mongoc_apm_server_heartbeat_failed_get_duration(event);
/* We need to process and convert the error right here, otherwise
* debug_info will turn into a recursive loop, and with the wrong trace
* locations */
mongoc_apm_server_heartbeat_failed_get_error(event, &tmp_error);
object_init_ex(&p_event->z_error, phongo_exception_from_mongoc_domain(tmp_error.domain, tmp_error.code));
zend_update_property_string(zend_ce_exception, PHONGO_COMPAT_OBJ_P(&p_event->z_error), ZEND_STRL("message"), tmp_error.message);
zend_update_property_long(zend_ce_exception, PHONGO_COMPAT_OBJ_P(&p_event->z_error), ZEND_STRL("code"), tmp_error.code);
phongo_apm_dispatch_event(subscribers, "serverHeartbeatFailed", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_server_heartbeat_succeeded(const mongoc_apm_server_heartbeat_succeeded_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_serverheartbeatsucceededevent_t* p_event;
zval z_event;
client = mongoc_apm_server_heartbeat_succeeded_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_serverheartbeatsucceededevent_ce);
p_event = Z_SERVERHEARTBEATSUCCEEDEDEVENT_OBJ_P(&z_event);
memcpy(&p_event->host, mongoc_apm_server_heartbeat_succeeded_get_host(event), sizeof(mongoc_host_list_t));
p_event->awaited = mongoc_apm_server_heartbeat_succeeded_get_awaited(event);
p_event->duration_micros = mongoc_apm_server_heartbeat_succeeded_get_duration(event);
p_event->reply = bson_copy(mongoc_apm_server_heartbeat_succeeded_get_reply(event));
phongo_apm_dispatch_event(subscribers, "serverHeartbeatSucceeded", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_server_heartbeat_started(const mongoc_apm_server_heartbeat_started_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_serverheartbeatstartedevent_t* p_event;
zval z_event;
client = mongoc_apm_server_heartbeat_started_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_serverheartbeatstartedevent_ce);
p_event = Z_SERVERHEARTBEATSTARTEDEVENT_OBJ_P(&z_event);
memcpy(&p_event->host, mongoc_apm_server_heartbeat_started_get_host(event), sizeof(mongoc_host_list_t));
p_event->awaited = mongoc_apm_server_heartbeat_started_get_awaited(event);
phongo_apm_dispatch_event(subscribers, "serverHeartbeatStarted", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_server_opening(const mongoc_apm_server_opening_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_serveropeningevent_t* p_event;
zval z_event;
client = mongoc_apm_server_opening_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_serveropeningevent_ce);
p_event = Z_SERVEROPENINGEVENT_OBJ_P(&z_event);
memcpy(&p_event->host, mongoc_apm_server_opening_get_host(event), sizeof(mongoc_host_list_t));
mongoc_apm_server_opening_get_topology_id(event, &p_event->topology_id);
phongo_apm_dispatch_event(subscribers, "serverOpening", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_topology_changed(const mongoc_apm_topology_changed_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_topologychangedevent_t* p_event;
zval z_event;
client = mongoc_apm_topology_changed_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_topologychangedevent_ce);
p_event = Z_TOPOLOGYCHANGEDEVENT_OBJ_P(&z_event);
mongoc_apm_topology_changed_get_topology_id(event, &p_event->topology_id);
p_event->new_topology_description = mongoc_topology_description_new_copy(mongoc_apm_topology_changed_get_new_description(event));
p_event->old_topology_description = mongoc_topology_description_new_copy(mongoc_apm_topology_changed_get_previous_description(event));
phongo_apm_dispatch_event(subscribers, "topologyChanged", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_topology_closed(const mongoc_apm_topology_closed_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_topologyclosedevent_t* p_event;
zval z_event;
client = mongoc_apm_topology_closed_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_topologyclosedevent_ce);
p_event = Z_TOPOLOGYCLOSEDEVENT_OBJ_P(&z_event);
mongoc_apm_topology_closed_get_topology_id(event, &p_event->topology_id);
phongo_apm_dispatch_event(subscribers, "topologyClosed", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
static void phongo_apm_topology_opening(const mongoc_apm_topology_opening_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_topologyopeningevent_t* p_event;
zval z_event;
client = mongoc_apm_topology_opening_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);
/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}
object_init_ex(&z_event, php_phongo_topologyopeningevent_ce);
p_event = Z_TOPOLOGYOPENINGEVENT_OBJ_P(&z_event);
mongoc_apm_topology_opening_get_topology_id(event, &p_event->topology_id);
phongo_apm_dispatch_event(subscribers, "topologyOpening", &z_event);
zval_ptr_dtor(&z_event);
cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}
/* Assigns APM callbacks to a client, which will notify any global or per-client
* subscribers. This should be called for all clients created by the driver.
* Returns true on success; otherwise, throws an exception and returns false. */
bool phongo_apm_set_callbacks(mongoc_client_t* client)
{
bool retval;
mongoc_apm_callbacks_t* callbacks = mongoc_apm_callbacks_new();
mongoc_apm_set_command_started_cb(callbacks, phongo_apm_command_started);
mongoc_apm_set_command_succeeded_cb(callbacks, phongo_apm_command_succeeded);
mongoc_apm_set_command_failed_cb(callbacks, phongo_apm_command_failed);
mongoc_apm_set_server_changed_cb(callbacks, phongo_apm_server_changed);
mongoc_apm_set_server_closed_cb(callbacks, phongo_apm_server_closed);
mongoc_apm_set_server_heartbeat_failed_cb(callbacks, phongo_apm_server_heartbeat_failed);
mongoc_apm_set_server_heartbeat_succeeded_cb(callbacks, phongo_apm_server_heartbeat_succeeded);
mongoc_apm_set_server_heartbeat_started_cb(callbacks, phongo_apm_server_heartbeat_started);
mongoc_apm_set_server_opening_cb(callbacks, phongo_apm_server_opening);
mongoc_apm_set_topology_changed_cb(callbacks, phongo_apm_topology_changed);
mongoc_apm_set_topology_closed_cb(callbacks, phongo_apm_topology_closed);
mongoc_apm_set_topology_opening_cb(callbacks, phongo_apm_topology_opening);
retval = mongoc_client_set_apm_callbacks(client, callbacks, client);
if (!retval) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to set APM callbacks");
}
mongoc_apm_callbacks_destroy(callbacks);
return retval;
}
/* Checks args for adding/removing a subscriber. Returns true on success;
* otherwise, throws an exception and returns false. */
static bool phongo_apm_check_args_for_add_and_remove(HashTable* subscribers, zval* subscriber)
{
if (!subscribers) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Subscriber HashTable is not initialized");
return false;
}
if (!subscriber || Z_TYPE_P(subscriber) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(subscriber), php_phongo_subscriber_ce)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Subscriber is not an instance of %s", ZSTR_VAL(php_phongo_subscriber_ce->name));
return false;
}
return true;
}
/* Adds a subscriber to the HashTable (global or Manager). Returns true on
* success (including NOP if already registered); otherwise, throws an exception
* and returns false. */
bool phongo_apm_add_subscriber(HashTable* subscribers, zval* subscriber)
{
if (!phongo_apm_check_args_for_add_and_remove(subscribers, subscriber)) {
/* Exception should already have been thrown */
return false;
}
/* NOP if the subscriber was already registered */
if (zend_hash_index_exists(subscribers, Z_OBJ_HANDLE_P(subscriber))) {
return true;
}
zend_hash_index_update(subscribers, Z_OBJ_HANDLE_P(subscriber), subscriber);
Z_ADDREF_P(subscriber);
return true;
}
/* Removes a subscriber from the HashTable (global or Manager). Returns true on
* success (including NOP if never registered); otherwise, throws an exception
* and returns false. */
bool phongo_apm_remove_subscriber(HashTable* subscribers, zval* subscriber)
{
if (!phongo_apm_check_args_for_add_and_remove(subscribers, subscriber)) {
/* Exception should already have been thrown */
return false;
}
/* Note: HashTables should specify ZVAL_PTR_DTOR as their element destructor
* so there is no need to decrement the subscriber's reference count here.
* We also don't care about whether zend_hash_index_del returns SUCCESS or
* FAILURE, as removing an unregistered subscriber is a NOP. */
zend_hash_index_del(subscribers, Z_OBJ_HANDLE_P(subscriber));
return true;
}
diff --git a/mongodb-1.13.0/src/phongo_apm.h b/mongodb-1.14.0/src/phongo_apm.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_apm.h
rename to mongodb-1.14.0/src/phongo_apm.h
diff --git a/mongodb-1.13.0/src/phongo_bson.c b/mongodb-1.14.0/src/phongo_bson.c
similarity index 100%
rename from mongodb-1.13.0/src/phongo_bson.c
rename to mongodb-1.14.0/src/phongo_bson.c
diff --git a/mongodb-1.13.0/src/phongo_bson.h b/mongodb-1.14.0/src/phongo_bson.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_bson.h
rename to mongodb-1.14.0/src/phongo_bson.h
diff --git a/mongodb-1.13.0/src/phongo_bson_encode.c b/mongodb-1.14.0/src/phongo_bson_encode.c
similarity index 98%
rename from mongodb-1.13.0/src/phongo_bson_encode.c
rename to mongodb-1.14.0/src/phongo_bson_encode.c
index dd4209f6..f9ec17ac 100644
--- a/mongodb-1.13.0/src/phongo_bson_encode.c
+++ b/mongodb-1.14.0/src/phongo_bson_encode.c
@@ -1,518 +1,517 @@
/*
* Copyright 2014-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include <php.h>
#include <Zend/zend_interfaces.h>
#include "php_phongo.h"
#include "phongo_bson.h"
#include "phongo_bson_encode.h"
#include "phongo_compat.h"
#include "phongo_error.h"
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "PHONGO-BSON"
#if SIZEOF_ZEND_LONG == 8
#define BSON_APPEND_INT(b, key, keylen, val) \
if (val > INT32_MAX || val < INT32_MIN) { \
bson_append_int64(b, key, keylen, val); \
} else { \
bson_append_int32(b, key, keylen, val); \
}
#elif SIZEOF_ZEND_LONG == 4
#define BSON_APPEND_INT(b, key, keylen, val) \
bson_append_int32(b, key, keylen, val)
#else
#error Unsupported architecture (integers are neither 32-bit nor 64-bit)
#endif
/* Forwards declarations */
static void php_phongo_zval_to_bson_internal(zval* data, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out);
/* Determines whether the argument should be serialized as a BSON array or
* document. IS_ARRAY is returned if the argument's keys are a sequence of
* integers starting at zero; otherwise, IS_OBJECT is returned. */
static int php_phongo_is_array_or_document(zval* val) /* {{{ */
{
HashTable* ht_data = HASH_OF(val);
int count;
if (Z_TYPE_P(val) != IS_ARRAY) {
return IS_OBJECT;
}
count = ht_data ? zend_hash_num_elements(ht_data) : 0;
if (count > 0) {
zend_string* key;
zend_ulong index, idx;
idx = 0;
ZEND_HASH_FOREACH_KEY(ht_data, index, key)
{
if (key) {
return IS_OBJECT;
} else {
if (index != idx) {
return IS_OBJECT;
}
}
idx++;
}
ZEND_HASH_FOREACH_END();
} else {
return Z_TYPE_P(val);
}
return IS_ARRAY;
} /* }}} */
/* Appends the array or object argument to the BSON document. If the object is
* an instance of MongoDB\BSON\Serializable, the return value of bsonSerialize()
* will be appended as an embedded document. Other MongoDB\BSON\Type instances
* will be appended as the appropriate BSON type. Other array or object values
* will be appended as an embedded document. */
static void php_phongo_bson_append_object(bson_t* bson, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, const char* key, long key_len, zval* object) /* {{{ */
{
if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_cursorid_ce)) {
bson_append_int64(bson, key, key_len, Z_CURSORID_OBJ_P(object)->id);
return;
}
if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_type_ce)) {
if (instanceof_function(Z_OBJCE_P(object), php_phongo_serializable_ce)) {
zval obj_data;
bson_t child;
zend_call_method_with_0_params(PHONGO_COMPAT_OBJ_P(object), NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data);
if (Z_ISUNDEF(obj_data)) {
/* zend_call_method() failed or bsonSerialize() threw an
* exception. Either way, there is nothing else to do. */
return;
}
if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def))) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE,
"Expected %s::%s() to return an array or stdClass, %s given",
ZSTR_VAL(Z_OBJCE_P(object)->name),
BSON_SERIALIZE_FUNC_NAME,
PHONGO_ZVAL_CLASS_OR_TYPE_NAME(obj_data));
zval_ptr_dtor(&obj_data);
return;
}
/* Persistable objects must always be serialized as BSON documents;
* otherwise, infer based on bsonSerialize()'s return value. */
if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce) || php_phongo_is_array_or_document(&obj_data) == IS_OBJECT) {
bson_append_document_begin(bson, key, key_len, &child);
if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce)) {
bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t*) Z_OBJCE_P(object)->name->val, Z_OBJCE_P(object)->name->len);
}
php_phongo_zval_to_bson_internal(&obj_data, field_path, flags, &child, NULL);
bson_append_document_end(bson, &child);
} else {
bson_append_array_begin(bson, key, key_len, &child);
php_phongo_zval_to_bson_internal(&obj_data, field_path, flags, &child, NULL);
bson_append_array_end(bson, &child);
}
zval_ptr_dtor(&obj_data);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_objectid_ce)) {
bson_oid_t oid;
php_phongo_objectid_t* intern = Z_OBJECTID_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding ObjectId");
bson_oid_init_from_string(&oid, intern->oid);
bson_append_oid(bson, key, key_len, &oid);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_utcdatetime_ce)) {
php_phongo_utcdatetime_t* intern = Z_UTCDATETIME_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding UTCDateTime");
bson_append_date_time(bson, key, key_len, intern->milliseconds);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_binary_ce)) {
php_phongo_binary_t* intern = Z_BINARY_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Binary");
bson_append_binary(bson, key, key_len, intern->type, (const uint8_t*) intern->data, (uint32_t) intern->data_len);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_decimal128_ce)) {
php_phongo_decimal128_t* intern = Z_DECIMAL128_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Decimal128");
bson_append_decimal128(bson, key, key_len, &intern->decimal);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_int64_ce)) {
php_phongo_int64_t* intern = Z_INT64_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Int64");
bson_append_int64(bson, key, key_len, intern->integer);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_regex_ce)) {
php_phongo_regex_t* intern = Z_REGEX_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Regex");
bson_append_regex(bson, key, key_len, intern->pattern, intern->flags);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_javascript_ce)) {
php_phongo_javascript_t* intern = Z_JAVASCRIPT_OBJ_P(object);
if (intern->scope) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript with scope");
bson_append_code_with_scope(bson, key, key_len, intern->code, intern->scope);
} else {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript without scope");
bson_append_code(bson, key, key_len, intern->code);
}
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_timestamp_ce)) {
php_phongo_timestamp_t* intern = Z_TIMESTAMP_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Timestamp");
bson_append_timestamp(bson, key, key_len, intern->timestamp, intern->increment);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_maxkey_ce)) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding MaxKey");
bson_append_maxkey(bson, key, key_len);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_minkey_ce)) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding MinKey");
bson_append_minkey(bson, key, key_len);
return;
}
/* Deprecated types */
if (instanceof_function(Z_OBJCE_P(object), php_phongo_dbpointer_ce)) {
bson_oid_t oid;
php_phongo_dbpointer_t* intern = Z_DBPOINTER_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding DBPointer");
bson_oid_init_from_string(&oid, intern->id);
bson_append_dbpointer(bson, key, key_len, intern->ref, &oid);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_symbol_ce)) {
php_phongo_symbol_t* intern = Z_SYMBOL_OBJ_P(object);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Symbol");
bson_append_symbol(bson, key, key_len, intern->symbol, intern->symbol_len);
return;
}
if (instanceof_function(Z_OBJCE_P(object), php_phongo_undefined_ce)) {
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Undefined");
bson_append_undefined(bson, key, key_len);
return;
}
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Unexpected %s instance: %s", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(object)->name));
return;
} else {
bson_t child;
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding document");
bson_append_document_begin(bson, key, key_len, &child);
php_phongo_zval_to_bson_internal(object, field_path, flags, &child, NULL);
bson_append_document_end(bson, &child);
}
} /* }}} */
/* Appends the zval argument to the BSON document. If the argument is an object,
* or an array that should be serialized as an embedded document, this function
* will defer to php_phongo_bson_append_object(). */
static void php_phongo_bson_append(bson_t* bson, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, const char* key, long key_len, zval* entry) /* {{{ */
{
php_phongo_field_path_write_item_at_current_level(field_path, key);
try_again:
switch (Z_TYPE_P(entry)) {
case IS_NULL:
bson_append_null(bson, key, key_len);
break;
case IS_TRUE:
bson_append_bool(bson, key, key_len, true);
break;
case IS_FALSE:
bson_append_bool(bson, key, key_len, false);
break;
case IS_LONG:
BSON_APPEND_INT(bson, key, key_len, Z_LVAL_P(entry));
break;
case IS_DOUBLE:
bson_append_double(bson, key, key_len, Z_DVAL_P(entry));
break;
case IS_STRING:
if (bson_utf8_validate(Z_STRVAL_P(entry), Z_STRLEN_P(entry), true)) {
bson_append_utf8(bson, key, key_len, Z_STRVAL_P(entry), Z_STRLEN_P(entry));
} else {
char* path_string = php_phongo_field_path_as_string(field_path);
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected invalid UTF-8 for field path \"%s\": %s", path_string, Z_STRVAL_P(entry));
efree(path_string);
}
break;
case IS_ARRAY:
if (php_phongo_is_array_or_document(entry) == IS_ARRAY) {
bson_t child;
HashTable* tmp_ht = HASH_OF(entry);
if (!php_phongo_zend_hash_apply_protection_begin(tmp_ht)) {
char* path_string = php_phongo_field_path_as_string(field_path);
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected recursion for field path \"%s\"", path_string);
efree(path_string);
break;
}
bson_append_array_begin(bson, key, key_len, &child);
php_phongo_field_path_write_type_at_current_level(field_path, PHONGO_FIELD_PATH_ITEM_ARRAY);
field_path->size++;
php_phongo_zval_to_bson_internal(entry, field_path, flags, &child, NULL);
field_path->size--;
bson_append_array_end(bson, &child);
php_phongo_zend_hash_apply_protection_end(tmp_ht);
break;
}
PHONGO_BREAK_INTENTIONALLY_MISSING
case IS_OBJECT: {
HashTable* tmp_ht = HASH_OF(entry);
if (!php_phongo_zend_hash_apply_protection_begin(tmp_ht)) {
char* path_string = php_phongo_field_path_as_string(field_path);
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected recursion for field path \"%s\"", path_string);
efree(path_string);
break;
}
php_phongo_field_path_write_type_at_current_level(field_path, PHONGO_FIELD_PATH_ITEM_DOCUMENT);
field_path->size++;
php_phongo_bson_append_object(bson, field_path, flags, key, key_len, entry);
field_path->size--;
php_phongo_zend_hash_apply_protection_end(tmp_ht);
break;
}
case IS_REFERENCE:
ZVAL_DEREF(entry);
goto try_again;
default: {
char* path_string = php_phongo_field_path_as_string(field_path);
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Detected unsupported PHP type for field path \"%s\": %d (%s)", path_string, Z_TYPE_P(entry), zend_get_type_by_const(Z_TYPE_P(entry)));
efree(path_string);
}
}
} /* }}} */
static void php_phongo_zval_to_bson_internal(zval* data, php_phongo_field_path* field_path, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out) /* {{{ */
{
HashTable* ht_data = NULL;
zval obj_data;
/* If we will be encoding a class that may contain protected and private
* properties, we'll need to filter them out later. */
bool ht_data_from_properties = false;
/* If the object is an instance of MongoDB\BSON\Persistable, we will need to
* inject the PHP class name as a BSON key and ignore any existing key in
* the return value of bsonSerialize(). */
bool skip_odm_field = false;
ZVAL_UNDEF(&obj_data);
switch (Z_TYPE_P(data)) {
case IS_OBJECT:
if (instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce)) {
zend_call_method_with_0_params(PHONGO_COMPAT_OBJ_P(data), NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data);
if (Z_ISUNDEF(obj_data)) {
/* zend_call_method() failed or bsonSerialize() threw an
* exception. Either way, there is nothing else to do. */
return;
}
if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def))) {
phongo_throw_exception(
PHONGO_ERROR_UNEXPECTED_VALUE,
"Expected %s::%s() to return an array or stdClass, %s given",
ZSTR_VAL(Z_OBJCE_P(data)->name),
BSON_SERIALIZE_FUNC_NAME,
PHONGO_ZVAL_CLASS_OR_TYPE_NAME(obj_data));
goto cleanup;
}
ht_data = HASH_OF(&obj_data);
if (instanceof_function(Z_OBJCE_P(data), php_phongo_persistable_ce)) {
bson_append_binary(bson, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t*) Z_OBJCE_P(data)->name->val, Z_OBJCE_P(data)->name->len);
/* Ensure that we ignore an existing key with the same name
* if one exists in the bsonSerialize() return value. */
skip_odm_field = true;
}
break;
}
if (instanceof_function(Z_OBJCE_P(data), php_phongo_type_ce)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "%s instance %s cannot be serialized as a root element", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(data)->name));
return;
}
ht_data = Z_OBJ_HT_P(data)->get_properties(PHONGO_COMPAT_OBJ_P(data));
ht_data_from_properties = true;
break;
case IS_ARRAY:
ht_data = HASH_OF(data);
break;
default:
return;
}
{
zend_string* string_key = NULL;
zend_ulong num_key = 0;
zval* value;
ZEND_HASH_FOREACH_KEY_VAL_IND(ht_data, num_key, string_key, value)
{
if (string_key) {
if (ht_data_from_properties) {
/* Skip protected and private properties */
if (ZSTR_VAL(string_key)[0] == '\0' && ZSTR_LEN(string_key) > 0) {
continue;
}
}
if (strlen(ZSTR_VAL(string_key)) != ZSTR_LEN(string_key)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key));
goto cleanup;
}
if (skip_odm_field && !strcmp(ZSTR_VAL(string_key), PHONGO_ODM_FIELD_NAME)) {
continue;
}
if (flags & PHONGO_BSON_ADD_ID) {
if (!strcmp(ZSTR_VAL(string_key), "_id")) {
flags &= ~PHONGO_BSON_ADD_ID;
}
}
}
/* Ensure we're working with a string key */
if (!string_key) {
string_key = zend_long_to_str(num_key);
} else {
zend_string_addref(string_key);
}
php_phongo_bson_append(bson, field_path, flags & ~PHONGO_BSON_ADD_ID, ZSTR_VAL(string_key), strlen(ZSTR_VAL(string_key)), value);
zend_string_release(string_key);
}
ZEND_HASH_FOREACH_END();
}
if (flags & PHONGO_BSON_ADD_ID) {
bson_oid_t oid;
bson_oid_init(&oid, NULL);
bson_append_oid(bson, "_id", strlen("_id"), &oid);
mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "Added new _id");
}
if (flags & PHONGO_BSON_RETURN_ID && bson_out) {
bson_iter_t iter;
*bson_out = bson_new();
if (bson_iter_init_find(&iter, bson, "_id") && !bson_append_iter(*bson_out, NULL, 0, &iter)) {
/* This should not be able to happen since we are copying from
* within a valid bson_t. */
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Error copying \"_id\" field from encoded document");
goto cleanup;
}
}
cleanup:
if (!Z_ISUNDEF(obj_data)) {
zval_ptr_dtor(&obj_data);
}
} /* }}} */
/* Converts the array or object argument to a BSON document. If the object is an
* instance of MongoDB\BSON\Serializable, the return value of bsonSerialize()
* will be used. */
void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t* bson, bson_t** bson_out) /* {{{ */
{
php_phongo_field_path* field_path = php_phongo_field_path_alloc(false);
php_phongo_zval_to_bson_internal(data, field_path, flags, bson, bson_out);
php_phongo_field_path_free(field_path);
} /* }}} */
/* Converts the argument to a bson_value_t. If the object is an instance of
* MongoDB\BSON\Serializable, the return value of bsonSerialize() will be
- * used. */
+ * used. It is the caller's responsibility to call bson_value_destroy. */
void php_phongo_zval_to_bson_value(zval* data, php_phongo_bson_flags_t flags, bson_value_t* value) /* {{{ */
{
bson_iter_t iter;
bson_t bson = BSON_INITIALIZER;
+ zval data_object;
- zval* data_object = ecalloc(1, sizeof(zval));
-
- array_init_size(data_object, 1);
- add_assoc_zval(data_object, "data", data);
+ array_init_size(&data_object, 1);
+ add_assoc_zval(&data_object, "data", data);
Z_TRY_ADDREF_P(data);
- php_phongo_zval_to_bson(data_object, flags, &bson, NULL);
+ php_phongo_zval_to_bson(&data_object, flags, &bson, NULL);
if (bson_iter_init_find(&iter, &bson, "data")) {
bson_value_copy(bson_iter_value(&iter), value);
}
- zval_ptr_dtor(data_object);
- efree(data_object);
+ bson_destroy(&bson);
+ zval_ptr_dtor(&data_object);
} /* }}} */
diff --git a/mongodb-1.13.0/src/phongo_bson_encode.h b/mongodb-1.14.0/src/phongo_bson_encode.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_bson_encode.h
rename to mongodb-1.14.0/src/phongo_bson_encode.h
diff --git a/mongodb-1.13.0/src/phongo_classes.h b/mongodb-1.14.0/src/phongo_classes.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_classes.h
rename to mongodb-1.14.0/src/phongo_classes.h
diff --git a/mongodb-1.13.0/src/phongo_client.c b/mongodb-1.14.0/src/phongo_client.c
similarity index 96%
rename from mongodb-1.13.0/src/phongo_client.c
rename to mongodb-1.14.0/src/phongo_client.c
index 58eb2126..a7017d2e 100644
--- a/mongodb-1.13.0/src/phongo_client.c
+++ b/mongodb-1.14.0/src/phongo_client.c
@@ -1,1688 +1,1713 @@
/*
* Copyright 2022-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <ext/standard/php_var.h>
#include <Zend/zend_smart_str.h>
#include "php_array_api.h"
#include "php_phongo.h"
#include "phongo_apm.h"
#include "phongo_bson_encode.h"
#include "phongo_client.h"
#include "phongo_error.h"
#include "phongo_util.h"
#include "MongoDB/ReadPreference.h"
#include "MongoDB/WriteConcern.h"
ZEND_EXTERN_MODULE_GLOBALS(mongodb)
#define PHONGO_METADATA_SEPARATOR " / "
#define PHONGO_METADATA_SEPARATOR_LEN (sizeof(PHONGO_METADATA_SEPARATOR) - 1)
#define PHONGO_METADATA_PHP_VERSION_PREFIX "PHP "
#define PHONGO_METADATA_PHP_VERSION_PREFIX_LEN (sizeof(PHONGO_METADATA_PHP_VERSION_PREFIX) - 1)
/* Structure for tracking libmongoc clients (both persisted and non-persisted).
* The PID is included to ensure that processes do not destroy clients created
* by other processes (relevant for forking). We avoid using pid_t for Windows
* compatibility. */
typedef struct {
mongoc_client_t* client;
int created_by_pid;
int last_reset_by_pid;
bool is_persistent;
} php_phongo_pclient_t;
static mongoc_uri_t* php_phongo_make_uri(const char* uri_string) /* {{{ */
{
mongoc_uri_t* uri;
bson_error_t error = { 0 };
uri = mongoc_uri_new_with_error(uri_string, &error);
MONGOC_DEBUG("Connection string: '%s'", uri_string);
if (!uri) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse MongoDB URI: '%s'. %s.", uri_string, error.message);
return NULL;
}
return uri;
} /* }}} */
static const char* php_phongo_bson_type_to_string(bson_type_t type) /* {{{ */
{
switch (type) {
case BSON_TYPE_EOD:
return "EOD";
case BSON_TYPE_DOUBLE:
return "double";
case BSON_TYPE_UTF8:
return "string";
case BSON_TYPE_DOCUMENT:
return "document";
case BSON_TYPE_ARRAY:
return "array";
case BSON_TYPE_BINARY:
return "Binary";
case BSON_TYPE_UNDEFINED:
return "undefined";
case BSON_TYPE_OID:
return "ObjectId";
case BSON_TYPE_BOOL:
return "boolean";
case BSON_TYPE_DATE_TIME:
return "UTCDateTime";
case BSON_TYPE_NULL:
return "null";
case BSON_TYPE_REGEX:
return "Regex";
case BSON_TYPE_DBPOINTER:
return "DBPointer";
case BSON_TYPE_CODE:
return "Javascript";
case BSON_TYPE_SYMBOL:
return "symbol";
case BSON_TYPE_CODEWSCOPE:
return "Javascript with scope";
case BSON_TYPE_INT32:
return "32-bit integer";
case BSON_TYPE_TIMESTAMP:
return "Timestamp";
case BSON_TYPE_INT64:
return "64-bit integer";
case BSON_TYPE_DECIMAL128:
return "Decimal128";
case BSON_TYPE_MAXKEY:
return "MaxKey";
case BSON_TYPE_MINKEY:
return "MinKey";
default:
return "unknown";
}
} /* }}} */
#define PHONGO_URI_INVALID_TYPE(iter, expected) \
phongo_throw_exception( \
PHONGO_ERROR_INVALID_ARGUMENT, \
"Expected %s for \"%s\" URI option, %s given", \
(expected), \
bson_iter_key(&(iter)), \
php_phongo_bson_type_to_string(bson_iter_type(&(iter))))
static bool php_phongo_apply_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
/* Skip read preference, read concern, and write concern options, as
* those will be processed by other functions. */
if (!strcasecmp(key, MONGOC_URI_JOURNAL) ||
!strcasecmp(key, MONGOC_URI_MAXSTALENESSSECONDS) ||
!strcasecmp(key, MONGOC_URI_READCONCERNLEVEL) ||
!strcasecmp(key, MONGOC_URI_READPREFERENCE) ||
!strcasecmp(key, MONGOC_URI_READPREFERENCETAGS) ||
!strcasecmp(key, MONGOC_URI_SAFE) ||
!strcasecmp(key, MONGOC_URI_W) ||
!strcasecmp(key, MONGOC_URI_WTIMEOUTMS)) {
continue;
}
if (mongoc_uri_option_is_bool(key)) {
/* The option's type is not validated because bson_iter_as_bool() is
* used to cast the value to a boolean. Validation may be introduced
* in PHPC-990. */
if (!mongoc_uri_set_option_as_bool(uri, key, bson_iter_as_bool(&iter))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (mongoc_uri_option_is_int32(key)) {
if (!BSON_ITER_HOLDS_INT32(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "32-bit integer");
return false;
}
if (!mongoc_uri_set_option_as_int32(uri, key, bson_iter_int32(&iter))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (mongoc_uri_option_is_utf8(key)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!strcasecmp(key, MONGOC_URI_REPLICASET) && !strcmp("", bson_iter_utf8(&iter, NULL))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Value for URI option \"%s\" cannot be empty string.", key);
return false;
}
if (!mongoc_uri_set_option_as_utf8(uri, key, bson_iter_utf8(&iter, NULL))) {
/* Assignment uses mongoc_uri_set_appname() for the "appname"
* option, which validates length in addition to UTF-8 encoding.
* For BC, we report the invalid string to the user. */
if (!strcasecmp(key, MONGOC_URI_APPNAME)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Invalid appname value: '%s'", bson_iter_utf8(&iter, NULL));
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
}
return false;
}
continue;
}
if (!strcasecmp(key, "username")) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_username(uri, bson_iter_utf8(&iter, NULL))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, "password")) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_password(uri, bson_iter_utf8(&iter, NULL))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_AUTHMECHANISM)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_auth_mechanism(uri, bson_iter_utf8(&iter, NULL))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_AUTHSOURCE)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_auth_source(uri, bson_iter_utf8(&iter, NULL))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_AUTHMECHANISMPROPERTIES)) {
bson_t properties;
uint32_t len;
const uint8_t* data;
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "array or object");
return false;
}
bson_iter_document(&iter, &len, &data);
if (!bson_init_static(&properties, data, len)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Could not initialize BSON structure for auth mechanism properties");
return false;
}
if (!mongoc_uri_set_mechanism_properties(uri, &properties)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
if (!strcasecmp(key, MONGOC_URI_GSSAPISERVICENAME)) {
bson_t unused, properties = BSON_INITIALIZER;
if (mongoc_uri_get_mechanism_properties(uri, &unused)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "authMechanismProperties SERVICE_NAME already set, ignoring \"%s\"", key);
return false;
}
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
bson_append_utf8(&properties, "SERVICE_NAME", -1, bson_iter_utf8(&iter, NULL), -1);
if (!mongoc_uri_set_mechanism_properties(uri, &properties)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
bson_destroy(&properties);
return false;
}
bson_destroy(&properties);
continue;
}
if (!strcasecmp(key, MONGOC_URI_COMPRESSORS)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
return false;
}
if (!mongoc_uri_set_compressors(uri, bson_iter_utf8(&iter, NULL))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" URI option", key);
return false;
}
continue;
}
}
return true;
} /* }}} */
static bool php_phongo_apply_rc_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
mongoc_read_concern_t* new_rc;
const mongoc_read_concern_t* old_rc;
if (!(old_rc = mongoc_uri_get_read_concern(uri))) {
phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED, "mongoc_uri_t does not have a read concern");
return false;
}
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
new_rc = mongoc_read_concern_copy(old_rc);
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
if (!strcasecmp(key, MONGOC_URI_READCONCERNLEVEL)) {
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
mongoc_read_concern_destroy(new_rc);
return false;
}
mongoc_read_concern_set_level(new_rc, bson_iter_utf8(&iter, NULL));
}
}
mongoc_uri_set_read_concern(uri, new_rc);
mongoc_read_concern_destroy(new_rc);
return true;
} /* }}} */
static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
mongoc_read_prefs_t* new_rp;
const mongoc_read_prefs_t* old_rp;
if (!(old_rp = mongoc_uri_get_read_prefs_t(uri))) {
phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED, "mongoc_uri_t does not have a read preference");
return false;
}
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
new_rp = mongoc_read_prefs_copy(old_rp);
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
if (!strcasecmp(key, MONGOC_URI_READPREFERENCE)) {
const char* str;
if (!BSON_ITER_HOLDS_UTF8(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "string");
mongoc_read_prefs_destroy(new_rp);
return false;
}
str = bson_iter_utf8(&iter, NULL);
if (0 == strcasecmp("primary", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY);
} else if (0 == strcasecmp("primarypreferred", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY_PREFERRED);
} else if (0 == strcasecmp("secondary", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY);
} else if (0 == strcasecmp("secondarypreferred", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED);
} else if (0 == strcasecmp("nearest", str)) {
mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_NEAREST);
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Unsupported %s value: '%s'", bson_iter_key(&iter), str);
mongoc_read_prefs_destroy(new_rp);
return false;
}
}
if (!strcasecmp(key, MONGOC_URI_READPREFERENCETAGS)) {
bson_t tags;
uint32_t len;
const uint8_t* data;
if (!BSON_ITER_HOLDS_ARRAY(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "array");
mongoc_read_prefs_destroy(new_rp);
return false;
}
bson_iter_array(&iter, &len, &data);
if (!bson_init_static(&tags, data, len)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Could not initialize BSON structure for read preference tags");
mongoc_read_prefs_destroy(new_rp);
return false;
}
if (!php_phongo_read_preference_tags_are_valid(&tags)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Read preference tags must be an array of zero or more documents");
mongoc_read_prefs_destroy(new_rp);
return false;
}
mongoc_read_prefs_set_tags(new_rp, &tags);
}
if (!strcasecmp(key, MONGOC_URI_MAXSTALENESSSECONDS)) {
int64_t max_staleness_seconds;
if (!BSON_ITER_HOLDS_INT(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "integer");
mongoc_read_prefs_destroy(new_rp);
return false;
}
max_staleness_seconds = bson_iter_as_int64(&iter);
if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected maxStalenessSeconds to be >= %d, %" PRId64 " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, max_staleness_seconds);
mongoc_read_prefs_destroy(new_rp);
return false;
}
if (max_staleness_seconds > INT32_MAX) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected maxStalenessSeconds to be <= %d, %" PRId64 " given", INT32_MAX, max_staleness_seconds);
mongoc_read_prefs_destroy(new_rp);
return false;
}
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Primary read preference mode conflicts with maxStalenessSeconds");
mongoc_read_prefs_destroy(new_rp);
return false;
}
}
mongoc_read_prefs_set_max_staleness_seconds(new_rp, max_staleness_seconds);
}
}
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY &&
!bson_empty(mongoc_read_prefs_get_tags(new_rp))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Primary read preference mode conflicts with tags");
mongoc_read_prefs_destroy(new_rp);
return false;
}
/* Make sure maxStalenessSeconds is not combined with primary readPreference */
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY &&
mongoc_read_prefs_get_max_staleness_seconds(new_rp) != MONGOC_NO_MAX_STALENESS) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Primary read preference mode conflicts with maxStalenessSeconds");
mongoc_read_prefs_destroy(new_rp);
return false;
}
/* This may be redundant in light of the previous checks (primary with tags
* or maxStalenessSeconds), but we'll check anyway in case additional
* validation is implemented. */
if (!mongoc_read_prefs_is_valid(new_rp)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Read preference is not valid");
mongoc_read_prefs_destroy(new_rp);
return false;
}
mongoc_uri_set_read_prefs_t(uri, new_rp);
mongoc_read_prefs_destroy(new_rp);
return true;
} /* }}} */
static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* options) /* {{{ */
{
bson_iter_t iter;
mongoc_write_concern_t* new_wc;
const mongoc_write_concern_t* old_wc;
bool ignore_safe = false;
if (!(old_wc = mongoc_uri_get_write_concern(uri))) {
phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED, "mongoc_uri_t does not have a write concern");
return false;
}
/* Return early if there are no options to apply */
if (bson_empty0(options) || !bson_iter_init(&iter, options)) {
return true;
}
new_wc = mongoc_write_concern_copy(old_wc);
while (bson_iter_next(&iter)) {
const char* key = bson_iter_key(&iter);
if (!ignore_safe && !strcasecmp(key, MONGOC_URI_SAFE)) {
if (!BSON_ITER_HOLDS_BOOL(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "boolean");
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_write_concern_set_w(new_wc, bson_iter_bool(&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED);
}
if (!strcasecmp(key, MONGOC_URI_WTIMEOUTMS)) {
int64_t wtimeout;
if (!BSON_ITER_HOLDS_INT(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "integer");
mongoc_write_concern_destroy(new_wc);
return false;
}
wtimeout = bson_iter_as_int64(&iter);
if (wtimeout < 0) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected wtimeoutMS to be >= 0, %" PRId64 " given", wtimeout);
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_write_concern_set_wtimeout_int64(new_wc, wtimeout);
}
if (!strcasecmp(key, MONGOC_URI_JOURNAL)) {
if (!BSON_ITER_HOLDS_BOOL(&iter)) {
PHONGO_URI_INVALID_TYPE(iter, "boolean");
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_write_concern_set_journal(new_wc, bson_iter_bool(&iter));
}
if (!strcasecmp(key, MONGOC_URI_W)) {
if (BSON_ITER_HOLDS_INT32(&iter)) {
int32_t value = bson_iter_int32(&iter);
switch (value) {
case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED:
case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED:
mongoc_write_concern_set_w(new_wc, value);
break;
default:
if (value > 0) {
mongoc_write_concern_set_w(new_wc, value);
break;
}
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Unsupported w value: %d", value);
mongoc_write_concern_destroy(new_wc);
return false;
}
} else if (BSON_ITER_HOLDS_UTF8(&iter)) {
const char* str = bson_iter_utf8(&iter, NULL);
if (0 == strcasecmp(PHONGO_WRITE_CONCERN_W_MAJORITY, str)) {
mongoc_write_concern_set_w(new_wc, MONGOC_WRITE_CONCERN_W_MAJORITY);
} else {
mongoc_write_concern_set_wtag(new_wc, str);
}
} else {
PHONGO_URI_INVALID_TYPE(iter, "32-bit integer or string");
mongoc_write_concern_destroy(new_wc);
return false;
}
ignore_safe = true;
}
}
if (mongoc_write_concern_get_journal(new_wc)) {
int32_t w = mongoc_write_concern_get_w(new_wc);
if (w == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || w == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Journal conflicts with w value: %d", w);
mongoc_write_concern_destroy(new_wc);
return false;
}
}
/* This may be redundant in light of the last check (unacknowledged w with
journal), but we'll check anyway in case additional validation is
implemented. */
if (!mongoc_write_concern_is_valid(new_wc)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Write concern is not valid");
mongoc_write_concern_destroy(new_wc);
return false;
}
mongoc_uri_set_write_concern(uri, new_wc);
mongoc_write_concern_destroy(new_wc);
return true;
} /* }}} */
#ifdef MONGOC_ENABLE_SSL
static void php_phongo_mongoc_ssl_opts_from_uri(mongoc_ssl_opt_t* ssl_opt, mongoc_uri_t* uri, bool* any_ssl_option_set)
{
bool insecure = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSINSECURE, false);
const char* pem_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, NULL);
const char* pem_pwd = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, NULL);
const char* ca_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCAFILE, NULL);
ssl_opt->pem_file = pem_file ? estrdup(pem_file) : NULL;
ssl_opt->pem_pwd = pem_pwd ? estrdup(pem_pwd) : NULL;
ssl_opt->ca_file = ca_file ? estrdup(ca_file) : NULL;
ssl_opt->weak_cert_validation = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, insecure);
ssl_opt->allow_invalid_hostname = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, insecure);
/* Boolean options default to false, so we cannot consider them for
* any_ssl_option_set. This isn't actually a problem as libmongoc will
* already have assigned them when creating the client, enabling SSL, and
* assigning SSL options. Therefore, we only need to check for non-defaults
* (i.e. non-NULL strings, true booleans). */
if (pem_file || pem_pwd || ca_file || ssl_opt->weak_cert_validation || ssl_opt->allow_invalid_hostname) {
*any_ssl_option_set = true;
}
}
static inline char* php_phongo_fetch_ssl_opt_string(zval* zoptions, const char* key)
{
int plen;
zend_bool pfree;
char* pval;
char* value;
pval = php_array_fetch_string(zoptions, key, &plen, &pfree);
value = pfree ? pval : estrndup(pval, plen);
return value;
}
static mongoc_ssl_opt_t* php_phongo_make_ssl_opt(mongoc_uri_t* uri, zval* zoptions)
{
mongoc_ssl_opt_t* ssl_opt;
bool any_ssl_option_set = false;
if (!zoptions) {
return NULL;
}
#if defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT)
if (php_array_existsc(zoptions, "ca_dir")) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"ca_dir\" option is not supported by Secure Channel and Secure Transport");
return NULL;
}
if (php_array_existsc(zoptions, "capath")) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"capath\" option is not supported by Secure Channel and Secure Transport");
return NULL;
}
#endif
#if defined(MONGOC_ENABLE_SSL_LIBRESSL) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT)
if (php_array_existsc(zoptions, "crl_file")) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "\"crl_file\" option is not supported by LibreSSL and Secure Transport");
return NULL;
}
#endif
ssl_opt = ecalloc(1, sizeof(mongoc_ssl_opt_t));
/* If SSL options are set in the URL, we need to read them and set them on
* the options struct so we can merge potential options from passed in
* driverOptions (zoptions) */
if (mongoc_uri_get_tls(uri)) {
php_phongo_mongoc_ssl_opts_from_uri(ssl_opt, uri, &any_ssl_option_set);
}
#define PHONGO_SSL_OPTION_SWAP_STRING(o, n) \
if ((o)) { \
efree((char*) (o)); \
} \
(o) = php_phongo_fetch_ssl_opt_string(zoptions, n);
/* Apply driver options that don't have a corresponding URI option. These
* are set directly on the SSL options struct. */
if (php_array_existsc(zoptions, "ca_dir")) {
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->ca_dir, "ca_dir");
any_ssl_option_set = true;
} else if (php_array_existsc(zoptions, "capath")) {
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->ca_dir, "capath");
any_ssl_option_set = true;
php_error_docref(NULL, E_DEPRECATED, "The \"capath\" context driver option is deprecated. Please use the \"ca_dir\" driver option instead.");
}
if (php_array_existsc(zoptions, "crl_file")) {
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->crl_file, "crl_file");
any_ssl_option_set = true;
}
#undef PHONGO_SSL_OPTION_SWAP_STRING
if (!any_ssl_option_set) {
efree(ssl_opt);
return NULL;
}
return ssl_opt;
}
static void php_phongo_free_ssl_opt(mongoc_ssl_opt_t* ssl_opt)
{
if (ssl_opt->pem_file) {
efree((char*) ssl_opt->pem_file);
}
if (ssl_opt->pem_pwd) {
efree((char*) ssl_opt->pem_pwd);
}
if (ssl_opt->ca_file) {
efree((char*) ssl_opt->ca_file);
}
if (ssl_opt->ca_dir) {
efree((char*) ssl_opt->ca_dir);
}
if (ssl_opt->crl_file) {
efree((char*) ssl_opt->crl_file);
}
efree(ssl_opt);
}
static inline bool php_phongo_apply_driver_option_to_uri(mongoc_uri_t* uri, zval* zoptions, const char* driverOptionKey, const char* optionKey)
{
bool ret;
char* value;
value = php_phongo_fetch_ssl_opt_string(zoptions, driverOptionKey);
ret = mongoc_uri_set_option_as_utf8(uri, optionKey, value);
efree(value);
return ret;
}
static bool php_phongo_apply_driver_options_to_uri(mongoc_uri_t* uri, zval* zoptions)
{
if (!zoptions) {
return true;
}
/* Map TLS driver options to the canonical tls options in the URI. */
if (php_array_existsc(zoptions, "allow_invalid_hostname")) {
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, php_array_fetchc_bool(zoptions, "allow_invalid_hostname"))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "allow_invalid_hostname");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"allow_invalid_hostname\" driver option is deprecated. Please use the \"tlsAllowInvalidHostnames\" URI option instead.");
}
if (php_array_existsc(zoptions, "weak_cert_validation")) {
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, php_array_fetchc_bool(zoptions, "weak_cert_validation"))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "weak_cert_validation");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"weak_cert_validation\" driver option is deprecated. Please use the \"tlsAllowInvalidCertificates\" URI option instead.");
} else if (php_array_existsc(zoptions, "allow_self_signed")) {
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, php_array_fetchc_bool(zoptions, "allow_self_signed"))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "allow_self_signed");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"allow_self_signed\" context driver option is deprecated. Please use the \"tlsAllowInvalidCertificates\" URI option instead.");
}
if (php_array_existsc(zoptions, "pem_file")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "pem_file", MONGOC_URI_TLSCERTIFICATEKEYFILE)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "pem_file");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"pem_file\" driver option is deprecated. Please use the \"tlsCertificateKeyFile\" URI option instead.");
} else if (php_array_existsc(zoptions, "local_cert")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "local_cert", MONGOC_URI_TLSCERTIFICATEKEYFILE)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "local_cert");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"local_cert\" context driver option is deprecated. Please use the \"tlsCertificateKeyFile\" URI option instead.");
}
if (php_array_existsc(zoptions, "pem_pwd")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "pem_pwd", MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "pem_pwd");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"pem_pwd\" driver option is deprecated. Please use the \"tlsCertificateKeyFilePassword\" URI option instead.");
} else if (php_array_existsc(zoptions, "passphrase")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "passphrase", MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "passphrase");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"passphrase\" context driver option is deprecated. Please use the \"tlsCertificateKeyFilePassword\" URI option instead.");
}
if (php_array_existsc(zoptions, "ca_file")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "ca_file", MONGOC_URI_TLSCAFILE)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "ca_file");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"ca_file\" driver option is deprecated. Please use the \"tlsCAFile\" URI option instead.");
} else if (php_array_existsc(zoptions, "cafile")) {
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "cafile", MONGOC_URI_TLSCAFILE)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse \"%s\" driver option", "cafile");
return false;
}
php_error_docref(NULL, E_DEPRECATED, "The \"cafile\" context driver option is deprecated. Please use the \"tlsCAFile\" URI option instead.");
}
return true;
}
#endif /* MONGOC_ENABLE_SSL */
static zval* php_phongo_manager_prepare_manager_for_hash(zval* driverOptions, bool* free)
{
php_phongo_manager_t* manager;
zval* autoEncryptionOpts = NULL;
zval* keyVaultClient = NULL;
zval* driverOptionsClone = NULL;
zval* autoEncryptionOptsClone = NULL;
zval stackAutoEncryptionOptsClone;
*free = false;
if (!driverOptions) {
return NULL;
}
if (!php_array_existsc(driverOptions, "autoEncryption")) {
goto ref;
}
autoEncryptionOpts = php_array_fetchc(driverOptions, "autoEncryption");
if (Z_TYPE_P(autoEncryptionOpts) != IS_ARRAY) {
goto ref;
}
if (!php_array_existsc(autoEncryptionOpts, "keyVaultClient")) {
goto ref;
}
keyVaultClient = php_array_fetchc(autoEncryptionOpts, "keyVaultClient");
if (Z_TYPE_P(keyVaultClient) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(keyVaultClient), php_phongo_manager_ce)) {
goto ref;
}
*free = true;
manager = Z_MANAGER_OBJ_P(keyVaultClient);
driverOptionsClone = ecalloc(1, sizeof(zval));
autoEncryptionOptsClone = &stackAutoEncryptionOptsClone;
ZVAL_DUP(autoEncryptionOptsClone, autoEncryptionOpts);
ADD_ASSOC_STRINGL(autoEncryptionOptsClone, "keyVaultClient", manager->client_hash, manager->client_hash_len);
ZVAL_DUP(driverOptionsClone, driverOptions);
ADD_ASSOC_ZVAL_EX(driverOptionsClone, "autoEncryption", autoEncryptionOptsClone);
return driverOptionsClone;
ref:
Z_ADDREF_P(driverOptions);
return driverOptions;
}
/* Creates a hash for a client by concatenating the URI string with serialized
* options arrays. On success, a persistent string is returned (i.e. pefree()
* should be used to free it) and hash_len will be set to the string's length.
* On error, an exception will have been thrown and NULL will be returned. */
static char* php_phongo_manager_make_client_hash(const char* uri_string, zval* options, zval* driverOptions, size_t* hash_len)
{
char* hash = NULL;
smart_str var_buf = { 0 };
php_serialize_data_t var_hash;
zval* serializable_driver_options = NULL;
bool free_driver_options = false;
zval args;
array_init_size(&args, 4);
ADD_ASSOC_LONG_EX(&args, "pid", getpid());
ADD_ASSOC_STRING(&args, "uri", uri_string);
if (options) {
ADD_ASSOC_ZVAL_EX(&args, "options", options);
Z_ADDREF_P(options);
} else {
ADD_ASSOC_NULL_EX(&args, "options");
}
if (driverOptions) {
serializable_driver_options = php_phongo_manager_prepare_manager_for_hash(driverOptions, &free_driver_options);
ADD_ASSOC_ZVAL_EX(&args, "driverOptions", serializable_driver_options);
} else {
ADD_ASSOC_NULL_EX(&args, "driverOptions");
}
PHP_VAR_SERIALIZE_INIT(var_hash);
php_var_serialize(&var_buf, &args, &var_hash);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
if (!EG(exception)) {
*hash_len = ZSTR_LEN(var_buf.s);
hash = estrndup(ZSTR_VAL(var_buf.s), *hash_len);
}
zval_ptr_dtor(&args);
if (free_driver_options) {
efree(serializable_driver_options);
}
smart_str_free(&var_buf);
return hash;
}
static bool php_phongo_extract_handshake_data(zval* driver, const char* key, char** value, size_t* value_len)
{
zval* zvalue;
if (!php_array_exists(driver, key)) {
*value = NULL;
*value_len = 0;
return true;
}
zvalue = php_array_fetch(driver, key);
if (Z_TYPE_P(zvalue) != IS_STRING) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" handshake option to be a string, %s given", key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zvalue));
return false;
}
*value = estrdup(Z_STRVAL_P(zvalue));
*value_len = Z_STRLEN_P(zvalue);
return true;
}
static char* php_phongo_concat_handshake_data(const char* default_value, const char* custom_value, size_t custom_value_len)
{
char* ret;
/* Length of the returned value needs to include a trailing space and null byte */
size_t ret_len = strlen(default_value) + 2;
if (custom_value) {
/* Increase the length by that of the custom value as well as the separator length */
ret_len += custom_value_len + PHONGO_METADATA_SEPARATOR_LEN;
}
ret = ecalloc(ret_len, sizeof(char));
if (custom_value) {
snprintf(ret, ret_len, "%s%s%s ", default_value, PHONGO_METADATA_SEPARATOR, custom_value);
} else {
snprintf(ret, ret_len, "%s ", default_value);
}
return ret;
}
static void php_phongo_handshake_data_append(const char* name, size_t name_len, const char* version, size_t version_len, const char* platform, size_t platform_len)
{
char* php_version_string;
size_t php_version_string_len;
char* driver_name;
char* driver_version;
char* full_platform;
php_version_string_len = strlen(PHP_VERSION) + PHONGO_METADATA_PHP_VERSION_PREFIX_LEN + 1;
php_version_string = ecalloc(php_version_string_len, sizeof(char));
snprintf(php_version_string, php_version_string_len, "%s%s", PHONGO_METADATA_PHP_VERSION_PREFIX, PHP_VERSION);
driver_name = php_phongo_concat_handshake_data("ext-mongodb:PHP", name, name_len);
driver_version = php_phongo_concat_handshake_data(PHP_MONGODB_VERSION, version, version_len);
full_platform = php_phongo_concat_handshake_data(php_version_string, platform, platform_len);
MONGOC_DEBUG(
"Setting driver handshake data: { name: '%s', version: '%s', platform: '%s' }",
driver_name,
driver_version,
full_platform);
mongoc_handshake_data_append(driver_name, driver_version, full_platform);
efree(php_version_string);
efree(driver_name);
efree(driver_version);
efree(full_platform);
}
static void php_phongo_set_handshake_data(zval* driverOptions)
{
char* name = NULL;
size_t name_len = 0;
char* version = NULL;
size_t version_len = 0;
char* platform = NULL;
size_t platform_len = 0;
if (driverOptions && php_array_existsc(driverOptions, "driver")) {
zval* driver = php_array_fetchc(driverOptions, "driver");
if (Z_TYPE_P(driver) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"driver\" driver option to be an array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(driver));
return;
}
if (!php_phongo_extract_handshake_data(driver, "name", &name, &name_len)) {
/* Exception already thrown */
goto cleanup;
}
if (!php_phongo_extract_handshake_data(driver, "version", &version, &version_len)) {
/* Exception already thrown */
goto cleanup;
}
if (!php_phongo_extract_handshake_data(driver, "platform", &platform, &platform_len)) {
/* Exception already thrown */
goto cleanup;
}
}
php_phongo_handshake_data_append(name, name_len, version, version_len, platform, platform_len);
cleanup:
if (name) {
efree(name);
}
if (version) {
efree(version);
}
if (platform) {
efree(platform);
}
}
static mongoc_client_t* php_phongo_make_mongo_client(const mongoc_uri_t* uri, zval* driverOptions) /* {{{ */
{
const char * mongoc_version, *bson_version;
mongoc_client_t* client;
bson_error_t error = { 0 };
#ifdef HAVE_SYSTEM_LIBMONGOC
mongoc_version = mongoc_get_version();
#else
mongoc_version = "bundled";
#endif
#ifdef HAVE_SYSTEM_LIBBSON
bson_version = bson_get_version();
#else
bson_version = "bundled";
#endif
MONGOC_DEBUG(
"Creating Manager, phongo-%s[%s] - mongoc-%s(%s), libbson-%s(%s), php-%s",
PHP_MONGODB_VERSION,
PHP_MONGODB_STABILITY,
MONGOC_VERSION_S,
mongoc_version,
BSON_VERSION_S,
bson_version,
PHP_VERSION);
php_phongo_set_handshake_data(driverOptions);
if (!(client = mongoc_client_new_from_uri_with_error(uri, &error))) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Failed to parse URI options: %s", error.message);
}
return client;
} /* }}} */
/* Adds a client to the appropriate registry. Persistent and request-scoped
* clients each have their own registries (i.e. HashTables), which use different
* forms of memory allocation. Both registries are used for PID tracking.
* Returns true if the client was successfully added; otherwise, false. */
bool php_phongo_client_register(php_phongo_manager_t* manager)
{
bool is_persistent = manager->use_persistent_client;
php_phongo_pclient_t* pclient = pecalloc(1, sizeof(php_phongo_pclient_t), is_persistent);
pclient->client = manager->client;
pclient->created_by_pid = (int) getpid();
pclient->is_persistent = is_persistent;
if (is_persistent) {
MONGOC_DEBUG("Stored persistent client with hash: %s", manager->client_hash);
return zend_hash_str_update_ptr(&MONGODB_G(persistent_clients), manager->client_hash, manager->client_hash_len, pclient) != NULL;
} else {
MONGOC_DEBUG("Stored non-persistent client");
return zend_hash_next_index_insert_ptr(MONGODB_G(request_clients), pclient) != NULL;
}
}
/* Removes a client from the request-scoped registry. This function is a NOP for
* persistent clients, since they are destroyed along with their registry (i.e.
* HashTable) in GSHUTDOWN. Returns true if the client was successfully removed;
* otherwise, false. */
bool php_phongo_client_unregister(php_phongo_manager_t* manager)
{
zend_ulong index;
php_phongo_pclient_t* pclient;
/* Persistent clients do not get unregistered. */
if (manager->use_persistent_client) {
MONGOC_DEBUG("Not destroying persistent client for Manager");
return false;
}
/* Ensure the request-scoped registry is initialized. This is needed because
* RSHUTDOWN may occur before a Manager's free_object handler is
* executed. */
if (MONGODB_G(request_clients) == NULL) {
return false;
}
ZEND_HASH_FOREACH_NUM_KEY_PTR(MONGODB_G(request_clients), index, pclient)
{
if (pclient->client == manager->client) {
MONGOC_DEBUG("Destroying non-persistent client for Manager");
return zend_hash_index_del(MONGODB_G(request_clients), index) == SUCCESS;
}
}
ZEND_HASH_FOREACH_END();
return false;
}
static mongoc_client_t* php_phongo_find_persistent_client(const char* hash, size_t hash_len)
{
php_phongo_pclient_t* pclient = zend_hash_str_find_ptr(&MONGODB_G(persistent_clients), hash, hash_len);
if (pclient) {
return pclient->client;
}
return NULL;
}
static bool phongo_manager_set_serverapi_opts(php_phongo_manager_t* manager, zval* driverOptions) /* {{{ */
{
zval* zServerApi;
php_phongo_serverapi_t* server_api;
bson_error_t error = { 0 };
if (!driverOptions || !php_array_existsc(driverOptions, "serverApi")) {
return true;
}
zServerApi = php_array_fetch(driverOptions, "serverApi");
if (Z_TYPE_P(zServerApi) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(zServerApi), php_phongo_serverapi_ce)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"serverApi\" driver option to be %s, %s given", ZSTR_VAL(php_phongo_serverapi_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zServerApi));
return false;
}
server_api = Z_SERVERAPI_OBJ_P(zServerApi);
if (!mongoc_client_set_server_api(manager->client, server_api->server_api, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
return false;
}
return true;
} /* }}} */
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manager, zval* driverOptions) /* {{{ */
{
zval* zAutoEncryptionOpts;
bson_error_t error = { 0 };
mongoc_auto_encryption_opts_t* auto_encryption_opts = NULL;
bool retval = false;
if (!driverOptions || !php_array_existsc(driverOptions, "autoEncryption")) {
return true;
}
zAutoEncryptionOpts = php_array_fetch(driverOptions, "autoEncryption");
if (Z_TYPE_P(zAutoEncryptionOpts) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"autoEncryption\" driver option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zAutoEncryptionOpts));
return false;
}
auto_encryption_opts = mongoc_auto_encryption_opts_new();
+ if (php_array_existsc(zAutoEncryptionOpts, "bypassAutoEncryption")) {
+ mongoc_auto_encryption_opts_set_bypass_auto_encryption(auto_encryption_opts, php_array_fetch_bool(zAutoEncryptionOpts, "bypassAutoEncryption"));
+ }
+
+ if (php_array_existsc(zAutoEncryptionOpts, "bypassQueryAnalysis")) {
+ mongoc_auto_encryption_opts_set_bypass_query_analysis(auto_encryption_opts, php_array_fetch_bool(zAutoEncryptionOpts, "bypassQueryAnalysis"));
+ }
+
+ if (php_array_existsc(zAutoEncryptionOpts, "encryptedFieldsMap")) {
+ zval* enc_fields_map = php_array_fetch(zAutoEncryptionOpts, "encryptedFieldsMap");
+ bson_t bson_map = BSON_INITIALIZER;
+
+ if (Z_TYPE_P(enc_fields_map) != IS_OBJECT && Z_TYPE_P(enc_fields_map) != IS_ARRAY) {
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"encryptedFieldsMap\" autoEncryption option to be an array or object, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(enc_fields_map));
+ goto cleanup;
+ }
+
+ php_phongo_zval_to_bson(enc_fields_map, PHONGO_BSON_NONE, &bson_map, NULL);
+ if (EG(exception)) {
+ goto cleanup;
+ }
+
+ mongoc_auto_encryption_opts_set_encrypted_fields_map(auto_encryption_opts, &bson_map);
+
+ bson_destroy(&bson_map);
+
+ /* Copy the encryptedFieldsMap to the Manager since PHPLIB may need to
+ * access it for createCollection and dropCollection helpers. */
+ ZVAL_ZVAL(&manager->enc_fields_map, enc_fields_map, 1, 0);
+ }
+
if (php_array_existsc(zAutoEncryptionOpts, "keyVaultClient")) {
zval* key_vault_client = php_array_fetch(zAutoEncryptionOpts, "keyVaultClient");
if (Z_TYPE_P(key_vault_client) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(key_vault_client), php_phongo_manager_ce)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultClient\" encryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultClient\" autoEncryption option to be %s, %s given", ZSTR_VAL(php_phongo_manager_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(key_vault_client));
goto cleanup;
}
/* Ensure the Manager and keyVaultClient are consistent in their use of
* persistent clients. A non-persistent Manager could theoretically use
* a persistent keyVaultClient, but this prohibition may help prevent
* users from inadvertently creating a persistent keyVaultClient. */
if (manager->use_persistent_client != Z_MANAGER_OBJ_P(key_vault_client)->use_persistent_client) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "The \"disableClientPersistence\" option for a Manager and its \"keyVaultClient\" must be the same");
goto cleanup;
}
mongoc_auto_encryption_opts_set_keyvault_client(auto_encryption_opts, Z_MANAGER_OBJ_P(key_vault_client)->client);
/* Copy the keyVaultClient to the Manager to allow for ref-counting (for
* non-persistent clients) and reset-on-fork behavior. */
ZVAL_ZVAL(&manager->key_vault_client_manager, key_vault_client, 1, 0);
}
if (php_array_existsc(zAutoEncryptionOpts, "keyVaultNamespace")) {
char* key_vault_ns;
char* db_name;
char* coll_name;
int plen;
zend_bool pfree;
key_vault_ns = php_array_fetch_string(zAutoEncryptionOpts, "keyVaultNamespace", &plen, &pfree);
if (!phongo_split_namespace(key_vault_ns, &db_name, &coll_name)) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultNamespace\" encryption option to contain a full collection name");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"keyVaultNamespace\" autoEncryption option to contain a full collection namespace");
if (pfree) {
efree(key_vault_ns);
}
goto cleanup;
}
mongoc_auto_encryption_opts_set_keyvault_namespace(auto_encryption_opts, db_name, coll_name);
efree(db_name);
efree(coll_name);
if (pfree) {
efree(key_vault_ns);
}
}
if (php_array_existsc(zAutoEncryptionOpts, "kmsProviders")) {
zval* kms_providers = php_array_fetch(zAutoEncryptionOpts, "kmsProviders");
bson_t bson_providers = BSON_INITIALIZER;
if (Z_TYPE_P(kms_providers) != IS_OBJECT && Z_TYPE_P(kms_providers) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"kmsProviders\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"kmsProviders\" autoEncryption option to be an array or object, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(kms_providers));
goto cleanup;
}
php_phongo_zval_to_bson(kms_providers, PHONGO_BSON_NONE, &bson_providers, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_auto_encryption_opts_set_kms_providers(auto_encryption_opts, &bson_providers);
bson_destroy(&bson_providers);
}
if (php_array_existsc(zAutoEncryptionOpts, "schemaMap")) {
zval* schema_map = php_array_fetch(zAutoEncryptionOpts, "schemaMap");
bson_t bson_map = BSON_INITIALIZER;
if (Z_TYPE_P(schema_map) != IS_OBJECT && Z_TYPE_P(schema_map) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"schemaMap\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"schemaMap\" autoEncryption option to be an array or object, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(schema_map));
goto cleanup;
}
php_phongo_zval_to_bson(schema_map, PHONGO_BSON_NONE, &bson_map, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_auto_encryption_opts_set_schema_map(auto_encryption_opts, &bson_map);
bson_destroy(&bson_map);
}
if (php_array_existsc(zAutoEncryptionOpts, "tlsOptions")) {
zval* tls_options = php_array_fetch(zAutoEncryptionOpts, "tlsOptions");
bson_t bson_options = BSON_INITIALIZER;
if (Z_TYPE_P(tls_options) != IS_OBJECT && Z_TYPE_P(tls_options) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"tlsOptions\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"tlsOptions\" autoEncryption option to be an array or object, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(tls_options));
goto cleanup;
}
php_phongo_zval_to_bson(tls_options, PHONGO_BSON_NONE, &bson_options, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_auto_encryption_opts_set_tls_opts(auto_encryption_opts, &bson_options);
bson_destroy(&bson_options);
}
- if (php_array_existsc(zAutoEncryptionOpts, "bypassAutoEncryption")) {
- zend_bool bypass_auto_encryption = php_array_fetch_bool(zAutoEncryptionOpts, "bypassAutoEncryption");
-
- mongoc_auto_encryption_opts_set_bypass_auto_encryption(auto_encryption_opts, bypass_auto_encryption);
- }
-
if (php_array_existsc(zAutoEncryptionOpts, "extraOptions")) {
zval* extra_options = php_array_fetch(zAutoEncryptionOpts, "extraOptions");
bson_t bson_options = BSON_INITIALIZER;
if (Z_TYPE_P(extra_options) != IS_OBJECT && Z_TYPE_P(extra_options) != IS_ARRAY) {
- phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"extraOptions\" encryption option to be an array or object");
+ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"extraOptions\" autoEncryption option to be an array or object, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(extra_options));
goto cleanup;
}
php_phongo_zval_to_bson(extra_options, PHONGO_BSON_NONE, &bson_options, NULL);
if (EG(exception)) {
goto cleanup;
}
mongoc_auto_encryption_opts_set_extra(auto_encryption_opts, &bson_options);
bson_destroy(&bson_options);
}
if (!mongoc_client_enable_auto_encryption(manager->client, auto_encryption_opts, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
goto cleanup;
}
retval = true;
cleanup:
mongoc_auto_encryption_opts_destroy(auto_encryption_opts);
return retval;
}
/* }}} */
#else /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
static bool phongo_manager_set_auto_encryption_opts(php_phongo_manager_t* manager, zval* driverOptions) /* {{{ */
{
if (!driverOptions || !php_array_existsc(driverOptions, "autoEncryption")) {
return true;
}
phongo_throw_exception_no_cse(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot enable automatic field-level encryption.");
return false;
}
/* }}} */
#endif /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions) /* {{{ */
{
bson_t bson_options = BSON_INITIALIZER;
mongoc_uri_t* uri = NULL;
#ifdef MONGOC_ENABLE_SSL
mongoc_ssl_opt_t* ssl_opt = NULL;
#endif
if (!(manager->client_hash = php_phongo_manager_make_client_hash(uri_string, options, driverOptions, &manager->client_hash_len))) {
/* Exception should already have been thrown and there is nothing to free */
return;
}
if (driverOptions && php_array_existsc(driverOptions, "disableClientPersistence")) {
manager->use_persistent_client = !php_array_fetchc_bool(driverOptions, "disableClientPersistence");
} else {
manager->use_persistent_client = true;
}
if (manager->use_persistent_client && (manager->client = php_phongo_find_persistent_client(manager->client_hash, manager->client_hash_len))) {
MONGOC_DEBUG("Found client for hash: %s", manager->client_hash);
goto cleanup;
}
if (options) {
php_phongo_zval_to_bson(options, PHONGO_BSON_NONE, &bson_options, NULL);
}
/* An exception may be thrown during BSON conversion */
if (EG(exception)) {
goto cleanup;
}
if (!(uri = php_phongo_make_uri(uri_string))) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!php_phongo_apply_options_to_uri(uri, &bson_options) ||
!php_phongo_apply_rc_options_to_uri(uri, &bson_options) ||
!php_phongo_apply_rp_options_to_uri(uri, &bson_options) ||
!php_phongo_apply_wc_options_to_uri(uri, &bson_options)) {
/* Exception should already have been thrown */
goto cleanup;
}
#ifdef MONGOC_ENABLE_SSL
if (!php_phongo_apply_driver_options_to_uri(uri, driverOptions)) {
/* Exception should already have been thrown */
goto cleanup;
}
ssl_opt = php_phongo_make_ssl_opt(uri, driverOptions);
/* An exception may be thrown during SSL option creation */
if (EG(exception)) {
goto cleanup;
}
#endif
manager->client = php_phongo_make_mongo_client(uri, driverOptions);
if (!manager->client) {
/* Exception should already have been thrown */
goto cleanup;
}
mongoc_client_set_error_api(manager->client, MONGOC_ERROR_API_VERSION_2);
#ifdef MONGOC_ENABLE_SSL
if (ssl_opt) {
mongoc_client_set_ssl_opts(manager->client, ssl_opt);
}
#endif
if (!phongo_manager_set_auto_encryption_opts(manager, driverOptions)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!phongo_manager_set_serverapi_opts(manager, driverOptions)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!phongo_apm_set_callbacks(manager->client)) {
/* Exception should already have been thrown */
goto cleanup;
}
MONGOC_DEBUG("Created client with hash: %s", manager->client_hash);
/* Register the newly created client in the appropriate registry (for either
* persistent or request-scoped clients). */
if (!php_phongo_client_register(manager)) {
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to add Manager client to internal registry");
goto cleanup;
}
cleanup:
bson_destroy(&bson_options);
if (uri) {
mongoc_uri_destroy(uri);
}
#ifdef MONGOC_ENABLE_SSL
if (ssl_opt) {
php_phongo_free_ssl_opt(ssl_opt);
}
#endif
} /* }}} */
static void phongo_pclient_reset_once(php_phongo_pclient_t* pclient, int pid)
{
if (pclient->last_reset_by_pid != pid) {
mongoc_client_reset(pclient->client);
pclient->last_reset_by_pid = pid;
}
}
/* Resets the libmongoc client if it has not already been reset for the current
* PID (based on information in the hash table of persisted libmongoc clients).
* This ensures that we do not reset a client multiple times from the same child
* process. */
void php_phongo_client_reset_once(php_phongo_manager_t* manager, int pid)
{
php_phongo_pclient_t* pclient;
/* Reset associated key vault client */
if (!Z_ISUNDEF(manager->key_vault_client_manager)) {
php_phongo_client_reset_once(Z_MANAGER_OBJ_P(&manager->key_vault_client_manager), pid);
}
if (manager->use_persistent_client) {
pclient = zend_hash_str_find_ptr(&MONGODB_G(persistent_clients), manager->client_hash, manager->client_hash_len);
if (pclient) {
phongo_pclient_reset_once(pclient, pid);
}
return;
}
ZEND_HASH_FOREACH_PTR(MONGODB_G(request_clients), pclient)
{
if (pclient->client == manager->client) {
phongo_pclient_reset_once(pclient, pid);
/* Request-scoped clients are only used by a single Manager, so we
* can return early after finding a match. */
return;
}
}
ZEND_HASH_FOREACH_END();
}
/* Returns whether a Manager exists in the request-scoped registry. If found and
* the output parameter is non-NULL, the Manager's index will be assigned. */
static bool php_phongo_manager_exists(php_phongo_manager_t* manager, zend_ulong* index_out)
{
zend_ulong index;
php_phongo_manager_t* value;
if (!MONGODB_G(managers) || zend_hash_num_elements(MONGODB_G(managers)) == 0) {
return false;
}
ZEND_HASH_FOREACH_NUM_KEY_PTR(MONGODB_G(managers), index, value)
{
if (value != manager) {
continue;
}
if (index_out) {
*index_out = index;
}
return true;
}
ZEND_HASH_FOREACH_END();
return false;
}
/* Adds a Manager to the request-scoped registry. Returns true if the Manager
* did not exist and was successfully added; otherwise, returns false. */
bool php_phongo_manager_register(php_phongo_manager_t* manager)
{
if (!MONGODB_G(managers)) {
return false;
}
if (php_phongo_manager_exists(manager, NULL)) {
return false;
}
return zend_hash_next_index_insert_ptr(MONGODB_G(managers), manager) != NULL;
}
/* Removes a Manager from the request-scoped registry. Returns true if the
* Manager was found and successfully removed; otherwise, false is returned. */
bool php_phongo_manager_unregister(php_phongo_manager_t* manager)
{
zend_ulong index;
/* Ensure the registry is initialized. This is needed because RSHUTDOWN may
* occur before a Manager's free_object handler is executed. */
if (!MONGODB_G(managers)) {
return false;
}
if (php_phongo_manager_exists(manager, &index)) {
return zend_hash_index_del(MONGODB_G(managers), index) == SUCCESS;
}
return false;
}
static void php_phongo_pclient_destroy(php_phongo_pclient_t* pclient)
{
/* Do not destroy mongoc_client_t objects created by other processes. This
* ensures that we do not shutdown sockets that may still be in use by our
* parent process (see: PHPC-1522).
*
* This is a leak; however, we are already in GSHUTDOWN for a persistent
* clients. For a request-scoped client, we are either in the Manager's
* free_object handler or RSHUTDOWN, but there the application is capable of
* freeing its Manager and its client before forking. */
if (pclient->created_by_pid == getpid()) {
/* If we are in request shutdown, disable APM to avoid dispatching more
* events. This means that certain events (e.g. TopologyClosedEvent,
* command monitoring for endSessions) may not be observed. */
if (EG(flags) & EG_FLAGS_IN_SHUTDOWN) {
mongoc_client_set_apm_callbacks(pclient->client, NULL, NULL);
}
mongoc_client_destroy(pclient->client);
}
/* Persistent and request-scoped clients use different memory allocation */
pefree(pclient, pclient->is_persistent);
}
void php_phongo_pclient_destroy_ptr(zval* ptr)
{
php_phongo_pclient_destroy(Z_PTR_P(ptr));
}
diff --git a/mongodb-1.13.0/src/phongo_client.h b/mongodb-1.14.0/src/phongo_client.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_client.h
rename to mongodb-1.14.0/src/phongo_client.h
diff --git a/mongodb-1.13.0/src/phongo_compat.c b/mongodb-1.14.0/src/phongo_compat.c
similarity index 100%
rename from mongodb-1.13.0/src/phongo_compat.c
rename to mongodb-1.14.0/src/phongo_compat.c
diff --git a/mongodb-1.13.0/src/phongo_compat.h b/mongodb-1.14.0/src/phongo_compat.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_compat.h
rename to mongodb-1.14.0/src/phongo_compat.h
diff --git a/mongodb-1.13.0/src/phongo_error.c b/mongodb-1.14.0/src/phongo_error.c
similarity index 100%
rename from mongodb-1.13.0/src/phongo_error.c
rename to mongodb-1.14.0/src/phongo_error.c
diff --git a/mongodb-1.13.0/src/phongo_error.h b/mongodb-1.14.0/src/phongo_error.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_error.h
rename to mongodb-1.14.0/src/phongo_error.h
diff --git a/mongodb-1.13.0/src/phongo_execute.c b/mongodb-1.14.0/src/phongo_execute.c
similarity index 99%
rename from mongodb-1.13.0/src/phongo_execute.c
rename to mongodb-1.14.0/src/phongo_execute.c
index 48b2f8d4..8c695b3c 100644
--- a/mongodb-1.13.0/src/phongo_execute.c
+++ b/mongodb-1.14.0/src/phongo_execute.c
@@ -1,621 +1,626 @@
/*
* Copyright 2022-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <Zend/zend_exceptions.h>
#include "php_array_api.h"
#include "php_phongo.h"
#include "phongo_error.h"
#include "phongo_execute.h"
#include "phongo_util.h"
#include "MongoDB/Cursor.h"
#include "MongoDB/ReadPreference.h"
#include "MongoDB/Session.h"
#include "MongoDB/WriteResult.h"
static void phongo_cursor_init(zval* return_value, zval* manager, mongoc_cursor_t* cursor, zval* readPreference, zval* session) /* {{{ */
{
php_phongo_cursor_t* intern;
object_init_ex(return_value, php_phongo_cursor_ce);
intern = Z_CURSOR_OBJ_P(return_value);
intern->cursor = cursor;
intern->server_id = mongoc_cursor_get_hint(cursor);
intern->advanced = false;
intern->current = 0;
ZVAL_ZVAL(&intern->manager, manager, 1, 0);
if (readPreference) {
ZVAL_ZVAL(&intern->read_preference, readPreference, 1, 0);
}
if (session) {
ZVAL_ZVAL(&intern->session, session, 1, 0);
}
} /* }}} */
static void phongo_cursor_init_for_command(zval* return_value, zval* manager, mongoc_cursor_t* cursor, const char* db, zval* command, zval* readPreference, zval* session) /* {{{ */
{
php_phongo_cursor_t* intern;
phongo_cursor_init(return_value, manager, cursor, readPreference, session);
intern = Z_CURSOR_OBJ_P(return_value);
intern->database = estrdup(db);
ZVAL_ZVAL(&intern->command, command, 1, 0);
} /* }}} */
static void phongo_cursor_init_for_query(zval* return_value, zval* manager, mongoc_cursor_t* cursor, const char* namespace, zval* query, zval* readPreference, zval* session) /* {{{ */
{
php_phongo_cursor_t* intern;
phongo_cursor_init(return_value, manager, cursor, readPreference, session);
intern = Z_CURSOR_OBJ_P(return_value);
/* namespace has already been validated by phongo_execute_query() */
phongo_split_namespace(namespace, &intern->database, &intern->collection);
/* cursor has already been advanced by phongo_execute_query() calling
* phongo_cursor_advance_and_check_for_error() */
intern->advanced = true;
ZVAL_ZVAL(&intern->query, query, 1, 0);
} /* }}} */
static bson_t* create_wrapped_command_envelope(const char* db, bson_t* reply)
{
bson_t* tmp;
size_t max_ns_len = strlen(db) + 5 + 1; /* db + ".$cmd" + '\0' */
char* ns = emalloc(max_ns_len);
snprintf(ns, max_ns_len, "%s.$cmd", db);
tmp = BCON_NEW("cursor", "{", "id", BCON_INT64(0), "ns", BCON_UTF8(ns), "firstBatch", "[", BCON_DOCUMENT(reply), "]", "}");
efree(ns);
return tmp;
}
static zval* phongo_create_implicit_session(zval* manager) /* {{{ */
{
mongoc_client_session_t* cs;
zval* zsession;
cs = mongoc_client_start_session(Z_MANAGER_OBJ_P(manager)->client, NULL, NULL);
if (!cs) {
return NULL;
}
zsession = ecalloc(1, sizeof(zval));
phongo_session_init(zsession, manager, cs);
return zsession;
} /* }}} */
/* Parses the "readConcern" option for an execute method. If mongoc_opts is not
* NULL, the option will be appended. On error, false is returned and an
* exception is thrown. */
static bool phongo_parse_read_concern(zval* options, bson_t* mongoc_opts) /* {{{ */
{
zval* option = NULL;
mongoc_read_concern_t* read_concern;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "readConcern");
if (!option) {
return true;
}
if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_readconcern_ce)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
read_concern = Z_READCONCERN_OBJ_P(option)->read_concern;
if (mongoc_opts && !mongoc_read_concern_append(read_concern, mongoc_opts)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"readConcern\" option");
return false;
}
return true;
} /* }}} */
/* Parses the "readPreference" option for an execute method. If zreadPreference
* is not NULL, it will be assigned to the option. On error, false is returned
* and an exception is thrown. */
bool phongo_parse_read_preference(zval* options, zval** zreadPreference) /* {{{ */
{
zval* option = NULL;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "readPreference");
if (!option) {
return true;
}
if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_readpreference_ce)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"readPreference\" option to be %s, %s given", ZSTR_VAL(php_phongo_readpreference_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
if (zreadPreference) {
*zreadPreference = option;
}
return true;
} /* }}} */
/* Parses the "session" option for an execute method. The client object should
* correspond to the Manager executing the operation and will be used to ensure
* that the session is correctly associated with that client. If mongoc_opts is
* not NULL, the option will be appended. If zsession is not NULL, it will be
* assigned to the option. On error, false is returned and an exception is
* thrown. */
bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession) /* {{{ */
{
zval* option = NULL;
const mongoc_client_session_t* client_session;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "session");
if (!option) {
return true;
}
if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_session_ce)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"session\" option to be %s, %s given", ZSTR_VAL(php_phongo_session_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
client_session = Z_SESSION_OBJ_P(option)->client_session;
if (client != mongoc_client_session_get_client(client_session)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use Session started from a different Manager");
return false;
}
if (mongoc_opts && !mongoc_client_session_append(client_session, mongoc_opts, NULL)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"session\" option");
return false;
}
if (zsession) {
*zsession = option;
}
return true;
} /* }}} */
/* Parses the "writeConcern" option for an execute method. If mongoc_opts is not
* NULL, the option will be appended. If zwriteConcern is not NULL, it will be
* assigned to the option. On error, false is returned and an exception is
* thrown. */
static bool phongo_parse_write_concern(zval* options, bson_t* mongoc_opts, zval** zwriteConcern) /* {{{ */
{
zval* option = NULL;
mongoc_write_concern_t* write_concern;
if (!options) {
return true;
}
if (Z_TYPE_P(options) != IS_ARRAY) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected options to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(options));
return false;
}
option = php_array_fetchc(options, "writeConcern");
if (!option) {
return true;
}
if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_writeconcern_ce)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"writeConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_writeconcern_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
return false;
}
write_concern = Z_WRITECONCERN_OBJ_P(option)->write_concern;
if (mongoc_opts && !mongoc_write_concern_append(write_concern, mongoc_opts)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"writeConcern\" option");
return false;
}
if (zwriteConcern) {
*zwriteConcern = option;
}
return true;
}
bool phongo_execute_bulk_write(zval* manager, const char* namespace, php_phongo_bulkwrite_t* bulk_write, zval* options, uint32_t server_id, zval* return_value) /* {{{ */
{
mongoc_client_t* client = NULL;
bson_error_t error = { 0 };
int success;
bson_t reply = BSON_INITIALIZER;
mongoc_bulk_operation_t* bulk = bulk_write->bulk;
php_phongo_writeresult_t* writeresult;
zval* zwriteConcern = NULL;
zval* zsession = NULL;
const mongoc_write_concern_t* write_concern = NULL;
client = Z_MANAGER_OBJ_P(manager)->client;
if (bulk_write->executed) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "BulkWrite objects may only be executed once and this instance has already been executed");
return false;
}
if (!phongo_split_namespace(namespace, &bulk_write->database, &bulk_write->collection)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s: %s", "Invalid namespace provided", namespace);
return false;
}
if (!phongo_parse_session(options, client, NULL, &zsession)) {
/* Exception should already have been thrown */
return false;
}
if (!phongo_parse_write_concern(options, NULL, &zwriteConcern)) {
/* Exception should already have been thrown */
return false;
}
/* If a write concern was not specified, libmongoc will use the client's
* write concern; however, we should still fetch it for the write result.
* Additionally, we need to check if an unacknowledged write concern would
* conflict with an explicit session. */
write_concern = zwriteConcern ? Z_WRITECONCERN_OBJ_P(zwriteConcern)->write_concern : mongoc_client_get_write_concern(client);
if (zsession && !mongoc_write_concern_is_acknowledged(write_concern)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot combine \"session\" option with an unacknowledged write concern");
return false;
}
mongoc_bulk_operation_set_database(bulk, bulk_write->database);
mongoc_bulk_operation_set_collection(bulk, bulk_write->collection);
mongoc_bulk_operation_set_client(bulk, client);
mongoc_bulk_operation_set_hint(bulk, server_id);
if (zsession) {
ZVAL_ZVAL(&bulk_write->session, zsession, 1, 0);
mongoc_bulk_operation_set_client_session(bulk, Z_SESSION_OBJ_P(zsession)->client_session);
}
if (zwriteConcern) {
mongoc_bulk_operation_set_write_concern(bulk, Z_WRITECONCERN_OBJ_P(zwriteConcern)->write_concern);
}
success = mongoc_bulk_operation_execute(bulk, &reply, &error);
bulk_write->executed = true;
writeresult = phongo_writeresult_init(return_value, &reply, manager, mongoc_bulk_operation_get_hint(bulk));
writeresult->write_concern = mongoc_write_concern_copy(write_concern);
/* A BulkWriteException is always thrown if mongoc_bulk_operation_execute()
* fails to ensure that the write result is accessible. If the error does
* not originate from the server (e.g. socket error), throw the appropriate
* exception first. It will be included in BulkWriteException's message and
* will also be accessible via Exception::getPrevious(). */
if (!success) {
if (error.domain != MONGOC_ERROR_SERVER && error.domain != MONGOC_ERROR_WRITE_CONCERN) {
phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply);
}
/* Argument errors occur before command execution, so there is no need
* to layer this InvalidArgumentException behind a BulkWriteException.
* In practice, this will be a "Cannot do an empty bulk write" error. */
if (error.domain == MONGOC_ERROR_COMMAND && error.code == MONGOC_ERROR_COMMAND_INVALID_ARG) {
goto cleanup;
}
if (EG(exception)) {
char* message;
(void) spprintf(&message, 0, "Bulk write failed due to previous %s: %s", PHONGO_ZVAL_EXCEPTION_NAME(EG(exception)), error.message);
zend_throw_exception(php_phongo_bulkwriteexception_ce, message, 0);
efree(message);
} else {
zend_throw_exception(php_phongo_bulkwriteexception_ce, error.message, error.code);
}
/* Ensure error labels are added to the final BulkWriteException. If a
* previous exception was also thrown, error labels will already have
* been added by phongo_throw_exception_from_bson_error_t_and_reply. */
phongo_exception_add_error_labels(&reply);
phongo_add_exception_prop(ZEND_STRL("writeResult"), return_value);
}
cleanup:
bson_destroy(&reply);
return success;
} /* }}} */
bool phongo_execute_command(zval* manager, php_phongo_command_type_t type, const char* db, zval* zcommand, zval* options, uint32_t server_id, zval* return_value) /* {{{ */
{
mongoc_client_t* client;
const php_phongo_command_t* command;
bson_iter_t iter;
bson_t reply;
bson_error_t error = { 0 };
bson_t opts = BSON_INITIALIZER;
mongoc_cursor_t* cmd_cursor;
zval* zreadPreference = NULL;
zval* zsession = NULL;
bool result = false;
bool free_reply = false;
bool free_zsession = false;
bool is_unacknowledged_write_concern = false;
client = Z_MANAGER_OBJ_P(manager)->client;
command = Z_COMMAND_OBJ_P(zcommand);
if ((type & PHONGO_OPTION_READ_CONCERN) && !phongo_parse_read_concern(options, &opts)) {
/* Exception should already have been thrown */
goto cleanup;
}
if ((type & PHONGO_OPTION_READ_PREFERENCE) && !phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (!phongo_parse_session(options, client, &opts, &zsession)) {
/* Exception should already have been thrown */
goto cleanup;
}
if (type & PHONGO_OPTION_WRITE_CONCERN) {
zval* zwriteConcern = NULL;
if (!phongo_parse_write_concern(options, &opts, &zwriteConcern)) {
/* Exception should already have been thrown */
goto cleanup;
}
/* Determine if the explicit or inherited write concern is
* unacknowledged so that we can ensure it does not conflict with an
* explicit or implicit session. */
if (zwriteConcern) {
is_unacknowledged_write_concern = !mongoc_write_concern_is_acknowledged(Z_WRITECONCERN_OBJ_P(zwriteConcern)->write_concern);
} else if (type != PHONGO_COMMAND_RAW) {
is_unacknowledged_write_concern = !mongoc_write_concern_is_acknowledged(mongoc_client_get_write_concern(client));
}
}
if (zsession && is_unacknowledged_write_concern) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot combine \"session\" option with an unacknowledged write concern");
goto cleanup;
}
/* If an explicit session was not provided and the effective write concern
* is not unacknowledged, attempt to create an implicit client session
* (ignoring any errors). */
if (!zsession && !is_unacknowledged_write_concern) {
zsession = phongo_create_implicit_session(manager);
if (zsession) {
free_zsession = true;
if (!mongoc_client_session_append(Z_SESSION_OBJ_P(zsession)->client_session, &opts, NULL)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending implicit \"sessionId\" option");
goto cleanup;
}
}
}
if (!BSON_APPEND_INT32(&opts, "serverId", server_id)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"serverId\" option");
goto cleanup;
}
/* Although "opts" already always includes the serverId option, the read
* preference is added to the command parts, which is relevant for mongos
* command construction. */
switch (type) {
case PHONGO_COMMAND_RAW:
result = mongoc_client_command_with_opts(client, db, command->bson, phongo_read_preference_from_zval(zreadPreference), &opts, &reply, &error);
break;
case PHONGO_COMMAND_READ:
result = mongoc_client_read_command_with_opts(client, db, command->bson, phongo_read_preference_from_zval(zreadPreference), &opts, &reply, &error);
break;
case PHONGO_COMMAND_WRITE:
result = mongoc_client_write_command_with_opts(client, db, command->bson, &opts, &reply, &error);
break;
case PHONGO_COMMAND_READ_WRITE:
/* We can pass NULL as readPreference, as this argument was added historically, but has no function */
result = mongoc_client_read_write_command_with_opts(client, db, command->bson, NULL, &opts, &reply, &error);
break;
default:
/* Should never happen, but if it does: exception */
phongo_throw_exception(PHONGO_ERROR_LOGIC, "Type '%d' should never have been passed to phongo_execute_command, please file a bug report", type);
goto cleanup;
}
free_reply = true;
if (!result) {
phongo_throw_exception_from_bson_error_t_and_reply(&error, &reply);
goto cleanup;
}
/* According to mongoc_cursor_new_from_command_reply_with_opts(), the reply
* bson_t is ultimately destroyed on both success and failure. */
if (bson_iter_init_find(&iter, &reply, "cursor") && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
bson_t initial_reply = BSON_INITIALIZER;
bson_t cursor_opts = BSON_INITIALIZER;
- bson_error_t error = { 0 };
+ bson_iter_t iter;
+ bson_error_t error = { 0 };
bson_copy_to(&reply, &initial_reply);
bson_append_int32(&cursor_opts, "serverId", -1, server_id);
if (command->max_await_time_ms) {
bson_append_bool(&cursor_opts, "awaitData", -1, 1);
bson_append_int64(&cursor_opts, "maxAwaitTimeMS", -1, command->max_await_time_ms);
bson_append_bool(&cursor_opts, "tailable", -1, 1);
}
if (command->batch_size) {
bson_append_int64(&cursor_opts, "batchSize", -1, command->batch_size);
}
+ if (bson_iter_init(&iter, command->bson) && bson_iter_find(&iter, "comment")) {
+ bson_append_value(&cursor_opts, "comment", -1, bson_iter_value(&iter));
+ }
+
if (zsession && !mongoc_client_session_append(Z_SESSION_OBJ_P(zsession)->client_session, &cursor_opts, &error)) {
phongo_throw_exception_from_bson_error_t(&error);
bson_destroy(&initial_reply);
bson_destroy(&cursor_opts);
result = false;
goto cleanup;
}
cmd_cursor = mongoc_cursor_new_from_command_reply_with_opts(client, &initial_reply, &cursor_opts);
bson_destroy(&cursor_opts);
} else {
bson_t cursor_opts = BSON_INITIALIZER;
bson_t* wrapped_reply = create_wrapped_command_envelope(db, &reply);
bson_append_int32(&cursor_opts, "serverId", -1, server_id);
cmd_cursor = mongoc_cursor_new_from_command_reply_with_opts(client, wrapped_reply, &cursor_opts);
bson_destroy(&cursor_opts);
}
phongo_cursor_init_for_command(return_value, manager, cmd_cursor, db, zcommand, zreadPreference, zsession);
cleanup:
bson_destroy(&opts);
if (free_reply) {
bson_destroy(&reply);
}
if (free_zsession) {
zval_ptr_dtor(zsession);
efree(zsession);
}
return result;
} /* }}} */
bool phongo_execute_query(zval* manager, const char* namespace, zval* zquery, zval* options, uint32_t server_id, zval* return_value) /* {{{ */
{
mongoc_client_t* client;
const php_phongo_query_t* query;
bson_t opts = BSON_INITIALIZER;
mongoc_cursor_t* cursor;
char* dbname;
char* collname;
mongoc_collection_t* collection;
zval* zreadPreference = NULL;
zval* zsession = NULL;
client = Z_MANAGER_OBJ_P(manager)->client;
if (!phongo_split_namespace(namespace, &dbname, &collname)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s: %s", "Invalid namespace provided", namespace);
return false;
}
collection = mongoc_client_get_collection(client, dbname, collname);
efree(dbname);
efree(collname);
query = Z_QUERY_OBJ_P(zquery);
bson_copy_to(query->opts, &opts);
if (query->read_concern) {
mongoc_collection_set_read_concern(collection, query->read_concern);
}
if (!phongo_parse_read_preference(options, &zreadPreference)) {
/* Exception should already have been thrown */
mongoc_collection_destroy(collection);
bson_destroy(&opts);
return false;
}
if (!phongo_parse_session(options, client, &opts, &zsession)) {
/* Exception should already have been thrown */
mongoc_collection_destroy(collection);
bson_destroy(&opts);
return false;
}
if (!BSON_APPEND_INT32(&opts, "serverId", server_id)) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"serverId\" option");
mongoc_collection_destroy(collection);
bson_destroy(&opts);
return false;
}
cursor = mongoc_collection_find_with_opts(collection, query->filter, &opts, phongo_read_preference_from_zval(zreadPreference));
mongoc_collection_destroy(collection);
bson_destroy(&opts);
/* maxAwaitTimeMS must be set before the cursor is sent */
if (query->max_await_time_ms) {
mongoc_cursor_set_max_await_time_ms(cursor, query->max_await_time_ms);
}
if (!phongo_cursor_advance_and_check_for_error(cursor)) {
mongoc_cursor_destroy(cursor);
return false;
}
phongo_cursor_init_for_query(return_value, manager, cursor, namespace, zquery, zreadPreference, zsession);
return true;
} /* }}} */
diff --git a/mongodb-1.13.0/src/phongo_execute.h b/mongodb-1.14.0/src/phongo_execute.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_execute.h
rename to mongodb-1.14.0/src/phongo_execute.h
diff --git a/mongodb-1.13.0/src/phongo_ini.c b/mongodb-1.14.0/src/phongo_ini.c
similarity index 89%
rename from mongodb-1.13.0/src/phongo_ini.c
rename to mongodb-1.14.0/src/phongo_ini.c
index c0bad3b5..f75367b5 100644
--- a/mongodb-1.13.0/src/phongo_ini.c
+++ b/mongodb-1.14.0/src/phongo_ini.c
@@ -1,146 +1,127 @@
/*
* Copyright 2021-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include <main/php_open_temporary_file.h>
#include <ext/date/php_date.h>
#include "php_phongo.h"
#include "phongo_ini.h"
-extern bool mongoc_global_mock_service_id;
-
ZEND_EXTERN_MODULE_GLOBALS(mongodb)
static void phongo_log(mongoc_log_level_t log_level, const char* log_domain, const char* message, void* user_data)
{
struct timeval tv;
time_t t;
zend_long tu;
zend_string* dt;
bson_gettimeofday(&tv);
t = tv.tv_sec;
tu = tv.tv_usec;
dt = php_format_date((char*) ZEND_STRL("Y-m-d\\TH:i:s"), t, 0);
fprintf(MONGODB_G(debug_fd), "[%s.%06" PHONGO_LONG_FORMAT "+00:00] %10s: %-8s> %s\n", ZSTR_VAL(dt), tu, log_domain, mongoc_log_level_str(log_level), message);
fflush(MONGODB_G(debug_fd));
efree(dt);
}
void phongo_log_disable(FILE* stream)
{
mongoc_log_trace_disable();
mongoc_log_set_handler(NULL, NULL);
/* Close any previously opened log file (excluding stderr/stdout) */
if (stream && stream != stderr && stream != stdout) {
fclose(stream);
}
}
static PHP_INI_MH(OnUpdateDebug)
{
char* tmp_dir = NULL;
phongo_log_disable(MONGODB_G(debug_fd));
MONGODB_G(debug_fd) = NULL;
if (!new_value || (new_value && !ZSTR_VAL(new_value)[0]) || strcasecmp("0", ZSTR_VAL(new_value)) == 0 || strcasecmp("off", ZSTR_VAL(new_value)) == 0 || strcasecmp("no", ZSTR_VAL(new_value)) == 0 || strcasecmp("false", ZSTR_VAL(new_value)) == 0) {
return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
}
if (strcasecmp(ZSTR_VAL(new_value), "stderr") == 0) {
MONGODB_G(debug_fd) = stderr;
} else if (strcasecmp(ZSTR_VAL(new_value), "stdout") == 0) {
MONGODB_G(debug_fd) = stdout;
} else if (
strcasecmp("1", ZSTR_VAL(new_value)) == 0 ||
strcasecmp("on", ZSTR_VAL(new_value)) == 0 ||
strcasecmp("yes", ZSTR_VAL(new_value)) == 0 ||
strcasecmp("true", ZSTR_VAL(new_value)) == 0) {
tmp_dir = NULL;
} else {
tmp_dir = ZSTR_VAL(new_value);
}
if (!MONGODB_G(debug_fd)) {
time_t t;
int fd = -1;
char* prefix;
int len;
zend_string* filename;
time(&t);
len = spprintf(&prefix, 0, "PHONGO-%ld", t);
fd = php_open_temporary_fd(tmp_dir, prefix, &filename);
if (fd != -1) {
const char* path = ZSTR_VAL(filename);
MONGODB_G(debug_fd) = VCWD_FOPEN(path, "a");
}
efree(filename);
efree(prefix);
close(fd);
}
mongoc_log_trace_enable();
mongoc_log_set_handler(phongo_log, NULL);
return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
}
-static PHP_INI_MH(OnUpdateMockServiceId)
-{
- mongoc_global_mock_service_id = zend_ini_parse_bool(new_value);
-
- return SUCCESS;
-}
-
-static PHP_INI_DISP(DisplayMockServiceId)
-{
- if (mongoc_global_mock_service_id) {
- ZEND_PUTS("On");
- } else {
- ZEND_PUTS("Off");
- }
-}
-
void phongo_display_ini_entries(ZEND_MODULE_INFO_FUNC_ARGS)
{
DISPLAY_INI_ENTRIES();
}
void phongo_register_ini_entries(INIT_FUNC_ARGS)
{
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("mongodb.debug", "", PHP_INI_ALL, OnUpdateDebug, debug, zend_mongodb_globals, mongodb_globals)
- PHP_INI_ENTRY_EX("mongodb.mock_service_id", "0", PHP_INI_ALL, OnUpdateMockServiceId, DisplayMockServiceId)
PHP_INI_END()
REGISTER_INI_ENTRIES();
}
void phongo_unregister_ini_entries(SHUTDOWN_FUNC_ARGS)
{
UNREGISTER_INI_ENTRIES();
}
diff --git a/mongodb-1.13.0/src/phongo_ini.h b/mongodb-1.14.0/src/phongo_ini.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_ini.h
rename to mongodb-1.14.0/src/phongo_ini.h
diff --git a/mongodb-1.13.0/src/phongo_structs.h b/mongodb-1.14.0/src/phongo_structs.h
similarity index 97%
rename from mongodb-1.13.0/src/phongo_structs.h
rename to mongodb-1.14.0/src/phongo_structs.h
index 8d37ef40..db7306df 100644
--- a/mongodb-1.13.0/src/phongo_structs.h
+++ b/mongodb-1.14.0/src/phongo_structs.h
@@ -1,355 +1,361 @@
/*
* Copyright 2015-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PHONGO_STRUCTS_H
#define PHONGO_STRUCTS_H
#include "bson/bson.h"
#include "mongoc/mongoc.h"
#include <php.h>
#include "phongo_bson.h"
typedef struct {
mongoc_bulk_operation_t* bulk;
size_t num_ops;
bool ordered;
int bypass;
+ bson_t* let;
+ bson_value_t* comment;
char* database;
char* collection;
bool executed;
zval session;
zend_object std;
} php_phongo_bulkwrite_t;
typedef struct {
mongoc_client_encryption_t* client_encryption;
zval key_vault_client_manager;
zend_object std;
} php_phongo_clientencryption_t;
typedef struct {
bson_t* bson;
uint32_t max_await_time_ms;
uint32_t batch_size;
zend_object std;
} php_phongo_command_t;
typedef struct {
mongoc_cursor_t* cursor;
zval manager;
int created_by_pid;
uint32_t server_id;
bool advanced;
php_phongo_bson_state visitor_data;
long current;
char* database;
char* collection;
zval query;
zval command;
zval read_preference;
zval session;
zend_object std;
} php_phongo_cursor_t;
typedef struct {
bool initialized;
int64_t id;
HashTable* properties;
zend_object std;
} php_phongo_cursorid_t;
typedef struct {
mongoc_client_t* client;
int created_by_pid;
char* client_hash;
size_t client_hash_len;
bool use_persistent_client;
+ zval enc_fields_map;
zval key_vault_client_manager;
HashTable* subscribers;
zend_object std;
} php_phongo_manager_t;
typedef struct {
bson_t* filter;
bson_t* opts;
mongoc_read_concern_t* read_concern;
uint32_t max_await_time_ms;
zend_object std;
} php_phongo_query_t;
typedef struct {
mongoc_read_concern_t* read_concern;
HashTable* properties;
zend_object std;
} php_phongo_readconcern_t;
typedef struct {
mongoc_read_prefs_t* read_preference;
HashTable* properties;
zend_object std;
} php_phongo_readpreference_t;
typedef struct {
zval manager;
int created_by_pid;
uint32_t server_id;
zend_object std;
} php_phongo_server_t;
typedef struct {
mongoc_server_api_t* server_api;
HashTable* properties;
zend_object std;
} php_phongo_serverapi_t;
typedef struct {
mongoc_server_description_t* server_description;
HashTable* properties;
zend_object std;
} php_phongo_serverdescription_t;
typedef struct {
mongoc_client_session_t* client_session;
zval manager;
int created_by_pid;
zend_object std;
} php_phongo_session_t;
typedef struct {
mongoc_topology_description_t* topology_description;
HashTable* properties;
zend_object std;
} php_phongo_topologydescription_t;
typedef struct {
HashTable* properties;
mongoc_write_concern_t* write_concern;
zend_object std;
} php_phongo_writeconcern_t;
typedef struct {
int code;
char* message;
zval info;
zend_object std;
} php_phongo_writeconcernerror_t;
typedef struct {
int code;
char* message;
zval info;
uint32_t index;
zend_object std;
} php_phongo_writeerror_t;
typedef struct {
mongoc_write_concern_t* write_concern;
bson_t* reply;
zval manager;
uint32_t server_id;
zend_object std;
} php_phongo_writeresult_t;
typedef struct {
char* data;
int data_len;
uint8_t type;
HashTable* properties;
zend_object std;
} php_phongo_binary_t;
typedef struct {
char* ref;
size_t ref_len;
char id[25];
HashTable* properties;
zend_object std;
} php_phongo_dbpointer_t;
typedef struct {
bool initialized;
bson_decimal128_t decimal;
HashTable* properties;
zend_object std;
} php_phongo_decimal128_t;
typedef struct {
bool initialized;
int64_t integer;
HashTable* properties;
zend_object std;
} php_phongo_int64_t;
typedef struct {
char* code;
size_t code_len;
bson_t* scope;
HashTable* properties;
zend_object std;
} php_phongo_javascript_t;
typedef struct {
zend_object std;
} php_phongo_maxkey_t;
typedef struct {
zend_object std;
} php_phongo_minkey_t;
typedef struct {
bool initialized;
char oid[25];
HashTable* properties;
zend_object std;
} php_phongo_objectid_t;
typedef struct {
char* pattern;
int pattern_len;
char* flags;
int flags_len;
HashTable* properties;
zend_object std;
} php_phongo_regex_t;
typedef struct {
char* symbol;
size_t symbol_len;
HashTable* properties;
zend_object std;
} php_phongo_symbol_t;
typedef struct {
bool initialized;
uint32_t increment;
uint32_t timestamp;
HashTable* properties;
zend_object std;
} php_phongo_timestamp_t;
typedef struct {
zend_object std;
} php_phongo_undefined_t;
typedef struct {
bool initialized;
int64_t milliseconds;
HashTable* properties;
zend_object std;
} php_phongo_utcdatetime_t;
typedef struct {
zval manager;
char* command_name;
uint32_t server_id;
uint64_t operation_id;
uint64_t request_id;
uint64_t duration_micros;
bson_t* reply;
zval z_error;
bool has_service_id;
bson_oid_t service_id;
+ int32_t server_connection_id;
zend_object std;
} php_phongo_commandfailedevent_t;
typedef struct {
zval manager;
char* command_name;
uint32_t server_id;
uint64_t operation_id;
uint64_t request_id;
bson_t* command;
char* database_name;
bool has_service_id;
bson_oid_t service_id;
+ int32_t server_connection_id;
zend_object std;
} php_phongo_commandstartedevent_t;
typedef struct {
zval manager;
char* command_name;
uint32_t server_id;
uint64_t operation_id;
uint64_t request_id;
uint64_t duration_micros;
bson_t* reply;
bool has_service_id;
bson_oid_t service_id;
+ int32_t server_connection_id;
zend_object std;
} php_phongo_commandsucceededevent_t;
typedef struct {
bson_oid_t topology_id;
mongoc_host_list_t host;
mongoc_server_description_t* new_server_description;
mongoc_server_description_t* old_server_description;
zend_object std;
} php_phongo_serverchangedevent_t;
typedef struct {
bson_oid_t topology_id;
mongoc_host_list_t host;
zend_object std;
} php_phongo_serverclosedevent_t;
typedef struct {
bool awaited;
uint64_t duration_micros;
zval z_error;
mongoc_host_list_t host;
zend_object std;
} php_phongo_serverheartbeatfailedevent_t;
typedef struct {
bool awaited;
mongoc_host_list_t host;
zend_object std;
} php_phongo_serverheartbeatstartedevent_t;
typedef struct {
bool awaited;
uint64_t duration_micros;
mongoc_host_list_t host;
bson_t* reply;
zend_object std;
} php_phongo_serverheartbeatsucceededevent_t;
typedef struct {
bson_oid_t topology_id;
mongoc_host_list_t host;
zend_object std;
} php_phongo_serveropeningevent_t;
typedef struct {
bson_oid_t topology_id;
mongoc_topology_description_t* new_topology_description;
mongoc_topology_description_t* old_topology_description;
zend_object std;
} php_phongo_topologychangedevent_t;
typedef struct {
bson_oid_t topology_id;
zend_object std;
} php_phongo_topologyclosedevent_t;
typedef struct {
bson_oid_t topology_id;
zend_object std;
} php_phongo_topologyopeningevent_t;
#endif /* PHONGO_STRUCTS */
diff --git a/mongodb-1.13.0/src/phongo_util.c b/mongodb-1.14.0/src/phongo_util.c
similarity index 100%
rename from mongodb-1.13.0/src/phongo_util.c
rename to mongodb-1.14.0/src/phongo_util.c
diff --git a/mongodb-1.13.0/src/phongo_util.h b/mongodb-1.14.0/src/phongo_util.h
similarity index 100%
rename from mongodb-1.13.0/src/phongo_util.h
rename to mongodb-1.14.0/src/phongo_util.h
diff --git a/mongodb-1.13.0/tests/apm/bug0950-001.phpt b/mongodb-1.14.0/tests/apm/bug0950-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/bug0950-001.phpt
rename to mongodb-1.14.0/tests/apm/bug0950-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/bug0950-002.phpt b/mongodb-1.14.0/tests/apm/bug0950-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/bug0950-002.phpt
rename to mongodb-1.14.0/tests/apm/bug0950-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-001.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandFailedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/commandFailedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-002.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandFailedEvent-002.phpt
rename to mongodb-1.14.0/tests/apm/commandFailedEvent-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-debug-001.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-debug-001.phpt
similarity index 97%
rename from mongodb-1.13.0/tests/apm/commandFailedEvent-debug-001.phpt
rename to mongodb-1.14.0/tests/apm/commandFailedEvent-debug-001.phpt
index 50312628..f8df2973 100644
--- a/mongodb-1.13.0/tests/apm/commandFailedEvent-debug-001.phpt
+++ b/mongodb-1.14.0/tests/apm/commandFailedEvent-debug-001.phpt
@@ -1,66 +1,68 @@
--TEST--
MongoDB\Driver\Monitoring\CommandFailedEvent debug output
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
var_dump($event);
}
}
$manager = create_test_manager();
$manager->addSubscriber(new MySubscriber);
$command = new MongoDB\Driver\Command([
'aggregate' => COLLECTION_NAME,
'pipeline' => [['$unsupported' => 1]],
]);
/* Note: Although executeCommand() throws a CommandException, CommandFailedEvent
* will report a ServerException for its "error" property (PHPC-1990) */
throws(function() use ($manager, $command) {
$manager->executeCommand(DATABASE_NAME, $command);
}, MongoDB\Driver\Exception\CommandException::class);
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\Monitoring\CommandFailedEvent)#%d (%d) {
["commandName"]=>
string(9) "aggregate"
["durationMicros"]=>
int(%d)
["error"]=>
object(MongoDB\Driver\Exception\ServerException)#%d (%d) {%A
}
["operationId"]=>
string(%d) "%d"
["reply"]=>
object(stdClass)#%d (%d) {%A
}
["requestId"]=>
string(%d) "%d"
["server"]=>
object(MongoDB\Driver\Server)#%d (%d) {%A
}
["serviceId"]=>
%r(NULL|object\(MongoDB\\BSON\\ObjectId\).*)%r
+ ["serverConnectionId"]=>
+ %r(NULL|int\(\d+\))%r
}
OK: Got MongoDB\Driver\Exception\CommandException
===DONE===
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-getReply-001.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-getReply-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandFailedEvent-getReply-001.phpt
rename to mongodb-1.14.0/tests/apm/commandFailedEvent-getReply-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-getServerConnectionId-001.phpt
similarity index 64%
copy from mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt
copy to mongodb-1.14.0/tests/apm/commandFailedEvent-getServerConnectionId-001.phpt
index 323a4afe..e4f52382 100644
--- a/mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt
+++ b/mongodb-1.14.0/tests/apm/commandFailedEvent-getServerConnectionId-001.phpt
@@ -1,47 +1,54 @@
--TEST--
-MongoDB\Driver\Monitoring\CommandFailedEvent omits serviceId for non-load balanced topology
+MongoDB\Driver\Monitoring\CommandFailedEvent includes serverConnectionId for 4.2+ server
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
-<?php skip_if_load_balanced(); ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('<', '4.2'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
+ private $commandStartedServerConnectionId;
+
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
printf("commandStarted: %s\n", $event->getCommandName());
- var_dump($event->getServiceId());
+
+ $this->commandStartedServerConnectionId = $event->getServerConnectionId();
+ var_dump($this->commandStartedServerConnectionId);
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event )
{
printf("commandFailed: %s\n", $event->getCommandName());
- var_dump($event->getServiceId());
+ printf("same serverConnectionId as last commandStarted: %s\n", $event->getServerConnectionId() == $this->commandStartedServerConnectionId ? 'yes' : 'no');
+ var_dump($event->getServerConnectionId());
}
}
$manager = create_test_manager();
$manager->addSubscriber(new MySubscriber);
$command = new MongoDB\Driver\Command([
'aggregate' => COLLECTION_NAME,
'pipeline' => [['$unsupported' => 1]],
]);
throws(function() use ($manager, $command) {
$manager->executeCommand(DATABASE_NAME, $command);
}, MongoDB\Driver\Exception\CommandException::class);
?>
--EXPECTF--
commandStarted: aggregate
-NULL
+int(%d)
commandFailed: aggregate
-NULL
+same serverConnectionId as last commandStarted: yes
+int(%d)
OK: Got MongoDB\Driver\Exception\CommandException
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-getServerConnectionId-002.phpt
similarity index 81%
copy from mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt
copy to mongodb-1.14.0/tests/apm/commandFailedEvent-getServerConnectionId-002.phpt
index 323a4afe..afd82619 100644
--- a/mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt
+++ b/mongodb-1.14.0/tests/apm/commandFailedEvent-getServerConnectionId-002.phpt
@@ -1,47 +1,48 @@
--TEST--
-MongoDB\Driver\Monitoring\CommandFailedEvent omits serviceId for non-load balanced topology
+MongoDB\Driver\Monitoring\CommandFailedEvent omits serverConnectionId for pre-4.2 server
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
-<?php skip_if_load_balanced(); ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('>=', '4.2'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
printf("commandStarted: %s\n", $event->getCommandName());
- var_dump($event->getServiceId());
+ var_dump($event->getServerConnectionId());
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event )
{
printf("commandFailed: %s\n", $event->getCommandName());
- var_dump($event->getServiceId());
+ var_dump($event->getServerConnectionId());
}
}
$manager = create_test_manager();
$manager->addSubscriber(new MySubscriber);
$command = new MongoDB\Driver\Command([
'aggregate' => COLLECTION_NAME,
'pipeline' => [['$unsupported' => 1]],
]);
throws(function() use ($manager, $command) {
$manager->executeCommand(DATABASE_NAME, $command);
}, MongoDB\Driver\Exception\CommandException::class);
?>
--EXPECTF--
commandStarted: aggregate
NULL
commandFailed: aggregate
NULL
OK: Got MongoDB\Driver\Exception\CommandException
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-001.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-getServiceId-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-001.phpt
rename to mongodb-1.14.0/tests/apm/commandFailedEvent-getServiceId-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt b/mongodb-1.14.0/tests/apm/commandFailedEvent-getServiceId-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandFailedEvent-getServiceId-002.phpt
rename to mongodb-1.14.0/tests/apm/commandFailedEvent-getServiceId-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandStartedEvent-001.phpt b/mongodb-1.14.0/tests/apm/commandStartedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandStartedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/commandStartedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandStartedEvent-002.phpt b/mongodb-1.14.0/tests/apm/commandStartedEvent-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandStartedEvent-002.phpt
rename to mongodb-1.14.0/tests/apm/commandStartedEvent-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandStartedEvent-debug-001.phpt b/mongodb-1.14.0/tests/apm/commandStartedEvent-debug-001.phpt
similarity index 96%
rename from mongodb-1.13.0/tests/apm/commandStartedEvent-debug-001.phpt
rename to mongodb-1.14.0/tests/apm/commandStartedEvent-debug-001.phpt
index 518ba509..3d6e0c45 100644
--- a/mongodb-1.13.0/tests/apm/commandStartedEvent-debug-001.phpt
+++ b/mongodb-1.14.0/tests/apm/commandStartedEvent-debug-001.phpt
@@ -1,53 +1,55 @@
--TEST--
MongoDB\Driver\Monitoring\CommandStartedEvent debug output
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
var_dump($event);
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
$manager = create_test_manager();
$manager->addSubscriber(new MySubscriber);
$manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\Monitoring\CommandStartedEvent)#%d (%d) {
["command"]=>
object(stdClass)#%d (%d) {%A
}
["commandName"]=>
string(4) "ping"
["databaseName"]=>
string(%d) "%s"
["operationId"]=>
string(%d) "%d"
["requestId"]=>
string(%d) "%d"
["server"]=>
object(MongoDB\Driver\Server)#%d (%d) {%A
}
["serviceId"]=>
%r(NULL|object\(MongoDB\\BSON\\ObjectId\).*)%r
+ ["serverConnectionId"]=>
+ %r(NULL|int\(\d+\))%r
}
===DONE===
diff --git a/mongodb-1.14.0/tests/apm/commandStartedEvent-getServerConnectionId-001.phpt b/mongodb-1.14.0/tests/apm/commandStartedEvent-getServerConnectionId-001.phpt
new file mode 100644
index 00000000..2f185b14
--- /dev/null
+++ b/mongodb-1.14.0/tests/apm/commandStartedEvent-getServerConnectionId-001.phpt
@@ -0,0 +1,51 @@
+--TEST--
+MongoDB\Driver\Monitoring\CommandStartedEvent includes serverConnectionId for 4.2+ server
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('<', '4.2'); ?>
+--FILE--
+<?php
+require_once __DIR__ . "/../utils/basic.inc";
+
+class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
+{
+ private $commandStartedServerConnectionId;
+
+ public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
+ {
+ printf("commandStarted: %s\n", $event->getCommandName());
+
+ if (isset($this->commandStartedServerConnectionId)) {
+ printf("same serverConnectionId as last commandStarted: %s\n", $event->getServerConnectionId() == $this->commandStartedServerConnectionId ? 'yes' : 'no');
+ }
+
+ $this->commandStartedServerConnectionId = $event->getServerConnectionId();
+ var_dump($this->commandStartedServerConnectionId);
+ }
+
+ public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
+ {
+ }
+
+ public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
+ {
+ }
+}
+
+$manager = create_test_manager();
+$manager->addSubscriber(new MySubscriber);
+
+// Select a single server in case the topology includes multiple mongoses
+$server = $manager->selectServer();
+
+$server->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
+$server->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
+
+?>
+--EXPECTF--
+commandStarted: ping
+int(%d)
+commandStarted: ping
+same serverConnectionId as last commandStarted: yes
+int(%d)
diff --git a/mongodb-1.13.0/tests/apm/commandStartedEvent-getServiceId-002.phpt b/mongodb-1.14.0/tests/apm/commandStartedEvent-getServerConnectionId-002.phpt
similarity index 78%
copy from mongodb-1.13.0/tests/apm/commandStartedEvent-getServiceId-002.phpt
copy to mongodb-1.14.0/tests/apm/commandStartedEvent-getServerConnectionId-002.phpt
index 1bf4af78..f9c1977d 100644
--- a/mongodb-1.13.0/tests/apm/commandStartedEvent-getServiceId-002.phpt
+++ b/mongodb-1.14.0/tests/apm/commandStartedEvent-getServerConnectionId-002.phpt
@@ -1,35 +1,36 @@
--TEST--
-MongoDB\Driver\Monitoring\CommandStartedEvent omits serviceId for non-load balanced topology
+MongoDB\Driver\Monitoring\CommandStartedEvent omits serverConnectionId for pre-4.2 server
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
-<?php skip_if_load_balanced(); ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('>=', '4.2'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
printf("commandStarted: %s\n", $event->getCommandName());
- var_dump($event->getServiceId());
+ var_dump($event->getServerConnectionId());
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
$manager = create_test_manager();
$manager->addSubscriber(new MySubscriber);
$manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
?>
--EXPECTF--
commandStarted: ping
NULL
diff --git a/mongodb-1.13.0/tests/apm/commandStartedEvent-getServiceId-001.phpt b/mongodb-1.14.0/tests/apm/commandStartedEvent-getServiceId-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandStartedEvent-getServiceId-001.phpt
rename to mongodb-1.14.0/tests/apm/commandStartedEvent-getServiceId-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandStartedEvent-getServiceId-002.phpt b/mongodb-1.14.0/tests/apm/commandStartedEvent-getServiceId-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandStartedEvent-getServiceId-002.phpt
rename to mongodb-1.14.0/tests/apm/commandStartedEvent-getServiceId-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandSucceededEvent-001.phpt b/mongodb-1.14.0/tests/apm/commandSucceededEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandSucceededEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/commandSucceededEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandSucceededEvent-002.phpt b/mongodb-1.14.0/tests/apm/commandSucceededEvent-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandSucceededEvent-002.phpt
rename to mongodb-1.14.0/tests/apm/commandSucceededEvent-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandSucceededEvent-debug-001.phpt b/mongodb-1.14.0/tests/apm/commandSucceededEvent-debug-001.phpt
similarity index 96%
rename from mongodb-1.13.0/tests/apm/commandSucceededEvent-debug-001.phpt
rename to mongodb-1.14.0/tests/apm/commandSucceededEvent-debug-001.phpt
index 3de9fc70..f0f7201c 100644
--- a/mongodb-1.13.0/tests/apm/commandSucceededEvent-debug-001.phpt
+++ b/mongodb-1.14.0/tests/apm/commandSucceededEvent-debug-001.phpt
@@ -1,53 +1,55 @@
--TEST--
MongoDB\Driver\Monitoring\CommandSucceededEvent debug output
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
var_dump($event);
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
$manager = create_test_manager();
$manager->addSubscriber(new MySubscriber);
$manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\Monitoring\CommandSucceededEvent)#%d (%d) {
["commandName"]=>
string(4) "ping"
["durationMicros"]=>
int(%d)
["operationId"]=>
string(%d) "%d"
["reply"]=>
object(stdClass)#%d (%d) {%A
}
["requestId"]=>
string(%d) "%d"
["server"]=>
object(MongoDB\Driver\Server)#%d (%d) {%A
}
["serviceId"]=>
%r(NULL|object\(MongoDB\\BSON\\ObjectId\).*)%r
+ ["serverConnectionId"]=>
+ %r(NULL|int\(\d+\))%r
}
===DONE===
diff --git a/mongodb-1.14.0/tests/apm/commandSucceededEvent-getServerConnectionId-001.phpt b/mongodb-1.14.0/tests/apm/commandSucceededEvent-getServerConnectionId-001.phpt
new file mode 100644
index 00000000..a215c339
--- /dev/null
+++ b/mongodb-1.14.0/tests/apm/commandSucceededEvent-getServerConnectionId-001.phpt
@@ -0,0 +1,46 @@
+--TEST--
+MongoDB\Driver\Monitoring\CommandSucceededEvent includes serverConnectionId for 4.2+ server
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('<', '4.2'); ?>
+--FILE--
+<?php
+require_once __DIR__ . "/../utils/basic.inc";
+
+class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
+{
+ private $commandStartedServerConnectionId;
+
+ public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
+ {
+ printf("commandStarted: %s\n", $event->getCommandName());
+
+ $this->commandStartedServerConnectionId = $event->getServerConnectionId();
+ var_dump($this->commandStartedServerConnectionId);
+ }
+
+ public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
+ {
+ printf("commandSucceeded: %s\n", $event->getCommandName());
+ printf("same serverConnectionId as last commandStarted: %s\n", $event->getServerConnectionId() == $this->commandStartedServerConnectionId ? 'yes' : 'no');
+ var_dump($event->getServerConnectionId());
+ }
+
+ public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event )
+ {
+ }
+}
+
+$manager = create_test_manager();
+$manager->addSubscriber(new MySubscriber);
+
+$manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
+
+?>
+--EXPECTF--
+commandStarted: ping
+int(%d)
+commandSucceeded: ping
+same serverConnectionId as last commandStarted: yes
+int(%d)
diff --git a/mongodb-1.13.0/tests/apm/commandSucceededEvent-getServiceId-002.phpt b/mongodb-1.14.0/tests/apm/commandSucceededEvent-getServerConnectionId-002.phpt
similarity index 61%
copy from mongodb-1.13.0/tests/apm/commandSucceededEvent-getServiceId-002.phpt
copy to mongodb-1.14.0/tests/apm/commandSucceededEvent-getServerConnectionId-002.phpt
index 2c40b237..1a4affb8 100644
--- a/mongodb-1.13.0/tests/apm/commandSucceededEvent-getServiceId-002.phpt
+++ b/mongodb-1.14.0/tests/apm/commandSucceededEvent-getServerConnectionId-002.phpt
@@ -1,39 +1,40 @@
--TEST--
-MongoDB\Driver\Monitoring\CommandSucceededEvent omits serviceId for non-load balanced topology
+MongoDB\Driver\Monitoring\CommandSucceededEvent omits serverConnectionId for pre-4.2 server
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
-<?php skip_if_load_balanced(); ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('>=', '4.2'); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class MySubscriber implements MongoDB\Driver\Monitoring\CommandSubscriber
{
- public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event )
+ public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
printf("commandStarted: %s\n", $event->getCommandName());
- var_dump($event->getServiceId());
+ var_dump($event->getServerConnectionId());
}
- public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event )
+ public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
printf("commandSucceeded: %s\n", $event->getCommandName());
- var_dump($event->getServiceId());
+ var_dump($event->getServerConnectionId());
}
public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event )
{
}
}
$manager = create_test_manager();
$manager->addSubscriber(new MySubscriber);
$manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
?>
--EXPECTF--
commandStarted: ping
NULL
commandSucceeded: ping
NULL
diff --git a/mongodb-1.13.0/tests/apm/commandSucceededEvent-getServiceId-001.phpt b/mongodb-1.14.0/tests/apm/commandSucceededEvent-getServiceId-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandSucceededEvent-getServiceId-001.phpt
rename to mongodb-1.14.0/tests/apm/commandSucceededEvent-getServiceId-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/commandSucceededEvent-getServiceId-002.phpt b/mongodb-1.14.0/tests/apm/commandSucceededEvent-getServiceId-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/commandSucceededEvent-getServiceId-002.phpt
rename to mongodb-1.14.0/tests/apm/commandSucceededEvent-getServiceId-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/monitoring-addSubscriber-001.phpt b/mongodb-1.14.0/tests/apm/monitoring-addSubscriber-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/monitoring-addSubscriber-001.phpt
rename to mongodb-1.14.0/tests/apm/monitoring-addSubscriber-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/monitoring-addSubscriber-002.phpt b/mongodb-1.14.0/tests/apm/monitoring-addSubscriber-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/monitoring-addSubscriber-002.phpt
rename to mongodb-1.14.0/tests/apm/monitoring-addSubscriber-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/monitoring-addSubscriber-003.phpt b/mongodb-1.14.0/tests/apm/monitoring-addSubscriber-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/monitoring-addSubscriber-003.phpt
rename to mongodb-1.14.0/tests/apm/monitoring-addSubscriber-003.phpt
diff --git a/mongodb-1.13.0/tests/apm/monitoring-addSubscriber-004.phpt b/mongodb-1.14.0/tests/apm/monitoring-addSubscriber-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/monitoring-addSubscriber-004.phpt
rename to mongodb-1.14.0/tests/apm/monitoring-addSubscriber-004.phpt
diff --git a/mongodb-1.13.0/tests/apm/monitoring-removeSubscriber-001.phpt b/mongodb-1.14.0/tests/apm/monitoring-removeSubscriber-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/monitoring-removeSubscriber-001.phpt
rename to mongodb-1.14.0/tests/apm/monitoring-removeSubscriber-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/monitoring-removeSubscriber-002.phpt b/mongodb-1.14.0/tests/apm/monitoring-removeSubscriber-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/monitoring-removeSubscriber-002.phpt
rename to mongodb-1.14.0/tests/apm/monitoring-removeSubscriber-002.phpt
diff --git a/mongodb-1.13.0/tests/apm/serverChangedEvent-001.phpt b/mongodb-1.14.0/tests/apm/serverChangedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/serverChangedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/serverChangedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/serverClosedEvent-001.phpt b/mongodb-1.14.0/tests/apm/serverClosedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/serverClosedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/serverClosedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/serverHeartbeatFailedEvent-001.phpt b/mongodb-1.14.0/tests/apm/serverHeartbeatFailedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/serverHeartbeatFailedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/serverHeartbeatFailedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/serverHeartbeatStartedEvent-001.phpt b/mongodb-1.14.0/tests/apm/serverHeartbeatStartedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/serverHeartbeatStartedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/serverHeartbeatStartedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/serverHeartbeatSucceededEvent-001.phpt b/mongodb-1.14.0/tests/apm/serverHeartbeatSucceededEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/serverHeartbeatSucceededEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/serverHeartbeatSucceededEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/serverOpeningEvent-001.phpt b/mongodb-1.14.0/tests/apm/serverOpeningEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/serverOpeningEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/serverOpeningEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/topologyChangedEvent-001.phpt b/mongodb-1.14.0/tests/apm/topologyChangedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/topologyChangedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/topologyChangedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/topologyClosedEvent-001.phpt b/mongodb-1.14.0/tests/apm/topologyClosedEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/topologyClosedEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/topologyClosedEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/topologyOpeningEvent-001.phpt b/mongodb-1.14.0/tests/apm/topologyOpeningEvent-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/topologyOpeningEvent-001.phpt
rename to mongodb-1.14.0/tests/apm/topologyOpeningEvent-001.phpt
diff --git a/mongodb-1.13.0/tests/apm/topologyOpeningEvent-002.phpt b/mongodb-1.14.0/tests/apm/topologyOpeningEvent-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/apm/topologyOpeningEvent-002.phpt
rename to mongodb-1.14.0/tests/apm/topologyOpeningEvent-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/array-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/array-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/array-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/array-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/array-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/array-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/array-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/array-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/array-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/array-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/array-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-decodeError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-decodeError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-decodeError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-parseError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-parseError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-parseError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-parseError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-parseError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-parseError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-parseError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-parseError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-parseError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-parseError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-parseError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-parseError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-parseError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-parseError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-parseError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-parseError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-parseError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-parseError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-parseError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-parseError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-010.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-011.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-012.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/binary-valid-013.phpt b/mongodb-1.14.0/tests/bson-corpus/binary-valid-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/binary-valid-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/binary-valid-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/boolean-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/boolean-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/boolean-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/boolean-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/boolean-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/boolean-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/boolean-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/boolean-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/boolean-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/boolean-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/boolean-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/boolean-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/boolean-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/boolean-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/boolean-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/boolean-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/code-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/code-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/code-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/code-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-decodeError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/code-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-decodeError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-decodeError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-decodeError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/code-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-decodeError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-decodeError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-decodeError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/code-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-decodeError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-decodeError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/code-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/code-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/code-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/code-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/code-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/code-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-008.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-009.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-010.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-011.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-decodeError-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-decodeError-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/code_w_scope-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/code_w_scope-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/datetime-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/datetime-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/datetime-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/datetime-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/datetime-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/datetime-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/datetime-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/datetime-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/datetime-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/datetime-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/datetime-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/datetime-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/datetime-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/datetime-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/datetime-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/datetime-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/datetime-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/datetime-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/datetime-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/datetime-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/datetime-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/datetime-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/datetime-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/datetime-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-decodeError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-decodeError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbpointer-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/dbpointer-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbpointer-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbpointer-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/dbref-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/dbref-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/dbref-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/dbref-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-014.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-015.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-016.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-017.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-018.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-019.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-020.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-021.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-021.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-021.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-021.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-022.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-022.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-022.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-022.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-023.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-023.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-023.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-023.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-024.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-024.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-024.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-024.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-025.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-025.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-025.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-025.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-026.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-026.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-026.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-026.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-027.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-027.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-027.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-027.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-028.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-028.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-028.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-028.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-029.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-029.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-029.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-029.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-030.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-030.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-030.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-030.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-031.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-031.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-031.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-031.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-032.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-032.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-032.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-032.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-033.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-033.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-033.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-033.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-034.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-034.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-034.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-034.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-035.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-035.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-035.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-035.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-036.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-036.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-036.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-036.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-037.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-037.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-037.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-037.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-038.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-038.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-038.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-038.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-039.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-039.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-039.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-039.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-040.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-040.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-040.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-040.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-041.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-041.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-041.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-041.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-042.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-042.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-042.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-042.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-043.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-043.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-043.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-043.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-044.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-044.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-044.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-044.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-045.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-045.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-045.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-045.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-046.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-046.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-046.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-046.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-047.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-047.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-047.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-047.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-048.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-048.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-048.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-048.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-049.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-049.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-049.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-049.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-050.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-050.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-050.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-050.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-051.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-051.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-051.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-051.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-052.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-052.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-052.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-052.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-053.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-053.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-053.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-053.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-054.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-054.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-054.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-054.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-055.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-055.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-055.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-055.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-056.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-056.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-1-valid-056.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-1-valid-056.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-014.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-015.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-016.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-017.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-018.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-019.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-020.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-021.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-021.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-021.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-021.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-022.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-022.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-022.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-022.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-023.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-023.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-023.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-023.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-024.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-024.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-024.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-024.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-025.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-025.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-025.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-025.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-026.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-026.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-026.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-026.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-027.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-027.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-027.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-027.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-028.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-028.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-028.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-028.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-029.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-029.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-029.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-029.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-030.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-030.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-030.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-030.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-031.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-031.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-031.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-031.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-032.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-032.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-032.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-032.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-033.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-033.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-033.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-033.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-034.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-034.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-034.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-034.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-035.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-035.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-035.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-035.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-036.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-036.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-036.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-036.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-037.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-037.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-037.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-037.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-038.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-038.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-038.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-038.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-039.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-039.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-039.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-039.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-040.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-040.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-040.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-040.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-041.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-041.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-041.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-041.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-042.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-042.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-042.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-042.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-043.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-043.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-043.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-043.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-044.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-044.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-044.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-044.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-045.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-045.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-045.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-045.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-046.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-046.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-046.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-046.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-047.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-047.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-047.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-047.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-048.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-048.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-048.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-048.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-049.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-049.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-049.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-049.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-050.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-050.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-050.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-050.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-051.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-051.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-051.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-051.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-052.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-052.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-052.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-052.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-053.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-053.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-053.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-053.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-054.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-054.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-054.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-054.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-055.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-055.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-055.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-055.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-056.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-056.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-056.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-056.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-057.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-057.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-057.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-057.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-058.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-058.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-058.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-058.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-059.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-059.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-059.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-059.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-060.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-060.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-060.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-060.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-061.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-061.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-061.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-061.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-062.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-062.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-062.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-062.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-063.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-063.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-063.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-063.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-064.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-064.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-064.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-064.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-065.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-065.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-065.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-065.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-066.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-066.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-066.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-066.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-067.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-067.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-067.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-067.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-068.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-068.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-068.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-068.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-069.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-069.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-069.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-069.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-070.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-070.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-070.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-070.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-071.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-071.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-071.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-071.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-072.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-072.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-072.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-072.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-073.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-073.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-073.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-073.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-074.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-074.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-074.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-074.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-075.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-075.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-075.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-075.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-076.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-076.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-076.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-076.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-077.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-077.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-077.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-077.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-078.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-078.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-078.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-078.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-079.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-079.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-079.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-079.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-080.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-080.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-080.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-080.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-081.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-081.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-081.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-081.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-082.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-082.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-082.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-082.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-083.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-083.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-083.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-083.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-084.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-084.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-084.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-084.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-085.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-085.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-085.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-085.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-086.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-086.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-086.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-086.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-087.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-087.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-087.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-087.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-088.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-088.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-088.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-088.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-089.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-089.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-089.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-089.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-090.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-090.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-090.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-090.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-091.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-091.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-091.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-091.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-092.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-092.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-092.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-092.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-093.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-093.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-093.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-093.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-094.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-094.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-094.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-094.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-095.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-095.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-095.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-095.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-096.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-096.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-096.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-096.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-097.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-097.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-097.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-097.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-098.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-098.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-098.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-098.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-099.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-099.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-099.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-099.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-100.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-100.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-100.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-100.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-101.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-101.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-101.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-101.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-102.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-102.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-102.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-102.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-103.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-103.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-103.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-103.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-104.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-104.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-104.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-104.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-105.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-105.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-105.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-105.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-106.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-106.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-106.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-106.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-107.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-107.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-107.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-107.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-108.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-108.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-108.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-108.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-109.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-109.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-109.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-109.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-110.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-110.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-110.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-110.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-111.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-111.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-111.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-111.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-112.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-112.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-112.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-112.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-113.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-113.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-113.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-113.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-114.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-114.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-114.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-114.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-115.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-115.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-115.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-115.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-116.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-116.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-116.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-116.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-117.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-117.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-117.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-117.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-118.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-118.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-118.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-118.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-119.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-119.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-119.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-119.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-120.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-120.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-120.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-120.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-121.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-121.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-121.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-121.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-122.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-122.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-122.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-122.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-123.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-123.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-123.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-123.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-124.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-124.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-124.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-124.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-125.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-125.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-125.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-125.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-126.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-126.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-126.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-126.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-127.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-127.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-127.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-127.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-128.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-128.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-128.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-128.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-129.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-129.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-129.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-129.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-130.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-130.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-130.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-130.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-131.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-131.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-131.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-131.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-132.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-132.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-132.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-132.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-133.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-133.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-133.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-133.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-134.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-134.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-134.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-134.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-135.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-135.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-135.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-135.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-136.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-136.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-136.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-136.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-137.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-137.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-137.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-137.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-138.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-138.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-138.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-138.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-139.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-139.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-139.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-139.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-140.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-140.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-140.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-140.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-141.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-141.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-141.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-141.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-142.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-142.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-142.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-142.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-143.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-143.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-143.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-143.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-144.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-144.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-144.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-144.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-145.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-145.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-145.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-145.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-146.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-146.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-146.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-146.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-147.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-147.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-147.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-147.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-148.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-148.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-148.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-148.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-149.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-149.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-149.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-149.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-150.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-150.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-150.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-150.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-151.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-151.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-151.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-151.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-152.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-152.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-152.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-152.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-153.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-153.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-153.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-153.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-154.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-154.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-154.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-154.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-155.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-155.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-155.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-155.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-156.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-156.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-156.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-156.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-157.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-157.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-2-valid-157.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-2-valid-157.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-014.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-015.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-016.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-017.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-018.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-019.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-020.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-021.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-021.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-021.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-021.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-022.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-022.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-022.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-022.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-023.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-023.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-023.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-023.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-024.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-024.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-024.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-024.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-025.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-025.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-025.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-025.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-026.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-026.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-026.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-026.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-027.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-027.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-027.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-027.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-028.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-028.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-028.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-028.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-029.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-029.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-029.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-029.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-030.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-030.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-030.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-030.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-031.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-031.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-031.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-031.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-032.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-032.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-032.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-032.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-033.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-033.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-033.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-033.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-034.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-034.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-034.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-034.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-035.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-035.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-035.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-035.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-036.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-036.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-036.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-036.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-037.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-037.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-037.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-037.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-038.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-038.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-038.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-038.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-039.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-039.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-039.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-039.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-040.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-040.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-040.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-040.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-041.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-041.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-041.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-041.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-042.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-042.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-042.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-042.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-043.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-043.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-043.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-043.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-044.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-044.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-044.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-044.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-045.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-045.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-045.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-045.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-046.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-046.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-046.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-046.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-047.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-047.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-047.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-047.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-048.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-048.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-048.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-048.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-049.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-049.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-049.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-049.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-050.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-050.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-050.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-050.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-051.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-051.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-051.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-051.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-052.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-052.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-052.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-052.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-053.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-053.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-053.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-053.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-054.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-054.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-054.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-054.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-055.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-055.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-055.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-055.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-056.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-056.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-056.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-056.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-057.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-057.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-057.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-057.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-058.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-058.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-058.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-058.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-059.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-059.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-059.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-059.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-060.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-060.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-060.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-060.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-061.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-061.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-061.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-061.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-062.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-062.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-062.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-062.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-063.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-063.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-063.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-063.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-064.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-064.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-064.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-064.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-065.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-065.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-065.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-065.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-066.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-066.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-066.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-066.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-067.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-067.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-067.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-067.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-068.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-068.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-068.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-068.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-069.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-069.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-069.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-069.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-070.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-070.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-070.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-070.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-071.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-071.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-071.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-071.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-072.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-072.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-072.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-072.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-073.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-073.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-073.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-073.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-074.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-074.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-074.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-074.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-075.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-075.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-075.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-075.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-076.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-076.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-076.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-076.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-077.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-077.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-077.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-077.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-078.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-078.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-078.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-078.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-079.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-079.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-079.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-079.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-080.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-080.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-080.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-080.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-081.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-081.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-081.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-081.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-082.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-082.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-082.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-082.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-083.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-083.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-083.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-083.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-084.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-084.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-084.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-084.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-085.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-085.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-085.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-085.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-086.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-086.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-086.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-086.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-087.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-087.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-087.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-087.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-088.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-088.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-088.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-088.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-089.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-089.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-089.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-089.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-090.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-090.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-090.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-090.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-091.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-091.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-091.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-091.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-092.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-092.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-092.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-092.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-093.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-093.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-093.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-093.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-094.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-094.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-094.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-094.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-095.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-095.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-095.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-095.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-096.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-096.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-096.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-096.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-097.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-097.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-097.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-097.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-098.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-098.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-098.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-098.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-099.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-099.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-099.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-099.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-100.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-100.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-100.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-100.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-101.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-101.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-101.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-101.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-102.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-102.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-102.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-102.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-103.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-103.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-103.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-103.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-104.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-104.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-104.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-104.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-105.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-105.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-105.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-105.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-106.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-106.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-106.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-106.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-107.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-107.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-107.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-107.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-108.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-108.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-108.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-108.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-109.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-109.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-109.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-109.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-110.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-110.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-110.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-110.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-111.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-111.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-111.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-111.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-112.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-112.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-112.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-112.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-113.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-113.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-113.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-113.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-114.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-114.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-114.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-114.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-115.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-115.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-115.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-115.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-116.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-116.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-116.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-116.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-117.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-117.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-117.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-117.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-118.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-118.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-118.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-118.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-119.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-119.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-119.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-119.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-120.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-120.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-120.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-120.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-121.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-121.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-121.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-121.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-122.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-122.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-122.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-122.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-123.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-123.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-123.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-123.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-124.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-124.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-124.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-124.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-125.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-125.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-125.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-125.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-126.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-126.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-126.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-126.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-127.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-127.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-127.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-127.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-128.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-128.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-128.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-128.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-129.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-129.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-129.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-129.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-130.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-130.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-130.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-130.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-131.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-131.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-131.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-131.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-132.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-132.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-132.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-132.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-133.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-133.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-133.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-133.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-134.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-134.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-134.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-134.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-135.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-135.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-135.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-135.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-136.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-136.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-136.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-136.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-137.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-137.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-137.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-137.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-138.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-138.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-138.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-138.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-139.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-139.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-139.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-139.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-140.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-140.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-140.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-140.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-141.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-141.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-141.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-141.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-142.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-142.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-142.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-142.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-143.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-143.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-143.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-143.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-144.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-144.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-144.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-144.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-145.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-145.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-145.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-145.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-146.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-146.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-146.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-146.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-147.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-147.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-147.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-147.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-148.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-148.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-148.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-148.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-149.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-149.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-149.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-149.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-150.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-150.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-150.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-150.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-151.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-151.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-151.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-151.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-152.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-152.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-152.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-152.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-153.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-153.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-153.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-153.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-154.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-154.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-154.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-154.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-155.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-155.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-155.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-155.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-156.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-156.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-156.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-156.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-157.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-157.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-157.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-157.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-158.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-158.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-158.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-158.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-159.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-159.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-159.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-159.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-160.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-160.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-160.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-160.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-161.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-161.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-161.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-161.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-162.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-162.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-162.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-162.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-163.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-163.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-163.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-163.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-164.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-164.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-164.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-164.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-165.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-165.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-165.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-165.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-166.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-166.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-166.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-166.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-167.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-167.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-167.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-167.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-168.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-168.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-168.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-168.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-169.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-169.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-169.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-169.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-170.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-170.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-170.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-170.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-171.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-171.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-171.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-171.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-172.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-172.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-172.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-172.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-173.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-173.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-173.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-173.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-174.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-174.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-174.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-174.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-175.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-175.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-175.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-175.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-176.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-176.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-176.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-176.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-177.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-177.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-177.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-177.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-178.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-178.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-178.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-178.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-179.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-179.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-179.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-179.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-180.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-180.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-180.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-180.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-181.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-181.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-181.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-181.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-182.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-182.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-182.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-182.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-183.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-183.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-183.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-183.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-184.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-184.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-184.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-184.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-185.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-185.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-185.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-185.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-186.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-186.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-186.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-186.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-187.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-187.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-187.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-187.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-188.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-188.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-188.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-188.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-189.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-189.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-189.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-189.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-190.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-190.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-190.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-190.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-191.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-191.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-191.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-191.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-192.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-192.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-192.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-192.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-193.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-193.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-193.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-193.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-194.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-194.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-194.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-194.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-195.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-195.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-195.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-195.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-196.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-196.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-196.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-196.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-197.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-197.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-197.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-197.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-198.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-198.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-198.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-198.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-199.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-199.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-199.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-199.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-200.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-200.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-200.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-200.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-201.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-201.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-201.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-201.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-202.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-202.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-202.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-202.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-203.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-203.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-203.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-203.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-204.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-204.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-204.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-204.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-205.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-205.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-205.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-205.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-206.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-206.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-206.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-206.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-207.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-207.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-207.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-207.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-208.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-208.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-208.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-208.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-209.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-209.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-209.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-209.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-210.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-210.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-210.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-210.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-211.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-211.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-211.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-211.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-212.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-212.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-212.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-212.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-213.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-213.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-213.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-213.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-214.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-214.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-214.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-214.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-215.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-215.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-215.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-215.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-216.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-216.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-216.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-216.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-217.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-217.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-217.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-217.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-218.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-218.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-218.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-218.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-219.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-219.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-219.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-219.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-220.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-220.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-220.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-220.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-221.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-221.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-221.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-221.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-222.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-222.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-222.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-222.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-223.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-223.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-223.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-223.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-224.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-224.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-224.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-224.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-225.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-225.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-225.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-225.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-226.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-226.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-226.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-226.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-227.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-227.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-227.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-227.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-228.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-228.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-228.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-228.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-229.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-229.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-229.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-229.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-230.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-230.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-230.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-230.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-231.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-231.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-231.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-231.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-232.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-232.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-232.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-232.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-233.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-233.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-233.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-233.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-234.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-234.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-234.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-234.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-235.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-235.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-235.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-235.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-236.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-236.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-236.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-236.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-237.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-237.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-237.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-237.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-238.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-238.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-238.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-238.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-239.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-239.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-239.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-239.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-240.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-240.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-240.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-240.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-241.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-241.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-241.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-241.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-242.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-242.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-242.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-242.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-243.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-243.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-243.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-243.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-244.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-244.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-244.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-244.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-245.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-245.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-245.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-245.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-246.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-246.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-246.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-246.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-247.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-247.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-247.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-247.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-248.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-248.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-248.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-248.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-249.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-249.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-249.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-249.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-250.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-250.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-250.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-250.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-251.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-251.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-251.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-251.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-252.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-252.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-252.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-252.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-253.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-253.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-253.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-253.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-254.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-254.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-254.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-254.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-255.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-255.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-255.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-255.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-256.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-256.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-256.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-256.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-257.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-257.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-257.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-257.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-258.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-258.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-258.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-258.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-259.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-259.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-259.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-259.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-260.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-260.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-260.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-260.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-261.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-261.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-261.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-261.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-262.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-262.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-262.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-262.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-263.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-263.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-263.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-263.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-264.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-264.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-264.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-264.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-265.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-265.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-265.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-265.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-266.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-266.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-266.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-266.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-267.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-267.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-267.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-267.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-268.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-268.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-268.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-268.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-269.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-269.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-269.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-269.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-270.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-270.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-270.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-270.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-271.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-271.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-271.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-271.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-272.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-272.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-272.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-272.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-273.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-273.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-273.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-273.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-274.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-274.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-274.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-274.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-275.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-275.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-275.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-275.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-276.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-276.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-276.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-276.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-277.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-277.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-277.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-277.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-278.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-278.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-278.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-278.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-279.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-279.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-279.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-279.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-280.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-280.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-280.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-280.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-281.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-281.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-281.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-281.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-282.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-282.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-282.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-282.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-283.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-283.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-283.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-283.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-284.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-284.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-284.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-284.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-285.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-285.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-285.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-285.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-286.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-286.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-286.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-286.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-287.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-287.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-287.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-287.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-288.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-288.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-288.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-288.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-289.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-289.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-289.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-289.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-290.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-290.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-290.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-290.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-291.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-291.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-291.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-291.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-292.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-292.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-292.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-292.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-293.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-293.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-293.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-293.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-294.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-294.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-294.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-294.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-295.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-295.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-295.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-295.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-296.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-296.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-296.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-296.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-297.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-297.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-297.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-297.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-298.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-298.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-298.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-298.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-299.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-299.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-299.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-299.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-300.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-300.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-300.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-300.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-301.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-301.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-301.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-301.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-302.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-302.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-302.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-302.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-303.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-303.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-303.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-303.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-304.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-304.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-304.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-304.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-305.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-305.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-305.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-305.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-306.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-306.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-306.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-306.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-307.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-307.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-307.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-307.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-308.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-308.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-3-valid-308.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-3-valid-308.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-014.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-015.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-016.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-017.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-018.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-019.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-020.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-parseError-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-parseError-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-4-valid-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-4-valid-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-014.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-015.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-016.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-017.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-018.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-019.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-020.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-021.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-021.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-021.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-021.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-022.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-022.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-022.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-022.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-023.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-023.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-023.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-023.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-024.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-024.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-024.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-024.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-025.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-025.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-025.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-025.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-026.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-026.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-026.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-026.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-027.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-027.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-027.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-027.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-028.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-028.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-028.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-028.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-029.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-029.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-029.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-029.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-030.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-030.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-030.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-030.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-031.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-031.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-031.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-031.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-032.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-032.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-032.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-032.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-033.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-033.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-033.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-033.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-034.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-034.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-034.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-034.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-035.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-035.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-035.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-035.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-036.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-036.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-036.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-036.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-037.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-037.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-037.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-037.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-038.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-038.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-038.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-038.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-039.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-039.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-039.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-039.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-040.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-040.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-040.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-040.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-041.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-041.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-041.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-041.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-042.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-042.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-042.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-042.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-043.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-043.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-043.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-043.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-044.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-044.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-044.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-044.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-045.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-045.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-045.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-045.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-046.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-046.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-046.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-046.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-047.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-047.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-047.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-047.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-048.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-048.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-048.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-048.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-049.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-049.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-049.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-049.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-050.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-050.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-050.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-050.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-051.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-051.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-051.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-051.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-052.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-052.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-052.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-052.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-053.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-053.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-053.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-053.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-054.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-054.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-054.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-054.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-055.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-055.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-055.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-055.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-056.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-056.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-056.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-056.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-057.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-057.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-057.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-057.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-058.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-058.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-058.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-058.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-059.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-059.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-059.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-059.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-060.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-060.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-060.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-060.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-061.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-061.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-061.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-061.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-062.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-062.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-062.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-062.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-063.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-063.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-063.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-063.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-064.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-064.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-064.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-064.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-065.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-065.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-065.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-065.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-066.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-066.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-066.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-066.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-067.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-067.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-5-valid-067.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-5-valid-067.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-014.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-015.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-016.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-017.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-018.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-019.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-020.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-021.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-021.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-021.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-021.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-022.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-022.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-022.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-022.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-023.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-023.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-023.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-023.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-024.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-024.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-024.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-024.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-025.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-025.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-025.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-025.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-026.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-026.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-026.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-026.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-027.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-027.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-027.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-027.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-028.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-028.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-028.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-028.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-029.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-029.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-029.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-029.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-030.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-030.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-030.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-030.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-031.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-031.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-6-parseError-031.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-6-parseError-031.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-008.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-009.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-010.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-011.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-012.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-013.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-014.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-015.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-016.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-017.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-018.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-019.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-020.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-021.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-021.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-021.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-021.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-022.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-022.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-022.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-022.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-023.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-023.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-023.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-023.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-024.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-024.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-024.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-024.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-025.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-025.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-025.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-025.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-026.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-026.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-026.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-026.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-027.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-027.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-027.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-027.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-028.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-028.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-028.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-028.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-029.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-029.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-029.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-029.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-030.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-030.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-030.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-030.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-031.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-031.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-031.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-031.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-032.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-032.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-032.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-032.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-033.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-033.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-033.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-033.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-034.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-034.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-034.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-034.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-035.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-035.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-035.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-035.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-036.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-036.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-036.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-036.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-037.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-037.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-037.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-037.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-038.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-038.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-038.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-038.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-039.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-039.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-039.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-039.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-040.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-040.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-040.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-040.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-041.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-041.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-041.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-041.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-042.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-042.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-042.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-042.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-043.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-043.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-043.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-043.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-044.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-044.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-044.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-044.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-045.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-045.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-045.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-045.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-046.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-046.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-046.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-046.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-047.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-047.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-047.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-047.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-048.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-048.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-048.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-048.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-049.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-049.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-049.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-049.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-050.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-050.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-050.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-050.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-051.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-051.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-051.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-051.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-052.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-052.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-052.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-052.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-053.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-053.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-053.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-053.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-054.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-054.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-054.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-054.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-055.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-055.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-055.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-055.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-056.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-056.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-056.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-056.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-057.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-057.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-057.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-057.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-058.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-058.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-058.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-058.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-059.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-059.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-059.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-059.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-060.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-060.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-060.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-060.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-061.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-061.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-061.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-061.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-062.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-062.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-062.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-062.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-063.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-063.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-063.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-063.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-064.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-064.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-064.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-064.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-065.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-065.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-065.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-065.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-066.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-066.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-066.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-066.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-067.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-067.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-067.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-067.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-068.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-068.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-068.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-068.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-069.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-069.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-069.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-069.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-070.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-070.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-070.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-070.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-071.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-071.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-071.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-071.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-072.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-072.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-072.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-072.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-073.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-073.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-073.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-073.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-074.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-074.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-074.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-074.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-075.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-075.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-075.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-075.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-076.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-076.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-076.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-076.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-077.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-077.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-077.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-077.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-078.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-078.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-078.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-078.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-079.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-079.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-079.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-079.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-080.phpt b/mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-080.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/decimal128-7-parseError-080.phpt
rename to mongodb-1.14.0/tests/bson-corpus/decimal128-7-parseError-080.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/document-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/document-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/document-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/document-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/document-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/document-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/document-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/document-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/document-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/document-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/document-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/document-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/document-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/document-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/double-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-010.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-011.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/double-valid-012.phpt b/mongodb-1.14.0/tests/bson-corpus/double-valid-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/double-valid-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/double-valid-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int32-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/int32-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int32-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int32-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int32-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/int32-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int32-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int32-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int32-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/int32-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int32-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int32-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int32-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/int32-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int32-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int32-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int32-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/int32-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int32-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int32-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int32-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/int32-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int32-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int32-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int64-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/int64-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int64-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int64-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int64-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/int64-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int64-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int64-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int64-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/int64-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int64-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int64-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int64-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/int64-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int64-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int64-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int64-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/int64-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int64-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int64-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/int64-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/int64-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/int64-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/int64-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/maxkey-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/maxkey-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/maxkey-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/maxkey-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/minkey-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/minkey-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/minkey-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/minkey-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/multi-type-deprecated-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/multi-type-deprecated-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/multi-type-deprecated-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/multi-type-deprecated-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/multi-type-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/multi-type-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/multi-type-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/multi-type-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/null-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/null-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/null-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/null-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/oid-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/oid-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/oid-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/oid-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/oid-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/oid-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/oid-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/oid-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/oid-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/oid-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/oid-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/oid-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/oid-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/oid-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/oid-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/oid-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-008.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/regex-valid-009.phpt b/mongodb-1.14.0/tests/bson-corpus/regex-valid-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/regex-valid-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/regex-valid-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/string-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/string-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/string-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/string-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-decodeError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/string-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-decodeError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-decodeError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-decodeError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/string-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-decodeError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-decodeError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-decodeError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/string-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-decodeError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-decodeError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/string-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/string-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/string-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/string-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/string-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/string-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/string-valid-007.phpt b/mongodb-1.14.0/tests/bson-corpus/string-valid-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/string-valid-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/string-valid-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-decodeError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-decodeError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-valid-005.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-valid-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-valid-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-valid-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/symbol-valid-006.phpt b/mongodb-1.14.0/tests/bson-corpus/symbol-valid-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/symbol-valid-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/symbol-valid-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/timestamp-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/timestamp-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/timestamp-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/timestamp-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/timestamp-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/timestamp-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/timestamp-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/timestamp-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/timestamp-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/timestamp-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/timestamp-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/timestamp-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/timestamp-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/timestamp-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/timestamp-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/timestamp-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/timestamp-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/timestamp-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/timestamp-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/timestamp-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-008.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-009.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-010.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-011.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-012.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-013.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-014.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-decodeError-015.phpt b/mongodb-1.14.0/tests/bson-corpus/top-decodeError-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-decodeError-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-decodeError-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-001.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-002.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-003.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-004.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-005.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-005.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-005.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-006.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-006.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-006.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-007.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-007.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-007.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-008.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-008.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-008.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-009.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-009.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-009.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-010.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-010.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-010.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-011.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-011.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-011.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-012.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-012.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-012.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-013.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-013.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-013.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-014.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-014.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-014.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-015.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-015.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-015.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-016.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-016.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-016.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-016.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-017.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-017.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-017.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-017.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-018.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-018.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-018.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-018.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-019.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-019.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-019.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-019.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-020.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-020.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-020.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-020.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-021.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-021.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-021.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-021.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-022.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-022.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-022.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-022.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-023.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-023.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-023.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-023.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-024.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-024.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-024.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-024.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-025.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-025.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-025.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-025.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-026.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-026.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-026.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-026.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-027.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-027.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-027.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-027.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-028.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-028.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-028.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-028.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-029.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-029.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-029.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-029.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-030.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-030.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-030.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-030.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-031.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-031.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-031.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-031.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-032.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-032.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-032.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-032.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-033.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-033.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-033.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-033.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-034.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-034.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-034.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-034.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-035.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-035.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-035.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-035.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-036.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-036.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-036.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-036.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-037.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-037.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-037.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-037.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-038.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-038.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-038.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-038.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-039.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-039.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-039.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-039.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-040.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-040.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-040.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-040.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-041.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-041.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-041.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-041.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-042.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-042.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-042.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-042.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-043.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-043.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-043.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-043.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-parseError-044.phpt b/mongodb-1.14.0/tests/bson-corpus/top-parseError-044.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-parseError-044.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-parseError-044.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/top-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-valid-002.phpt b/mongodb-1.14.0/tests/bson-corpus/top-valid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-valid-002.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-valid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-valid-003.phpt b/mongodb-1.14.0/tests/bson-corpus/top-valid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-valid-003.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-valid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/top-valid-004.phpt b/mongodb-1.14.0/tests/bson-corpus/top-valid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/top-valid-004.phpt
rename to mongodb-1.14.0/tests/bson-corpus/top-valid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson-corpus/undefined-valid-001.phpt b/mongodb-1.14.0/tests/bson-corpus/undefined-valid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson-corpus/undefined-valid-001.phpt
rename to mongodb-1.14.0/tests/bson-corpus/undefined-valid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-compare-002.phpt b/mongodb-1.14.0/tests/bson/bson-binary-compare-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-compare-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-compare-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-binary-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-binary-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization_error-005.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization_error-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-serialization_error-006.phpt b/mongodb-1.14.0/tests/bson/bson-binary-serialization_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-serialization_error-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-serialization_error-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-set_state_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-set_state_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-binary-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-set_state_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-binary-set_state_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-set_state_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-set_state_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary-tostring-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary-tostring-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-binary_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-binary_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-binary_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binary_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-binary_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binary_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-binary_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-binaryinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-binaryinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-binaryinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-binaryinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-002.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-jsonserialize-003.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-jsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-jsonserialize-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-jsonserialize-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer-tostring-001.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer-tostring-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-dbpointer_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-dbpointer_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-dbpointer_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-dbpointer_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-002.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-003.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-004.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-set_state_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128-set_state_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decimal128interface-001.phpt b/mongodb-1.14.0/tests/bson/bson-decimal128interface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decimal128interface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decimal128interface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decode-001.phpt b/mongodb-1.14.0/tests/bson/bson-decode-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decode-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-decode-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-decode-002.phpt b/mongodb-1.14.0/tests/bson/bson-decode-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-decode-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-decode-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-encode-001.phpt b/mongodb-1.14.0/tests/bson/bson-encode-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-encode-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-encode-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-encode-002.phpt b/mongodb-1.14.0/tests/bson/bson-encode-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-encode-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-encode-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-encode-003.phpt b/mongodb-1.14.0/tests/bson/bson-encode-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-encode-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-encode-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-encode-004.phpt b/mongodb-1.14.0/tests/bson/bson-encode-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-encode-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-encode-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-encode-005.phpt b/mongodb-1.14.0/tests/bson/bson-encode-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-encode-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-encode-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromJSON-001.phpt b/mongodb-1.14.0/tests/bson/bson-fromJSON-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromJSON-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromJSON-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromJSON-002.phpt b/mongodb-1.14.0/tests/bson/bson-fromJSON-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromJSON-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromJSON-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromJSON-003.phpt b/mongodb-1.14.0/tests/bson/bson-fromJSON-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromJSON-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromJSON-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromJSON_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-fromJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromJSON_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromJSON_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP-001.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP-002.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP-003.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP-005.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP-006.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-005.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-006.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-007.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-007.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-007.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-fromPHP_error-008.phpt b/mongodb-1.14.0/tests/bson/bson-fromPHP_error-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-fromPHP_error-008.phpt
rename to mongodb-1.14.0/tests/bson/bson-fromPHP_error-008.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-generate-document-id.phpt b/mongodb-1.14.0/tests/bson/bson-generate-document-id.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-generate-document-id.phpt
rename to mongodb-1.14.0/tests/bson/bson-generate-document-id.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-002.phpt b/mongodb-1.14.0/tests/bson/bson-int64-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-003.phpt b/mongodb-1.14.0/tests/bson/bson-int64-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-debug-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-debug-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-int64-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-int64-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-int64-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-int64-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-int64-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-int64-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64-tostring-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64-tostring-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-int64_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-int64_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-int64_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-int64_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-compare-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-compare-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-compare-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-compare-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-getCode-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-getCode-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-getCode-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-getCode-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-getScope-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-getScope-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-getScope-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-getScope-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-003.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-004.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-jsonserialize-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-jsonserialize-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-005.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-006.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-serialization_error-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-serialization_error-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-set_state_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-set_state_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-set_state_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-set_state_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-set_state_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-set_state_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript-tostring-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript-tostring-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascript_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-javascript_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascript_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-javascript_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascript_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascript_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-javascriptinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-javascriptinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-javascriptinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-javascriptinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkey_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkey_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkey_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkey_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-maxkeyinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-maxkeyinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-maxkeyinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-maxkeyinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkey-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkey_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkey_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkey_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkey_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-minkeyinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-minkeyinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-minkeyinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-minkeyinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-003.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-004.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-compare-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-compare-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-compare-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-compare-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-getTimestamp-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-getTimestamp-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-getTimestamp-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-getTimestamp-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-getTimestamp-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-getTimestamp-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-getTimestamp-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-getTimestamp-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-set_state_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-set_state_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid-tostring_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid-tostring_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid-tostring_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid-tostring_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectid_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-objectid_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectid_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-objectid_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectid_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectid_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-objectidinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-objectidinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-objectidinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-objectidinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-003.phpt b/mongodb-1.14.0/tests/bson/bson-regex-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-004.phpt b/mongodb-1.14.0/tests/bson/bson-regex-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-005.phpt b/mongodb-1.14.0/tests/bson/bson-regex-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-compare-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-compare-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-compare-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-compare-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-003.phpt b/mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-004.phpt b/mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-jsonserialize-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-jsonserialize-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization-003.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization-004.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization-005.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization-006.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-regex-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-set_state-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-set_state-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-set_state-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-set_state-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-set_state_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex-set_state_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-regex_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-regex_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regex_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-regex_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regex_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-regex_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-regexinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-regexinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-regexinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-regexinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol-tostring-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol-tostring-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-symbol_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-symbol_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-symbol_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-symbol_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-003.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-004.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-005.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-getIncrement-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-getIncrement-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-getIncrement-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-getIncrement-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-getTimestamp-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-getTimestamp-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-getTimestamp-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-getTimestamp-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization-003.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization-004.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-005.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-006.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-007.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-007.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-007.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-008.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-serialization_error-008.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-serialization_error-008.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-set_state-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-set_state-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-set_state-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-set_state-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp-set_state_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp-set_state_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp_error-005.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp_error-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestamp_error-006.phpt b/mongodb-1.14.0/tests/bson/bson-timestamp_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestamp_error-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestamp_error-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-timestampinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-timestampinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-timestampinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-timestampinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toCanonicalJSON-001.phpt b/mongodb-1.14.0/tests/bson/bson-toCanonicalJSON-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toCanonicalJSON-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toCanonicalJSON-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toCanonicalJSON-002.phpt b/mongodb-1.14.0/tests/bson/bson-toCanonicalJSON-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toCanonicalJSON-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toCanonicalJSON-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toCanonicalJSON_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-toCanonicalJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toCanonicalJSON_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toCanonicalJSON_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toCanonicalJSON_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-toCanonicalJSON_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toCanonicalJSON_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toCanonicalJSON_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toCanonicalJSON_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-toCanonicalJSON_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toCanonicalJSON_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-toCanonicalJSON_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toJSON-001.phpt b/mongodb-1.14.0/tests/bson/bson-toJSON-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toJSON-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toJSON-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toJSON-002.phpt b/mongodb-1.14.0/tests/bson/bson-toJSON-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toJSON-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toJSON-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toJSON-003.phpt b/mongodb-1.14.0/tests/bson/bson-toJSON-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toJSON-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-toJSON-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toJSON_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-toJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toJSON_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toJSON_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toJSON_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-toJSON_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toJSON_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toJSON_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toJSON_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-toJSON_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toJSON_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-toJSON_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-001.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-002.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-003.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-004.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-006.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-007.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-007.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-007.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-008.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-008.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-008.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-009.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-009.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-009.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-010.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-010.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-010.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-011.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-011.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-011.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP-012.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP-012.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP-012.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP_error-005.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP_error-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toPHP_error-006.phpt b/mongodb-1.14.0/tests/bson/bson-toPHP_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toPHP_error-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-toPHP_error-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toRelaxedJSON-001.phpt b/mongodb-1.14.0/tests/bson/bson-toRelaxedJSON-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toRelaxedJSON-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toRelaxedJSON-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toRelaxedJSON-002.phpt b/mongodb-1.14.0/tests/bson/bson-toRelaxedJSON-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toRelaxedJSON-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toRelaxedJSON-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toRelaxedJSON_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-toRelaxedJSON_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toRelaxedJSON_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-toRelaxedJSON_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toRelaxedJSON_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-toRelaxedJSON_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toRelaxedJSON_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-toRelaxedJSON_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-toRelaxedJSON_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-toRelaxedJSON_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-toRelaxedJSON_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-toRelaxedJSON_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-001.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined-tostring-001.phpt b/mongodb-1.14.0/tests/bson/bson-undefined-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined-tostring-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-undefined_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-undefined_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-undefined_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-undefined_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-unknown-001.phpt b/mongodb-1.14.0/tests/bson/bson-unknown-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-unknown-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-unknown-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-003.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-004.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-005.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-005.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-006.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-006.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-007.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-007.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-007.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-clone-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-clone-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-clone-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-clone-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-compare-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-compare-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-compare-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-compare-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-get_properties-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-get_properties-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-get_properties-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-get_properties-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-get_properties-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-get_properties-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-get_properties-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-get_properties-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-int-size-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-int-size-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-int-size-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-int-size-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-int-size-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-int-size-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-int-size-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-int-size-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-jsonserialize-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-jsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-jsonserialize-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-jsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-jsonserialize-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-jsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-jsonserialize-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-jsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-003.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-004.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-serialization_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-serialization_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-todatetime-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-todatetime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-todatetime-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-todatetime-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-todatetime-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-todatetime-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-todatetime-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-todatetime-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime-tostring-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime-tostring-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime_error-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime_error-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime_error-002.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime_error-002.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime_error-003.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime_error-003.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetime_error-004.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetime_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetime_error-004.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetime_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bson-utcdatetimeinterface-001.phpt b/mongodb-1.14.0/tests/bson/bson-utcdatetimeinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bson-utcdatetimeinterface-001.phpt
rename to mongodb-1.14.0/tests/bson/bson-utcdatetimeinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0274.phpt b/mongodb-1.14.0/tests/bson/bug0274.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0274.phpt
rename to mongodb-1.14.0/tests/bson/bug0274.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0325.phpt b/mongodb-1.14.0/tests/bson/bug0325.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0325.phpt
rename to mongodb-1.14.0/tests/bson/bug0325.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0334-001.phpt b/mongodb-1.14.0/tests/bson/bug0334-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0334-001.phpt
rename to mongodb-1.14.0/tests/bson/bug0334-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0334-002.phpt b/mongodb-1.14.0/tests/bson/bug0334-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0334-002.phpt
rename to mongodb-1.14.0/tests/bson/bug0334-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0341.phpt b/mongodb-1.14.0/tests/bson/bug0341.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0341.phpt
rename to mongodb-1.14.0/tests/bson/bug0341.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0347.phpt b/mongodb-1.14.0/tests/bson/bug0347.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0347.phpt
rename to mongodb-1.14.0/tests/bson/bug0347.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0528.phpt b/mongodb-1.14.0/tests/bson/bug0528.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0528.phpt
rename to mongodb-1.14.0/tests/bson/bug0528.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0531-001.phpt b/mongodb-1.14.0/tests/bson/bug0531-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0531-001.phpt
rename to mongodb-1.14.0/tests/bson/bug0531-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0544.phpt b/mongodb-1.14.0/tests/bson/bug0544.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0544.phpt
rename to mongodb-1.14.0/tests/bson/bug0544.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0592.phpt b/mongodb-1.14.0/tests/bson/bug0592.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0592.phpt
rename to mongodb-1.14.0/tests/bson/bug0592.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0623.phpt b/mongodb-1.14.0/tests/bson/bug0623.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0623.phpt
rename to mongodb-1.14.0/tests/bson/bug0623.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0631.phpt b/mongodb-1.14.0/tests/bson/bug0631.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0631.phpt
rename to mongodb-1.14.0/tests/bson/bug0631.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0672.phpt b/mongodb-1.14.0/tests/bson/bug0672.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0672.phpt
rename to mongodb-1.14.0/tests/bson/bug0672.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0894-001.phpt b/mongodb-1.14.0/tests/bson/bug0894-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0894-001.phpt
rename to mongodb-1.14.0/tests/bson/bug0894-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0923-001.phpt b/mongodb-1.14.0/tests/bson/bug0923-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0923-001.phpt
rename to mongodb-1.14.0/tests/bson/bug0923-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0923-002.phpt b/mongodb-1.14.0/tests/bson/bug0923-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0923-002.phpt
rename to mongodb-1.14.0/tests/bson/bug0923-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0939-001.phpt b/mongodb-1.14.0/tests/bson/bug0939-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0939-001.phpt
rename to mongodb-1.14.0/tests/bson/bug0939-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug0974-001.phpt b/mongodb-1.14.0/tests/bson/bug0974-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug0974-001.phpt
rename to mongodb-1.14.0/tests/bson/bug0974-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1006-001.phpt b/mongodb-1.14.0/tests/bson/bug1006-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1006-001.phpt
rename to mongodb-1.14.0/tests/bson/bug1006-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1006-002.phpt b/mongodb-1.14.0/tests/bson/bug1006-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1006-002.phpt
rename to mongodb-1.14.0/tests/bson/bug1006-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1053.phpt b/mongodb-1.14.0/tests/bson/bug1053.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1053.phpt
rename to mongodb-1.14.0/tests/bson/bug1053.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1067.phpt b/mongodb-1.14.0/tests/bson/bug1067.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1067.phpt
rename to mongodb-1.14.0/tests/bson/bug1067.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1266.phpt b/mongodb-1.14.0/tests/bson/bug1266.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1266.phpt
rename to mongodb-1.14.0/tests/bson/bug1266.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1598-001.phpt b/mongodb-1.14.0/tests/bson/bug1598-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1598-001.phpt
rename to mongodb-1.14.0/tests/bson/bug1598-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1598-002.phpt b/mongodb-1.14.0/tests/bson/bug1598-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1598-002.phpt
rename to mongodb-1.14.0/tests/bson/bug1598-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-001.phpt b/mongodb-1.14.0/tests/bson/bug1839-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-001.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-002.phpt b/mongodb-1.14.0/tests/bson/bug1839-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-002.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-003.phpt b/mongodb-1.14.0/tests/bson/bug1839-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-003.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-004.phpt b/mongodb-1.14.0/tests/bson/bug1839-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-004.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-005.phpt b/mongodb-1.14.0/tests/bson/bug1839-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-005.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-006.phpt b/mongodb-1.14.0/tests/bson/bug1839-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-006.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-007.phpt b/mongodb-1.14.0/tests/bson/bug1839-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-007.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-007.phpt
diff --git a/mongodb-1.13.0/tests/bson/bug1839-008.phpt b/mongodb-1.14.0/tests/bson/bug1839-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/bug1839-008.phpt
rename to mongodb-1.14.0/tests/bson/bug1839-008.phpt
diff --git a/mongodb-1.14.0/tests/bson/bug2083-001.phpt b/mongodb-1.14.0/tests/bson/bug2083-001.phpt
new file mode 100644
index 00000000..b781d174
--- /dev/null
+++ b/mongodb-1.14.0/tests/bson/bug2083-001.phpt
@@ -0,0 +1,34 @@
+--TEST--
+PHPC-2083: Enum classes cannot be instantiated via bsonUnserialize()
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_php_version('<', '8.1'); ?>
+--FILE--
+<?php
+require_once __DIR__ . "/../utils/basic.inc";
+
+enum MyEnum : string implements MongoDB\BSON\Persistable {
+ case MYNAME = 'myvalue';
+
+ public function bsonSerialize() {
+ var_dump($this);
+ return (array)$this;
+ }
+
+ public function bsonUnserialize(array $data) {
+ var_dump($data);
+ }
+}
+
+$bson = MongoDB\BSON\fromPHP(MyEnum::MYNAME);
+
+hex_dump($bson);
+
+var_dump(MongoDB\BSON\toPHP($bson));
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+
+===DONE===
diff --git a/mongodb-1.13.0/tests/bson/typemap-001.phpt b/mongodb-1.14.0/tests/bson/typemap-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/typemap-001.phpt
rename to mongodb-1.14.0/tests/bson/typemap-001.phpt
diff --git a/mongodb-1.13.0/tests/bson/typemap-002.phpt b/mongodb-1.14.0/tests/bson/typemap-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/typemap-002.phpt
rename to mongodb-1.14.0/tests/bson/typemap-002.phpt
diff --git a/mongodb-1.13.0/tests/bson/typemap-003.phpt b/mongodb-1.14.0/tests/bson/typemap-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/typemap-003.phpt
rename to mongodb-1.14.0/tests/bson/typemap-003.phpt
diff --git a/mongodb-1.13.0/tests/bson/typemap-004.phpt b/mongodb-1.14.0/tests/bson/typemap-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/typemap-004.phpt
rename to mongodb-1.14.0/tests/bson/typemap-004.phpt
diff --git a/mongodb-1.13.0/tests/bson/typemap-005.phpt b/mongodb-1.14.0/tests/bson/typemap-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/typemap-005.phpt
rename to mongodb-1.14.0/tests/bson/typemap-005.phpt
diff --git a/mongodb-1.13.0/tests/bson/typemap-006.phpt b/mongodb-1.14.0/tests/bson/typemap-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/typemap-006.phpt
rename to mongodb-1.14.0/tests/bson/typemap-006.phpt
diff --git a/mongodb-1.13.0/tests/bson/typemap-007.phpt b/mongodb-1.14.0/tests/bson/typemap-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bson/typemap-007.phpt
rename to mongodb-1.14.0/tests/bson/typemap-007.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bug0667.phpt b/mongodb-1.14.0/tests/bulk/bug0667.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bug0667.phpt
rename to mongodb-1.14.0/tests/bulk/bug0667.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-count-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-count-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-count-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-count-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-countable-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-countable-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-countable-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-countable-001.phpt
diff --git a/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-comment-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-comment-001.phpt
new file mode 100644
index 00000000..7b996f80
--- /dev/null
+++ b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-comment-001.phpt
@@ -0,0 +1,68 @@
+--TEST--
+MongoDB\Driver\BulkWrite::__construct(): comment option
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('<', '4.4'); ?>
+<?php skip_if_not_clean(); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . "/../utils/basic.inc";
+
+class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
+{
+ public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
+ {
+ $command = $event->getCommand();
+
+ if (!isset($command->comment)) {
+ printf("%s does not include comment option\n", $event->getCommandName());
+
+ return;
+ }
+
+ printf("%s included comment: %s\n", $event->getCommandName(), json_encode($command->comment));
+ }
+
+ public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
+ {
+ }
+
+ public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
+ {
+ }
+}
+
+$manager = create_test_manager();
+
+$bulk = new MongoDB\Driver\BulkWrite(['comment' => ['foo' => 1]]);
+$bulk->insert(['_id' => 1]);
+$bulk->insert(['_id' => 2]);
+$bulk->delete(['_id' => 1]);
+$bulk->update(['_id' => 2], ['$set' => ['x' => 1]]);
+
+$manager->addSubscriber(new CommandLogger);
+$manager->executeBulkWrite(NS, $bulk);
+
+$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([]));
+var_dump($cursor->toArray());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+insert included comment: {"foo":1}
+delete included comment: {"foo":1}
+update included comment: {"foo":1}
+find does not include comment option
+array(1) {
+ [0]=>
+ object(stdClass)#%d (%d) {
+ ["_id"]=>
+ int(2)
+ ["x"]=>
+ int(1)
+ }
+}
+===DONE===
diff --git a/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-comment_error-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-comment_error-001.phpt
new file mode 100644
index 00000000..7ecf4c60
--- /dev/null
+++ b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-comment_error-001.phpt
@@ -0,0 +1,26 @@
+--TEST--
+MongoDB\Driver\BulkWrite::__construct(): comment option bsonSerialize() exception
+--FILE--
+<?php
+
+require_once __DIR__ . "/../utils/basic.inc";
+
+class Comment implements MongoDB\BSON\Serializable
+{
+ public function bsonSerialize(): array
+ {
+ throw new Exception('php_phongo_zval_to_bson_value fails');
+ }
+}
+
+echo throws(function() {
+ new MongoDB\Driver\BulkWrite(['comment' => new Comment()]);
+}, Exception::class), "\n";
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got Exception
+php_phongo_zval_to_bson_value fails
+===DONE===
diff --git a/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-let-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-let-001.phpt
new file mode 100644
index 00000000..e9243f21
--- /dev/null
+++ b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-let-001.phpt
@@ -0,0 +1,68 @@
+--TEST--
+MongoDB\Driver\BulkWrite::__construct(): let option
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('<', '5.0'); ?>
+<?php skip_if_not_clean(); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . "/../utils/basic.inc";
+
+class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
+{
+ public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
+ {
+ $command = $event->getCommand();
+
+ if (!isset($command->let)) {
+ printf("%s does not include let option\n", $event->getCommandName());
+
+ return;
+ }
+
+ printf("%s included let: %s\n", $event->getCommandName(), json_encode($command->let));
+ }
+
+ public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
+ {
+ }
+
+ public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
+ {
+ }
+}
+
+$manager = create_test_manager();
+
+$bulk = new MongoDB\Driver\BulkWrite(['let' => ['id' => 1, 'x' => 'foo']]);
+$bulk->insert(['_id' => 1]);
+$bulk->insert(['_id' => 2]);
+$bulk->delete(['$expr' => ['$eq' => ['$_id', '$$id']]]);
+$bulk->update(['_id' => 2], [['$set' => ['x' => '$$x']]]);
+
+$manager->addSubscriber(new CommandLogger);
+$manager->executeBulkWrite(NS, $bulk);
+
+$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([]));
+var_dump($cursor->toArray());
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+insert does not include let option
+delete included let: {"id":1,"x":"foo"}
+update included let: {"id":1,"x":"foo"}
+find does not include let option
+array(1) {
+ [0]=>
+ object(stdClass)#%d (%d) {
+ ["_id"]=>
+ int(2)
+ ["x"]=>
+ string(3) "foo"
+ }
+}
+===DONE===
diff --git a/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-let_error-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-let_error-001.phpt
new file mode 100644
index 00000000..8579fbd9
--- /dev/null
+++ b/mongodb-1.14.0/tests/bulk/bulkwrite-ctor-let_error-001.phpt
@@ -0,0 +1,28 @@
+--TEST--
+MongoDB\Driver\BulkWrite::__construct(): let option invalid type
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/basic.inc';
+
+$invalidValues = [true, 1, 'string', null];
+
+foreach ($invalidValues as $invalidValue) {
+ echo throws(function() use ($invalidValue) {
+ new MongoDB\Driver\BulkWrite(['let' => $invalidValue]);
+ }, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, %r(bool|boolean)%r given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, %r(int|integer)%r given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, string given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, null given
+===DONE===
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-debug-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-debug-001.phpt
similarity index 68%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-debug-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-debug-001.phpt
index 4e43821c..4b5c543f 100644
--- a/mongodb-1.13.0/tests/bulk/bulkwrite-debug-001.phpt
+++ b/mongodb-1.14.0/tests/bulk/bulkwrite-debug-001.phpt
@@ -1,112 +1,162 @@
--TEST--
MongoDB\Driver\BulkWrite debug output before execution
--FILE--
<?php
$tests = [
[],
['ordered' => true],
['ordered' => false],
['bypassDocumentValidation' => true],
['bypassDocumentValidation' => false],
+ ['comment' => ['foo' => 1]],
+ ['let' => ['id' => 1, 'x' => 'foo']],
];
foreach ($tests as $options) {
var_dump(new MongoDB\Driver\BulkWrite($options));
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\BulkWrite)#%d (%d) {
["database"]=>
NULL
["collection"]=>
NULL
["ordered"]=>
bool(true)
["bypassDocumentValidation"]=>
NULL
["executed"]=>
bool(false)
["server_id"]=>
int(0)
["session"]=>
NULL
["write_concern"]=>
NULL
}
object(MongoDB\Driver\BulkWrite)#%d (%d) {
["database"]=>
NULL
["collection"]=>
NULL
["ordered"]=>
bool(true)
["bypassDocumentValidation"]=>
NULL
["executed"]=>
bool(false)
["server_id"]=>
int(0)
["session"]=>
NULL
["write_concern"]=>
NULL
}
object(MongoDB\Driver\BulkWrite)#%d (%d) {
["database"]=>
NULL
["collection"]=>
NULL
["ordered"]=>
bool(false)
["bypassDocumentValidation"]=>
NULL
["executed"]=>
bool(false)
["server_id"]=>
int(0)
["session"]=>
NULL
["write_concern"]=>
NULL
}
object(MongoDB\Driver\BulkWrite)#%d (%d) {
["database"]=>
NULL
["collection"]=>
NULL
["ordered"]=>
bool(true)
["bypassDocumentValidation"]=>
bool(true)
["executed"]=>
bool(false)
["server_id"]=>
int(0)
["session"]=>
NULL
["write_concern"]=>
NULL
}
object(MongoDB\Driver\BulkWrite)#%d (%d) {
["database"]=>
NULL
["collection"]=>
NULL
["ordered"]=>
bool(true)
["bypassDocumentValidation"]=>
bool(false)
["executed"]=>
bool(false)
["server_id"]=>
int(0)
["session"]=>
NULL
["write_concern"]=>
NULL
}
+object(MongoDB\Driver\BulkWrite)#%d (%d) {
+ ["database"]=>
+ NULL
+ ["collection"]=>
+ NULL
+ ["ordered"]=>
+ bool(true)
+ ["bypassDocumentValidation"]=>
+ NULL
+ ["comment"]=>
+ object(stdClass)#%d (%d) {
+ ["foo"]=>
+ int(1)
+ }
+ ["executed"]=>
+ bool(false)
+ ["server_id"]=>
+ int(0)
+ ["session"]=>
+ NULL
+ ["write_concern"]=>
+ NULL
+}
+object(MongoDB\Driver\BulkWrite)#%d (%d) {
+ ["database"]=>
+ NULL
+ ["collection"]=>
+ NULL
+ ["ordered"]=>
+ bool(true)
+ ["bypassDocumentValidation"]=>
+ NULL
+ ["let"]=>
+ object(stdClass)#%d (%d) {
+ ["id"]=>
+ int(1)
+ ["x"]=>
+ string(3) "foo"
+ }
+ ["executed"]=>
+ bool(false)
+ ["server_id"]=>
+ int(0)
+ ["session"]=>
+ NULL
+ ["write_concern"]=>
+ NULL
+}
===DONE===
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-debug-002.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-debug-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-debug-002.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-debug-002.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-delete-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-delete-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-delete-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-delete-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-delete-002.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-delete-002.phpt
similarity index 100%
copy from mongodb-1.13.0/tests/bulk/bulkwrite-delete-002.phpt
copy to mongodb-1.14.0/tests/bulk/bulkwrite-delete-002.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-002.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-002.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-003.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-003.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-005.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-delete_error-005.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-delete_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-insert-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-insert-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-insert-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-insert-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-insert-004.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-insert-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-insert-004.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-insert-004.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-insert_error-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-insert_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-insert_error-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-insert_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-insert_error-002.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-insert_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-insert_error-002.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-insert_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-insert_error-003.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-insert_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-insert_error-003.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-insert_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update-002.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update-002.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update-002.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update-003.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update-003.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update-003.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update-004.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update-004.phpt
similarity index 100%
copy from mongodb-1.13.0/tests/bulk/bulkwrite-update-004.phpt
copy to mongodb-1.14.0/tests/bulk/bulkwrite-update-004.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update_error-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update_error-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update_error-002.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update_error-002.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update_error-003.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update_error-003.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update_error-003.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update_error-004.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update_error-004.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update_error-004.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update_error-005.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update_error-005.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update_error-005.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update_error-008.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite-update_error-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update_error-008.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite-update_error-008.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite_error-001.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite_error-001.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite_error-001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite_error-002.phpt b/mongodb-1.14.0/tests/bulk/bulkwrite_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/bulkwrite_error-002.phpt
rename to mongodb-1.14.0/tests/bulk/bulkwrite_error-002.phpt
diff --git a/mongodb-1.13.0/tests/bulk/write-0001.phpt b/mongodb-1.14.0/tests/bulk/write-0001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/write-0001.phpt
rename to mongodb-1.14.0/tests/bulk/write-0001.phpt
diff --git a/mongodb-1.13.0/tests/bulk/write-0002.phpt b/mongodb-1.14.0/tests/bulk/write-0002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/bulk/write-0002.phpt
rename to mongodb-1.14.0/tests/bulk/write-0002.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-001.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-001.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-001.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-002.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-002.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-002.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-003.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-003.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-003.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-004.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-004.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-004.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-005.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-005.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-005.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-006.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-006.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-006.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-007.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-007.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-007.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-008.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-008.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-008.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-009.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-009.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-009.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-010.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-010.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-010.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-011.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-011.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-011.phpt
diff --git a/mongodb-1.13.0/tests/causal-consistency/causal-consistency-012.phpt b/mongodb-1.14.0/tests/causal-consistency/causal-consistency-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/causal-consistency/causal-consistency-012.phpt
rename to mongodb-1.14.0/tests/causal-consistency/causal-consistency-012.phpt
diff --git a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-constants.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-constants.phpt
similarity index 61%
rename from mongodb-1.13.0/tests/clientEncryption/clientEncryption-constants.phpt
rename to mongodb-1.14.0/tests/clientEncryption/clientEncryption-constants.phpt
index 709d8435..b7345df3 100644
--- a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-constants.phpt
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-constants.phpt
@@ -1,15 +1,21 @@
--TEST--
MongoDB\Driver\ClientEncryption constants
--FILE--
<?php
var_dump(MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
var_dump(MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM);
+var_dump(MongoDB\Driver\ClientEncryption::ALGORITHM_INDEXED);
+var_dump(MongoDB\Driver\ClientEncryption::ALGORITHM_UNINDEXED);
+var_dump(MongoDB\Driver\ClientEncryption::QUERY_TYPE_EQUALITY);
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
string(43) "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
string(36) "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+string(7) "Indexed"
+string(9) "Unindexed"
+string(8) "equality"
===DONE===
diff --git a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-createDataKey-001.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
similarity index 60%
rename from mongodb-1.13.0/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
rename to mongodb-1.14.0/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
index 485fb76b..15539e3a 100644
--- a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-createDataKey-001.phpt
@@ -1,28 +1,31 @@
--TEST--
MongoDB\Driver\ClientEncryption::createDataKey()
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
<?php skip_if_not_live(); ?>
--FILE--
<?php
-require_once __DIR__ . "/../utils/basic.inc";
-$key = base64_decode('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk');
+require_once __DIR__ . "/../utils/basic.inc";
$manager = create_test_manager();
-$clientEncryption = $manager->createClientEncryption(['keyVaultNamespace' => 'default.keys', 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary($key, 0)]]]);
+
+$clientEncryption = $manager->createClientEncryption([
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+]);
var_dump($clientEncryption->createDataKey('local'));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\BSON\Binary)#%d (%d) {
["data"]=>
string(16) "%a"
["type"]=>
int(4)
}
===DONE===
diff --git a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
similarity index 76%
rename from mongodb-1.13.0/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
rename to mongodb-1.14.0/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
index 282d3707..529f821a 100644
--- a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt
@@ -1,38 +1,40 @@
--TEST--
MongoDB\Driver\ClientEncryption::createDataKey() with invalid keyAltNames
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
<?php skip_if_not_live(); ?>
--FILE--
<?php
-require_once __DIR__ . "/../utils/basic.inc";
-$key = base64_decode('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk');
+require_once __DIR__ . "/../utils/basic.inc";
$tests = [
['keyAltNames' => 'foo'],
['keyAltNames' => [0 => []]],
['keyAltNames' => ['foo' => []]],
];
$manager = create_test_manager();
-$clientEncryption = $manager->createClientEncryption(['keyVaultNamespace' => 'default.keys', 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary($key, 0)]]]);
+$clientEncryption = $manager->createClientEncryption([
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+]);
foreach ($tests as $opts) {
echo throws(function () use ($clientEncryption, $opts) {
$clientEncryption->createDataKey('local', $opts);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected keyAltNames to be array, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected keyAltName with index "0" to be string, array given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected keyAltName with index "foo" to be string, array given
===DONE===
diff --git a/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor-001.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor-001.phpt
new file mode 100644
index 00000000..f06c3d28
--- /dev/null
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor-001.phpt
@@ -0,0 +1,25 @@
+--TEST--
+MongoDB\Driver\ClientEncryption::__construct()
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_libmongocrypt(); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . "/../utils/basic.inc";
+
+$clientEncryption = new MongoDB\Driver\ClientEncryption([
+ 'keyVaultClient' => create_test_manager(),
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+]);
+
+var_dump($clientEncryption);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+object(MongoDB\Driver\ClientEncryption)#%d (%d) {
+}
+===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-001.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor_error-001.phpt
similarity index 74%
copy from mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-001.phpt
copy to mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor_error-001.phpt
index 5927af92..631f0010 100644
--- a/mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-001.phpt
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor_error-001.phpt
@@ -1,22 +1,21 @@
--TEST--
-MongoDB\Driver\Manager::createClientEncryption() fails if compiled without FLE
+MongoDB\Driver\ClientEncryption::__construct() fails if compiled without FLE
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_libmongocrypt(); ?>
--FILE--
<?php
require_once __DIR__ . '/../utils/basic.inc';
echo throws(function () {
- $manager = create_test_manager();
- $clientEncryption = $manager->createClientEncryption([]);
+ new MongoDB\Driver\ClientEncryption([]);
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\RuntimeException
Cannot configure clientEncryption object. Please recompile with support for libmongocrypt using the with-mongodb-client-side-encryption configure switch.
===DONE===
diff --git a/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor_error-002.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor_error-002.phpt
new file mode 100644
index 00000000..8b57d9b0
--- /dev/null
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-ctor_error-002.phpt
@@ -0,0 +1,53 @@
+--TEST--
+MongoDB\Driver\ClientEncryption::__construct() with invalid option types
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_libmongocrypt(); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/basic.inc';
+
+/* phongo_clientencryption_opts_from_zval always requires a keyVaultClient
+ * option when constructing ClientEncryption directly, so this will be used to
+ * test other options. */
+$baseOptions = ['keyVaultClient' => create_test_manager()];
+
+$tests = [
+ [],
+ ['keyVaultClient' => 'not_an_array_or_object'],
+ [
+ 'keyVaultNamespace' => 'not_a_namespace',
+ // keyVaultNamespace requires a valid kmsProviders option
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+ ] + $baseOptions,
+ ['kmsProviders' => 'not_an_array_or_object'] + $baseOptions,
+ ['tlsOptions' => 'not_an_array_or_object'] + $baseOptions,
+];
+
+foreach ($tests as $test) {
+ echo throws(function () use ($test) {
+ new MongoDB\Driver\ClientEncryption($test);
+ }, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n\n";
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+The "keyVaultClient" option is required when constructing a ClientEncryption object directly
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "keyVaultClient" option to be MongoDB\Driver\Manager, string given
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "keyVaultNamespace" option to contain a full collection namespace
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "kmsProviders" option to be an array or object, string given
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "tlsOptions" option to be an array or object, string given
+
+===DONE===
diff --git a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-decrypt-001.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-decrypt-001.phpt
similarity index 52%
rename from mongodb-1.13.0/tests/clientEncryption/clientEncryption-decrypt-001.phpt
rename to mongodb-1.14.0/tests/clientEncryption/clientEncryption-decrypt-001.phpt
index c76971b6..5dae50fd 100644
--- a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-decrypt-001.phpt
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-decrypt-001.phpt
@@ -1,27 +1,30 @@
--TEST--
MongoDB\Driver\ClientEncryption::decrypt()
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
<?php skip_if_not_live(); ?>
<?php skip_if_not_server_storage_engine('wiredTiger'); ?>
--FILE--
<?php
-require_once __DIR__ . "/../utils/basic.inc";
-$key = base64_decode('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk');
+require_once __DIR__ . "/../utils/basic.inc";
$manager = create_test_manager();
-$clientEncryption = $manager->createClientEncryption(['keyVaultNamespace' => 'default.keys', 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary($key, 0)]]]);
-$key = $clientEncryption->createDataKey('local');
+$clientEncryption = $manager->createClientEncryption([
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+]);
+
+$keyId = $clientEncryption->createDataKey('local');
-$encrypted = $clientEncryption->encrypt('top-secret', ['keyId' => $key, 'algorithm' => MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC]);
+$encrypted = $clientEncryption->encrypt('top-secret', ['keyId' => $keyId, 'algorithm' => MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC]);
var_dump($clientEncryption->decrypt($encrypted));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
string(10) "top-secret"
===DONE===
diff --git a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-encrypt-001.phpt b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-encrypt-001.phpt
similarity index 53%
rename from mongodb-1.13.0/tests/clientEncryption/clientEncryption-encrypt-001.phpt
rename to mongodb-1.14.0/tests/clientEncryption/clientEncryption-encrypt-001.phpt
index 9dd1922f..21f85e5b 100644
--- a/mongodb-1.13.0/tests/clientEncryption/clientEncryption-encrypt-001.phpt
+++ b/mongodb-1.14.0/tests/clientEncryption/clientEncryption-encrypt-001.phpt
@@ -1,31 +1,34 @@
--TEST--
MongoDB\Driver\ClientEncryption::encrypt()
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
<?php skip_if_not_live(); ?>
<?php skip_if_not_server_storage_engine('wiredTiger'); ?>
--FILE--
<?php
-require_once __DIR__ . "/../utils/basic.inc";
-$key = base64_decode('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk');
+require_once __DIR__ . "/../utils/basic.inc";
$manager = create_test_manager();
-$clientEncryption = $manager->createClientEncryption(['keyVaultNamespace' => 'default.keys', 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary($key, 0)]]]);
-$key = $clientEncryption->createDataKey('local');
+$clientEncryption = $manager->createClientEncryption([
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+]);
+
+$keyId = $clientEncryption->createDataKey('local');
-var_dump($clientEncryption->encrypt('top-secret', ['keyId' => $key, 'algorithm' => MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC]));
+var_dump($clientEncryption->encrypt('top-secret', ['keyId' => $keyId, 'algorithm' => MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC]));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\BSON\Binary)#%d (%d) {
["data"]=>
string(82) "%a"
["type"]=>
int(6)
}
===DONE===
diff --git a/mongodb-1.13.0/tests/command/command-ctor-001.phpt b/mongodb-1.14.0/tests/command/command-ctor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/command/command-ctor-001.phpt
rename to mongodb-1.14.0/tests/command/command-ctor-001.phpt
diff --git a/mongodb-1.13.0/tests/command/command_error-001.phpt b/mongodb-1.14.0/tests/command/command_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/command/command_error-001.phpt
rename to mongodb-1.14.0/tests/command/command_error-001.phpt
diff --git a/mongodb-1.13.0/tests/command/cursor-batchsize-001.phpt b/mongodb-1.14.0/tests/command/cursor-batchsize-001.phpt
similarity index 100%
copy from mongodb-1.13.0/tests/command/cursor-batchsize-001.phpt
copy to mongodb-1.14.0/tests/command/cursor-batchsize-001.phpt
diff --git a/mongodb-1.13.0/tests/command/cursor-batchsize-002.phpt b/mongodb-1.14.0/tests/command/cursor-batchsize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/command/cursor-batchsize-002.phpt
rename to mongodb-1.14.0/tests/command/cursor-batchsize-002.phpt
diff --git a/mongodb-1.13.0/tests/command/cursor-batchsize-001.phpt b/mongodb-1.14.0/tests/command/cursor-comment-001.phpt
similarity index 60%
rename from mongodb-1.13.0/tests/command/cursor-batchsize-001.phpt
rename to mongodb-1.14.0/tests/command/cursor-comment-001.phpt
index bd72cf1a..7a8393c1 100644
--- a/mongodb-1.13.0/tests/command/cursor-batchsize-001.phpt
+++ b/mongodb-1.14.0/tests/command/cursor-comment-001.phpt
@@ -1,84 +1,70 @@
--TEST--
-MongoDB\Driver\Command non-zero batchSize applies to getMore
+MongoDB\Driver\Command comment applies to getMore
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
+<?php skip_if_server_version('<', '4.4'); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class Test implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function executeCommand()
{
MongoDB\Driver\Monitoring\addSubscriber($this);
$manager = create_test_manager();
$bulkWrite = new MongoDB\Driver\BulkWrite;
for ($i = 0; $i < 5; $i++) {
$bulkWrite->insert(['_id' => $i]);
}
$writeResult = $manager->executeBulkWrite(NS, $bulkWrite);
printf("Inserted: %d\n", $writeResult->getInsertedCount());
$command = new MongoDB\Driver\Command([
'aggregate' => COLLECTION_NAME,
'pipeline' => [['$match' => new stdClass]],
+ 'comment' => ['foo' => 1],
'cursor' => ['batchSize' => 2]
]);
$cursor = $manager->executeCommand(DATABASE_NAME, $command);
$cursor->toArray();
MongoDB\Driver\Monitoring\removeSubscriber($this);
}
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
$command = $event->getCommand();
- if ($event->getCommandName() === 'aggregate') {
- printf("aggregate command specifies batchSize: %d\n", $command->cursor->batchSize);
- }
-
- if ($event->getCommandName() === 'getMore') {
- printf("getMore command specifies batchSize: %d\n", $command->batchSize);
+ if ($event->getCommandName() === 'aggregate' || $event->getCommandName() === 'getMore') {
+ printf("%s command includes comment: %s\n", $event->getCommandName(), json_encode($command->comment));
}
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
- $reply = $event->getReply();
-
- if ($event->getCommandName() === 'aggregate') {
- printf("aggregate response contains %d document(s)\n", count($reply->cursor->firstBatch));
- }
-
- if ($event->getCommandName() === 'getMore') {
- printf("getMore response contains %d document(s)\n", count($reply->cursor->nextBatch));
- }
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
(new Test)->executeCommand();
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
Inserted: 5
-aggregate command specifies batchSize: 2
-aggregate response contains 2 document(s)
-getMore command specifies batchSize: 2
-getMore response contains 2 document(s)
-getMore command specifies batchSize: 2
-getMore response contains 1 document(s)
+aggregate command includes comment: {"foo":1}
+getMore command includes comment: {"foo":1}
+getMore command includes comment: {"foo":1}
===DONE===
diff --git a/mongodb-1.13.0/tests/command/cursor-tailable-001.phpt b/mongodb-1.14.0/tests/command/cursor-tailable-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/command/cursor-tailable-001.phpt
rename to mongodb-1.14.0/tests/command/cursor-tailable-001.phpt
diff --git a/mongodb-1.13.0/tests/command/findAndModify-001.phpt b/mongodb-1.14.0/tests/command/findAndModify-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/command/findAndModify-001.phpt
rename to mongodb-1.14.0/tests/command/findAndModify-001.phpt
diff --git a/mongodb-1.13.0/tests/command/update-001.phpt b/mongodb-1.14.0/tests/command/update-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/command/update-001.phpt
rename to mongodb-1.14.0/tests/command/update-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/bug0720.phpt b/mongodb-1.14.0/tests/connect/bug0720.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/bug0720.phpt
rename to mongodb-1.14.0/tests/connect/bug0720.phpt
diff --git a/mongodb-1.13.0/tests/connect/bug1015.phpt b/mongodb-1.14.0/tests/connect/bug1015.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/bug1015.phpt
rename to mongodb-1.14.0/tests/connect/bug1015.phpt
diff --git a/mongodb-1.13.0/tests/connect/bug1045.phpt b/mongodb-1.14.0/tests/connect/bug1045.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/bug1045.phpt
rename to mongodb-1.14.0/tests/connect/bug1045.phpt
diff --git a/mongodb-1.13.0/tests/connect/compression_error-001.phpt b/mongodb-1.14.0/tests/connect/compression_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/compression_error-001.phpt
rename to mongodb-1.14.0/tests/connect/compression_error-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/compression_error-002.phpt b/mongodb-1.14.0/tests/connect/compression_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/compression_error-002.phpt
rename to mongodb-1.14.0/tests/connect/compression_error-002.phpt
diff --git a/mongodb-1.13.0/tests/connect/replicaset-seedlist-001.phpt b/mongodb-1.14.0/tests/connect/replicaset-seedlist-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/replicaset-seedlist-001.phpt
rename to mongodb-1.14.0/tests/connect/replicaset-seedlist-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/replicaset-seedlist-002.phpt b/mongodb-1.14.0/tests/connect/replicaset-seedlist-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/replicaset-seedlist-002.phpt
rename to mongodb-1.14.0/tests/connect/replicaset-seedlist-002.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-auth-001.phpt b/mongodb-1.14.0/tests/connect/standalone-auth-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-auth-001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-auth-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-auth_error-001.phpt b/mongodb-1.14.0/tests/connect/standalone-auth_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-auth_error-001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-auth_error-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-plain-0001.phpt b/mongodb-1.14.0/tests/connect/standalone-plain-0001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-plain-0001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-plain-0001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-plain-0002.phpt b/mongodb-1.14.0/tests/connect/standalone-plain-0002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-plain-0002.phpt
rename to mongodb-1.14.0/tests/connect/standalone-plain-0002.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-no_verify-001.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-no_verify-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-no_verify-001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-no_verify-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-no_verify-002.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-no_verify-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-no_verify-002.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-no_verify-002.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-no_verify-003.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-no_verify-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-no_verify-003.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-no_verify-003.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-001.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-002.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-002.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-002.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-003.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-003.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-003.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-error-001.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-error-001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-error-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-error-002.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-error-002.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-error-002.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-error-003.phpt b/mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-ssl-verify_cert-error-003.phpt
rename to mongodb-1.14.0/tests/connect/standalone-ssl-verify_cert-error-003.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-x509-auth-001.phpt b/mongodb-1.14.0/tests/connect/standalone-x509-auth-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-x509-auth-001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-x509-auth-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-x509-auth-002.phpt b/mongodb-1.14.0/tests/connect/standalone-x509-auth-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-x509-auth-002.phpt
rename to mongodb-1.14.0/tests/connect/standalone-x509-auth-002.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-x509-error-0001.phpt b/mongodb-1.14.0/tests/connect/standalone-x509-error-0001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-x509-error-0001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-x509-error-0001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-x509-extract_username-001.phpt b/mongodb-1.14.0/tests/connect/standalone-x509-extract_username-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-x509-extract_username-001.phpt
rename to mongodb-1.14.0/tests/connect/standalone-x509-extract_username-001.phpt
diff --git a/mongodb-1.13.0/tests/connect/standalone-x509-extract_username-002.phpt b/mongodb-1.14.0/tests/connect/standalone-x509-extract_username-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/connect/standalone-x509-extract_username-002.phpt
rename to mongodb-1.14.0/tests/connect/standalone-x509-extract_username-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug0671-001.phpt b/mongodb-1.14.0/tests/cursor/bug0671-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug0671-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug0671-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug0732-001.phpt b/mongodb-1.14.0/tests/cursor/bug0732-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug0732-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug0732-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug0849-001.phpt b/mongodb-1.14.0/tests/cursor/bug0849-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug0849-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug0849-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug0924-001.phpt b/mongodb-1.14.0/tests/cursor/bug0924-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug0924-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug0924-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug0924-002.phpt b/mongodb-1.14.0/tests/cursor/bug0924-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug0924-002.phpt
rename to mongodb-1.14.0/tests/cursor/bug0924-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1050-001.phpt b/mongodb-1.14.0/tests/cursor/bug1050-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1050-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1050-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1050-002.phpt b/mongodb-1.14.0/tests/cursor/bug1050-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1050-002.phpt
rename to mongodb-1.14.0/tests/cursor/bug1050-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1151-001.phpt b/mongodb-1.14.0/tests/cursor/bug1151-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1151-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1151-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1151-002.phpt b/mongodb-1.14.0/tests/cursor/bug1151-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1151-002.phpt
rename to mongodb-1.14.0/tests/cursor/bug1151-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1151-003.phpt b/mongodb-1.14.0/tests/cursor/bug1151-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1151-003.phpt
rename to mongodb-1.14.0/tests/cursor/bug1151-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1151-004.phpt b/mongodb-1.14.0/tests/cursor/bug1151-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1151-004.phpt
rename to mongodb-1.14.0/tests/cursor/bug1151-004.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1152-001.phpt b/mongodb-1.14.0/tests/cursor/bug1152-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1152-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1152-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1152-002.phpt b/mongodb-1.14.0/tests/cursor/bug1152-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1152-002.phpt
rename to mongodb-1.14.0/tests/cursor/bug1152-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1162-001.phpt b/mongodb-1.14.0/tests/cursor/bug1162-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1162-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1162-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1274-001.phpt b/mongodb-1.14.0/tests/cursor/bug1274-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1274-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1274-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1274-002.phpt b/mongodb-1.14.0/tests/cursor/bug1274-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1274-002.phpt
rename to mongodb-1.14.0/tests/cursor/bug1274-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1274-003.phpt b/mongodb-1.14.0/tests/cursor/bug1274-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1274-003.phpt
rename to mongodb-1.14.0/tests/cursor/bug1274-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1274-004.phpt b/mongodb-1.14.0/tests/cursor/bug1274-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1274-004.phpt
rename to mongodb-1.14.0/tests/cursor/bug1274-004.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1274-005.phpt b/mongodb-1.14.0/tests/cursor/bug1274-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1274-005.phpt
rename to mongodb-1.14.0/tests/cursor/bug1274-005.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1274-006.phpt b/mongodb-1.14.0/tests/cursor/bug1274-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1274-006.phpt
rename to mongodb-1.14.0/tests/cursor/bug1274-006.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1419-001.phpt b/mongodb-1.14.0/tests/cursor/bug1419-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1419-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1419-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/bug1529-001.phpt b/mongodb-1.14.0/tests/cursor/bug1529-001.phpt
similarity index 97%
rename from mongodb-1.13.0/tests/cursor/bug1529-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1529-001.phpt
index e1082546..90045fa4 100644
--- a/mongodb-1.13.0/tests/cursor/bug1529-001.phpt
+++ b/mongodb-1.14.0/tests/cursor/bug1529-001.phpt
@@ -1,105 +1,105 @@
--TEST--
PHPC-1529: Resetting a client should also reset the keyVaultClient
--SKIPIF--
<?php if (!function_exists('pcntl_fork')) { die('skip pcntl_fork() not available'); } ?>
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
<?php skip_if_server_version('<', '4.2'); ?>
<?php skip_if_not_libmongocrypt(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
{
private $pid;
public function __construct()
{
$this->pid = getmypid();
}
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
$command = $event->getCommand();
$commandName = $event->getCommandName();
$process = $this->pid === getmypid() ? 'Parent' : 'Child';
if ($commandName === 'find' || $commandName === 'getMore') {
printf("%s executes %s with batchSize: %d\n", $process, $commandName, $command->batchSize);
return;
}
printf("%s executes %s\n", $process, $commandName);
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
$keyVaultClient = create_test_manager(URI, [], ['disableClientPersistence' => true]);
$autoEncryptionOpts = [
'keyVaultClient' => $keyVaultClient,
- 'keyVaultNamespace' => 'default.keys',
- 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(str_repeat('0', 96), 0)]],
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
];
$manager = create_test_manager(URI, [], ['autoEncryption' => $autoEncryptionOpts, 'disableClientPersistence' => true]);
$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert(['x' => 1]);
$bulk->insert(['x' => 2]);
$bulk->insert(['x' => 3]);
$keyVaultClient->executeBulkWrite(NS, $bulk);
MongoDB\Driver\Monitoring\addSubscriber(new CommandLogger);
$query = new MongoDB\Driver\Query([], ['batchSize' => 2]);
$cursor = $keyVaultClient->executeQuery(NS, $query);
$childPid = pcntl_fork();
if ($childPid === 0) {
/* Executing any operation with the parent's client resets this client as well as
* the keyVaultClient. Continuing iteration of the cursor opened on the
* keyVaultClient before resetting it should then result in an error due to
* the client having been reset. */
$manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
echo throws(
function () use ($cursor) { iterator_count($cursor); },
MongoDB\Driver\Exception\RuntimeException::class
), "\n";
echo "Child exits\n";
exit;
}
if ($childPid > 0) {
$waitPid = pcntl_waitpid($childPid, $status);
if ($waitPid === $childPid) {
echo "Parent waited for child to exit\n";
}
unset($cursor);
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
Parent executes find with batchSize: 2
Child executes ping
OK: Got MongoDB\Driver\Exception\RuntimeException
Cannot advance cursor after client reset
Child exits
Parent waited for child to exit
Parent executes killCursors
===DONE===
diff --git a/mongodb-1.13.0/tests/cursor/bug1713-001.phpt b/mongodb-1.14.0/tests/cursor/bug1713-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/bug1713-001.phpt
rename to mongodb-1.14.0/tests/cursor/bug1713-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-IteratorIterator-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-IteratorIterator-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-IteratorIterator-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-IteratorIterator-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-IteratorIterator-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-IteratorIterator-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-IteratorIterator-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-IteratorIterator-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-IteratorIterator-003.phpt b/mongodb-1.14.0/tests/cursor/cursor-IteratorIterator-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-IteratorIterator-003.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-IteratorIterator-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-NoRewindIterator-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-NoRewindIterator-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-NoRewindIterator-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-NoRewindIterator-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-destruct-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-destruct-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-destruct-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-destruct-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-getmore-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-getmore-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-getmore-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-getmore-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-getmore-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-getmore-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-getmore-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-getmore-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-getmore-003.phpt b/mongodb-1.14.0/tests/cursor/cursor-getmore-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-getmore-003.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-getmore-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-getmore-004.phpt b/mongodb-1.14.0/tests/cursor/cursor-getmore-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-getmore-004.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-getmore-004.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-getmore-005.phpt b/mongodb-1.14.0/tests/cursor/cursor-getmore-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-getmore-005.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-getmore-005.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-getmore-006.phpt b/mongodb-1.14.0/tests/cursor/cursor-getmore-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-getmore-006.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-getmore-006.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-isDead-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-isDead-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-isDead-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-isDead-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-isDead-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-isDead-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-isDead-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-isDead-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-iterator-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-iterator-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-iterator-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-iterator-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-iterator-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-iterator-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-iterator-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-iterator-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-iterator-003.phpt b/mongodb-1.14.0/tests/cursor/cursor-iterator-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-iterator-003.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-iterator-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-iterator_handlers-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-iterator_handlers-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-iterator_handlers-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-iterator_handlers-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-rewind-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-rewind-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-rewind-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-rewind-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-session-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-session-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-session-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-session-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-session-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-session-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-session-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-session-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-session-003.phpt b/mongodb-1.14.0/tests/cursor/cursor-session-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-session-003.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-session-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-session-004.phpt b/mongodb-1.14.0/tests/cursor/cursor-session-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-session-004.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-session-004.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-003.phpt b/mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-003.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-004.phpt b/mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-setTypeMap_error-004.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-setTypeMap_error-004.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-tailable-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-tailable-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-tailable-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-tailable-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-tailable-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-tailable-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-tailable-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-tailable-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-tailable-003.phpt b/mongodb-1.14.0/tests/cursor/cursor-tailable-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-tailable-003.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-tailable-003.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-tailable_error-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-tailable_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-tailable_error-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-tailable_error-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-tailable_error-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-tailable_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-tailable_error-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-tailable_error-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-toArray-001.phpt b/mongodb-1.14.0/tests/cursor/cursor-toArray-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-toArray-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-toArray-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor-toArray-002.phpt b/mongodb-1.14.0/tests/cursor/cursor-toArray-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor-toArray-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursor-toArray-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursor_error-001.phpt b/mongodb-1.14.0/tests/cursor/cursor_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursor_error-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursor_error-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursorinterface-001.phpt b/mongodb-1.14.0/tests/cursor/cursorinterface-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursorinterface-001.phpt
rename to mongodb-1.14.0/tests/cursor/cursorinterface-001.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursorinterface-002.phpt b/mongodb-1.14.0/tests/cursor/cursorinterface-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursorinterface-002.phpt
rename to mongodb-1.14.0/tests/cursor/cursorinterface-002.phpt
diff --git a/mongodb-1.13.0/tests/cursor/cursorinterface-003.phpt b/mongodb-1.14.0/tests/cursor/cursorinterface-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursor/cursorinterface-003.phpt
rename to mongodb-1.14.0/tests/cursor/cursorinterface-003.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-002.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-002.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-002.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-debug-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-debug-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-debug-002.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-debug-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-debug-002.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-debug-002.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-debug-003.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-debug-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-debug-003.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-debug-003.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-serialization-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-serialization-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-serialization-002.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-serialization-002.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-serialization_error-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-serialization_error-002.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-set_state-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-set_state-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-set_state_error-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-tostring-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-tostring-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-tostring-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-tostring-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid-var_export-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid-var_export-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid-var_export-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid-var_export-001.phpt
diff --git a/mongodb-1.13.0/tests/cursorid/cursorid_error-001.phpt b/mongodb-1.14.0/tests/cursorid/cursorid_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/cursorid/cursorid_error-001.phpt
rename to mongodb-1.14.0/tests/cursorid/cursorid_error-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/bulkwriteexception-getwriteresult-001.phpt b/mongodb-1.14.0/tests/exception/bulkwriteexception-getwriteresult-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/bulkwriteexception-getwriteresult-001.phpt
rename to mongodb-1.14.0/tests/exception/bulkwriteexception-getwriteresult-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/bulkwriteexception-haserrorlabel-001.phpt b/mongodb-1.14.0/tests/exception/bulkwriteexception-haserrorlabel-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/bulkwriteexception-haserrorlabel-001.phpt
rename to mongodb-1.14.0/tests/exception/bulkwriteexception-haserrorlabel-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/bulkwriteexception-haserrorlabel-002.phpt b/mongodb-1.14.0/tests/exception/bulkwriteexception-haserrorlabel-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/bulkwriteexception-haserrorlabel-002.phpt
rename to mongodb-1.14.0/tests/exception/bulkwriteexception-haserrorlabel-002.phpt
diff --git a/mongodb-1.13.0/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt b/mongodb-1.14.0/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt
rename to mongodb-1.14.0/tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/commandexception-getresultdocument-001.phpt b/mongodb-1.14.0/tests/exception/commandexception-getresultdocument-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/commandexception-getresultdocument-001.phpt
rename to mongodb-1.14.0/tests/exception/commandexception-getresultdocument-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/commandexception-haserrorlabel-001.phpt b/mongodb-1.14.0/tests/exception/commandexception-haserrorlabel-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/commandexception-haserrorlabel-001.phpt
rename to mongodb-1.14.0/tests/exception/commandexception-haserrorlabel-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/commandexception-haserrorlabel_error-001.phpt b/mongodb-1.14.0/tests/exception/commandexception-haserrorlabel_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/commandexception-haserrorlabel_error-001.phpt
rename to mongodb-1.14.0/tests/exception/commandexception-haserrorlabel_error-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/exception-001.phpt b/mongodb-1.14.0/tests/exception/exception-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/exception-001.phpt
rename to mongodb-1.14.0/tests/exception/exception-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/runtimeexception-haserrorlabel-001.phpt b/mongodb-1.14.0/tests/exception/runtimeexception-haserrorlabel-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/runtimeexception-haserrorlabel-001.phpt
rename to mongodb-1.14.0/tests/exception/runtimeexception-haserrorlabel-001.phpt
diff --git a/mongodb-1.13.0/tests/exception/runtimeexception-haserrorlabel_error-001.phpt b/mongodb-1.14.0/tests/exception/runtimeexception-haserrorlabel_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/exception/runtimeexception-haserrorlabel_error-001.phpt
rename to mongodb-1.14.0/tests/exception/runtimeexception-haserrorlabel_error-001.phpt
diff --git a/mongodb-1.13.0/tests/functional/cursor-001.phpt b/mongodb-1.14.0/tests/functional/cursor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/functional/cursor-001.phpt
rename to mongodb-1.14.0/tests/functional/cursor-001.phpt
diff --git a/mongodb-1.13.0/tests/functional/cursorid-001.phpt b/mongodb-1.14.0/tests/functional/cursorid-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/functional/cursorid-001.phpt
rename to mongodb-1.14.0/tests/functional/cursorid-001.phpt
diff --git a/mongodb-1.13.0/tests/functional/query-sort-001.phpt b/mongodb-1.14.0/tests/functional/query-sort-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/functional/query-sort-001.phpt
rename to mongodb-1.14.0/tests/functional/query-sort-001.phpt
diff --git a/mongodb-1.13.0/tests/functional/query-sort-002.phpt b/mongodb-1.14.0/tests/functional/query-sort-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/functional/query-sort-002.phpt
rename to mongodb-1.14.0/tests/functional/query-sort-002.phpt
diff --git a/mongodb-1.13.0/tests/functional/query-sort-003.phpt b/mongodb-1.14.0/tests/functional/query-sort-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/functional/query-sort-003.phpt
rename to mongodb-1.14.0/tests/functional/query-sort-003.phpt
diff --git a/mongodb-1.13.0/tests/functional/query-sort-004.phpt b/mongodb-1.14.0/tests/functional/query-sort-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/functional/query-sort-004.phpt
rename to mongodb-1.14.0/tests/functional/query-sort-004.phpt
diff --git a/mongodb-1.13.0/tests/ini/ini-debug-ini_get-001.phpt b/mongodb-1.14.0/tests/ini/ini-debug-ini_get-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/ini/ini-debug-ini_get-001.phpt
rename to mongodb-1.14.0/tests/ini/ini-debug-ini_get-001.phpt
diff --git a/mongodb-1.13.0/tests/ini/ini-debug-ini_get-002.phpt b/mongodb-1.14.0/tests/ini/ini-debug-ini_get-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/ini/ini-debug-ini_get-002.phpt
rename to mongodb-1.14.0/tests/ini/ini-debug-ini_get-002.phpt
diff --git a/mongodb-1.13.0/tests/ini/ini-debug-phpinfo-001.phpt b/mongodb-1.14.0/tests/ini/ini-debug-phpinfo-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/ini/ini-debug-phpinfo-001.phpt
rename to mongodb-1.14.0/tests/ini/ini-debug-phpinfo-001.phpt
diff --git a/mongodb-1.13.0/tests/ini/ini-debug-phpinfo-002.phpt b/mongodb-1.14.0/tests/ini/ini-debug-phpinfo-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/ini/ini-debug-phpinfo-002.phpt
rename to mongodb-1.14.0/tests/ini/ini-debug-phpinfo-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug0572.phpt b/mongodb-1.14.0/tests/manager/bug0572.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug0572.phpt
rename to mongodb-1.14.0/tests/manager/bug0572.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug0851-001.phpt b/mongodb-1.14.0/tests/manager/bug0851-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug0851-001.phpt
rename to mongodb-1.14.0/tests/manager/bug0851-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug0851-002.phpt b/mongodb-1.14.0/tests/manager/bug0851-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug0851-002.phpt
rename to mongodb-1.14.0/tests/manager/bug0851-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug0912-001.phpt b/mongodb-1.14.0/tests/manager/bug0912-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug0912-001.phpt
rename to mongodb-1.14.0/tests/manager/bug0912-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug0913-001.phpt b/mongodb-1.14.0/tests/manager/bug0913-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug0913-001.phpt
rename to mongodb-1.14.0/tests/manager/bug0913-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug0940-001.phpt b/mongodb-1.14.0/tests/manager/bug0940-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug0940-001.phpt
rename to mongodb-1.14.0/tests/manager/bug0940-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug0940-002.phpt b/mongodb-1.14.0/tests/manager/bug0940-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug0940-002.phpt
rename to mongodb-1.14.0/tests/manager/bug0940-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug1163-001.phpt b/mongodb-1.14.0/tests/manager/bug1163-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug1163-001.phpt
rename to mongodb-1.14.0/tests/manager/bug1163-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/bug1701-001.phpt b/mongodb-1.14.0/tests/manager/bug1701-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/bug1701-001.phpt
rename to mongodb-1.14.0/tests/manager/bug1701-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-addSubscriber-001.phpt b/mongodb-1.14.0/tests/manager/manager-addSubscriber-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-addSubscriber-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-addSubscriber-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-addSubscriber-002.phpt b/mongodb-1.14.0/tests/manager/manager-addSubscriber-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-addSubscriber-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-addSubscriber-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-addSubscriber-003.phpt b/mongodb-1.14.0/tests/manager/manager-addSubscriber-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-addSubscriber-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-addSubscriber-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-addSubscriber-004.phpt b/mongodb-1.14.0/tests/manager/manager-addSubscriber-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-addSubscriber-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-addSubscriber-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-addSubscriber-005.phpt b/mongodb-1.14.0/tests/manager/manager-addSubscriber-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-addSubscriber-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-addSubscriber-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-addSubscriber-006.phpt b/mongodb-1.14.0/tests/manager/manager-addSubscriber-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-addSubscriber-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-addSubscriber-006.phpt
diff --git a/mongodb-1.14.0/tests/manager/manager-createClientEncryption-001.phpt b/mongodb-1.14.0/tests/manager/manager-createClientEncryption-001.phpt
new file mode 100644
index 00000000..ef3bcee2
--- /dev/null
+++ b/mongodb-1.14.0/tests/manager/manager-createClientEncryption-001.phpt
@@ -0,0 +1,26 @@
+--TEST--
+MongoDB\Driver\Manager::createClientEncryption()
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_libmongocrypt(); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/basic.inc';
+
+$manager = create_test_manager();
+
+$clientEncryption = $manager->createClientEncryption([
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]]
+]);
+
+var_dump($clientEncryption);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+object(MongoDB\Driver\ClientEncryption)#%d (%d) {
+}
+===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-createClientEncryption-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-createClientEncryption-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-002.phpt b/mongodb-1.14.0/tests/manager/manager-createClientEncryption-error-002.phpt
similarity index 78%
rename from mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-createClientEncryption-error-002.phpt
index cdd729de..60319d8d 100644
--- a/mongodb-1.13.0/tests/manager/manager-createClientEncryption-error-002.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-createClientEncryption-error-002.phpt
@@ -1,45 +1,45 @@
--TEST--
MongoDB\Driver\Manager::createClientEncryption() with invalid option types
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
require_once __DIR__ . '/../utils/basic.inc';
$tests = [
['keyVaultClient' => 'not_an_array_or_object'],
[
'keyVaultNamespace' => 'not_a_namespace',
// keyVaultNamespace requires a valid kmsProviders option
- 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary('', 0)]],
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
],
['kmsProviders' => 'not_an_array_or_object'],
['tlsOptions' => 'not_an_array_or_object'],
];
foreach ($tests as $test) {
echo throws(function () use ($test) {
$manager = create_test_manager();
$clientEncryption = $manager->createClientEncryption($test);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "keyVaultClient" encryption option to be MongoDB\Driver\Manager, string given
+Expected "keyVaultClient" option to be MongoDB\Driver\Manager, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "keyVaultNamespace" encryption option to contain a full collection name
+Expected "keyVaultNamespace" option to contain a full collection namespace
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "kmsProviders" encryption option to be an array or object
+Expected "kmsProviders" option to be an array or object, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "tlsOptions" encryption option to be an array or object
+Expected "tlsOptions" option to be an array or object, string given
===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-004.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-005.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-006.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-006.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-007.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-007.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-007.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-008.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-008.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-008.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-appname-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-appname-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-appname-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-appname-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-appname_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-appname_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-appname_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-appname_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auth_mechanism-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auth_mechanism-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auth_mechanism-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auth_mechanism-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auth_mechanism-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auth_mechanism-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auth_mechanism-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auth_mechanism-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auth_mechanism-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auth_mechanism-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auth_source-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auth_source-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auth_source-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auth_source-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-001.phpt
similarity index 74%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-001.phpt
index 9742b692..564cb901 100644
--- a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-001.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-001.phpt
@@ -1,51 +1,54 @@
--TEST--
-MongoDB\Driver\Manager::__construct(): auto encryption options
+MongoDB\Driver\Manager::__construct(): autoEncryption options
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_appveyor(); /* AppVeyor does not have mongocryptd installed */ ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
+require_once __DIR__ . '/../utils/basic.inc';
+
$baseOptions = [
- 'keyVaultNamespace' => 'admin.dataKeys',
- 'kmsProviders' => ['aws' => (object) ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']]
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
];
$tests = [
[],
- ['keyVaultClient' => new MongoDB\Driver\Manager()],
+ ['bypassAutoEncryption' => true],
+ ['bypassQueryAnalysis' => true],
+ ['keyVaultClient' => create_test_manager()],
['schemaMap' => [
'default.default' => [
'properties' => [
'encrypted_objectId' => [
'encrypt' => [
'keyId' => [
[
'$binary' => [
'base64' => 'AAAAAAAAAAAAAAAAAAAAAA==',
'subType' => '04',
],
],
],
'bsonType' => 'objectId',
'algorithm' => MongoDB\Driver\ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
],
],
],
'bsonType' => 'object',
],
]],
- ['bypassAutoEncryption' => true],
['extraOptions' => ['mongocryptdBypassSpawn' => true]],
];
foreach ($tests as $autoEncryptionOptions) {
- $manager = new MongoDB\Driver\Manager(null, [], ['autoEncryption' => $autoEncryptionOptions + $baseOptions]);
+ create_test_manager(null, [], ['autoEncryption' => $autoEncryptionOptions + $baseOptions]);
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
===DONE===
diff --git a/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-002.phpt
new file mode 100644
index 00000000..8b381084
--- /dev/null
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-002.phpt
@@ -0,0 +1,24 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): crypt_shared is required
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_libmongocrypt(); ?>
+<?php skip_if_no_crypt_shared(); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/basic.inc';
+
+$autoEncryptionOptions = [
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+ 'extraOptions' => ['cryptSharedLibRequired' => true],
+];
+
+create_test_manager(null, [], ['autoEncryption' => $autoEncryptionOptions]);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-001.phpt
similarity index 62%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-001.phpt
index 1ac53abb..d0190995 100644
--- a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-001.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-001.phpt
@@ -1,32 +1,31 @@
--TEST--
-MongoDB\Driver\Manager::__construct(): incomplete auto encryption options
+MongoDB\Driver\Manager::__construct(): incomplete autoEncryption options
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
-
require_once __DIR__ . '/../utils/basic.inc';
$tests = [
[],
- ['keyVaultNamespace' => 'admin.keys'],
+ ['keyVaultNamespace' => CSFLE_KEY_VAULT_NS],
];
-foreach ($tests as $driverOptions) {
- echo throws(function() use ($driverOptions) {
- $manager = create_test_manager(null, [], ['autoEncryption' => $driverOptions]);
+foreach ($tests as $autoEncryptionOptions) {
+ echo throws(function() use ($autoEncryptionOptions) {
+ create_test_manager(null, [], ['autoEncryption' => $autoEncryptionOptions]);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Key vault namespace option required
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
KMS providers option required
===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-002.phpt
similarity index 76%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-002.phpt
index de58316f..bda8071d 100644
--- a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-002.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-002.phpt
@@ -1,21 +1,21 @@
--TEST--
-MongoDB\Driver\Manager::__construct(): auto encryption when compiling without libmongocrypt
+MongoDB\Driver\Manager::__construct(): autoEncryption when compiling without libmongocrypt
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_libmongocrypt(); ?>
--FILE--
<?php
require_once __DIR__ . '/../utils/basic.inc';
echo throws(function () {
- $manager = create_test_manager(null, [], ['autoEncryption' => []]);
+ create_test_manager(null, [], ['autoEncryption' => []]);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Cannot enable automatic field-level encryption. Please recompile with support for libmongocrypt using the with-mongodb-client-side-encryption configure switch.
===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-003.phpt
similarity index 55%
rename from mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-003.phpt
index 9d988252..e36237e1 100644
--- a/mongodb-1.13.0/tests/manager/manager-ctor-auto_encryption-error-003.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-003.phpt
@@ -1,56 +1,60 @@
--TEST--
-MongoDB\Driver\Manager::__construct(): invalid option types
+MongoDB\Driver\Manager::__construct(): invalid types in autoEncryption options
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
require_once __DIR__ . '/../utils/basic.inc';
$tests = [
'not_an_array',
+ ['encryptedFieldsMap' => 'not_an_array_or_object'],
['keyVaultClient' => 'not_an_array_or_object'],
[
'keyVaultNamespace' => 'not_a_namespace',
// keyVaultNamespace requires a valid kmsProviders option
- 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary('', 0)]],
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
],
['kmsProviders' => 'not_an_array_or_object'],
['schemaMap' => 'not_an_array_or_object'],
['tlsOptions' => 'not_an_array_or_object'],
['extraOptions' => 'not_an_array_or_object'],
];
-foreach ($tests as $test) {
- echo throws(function() use ($test) {
- $manager = create_test_manager(null, [], ['autoEncryption' => $test]);
+foreach ($tests as $autoEncryptionOptions) {
+ echo throws(function() use ($autoEncryptionOptions) {
+ create_test_manager(null, [], ['autoEncryption' => $autoEncryptionOptions]);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "autoEncryption" driver option to be array, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "keyVaultClient" encryption option to be MongoDB\Driver\Manager, string given
+Expected "encryptedFieldsMap" autoEncryption option to be an array or object, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "keyVaultNamespace" encryption option to contain a full collection name
+Expected "keyVaultClient" autoEncryption option to be MongoDB\Driver\Manager, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "kmsProviders" encryption option to be an array or object
+Expected "keyVaultNamespace" autoEncryption option to contain a full collection namespace
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "schemaMap" encryption option to be an array or object
+Expected "kmsProviders" autoEncryption option to be an array or object, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "tlsOptions" encryption option to be an array or object
+Expected "schemaMap" autoEncryption option to be an array or object, string given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "extraOptions" encryption option to be an array or object
+Expected "tlsOptions" autoEncryption option to be an array or object, string given
+
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "extraOptions" autoEncryption option to be an array or object, string given
===DONE===
diff --git a/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-004.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-004.phpt
new file mode 100644
index 00000000..e4f6b89a
--- /dev/null
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-auto_encryption-error-004.phpt
@@ -0,0 +1,38 @@
+--TEST--
+MongoDB\Driver\Manager::__construct(): crypt_shared is required and unavailable
+--SKIPIF--
+<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
+<?php skip_if_not_libmongocrypt(); ?>
+<?php skip_if_crypt_shared(); ?>
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/basic.inc';
+
+$baseOptions = [
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+];
+
+$tests = [
+ ['extraOptions' => ['cryptSharedLibPath' => '/not/found']],
+ ['extraOptions' => ['cryptSharedLibRequired' => true]],
+];
+
+foreach ($tests as $autoEncryptionOptions) {
+ echo throws(function() use ($autoEncryptionOptions, $baseOptions) {
+ create_test_manager(null, [], ['autoEncryption' => $autoEncryptionOptions + $baseOptions]);
+ }, MongoDB\Driver\Exception\EncryptionException::class), "\n\n";
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got MongoDB\Driver\Exception\EncryptionException
+A crypt_shared override path was specified [/not/found], but we failed to open a dynamic library at that location
+
+OK: Got MongoDB\Driver\Exception\EncryptionException
+Option 'cryptSharedLibRequired' is 'true', but failed to load the crypt_shared runtime libary
+
+===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-directconnection-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-directconnection-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-directconnection-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-directconnection-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-directconnection-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-directconnection-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-directconnection-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-directconnection-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-directconnection-error-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-directconnection-error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-directconnection-error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-directconnection-error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-004.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-005.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-006.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-006.phpt
similarity index 93%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-006.phpt
index 33692787..5ae183d5 100644
--- a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-006.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-006.phpt
@@ -1,41 +1,41 @@
--TEST--
MongoDB\Driver\Manager with disableClientPersistence=true referenced by ClientEncryption (implicit keyVaultClient)
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
ini_set('mongodb.debug', 'stderr');
$manager = create_test_manager(null, [], ['disableClientPersistence' => true]);
ini_set('mongodb.debug', '');
echo "Creating clientEncryption\n";
$clientEncryption = $manager->createClientEncryption([
- 'keyVaultNamespace' => 'default.keys',
- 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(str_repeat('0', 96), 0)]],
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
]);
echo "Unsetting manager\n";
ini_set('mongodb.debug', 'stderr');
unset($manager);
ini_set('mongodb.debug', '');
echo "Unsetting clientEncryption\n";
ini_set('mongodb.debug', 'stderr');
unset($clientEncryption);
ini_set('mongodb.debug', '');
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
%A
[%s] PHONGO: DEBUG > Created client with hash: %s
[%s] PHONGO: DEBUG > Stored non-persistent client
Creating clientEncryption
Unsetting manager
Unsetting clientEncryption%A
[%s] PHONGO: DEBUG > Destroying non-persistent client for Manager%A
===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-007.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-007.phpt
similarity index 95%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-007.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-007.phpt
index b1400c5e..4c05a77d 100644
--- a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-007.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-007.phpt
@@ -1,53 +1,53 @@
--TEST--
MongoDB\Driver\Manager with disableClientPersistence=true referenced by ClientEncryption (explicit keyVaultClient)
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
ini_set('mongodb.debug', 'stderr');
$manager = create_test_manager(null, [], ['disableClientPersistence' => true]);
$keyVaultClient = create_test_manager(null, [], ['disableClientPersistence' => true]);
ini_set('mongodb.debug', '');
echo "Creating clientEncryption\n";
$clientEncryption = $manager->createClientEncryption([
'keyVaultClient' => $keyVaultClient,
- 'keyVaultNamespace' => 'default.keys',
- 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(str_repeat('0', 96), 0)]],
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
]);
echo "Unsetting manager\n";
ini_set('mongodb.debug', 'stderr');
unset($manager);
ini_set('mongodb.debug', '');
echo "Unsetting keyVaultClient\n";
ini_set('mongodb.debug', 'stderr');
unset($keyVaultClient);
ini_set('mongodb.debug', '');
echo "Unsetting clientEncryption\n";
ini_set('mongodb.debug', 'stderr');
unset($clientEncryption);
ini_set('mongodb.debug', '');
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
%A
[%s] PHONGO: DEBUG > Created client with hash: %s
[%s] PHONGO: DEBUG > Stored non-persistent client
%A
[%s] PHONGO: DEBUG > Created client with hash: %s
[%s] PHONGO: DEBUG > Stored non-persistent client
Creating clientEncryption
Unsetting manager
[%s] PHONGO: DEBUG > Destroying non-persistent client for Manager%A
Unsetting keyVaultClient
Unsetting clientEncryption%A
[%s] PHONGO: DEBUG > Destroying non-persistent client for Manager%A
===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-008.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-008.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-008.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-009.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-009.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-009.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-010.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-010.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-010.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-011.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence-011.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence-011.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence_error-001.phpt
similarity index 87%
rename from mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence_error-001.phpt
index 18d20b61..50552ec7 100644
--- a/mongodb-1.13.0/tests/manager/manager-ctor-disableClientPersistence_error-001.phpt
+++ b/mongodb-1.14.0/tests/manager/manager-ctor-disableClientPersistence_error-001.phpt
@@ -1,39 +1,39 @@
--TEST--
MongoDB\Driver\Manager and keyVaultClient must have same disableClientPersistence option
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongocrypt(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
echo throws(function() {
create_test_manager(null, [], [
'autoEncryption' => [
'keyVaultClient' => create_test_manager(null),
- 'keyVaultNamespace' => 'default.keys',
- 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(str_repeat('0', 96), 0)]],
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
],
'disableClientPersistence' => true,
]);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
echo throws(function() {
create_test_manager(null, [], [
'autoEncryption' => [
'keyVaultClient' => create_test_manager(null, [], ['disableClientPersistence' => true]),
- 'keyVaultNamespace' => 'default.keys',
- 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(str_repeat('0', 96), 0)]],
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
]
]);
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
The "disableClientPersistence" option for a Manager and its "keyVaultClient" must be the same
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
The "disableClientPersistence" option for a Manager and its "keyVaultClient" must be the same
===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-driver-metadata-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-driver-metadata-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-driver-metadata-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-driver-metadata-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-004.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-duplicate-option-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-duplicate-option-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-loadBalanced_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-loadBalanced_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-loadBalanced_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-loadBalanced_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-read_concern-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-read_concern-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-read_concern-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-read_concern-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-read_concern-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-read_concern-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-read_concern-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-read_concern-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-read_preference-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-read_preference-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-read_preference-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-read_preference-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-read_preference-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-read_preference-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-read_preference-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-read_preference-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-read_preference-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-read_preference-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-read_preference-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-read_preference-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-read_preference-error-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-read_preference-error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-read_preference-error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-read_preference-error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-read_preference-error-004.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-read_preference-error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-read_preference-error-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-read_preference-error-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-server.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-server.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-server.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-server.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-serverApi-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-serverApi-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-serverApi-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-serverApi-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-serverApi-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-serverApi-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-serverApi-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-serverApi-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-srvMaxHosts_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-srvMaxHosts_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-srvMaxHosts_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-srvMaxHosts_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-srvServiceName_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-srvServiceName_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-srvServiceName_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-srvServiceName_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-ssl-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-ssl-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-ssl-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-ssl-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-ssl-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-ssl-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-ssl-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-ssl-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-ssl-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-ssl-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-ssl-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-ssl-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-ssl-deprecated-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-ssl-deprecated-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-ssl-deprecated-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-ssl-deprecated-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-ssl-deprecated-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-ssl-deprecated-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-ssl-deprecated-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-ssl-deprecated-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-tls-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-tls-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-tls-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-tls-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-wireversion.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-wireversion.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-wireversion.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-wireversion.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-004.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-005.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-006.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-006.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-005.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-006.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-006.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-007.phpt b/mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor-write_concern-error-007.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor-write_concern-error-007.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor_error-002.phpt b/mongodb-1.14.0/tests/manager/manager-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor_error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor_error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor_error-003.phpt b/mongodb-1.14.0/tests/manager/manager-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor_error-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor_error-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor_error-004.phpt b/mongodb-1.14.0/tests/manager/manager-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor_error-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor_error-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-ctor_error-005.phpt b/mongodb-1.14.0/tests/manager/manager-ctor_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-ctor_error-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-ctor_error-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-debug-001.phpt b/mongodb-1.14.0/tests/manager/manager-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-debug-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-debug-002.phpt b/mongodb-1.14.0/tests/manager/manager-debug-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-debug-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-debug-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-debug-003.phpt b/mongodb-1.14.0/tests/manager/manager-debug-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-debug-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-debug-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-destruct-001.phpt b/mongodb-1.14.0/tests/manager/manager-destruct-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-destruct-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-destruct-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-004.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-005.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-006.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-006.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-007.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-007.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-007.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-008.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-008.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-008.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-009.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-009.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-009.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-010.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-010.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-010.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-011.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-011.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-011.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-012.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-012.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-012.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-013.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-013.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-013.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite-014.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite-014.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite-014.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite-014.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-004.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-005.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-006.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-006.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-007.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-007.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-007.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-008.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-008.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-008.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-009.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-009.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-009.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-010.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-010.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-010.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-011.phpt b/mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeBulkWrite_error-011.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeBulkWrite_error-011.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand-004.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand-005.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand-006.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand-006.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand-007.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand-007.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand-007.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand_error-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand_error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand_error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand_error-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand_error-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand_error-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand_error-004.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand_error-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand_error-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeCommand_error-005.phpt b/mongodb-1.14.0/tests/manager/manager-executeCommand_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeCommand_error-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeCommand_error-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery-004.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery-004.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery-005.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery-005.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery-005.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery-006.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery-006.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery-006.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery-007.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery-007.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery-007.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery_error-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery_error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery_error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeQuery_error-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeQuery_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeQuery_error-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeQuery_error-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadCommand-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadCommand-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadCommand-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadCommand-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadCommand-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadCommand-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadCommand_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadCommand_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand_error-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeReadWriteCommand_error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeReadWriteCommand_error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeWriteCommand-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeWriteCommand-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeWriteCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeWriteCommand-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeWriteCommand-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeWriteCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeWriteCommand-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeWriteCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeWriteCommand-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeWriteCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-002.phpt b/mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-003.phpt b/mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-004.phpt b/mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-executeWriteCommand_error-004.phpt
rename to mongodb-1.14.0/tests/manager/manager-executeWriteCommand_error-004.phpt
diff --git a/mongodb-1.14.0/tests/manager/manager-getencryptedfieldsmap-001.phpt b/mongodb-1.14.0/tests/manager/manager-getencryptedfieldsmap-001.phpt
new file mode 100644
index 00000000..38f245b0
--- /dev/null
+++ b/mongodb-1.14.0/tests/manager/manager-getencryptedfieldsmap-001.phpt
@@ -0,0 +1,83 @@
+--TEST--
+MongoDB\Driver\Manager::getEncryptedFieldsMap()
+--FILE--
+<?php
+
+require_once __DIR__ . "/../utils/basic.inc";
+
+/* autoEncryption requires keyVaultNamespace and a kmsProvider. Additionally,
+ * disable mongocryptd spawning since it is not required for this test. */
+$baseOptions = [
+ 'keyVaultNamespace' => CSFLE_KEY_VAULT_NS,
+ 'kmsProviders' => ['local' => ['key' => new MongoDB\BSON\Binary(CSFLE_LOCAL_KEY, 0)]],
+ 'extraOptions' => ['mongocryptdBypassSpawn' => true],
+];
+
+$encryptedFields = [
+ 'escCollection' => 'escCollectionName',
+ 'eccCollection' => 'eccCollectionName',
+ 'ecocCollection' => 'ecocCollectionName',
+ 'fields' => [
+ [
+ 'path' => 'foo',
+ 'keyId' => new MongoDB\BSON\Binary(str_repeat('0', 16), MongoDB\BSON\Binary::TYPE_UUID),
+ 'bsonType' => 'string',
+ 'queries' => ['queryType' => 'equality'],
+ ],
+ ],
+];
+
+$tests = [
+ [],
+ ['autoEncryption' => $baseOptions],
+ ['autoEncryption' => ['encryptedFieldsMap' => []] + $baseOptions],
+ ['autoEncryption' => ['encryptedFieldsMap' => ['db.coll' => $encryptedFields]] + $baseOptions],
+];
+
+foreach ($tests as $i => $driverOptions) {
+ $manager = create_test_manager(null, [], $driverOptions);
+ var_dump($manager->getEncryptedFieldsMap());
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+NULL
+NULL
+array(0) {
+}
+array(1) {
+ ["db.coll"]=>
+ array(4) {
+ ["escCollection"]=>
+ string(17) "escCollectionName"
+ ["eccCollection"]=>
+ string(17) "eccCollectionName"
+ ["ecocCollection"]=>
+ string(18) "ecocCollectionName"
+ ["fields"]=>
+ array(1) {
+ [0]=>
+ array(4) {
+ ["path"]=>
+ string(3) "foo"
+ ["keyId"]=>
+ object(MongoDB\BSON\Binary)#%d (%d) {
+ ["data"]=>
+ string(16) "0000000000000000"
+ ["type"]=>
+ int(4)
+ }
+ ["bsonType"]=>
+ string(6) "string"
+ ["queries"]=>
+ array(1) {
+ ["queryType"]=>
+ string(8) "equality"
+ }
+ }
+ }
+ }
+}
+===DONE===
diff --git a/mongodb-1.13.0/tests/manager/manager-getreadconcern-001.phpt b/mongodb-1.14.0/tests/manager/manager-getreadconcern-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-getreadconcern-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-getreadconcern-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-getreadpreference-001.phpt b/mongodb-1.14.0/tests/manager/manager-getreadpreference-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-getreadpreference-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-getreadpreference-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-getservers-001.phpt b/mongodb-1.14.0/tests/manager/manager-getservers-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-getservers-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-getservers-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-getservers-002.phpt b/mongodb-1.14.0/tests/manager/manager-getservers-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-getservers-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-getservers-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-getwriteconcern-001.phpt b/mongodb-1.14.0/tests/manager/manager-getwriteconcern-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-getwriteconcern-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-getwriteconcern-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-invalidnamespace.phpt b/mongodb-1.14.0/tests/manager/manager-invalidnamespace.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-invalidnamespace.phpt
rename to mongodb-1.14.0/tests/manager/manager-invalidnamespace.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-removeSubscriber-001.phpt b/mongodb-1.14.0/tests/manager/manager-removeSubscriber-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-removeSubscriber-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-removeSubscriber-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-removeSubscriber-002.phpt b/mongodb-1.14.0/tests/manager/manager-removeSubscriber-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-removeSubscriber-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-removeSubscriber-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-selectServer-001.phpt b/mongodb-1.14.0/tests/manager/manager-selectServer-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-selectServer-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-selectServer-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-selectServer-002.phpt b/mongodb-1.14.0/tests/manager/manager-selectServer-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-selectServer-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-selectServer-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-selectserver_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-selectserver_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-selectserver_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-selectserver_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-set-uri-options-001.phpt b/mongodb-1.14.0/tests/manager/manager-set-uri-options-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-set-uri-options-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-set-uri-options-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-set-uri-options-002.phpt b/mongodb-1.14.0/tests/manager/manager-set-uri-options-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-set-uri-options-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-set-uri-options-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-set-uri-options-003.phpt b/mongodb-1.14.0/tests/manager/manager-set-uri-options-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-set-uri-options-003.phpt
rename to mongodb-1.14.0/tests/manager/manager-set-uri-options-003.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-startSession_error-001.phpt b/mongodb-1.14.0/tests/manager/manager-startSession_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-startSession_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-startSession_error-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-startSession_error-002.phpt b/mongodb-1.14.0/tests/manager/manager-startSession_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-startSession_error-002.phpt
rename to mongodb-1.14.0/tests/manager/manager-startSession_error-002.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-var-dump-001.phpt b/mongodb-1.14.0/tests/manager/manager-var-dump-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-var-dump-001.phpt
rename to mongodb-1.14.0/tests/manager/manager-var-dump-001.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager-wakeup.phpt b/mongodb-1.14.0/tests/manager/manager-wakeup.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager-wakeup.phpt
rename to mongodb-1.14.0/tests/manager/manager-wakeup.phpt
diff --git a/mongodb-1.13.0/tests/manager/manager_error-001.phpt b/mongodb-1.14.0/tests/manager/manager_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/manager/manager_error-001.phpt
rename to mongodb-1.14.0/tests/manager/manager_error-001.phpt
diff --git a/mongodb-1.13.0/tests/query/bug0430-001.phpt b/mongodb-1.14.0/tests/query/bug0430-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/bug0430-001.phpt
rename to mongodb-1.14.0/tests/query/bug0430-001.phpt
diff --git a/mongodb-1.13.0/tests/query/bug0430-002.phpt b/mongodb-1.14.0/tests/query/bug0430-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/bug0430-002.phpt
rename to mongodb-1.14.0/tests/query/bug0430-002.phpt
diff --git a/mongodb-1.13.0/tests/query/bug0430-003.phpt b/mongodb-1.14.0/tests/query/bug0430-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/bug0430-003.phpt
rename to mongodb-1.14.0/tests/query/bug0430-003.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor-001.phpt b/mongodb-1.14.0/tests/query/query-ctor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor-001.phpt
rename to mongodb-1.14.0/tests/query/query-ctor-001.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor-002.phpt b/mongodb-1.14.0/tests/query/query-ctor-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor-002.phpt
rename to mongodb-1.14.0/tests/query/query-ctor-002.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor-003.phpt b/mongodb-1.14.0/tests/query/query-ctor-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor-003.phpt
rename to mongodb-1.14.0/tests/query/query-ctor-003.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor-004.phpt b/mongodb-1.14.0/tests/query/query-ctor-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor-004.phpt
rename to mongodb-1.14.0/tests/query/query-ctor-004.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor-005.phpt b/mongodb-1.14.0/tests/query/query-ctor-005.phpt
similarity index 100%
copy from mongodb-1.13.0/tests/query/query-ctor-005.phpt
copy to mongodb-1.14.0/tests/query/query-ctor-005.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor-006.phpt b/mongodb-1.14.0/tests/query/query-ctor-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor-006.phpt
rename to mongodb-1.14.0/tests/query/query-ctor-006.phpt
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-delete-002.phpt b/mongodb-1.14.0/tests/query/query-ctor-comment-001.phpt
similarity index 51%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-delete-002.phpt
rename to mongodb-1.14.0/tests/query/query-ctor-comment-001.phpt
index 47cd3ac9..b0ecc3f4 100644
--- a/mongodb-1.13.0/tests/bulk/bulkwrite-delete-002.phpt
+++ b/mongodb-1.14.0/tests/query/query-ctor-comment-001.phpt
@@ -1,55 +1,65 @@
--TEST--
-MongoDB\Driver\BulkWrite::delete() with hint option
+MongoDB\Driver\Query::__construct(): comment option
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
-<?php skip_if_server_version('<', '4.3.4'); ?>
+<?php skip_if_server_version('<', '4.4'); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
+
require_once __DIR__ . "/../utils/basic.inc";
class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
- if ($event->getCommandName() !== 'delete') {
+ $command = $event->getCommand();
+
+ if (!isset($command->comment)) {
+ printf("%s does not include comment option\n", $event->getCommandName());
+
return;
}
- printf("delete included hint: %s\n", json_encode($event->getCommand()->deletes[0]->hint));
+ printf("%s included comment: %s\n", $event->getCommandName(), json_encode($command->comment));
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
$manager = create_test_manager();
-$bulk = new MongoDB\Driver\BulkWrite();
-$bulk->insert(['x' => 1]);
-$bulk->insert(['x' => 2]);
-$manager->executeBulkWrite(NS, $bulk);
-
-MongoDB\Driver\Monitoring\addSubscriber(new CommandLogger);
-
$bulk = new MongoDB\Driver\BulkWrite;
-$bulk->delete(['_id' => 1], ['hint' => '_id_']);
+$bulk->insert(['_id' => 1]);
+$bulk->insert(['_id' => 2]);
$manager->executeBulkWrite(NS, $bulk);
-$bulk = new MongoDB\Driver\BulkWrite;
-$bulk->delete(['_id' => 2], ['hint' => ['_id' => 1]]);
-$manager->executeBulkWrite(NS, $bulk);
+$query = new MongoDB\Driver\Query(
+ ['_id' => 1],
+ ['comment' => ['foo' => 1]]
+);
+
+$manager->addSubscriber(new CommandLogger);
+$cursor = $manager->executeQuery(NS, $query);
+var_dump($cursor->toArray());
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
-delete included hint: "_id_"
-delete included hint: {"_id":1}
+find included comment: {"foo":1}
+array(1) {
+ [0]=>
+ object(stdClass)#%d (%d) {
+ ["_id"]=>
+ int(1)
+ }
+}
===DONE===
diff --git a/mongodb-1.14.0/tests/query/query-ctor-comment_error-001.phpt b/mongodb-1.14.0/tests/query/query-ctor-comment_error-001.phpt
new file mode 100644
index 00000000..c4f1bd80
--- /dev/null
+++ b/mongodb-1.14.0/tests/query/query-ctor-comment_error-001.phpt
@@ -0,0 +1,26 @@
+--TEST--
+MongoDB\Driver\Query::__construct(): comment option bsonSerialize() exception
+--FILE--
+<?php
+
+require_once __DIR__ . "/../utils/basic.inc";
+
+class Comment implements MongoDB\BSON\Serializable
+{
+ public function bsonSerialize(): array
+ {
+ throw new Exception('php_phongo_zval_to_bson_value fails');
+ }
+}
+
+echo throws(function() {
+ new MongoDB\Driver\Query([], ['comment' => new Comment()]);
+}, Exception::class), "\n";
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+OK: Got Exception
+php_phongo_zval_to_bson_value fails
+===DONE===
diff --git a/mongodb-1.13.0/tests/bulk/bulkwrite-update-004.phpt b/mongodb-1.14.0/tests/query/query-ctor-let-001.phpt
similarity index 51%
rename from mongodb-1.13.0/tests/bulk/bulkwrite-update-004.phpt
rename to mongodb-1.14.0/tests/query/query-ctor-let-001.phpt
index d242b9f8..14a3a88f 100644
--- a/mongodb-1.13.0/tests/bulk/bulkwrite-update-004.phpt
+++ b/mongodb-1.14.0/tests/query/query-ctor-let-001.phpt
@@ -1,55 +1,65 @@
--TEST--
-MongoDB\Driver\BulkWrite::update() with hint option
+MongoDB\Driver\Query::__construct(): let option
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
-<?php skip_if_server_version('<', '4.2'); ?>
+<?php skip_if_server_version('<', '5.0'); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
+
require_once __DIR__ . "/../utils/basic.inc";
class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
{
- if ($event->getCommandName() !== 'update') {
+ $command = $event->getCommand();
+
+ if (!isset($command->let)) {
+ printf("%s does not include let option\n", $event->getCommandName());
+
return;
}
- printf("update included hint: %s\n", json_encode($event->getCommand()->updates[0]->hint));
+ printf("%s included let: %s\n", $event->getCommandName(), json_encode($command->let));
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
{
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
{
}
}
$manager = create_test_manager();
-$bulk = new MongoDB\Driver\BulkWrite();
-$bulk->insert(['x' => 1]);
-$bulk->insert(['x' => 2]);
-$manager->executeBulkWrite(NS, $bulk);
-
-MongoDB\Driver\Monitoring\addSubscriber(new CommandLogger);
-
$bulk = new MongoDB\Driver\BulkWrite;
-$bulk->update(['_id' => 1], ['$set' => ['x' => 11]], ['hint' => '_id_']);
+$bulk->insert(['_id' => 1]);
+$bulk->insert(['_id' => 2]);
$manager->executeBulkWrite(NS, $bulk);
-$bulk = new MongoDB\Driver\BulkWrite;
-$bulk->update(['_id' => 2], ['$set' => ['x' => 22]], ['hint' => ['_id' => 1]]);
-$manager->executeBulkWrite(NS, $bulk);
+$query = new MongoDB\Driver\Query(
+ ['$expr' => ['$eq' => ['$_id', '$$id']]],
+ ['let' => ['id' => 1]]
+);
+
+$manager->addSubscriber(new CommandLogger);
+$cursor = $manager->executeQuery(NS, $query);
+var_dump($cursor->toArray());
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
-update included hint: "_id_"
-update included hint: {"_id":1}
+find included let: {"id":1}
+array(1) {
+ [0]=>
+ object(stdClass)#%d (%d) {
+ ["_id"]=>
+ int(1)
+ }
+}
===DONE===
diff --git a/mongodb-1.14.0/tests/query/query-ctor-let_error-001.phpt b/mongodb-1.14.0/tests/query/query-ctor-let_error-001.phpt
new file mode 100644
index 00000000..bb5599cd
--- /dev/null
+++ b/mongodb-1.14.0/tests/query/query-ctor-let_error-001.phpt
@@ -0,0 +1,28 @@
+--TEST--
+MongoDB\Driver\Query::__construct(): let option invalid type
+--FILE--
+<?php
+
+require_once __DIR__ . '/../utils/basic.inc';
+
+$invalidValues = [true, 1, 'string', null];
+
+foreach ($invalidValues as $invalidValue) {
+ echo throws(function() use ($invalidValue) {
+ new MongoDB\Driver\Query([], ['let' => $invalidValue]);
+ }, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, %r(bool|boolean)%r given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, %r(int|integer)%r given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, string given
+OK: Got MongoDB\Driver\Exception\InvalidArgumentException
+Expected "let" option to be array or object, null given
+===DONE===
diff --git a/mongodb-1.13.0/tests/query/query-ctor_error-001.phpt b/mongodb-1.14.0/tests/query/query-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor_error-001.phpt
rename to mongodb-1.14.0/tests/query/query-ctor_error-001.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor_error-002.phpt b/mongodb-1.14.0/tests/query/query-ctor_error-002.phpt
similarity index 87%
rename from mongodb-1.13.0/tests/query/query-ctor_error-002.phpt
rename to mongodb-1.14.0/tests/query/query-ctor_error-002.phpt
index 2a18d50e..d92be199 100644
--- a/mongodb-1.13.0/tests/query/query-ctor_error-002.phpt
+++ b/mongodb-1.14.0/tests/query/query-ctor_error-002.phpt
@@ -1,73 +1,65 @@
--TEST--
MongoDB\Driver\Query construction (invalid option types)
--FILE--
<?php
require_once __DIR__ . '/../utils/basic.inc';
$tests = [
['modifiers' => 0],
['collation' => 0],
- ['comment' => 0],
['hint' => 0],
['max' => 0],
['min' => 0],
['projection' => 0],
['sort' => 0],
- ['modifiers' => ['$comment' => 0]],
['modifiers' => ['$hint' => 0]],
['modifiers' => ['$max' => 0]],
['modifiers' => ['$min' => 0]],
['modifiers' => ['$orderby' => 0]],
];
foreach ($tests as $options) {
echo throws(function() use ($options) {
new MongoDB\Driver\Query([], $options);
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "modifiers" option to be array, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "collation" option to be array or object, int%S given
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "comment" option to be string, int%S given
-
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "hint" option to be string, array, or object, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "max" option to be array or object, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "min" option to be array or object, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "projection" option to be array or object, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "sort" option to be array or object, int%S given
-OK: Got MongoDB\Driver\Exception\InvalidArgumentException
-Expected "$comment" modifier to be string, int%S given
-
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "$hint" modifier to be string, array, or object, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "$max" modifier to be array or object, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "$min" modifier to be array or object, int%S given
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected "$orderby" modifier to be array or object, int%S given
===DONE===
diff --git a/mongodb-1.13.0/tests/query/query-ctor_error-003.phpt b/mongodb-1.14.0/tests/query/query-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor_error-003.phpt
rename to mongodb-1.14.0/tests/query/query-ctor_error-003.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor_error-004.phpt b/mongodb-1.14.0/tests/query/query-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor_error-004.phpt
rename to mongodb-1.14.0/tests/query/query-ctor_error-004.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor_error-005.phpt b/mongodb-1.14.0/tests/query/query-ctor_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor_error-005.phpt
rename to mongodb-1.14.0/tests/query/query-ctor_error-005.phpt
diff --git a/mongodb-1.13.0/tests/query/query-ctor_error-006.phpt b/mongodb-1.14.0/tests/query/query-ctor_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-ctor_error-006.phpt
rename to mongodb-1.14.0/tests/query/query-ctor_error-006.phpt
diff --git a/mongodb-1.13.0/tests/query/query-debug-001.phpt b/mongodb-1.14.0/tests/query/query-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query-debug-001.phpt
rename to mongodb-1.14.0/tests/query/query-debug-001.phpt
diff --git a/mongodb-1.14.0/tests/query/query-debug-002.phpt b/mongodb-1.14.0/tests/query/query-debug-002.phpt
new file mode 100644
index 00000000..a73dd25b
--- /dev/null
+++ b/mongodb-1.14.0/tests/query/query-debug-002.phpt
@@ -0,0 +1,40 @@
+--TEST--
+MongoDB\Driver\Query debug output with let option
+--FILE--
+<?php
+
+var_dump(new MongoDB\Driver\Query(
+ ['$expr' => ['$eq' => ['$_id', '$$id']]],
+ ['let' => ['id' => 1]]
+));
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+object(MongoDB\Driver\Query)#%d (%d) {
+ ["filter"]=>
+ object(stdClass)#%d (%d) {
+ ["$expr"]=>
+ object(stdClass)#%d (%d) {
+ ["$eq"]=>
+ array(2) {
+ [0]=>
+ string(4) "$_id"
+ [1]=>
+ string(4) "$$id"
+ }
+ }
+ }
+ ["options"]=>
+ object(stdClass)#%d (%d) {
+ ["let"]=>
+ object(stdClass)#%d (%d) {
+ ["id"]=>
+ int(1)
+ }
+ }
+ ["readConcern"]=>
+ NULL
+}
+===DONE===
diff --git a/mongodb-1.13.0/tests/query/query-ctor-005.phpt b/mongodb-1.14.0/tests/query/query-debug-003.phpt
similarity index 51%
rename from mongodb-1.13.0/tests/query/query-ctor-005.phpt
rename to mongodb-1.14.0/tests/query/query-debug-003.phpt
index e206d731..dee480a8 100644
--- a/mongodb-1.13.0/tests/query/query-ctor-005.phpt
+++ b/mongodb-1.14.0/tests/query/query-debug-003.phpt
@@ -1,55 +1,50 @@
--TEST--
-MongoDB\Driver\Query construction with negative limit
+MongoDB\Driver\Query debug output with comment option
--FILE--
<?php
var_dump(new MongoDB\Driver\Query(
- ['x' => 1],
- ['limit' => -5]
+ [],
+ ['comment' => ['foo' => 1]]
));
var_dump(new MongoDB\Driver\Query(
- ['x' => 1],
- [
- 'limit' => -5,
- 'singleBatch' => true
- ]
+ [],
+ ['modifiers' => ['$comment' => ['foo' => 1]]]
));
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\Driver\Query)#%d (%d) {
["filter"]=>
- object(stdClass)#%d (%d) {
- ["x"]=>
- int(1)
+ object(stdClass)#%d (0) {
}
["options"]=>
object(stdClass)#%d (%d) {
- ["limit"]=>
- int(5)
- ["singleBatch"]=>
- bool(true)
+ ["comment"]=>
+ object(stdClass)#%d (%d) {
+ ["foo"]=>
+ int(1)
+ }
}
["readConcern"]=>
NULL
}
object(MongoDB\Driver\Query)#%d (%d) {
["filter"]=>
- object(stdClass)#%d (%d) {
- ["x"]=>
- int(1)
+ object(stdClass)#%d (0) {
}
["options"]=>
object(stdClass)#%d (%d) {
- ["limit"]=>
- int(5)
- ["singleBatch"]=>
- bool(true)
+ ["comment"]=>
+ object(stdClass)#%d (%d) {
+ ["foo"]=>
+ int(1)
+ }
}
["readConcern"]=>
NULL
}
===DONE===
diff --git a/mongodb-1.13.0/tests/query/query_error-001.phpt b/mongodb-1.14.0/tests/query/query_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/query/query_error-001.phpt
rename to mongodb-1.14.0/tests/query/query_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/bug1598-001.phpt b/mongodb-1.14.0/tests/readConcern/bug1598-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/bug1598-001.phpt
rename to mongodb-1.14.0/tests/readConcern/bug1598-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/bug1598-002.phpt b/mongodb-1.14.0/tests/readConcern/bug1598-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/bug1598-002.phpt
rename to mongodb-1.14.0/tests/readConcern/bug1598-002.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-bsonserialize-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-bsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-bsonserialize-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-bsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-bsonserialize-002.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-bsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-bsonserialize-002.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-bsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-constants.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-constants.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-constants.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-constants.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-ctor-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-ctor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-ctor-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-ctor-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-ctor_error-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-ctor_error-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-ctor_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-ctor_error-002.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-ctor_error-002.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-ctor_error-002.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-debug-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-debug-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-getlevel-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-getlevel-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-getlevel-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-getlevel-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-isdefault-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-isdefault-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-isdefault-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-isdefault-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-serialization-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-serialization-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-serialization-002.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-serialization-002.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-serialization_error-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-serialization_error-002.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-set_state-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-set_state-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-set_state_error-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern-var_export-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern-var_export-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern-var_export-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern-var_export-001.phpt
diff --git a/mongodb-1.13.0/tests/readConcern/readconcern_error-001.phpt b/mongodb-1.14.0/tests/readConcern/readconcern_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readConcern/readconcern_error-001.phpt
rename to mongodb-1.14.0/tests/readConcern/readconcern_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/bug0146-001.phpt b/mongodb-1.14.0/tests/readPreference/bug0146-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/bug0146-001.phpt
rename to mongodb-1.14.0/tests/readPreference/bug0146-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/bug0851-001.phpt b/mongodb-1.14.0/tests/readPreference/bug0851-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/bug0851-001.phpt
rename to mongodb-1.14.0/tests/readPreference/bug0851-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/bug1598-001.phpt b/mongodb-1.14.0/tests/readPreference/bug1598-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/bug1598-001.phpt
rename to mongodb-1.14.0/tests/readPreference/bug1598-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/bug1598-002.phpt b/mongodb-1.14.0/tests/readPreference/bug1598-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/bug1598-002.phpt
rename to mongodb-1.14.0/tests/readPreference/bug1598-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/bug1698-001.phpt b/mongodb-1.14.0/tests/readPreference/bug1698-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/bug1698-001.phpt
rename to mongodb-1.14.0/tests/readPreference/bug1698-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-bsonserialize-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-bsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-bsonserialize-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-bsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-bsonserialize-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-bsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-bsonserialize-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-bsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-constants.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-constants.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-constants.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-constants.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-003.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-003.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-003.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-004.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-004.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-004.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-005.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-005.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-005.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-006.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-006.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-006.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-007.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-ctor_error-007.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-ctor_error-007.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-debug-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-debug-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-getHedge-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-getHedge-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-getHedge-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-getHedge-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-getMode-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-getMode-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-getMode-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-getMode-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-getModeString-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-getModeString-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-getModeString-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-getModeString-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-getTagSets-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-getTagSets-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-getTagSets-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-getTagSets-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-getTagSets-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-getTagSets-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-getTagSets-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-getTagSets-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-serialization-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-serialization-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-serialization-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-serialization-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-serialization_error-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-serialization_error-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-set_state-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-set_state-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-set_state_error-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-set_state_error-002.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-set_state_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-set_state_error-002.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-set_state_error-002.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference-var_export-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference-var_export-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference-var_export-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference-var_export-001.phpt
diff --git a/mongodb-1.13.0/tests/readPreference/readpreference_error-001.phpt b/mongodb-1.14.0/tests/readPreference/readpreference_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/readPreference/readpreference_error-001.phpt
rename to mongodb-1.14.0/tests/readPreference/readpreference_error-001.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/bug0155.phpt b/mongodb-1.14.0/tests/replicaset/bug0155.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/bug0155.phpt
rename to mongodb-1.14.0/tests/replicaset/bug0155.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/bug0898-001.phpt b/mongodb-1.14.0/tests/replicaset/bug0898-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/bug0898-001.phpt
rename to mongodb-1.14.0/tests/replicaset/bug0898-001.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/bug0898-002.phpt b/mongodb-1.14.0/tests/replicaset/bug0898-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/bug0898-002.phpt
rename to mongodb-1.14.0/tests/replicaset/bug0898-002.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/manager-selectserver-001.phpt b/mongodb-1.14.0/tests/replicaset/manager-selectserver-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/manager-selectserver-001.phpt
rename to mongodb-1.14.0/tests/replicaset/manager-selectserver-001.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/readconcern-001.phpt b/mongodb-1.14.0/tests/replicaset/readconcern-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/readconcern-001.phpt
rename to mongodb-1.14.0/tests/replicaset/readconcern-001.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/writeconcernerror-001.phpt b/mongodb-1.14.0/tests/replicaset/writeconcernerror-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/writeconcernerror-001.phpt
rename to mongodb-1.14.0/tests/replicaset/writeconcernerror-001.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/writeconcernerror-002.phpt b/mongodb-1.14.0/tests/replicaset/writeconcernerror-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/writeconcernerror-002.phpt
rename to mongodb-1.14.0/tests/replicaset/writeconcernerror-002.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/writeresult-getserver-001.phpt b/mongodb-1.14.0/tests/replicaset/writeresult-getserver-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/writeresult-getserver-001.phpt
rename to mongodb-1.14.0/tests/replicaset/writeresult-getserver-001.phpt
diff --git a/mongodb-1.13.0/tests/replicaset/writeresult-getserver-002.phpt b/mongodb-1.14.0/tests/replicaset/writeresult-getserver-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/replicaset/writeresult-getserver-002.phpt
rename to mongodb-1.14.0/tests/replicaset/writeresult-getserver-002.phpt
diff --git a/mongodb-1.13.0/tests/retryable-reads/retryable-reads-001.phpt b/mongodb-1.14.0/tests/retryable-reads/retryable-reads-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-reads/retryable-reads-001.phpt
rename to mongodb-1.14.0/tests/retryable-reads/retryable-reads-001.phpt
diff --git a/mongodb-1.13.0/tests/retryable-reads/retryable-reads-002.phpt b/mongodb-1.14.0/tests/retryable-reads/retryable-reads-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-reads/retryable-reads-002.phpt
rename to mongodb-1.14.0/tests/retryable-reads/retryable-reads-002.phpt
diff --git a/mongodb-1.13.0/tests/retryable-reads/retryable-reads_error-001.phpt b/mongodb-1.14.0/tests/retryable-reads/retryable-reads_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-reads/retryable-reads_error-001.phpt
rename to mongodb-1.14.0/tests/retryable-reads/retryable-reads_error-001.phpt
diff --git a/mongodb-1.13.0/tests/retryable-reads/retryable-reads_error-002.phpt b/mongodb-1.14.0/tests/retryable-reads/retryable-reads_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-reads/retryable-reads_error-002.phpt
rename to mongodb-1.14.0/tests/retryable-reads/retryable-reads_error-002.phpt
diff --git a/mongodb-1.13.0/tests/retryable-writes/retryable-writes-001.phpt b/mongodb-1.14.0/tests/retryable-writes/retryable-writes-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-writes/retryable-writes-001.phpt
rename to mongodb-1.14.0/tests/retryable-writes/retryable-writes-001.phpt
diff --git a/mongodb-1.13.0/tests/retryable-writes/retryable-writes-002.phpt b/mongodb-1.14.0/tests/retryable-writes/retryable-writes-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-writes/retryable-writes-002.phpt
rename to mongodb-1.14.0/tests/retryable-writes/retryable-writes-002.phpt
diff --git a/mongodb-1.13.0/tests/retryable-writes/retryable-writes-003.phpt b/mongodb-1.14.0/tests/retryable-writes/retryable-writes-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-writes/retryable-writes-003.phpt
rename to mongodb-1.14.0/tests/retryable-writes/retryable-writes-003.phpt
diff --git a/mongodb-1.13.0/tests/retryable-writes/retryable-writes-004.phpt b/mongodb-1.14.0/tests/retryable-writes/retryable-writes-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-writes/retryable-writes-004.phpt
rename to mongodb-1.14.0/tests/retryable-writes/retryable-writes-004.phpt
diff --git a/mongodb-1.13.0/tests/retryable-writes/retryable-writes-005.phpt b/mongodb-1.14.0/tests/retryable-writes/retryable-writes-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-writes/retryable-writes-005.phpt
rename to mongodb-1.14.0/tests/retryable-writes/retryable-writes-005.phpt
diff --git a/mongodb-1.13.0/tests/retryable-writes/retryable-writes_error-001.phpt b/mongodb-1.14.0/tests/retryable-writes/retryable-writes_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/retryable-writes/retryable-writes_error-001.phpt
rename to mongodb-1.14.0/tests/retryable-writes/retryable-writes_error-001.phpt
diff --git a/mongodb-1.13.0/tests/server/bug0671-002.phpt b/mongodb-1.14.0/tests/server/bug0671-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/bug0671-002.phpt
rename to mongodb-1.14.0/tests/server/bug0671-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-constants.phpt b/mongodb-1.14.0/tests/server/server-constants.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-constants.phpt
rename to mongodb-1.14.0/tests/server/server-constants.phpt
diff --git a/mongodb-1.13.0/tests/server/server-construct-001.phpt b/mongodb-1.14.0/tests/server/server-construct-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-construct-001.phpt
rename to mongodb-1.14.0/tests/server/server-construct-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-debug.phpt b/mongodb-1.14.0/tests/server/server-debug.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-debug.phpt
rename to mongodb-1.14.0/tests/server/server-debug.phpt
diff --git a/mongodb-1.13.0/tests/server/server-errors.phpt b/mongodb-1.14.0/tests/server/server-errors.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-errors.phpt
rename to mongodb-1.14.0/tests/server/server-errors.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-001.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-002.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-002.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-003.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-003.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-003.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-004.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-004.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-004.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-005.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-005.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-005.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-006.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-006.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-006.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-007.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-007.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-007.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-008.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-008.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-008.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite-009.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite-009.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite-009.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite_error-001.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite_error-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite_error-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeBulkWrite_error-002.phpt b/mongodb-1.14.0/tests/server/server-executeBulkWrite_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeBulkWrite_error-002.phpt
rename to mongodb-1.14.0/tests/server/server-executeBulkWrite_error-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-001.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-002.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-002.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-003.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-003.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-004.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-004.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-004.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-005.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-005.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-005.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-006.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-006.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-006.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-007.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-007.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-007.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-008.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-008.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-008.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-009.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-009.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-009.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand-010.phpt b/mongodb-1.14.0/tests/server/server-executeCommand-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand-010.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand-010.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeCommand_error-001.phpt b/mongodb-1.14.0/tests/server/server-executeCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeCommand_error-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-001.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-002.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-002.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-003.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-003.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-003.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-004.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-004.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-004.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-006.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-006.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-006.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-007.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-007.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-007.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-008.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-008.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-008.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-008.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-009.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-009.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-009.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-009.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-010.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-010.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-010.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-010.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-011.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-011.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-011.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-011.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-012.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-012.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-012.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-012.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery-013.phpt b/mongodb-1.14.0/tests/server/server-executeQuery-013.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery-013.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery-013.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeQuery_error-001.phpt b/mongodb-1.14.0/tests/server/server-executeQuery_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeQuery_error-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeQuery_error-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadCommand-001.phpt b/mongodb-1.14.0/tests/server/server-executeReadCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadCommand-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadCommand-002.phpt b/mongodb-1.14.0/tests/server/server-executeReadCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadCommand-002.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadCommand-003.phpt b/mongodb-1.14.0/tests/server/server-executeReadCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadCommand-003.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadCommand_error-001.phpt b/mongodb-1.14.0/tests/server/server-executeReadCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadCommand_error-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadWriteCommand-001.phpt b/mongodb-1.14.0/tests/server/server-executeReadWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadWriteCommand-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadWriteCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadWriteCommand-002.phpt b/mongodb-1.14.0/tests/server/server-executeReadWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadWriteCommand-002.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadWriteCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadWriteCommand-003.phpt b/mongodb-1.14.0/tests/server/server-executeReadWriteCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadWriteCommand-003.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadWriteCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeReadWriteCommand_error-001.phpt b/mongodb-1.14.0/tests/server/server-executeReadWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeReadWriteCommand_error-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeReadWriteCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeWriteCommand-001.phpt b/mongodb-1.14.0/tests/server/server-executeWriteCommand-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeWriteCommand-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeWriteCommand-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeWriteCommand-002.phpt b/mongodb-1.14.0/tests/server/server-executeWriteCommand-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeWriteCommand-002.phpt
rename to mongodb-1.14.0/tests/server/server-executeWriteCommand-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeWriteCommand-003.phpt b/mongodb-1.14.0/tests/server/server-executeWriteCommand-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeWriteCommand-003.phpt
rename to mongodb-1.14.0/tests/server/server-executeWriteCommand-003.phpt
diff --git a/mongodb-1.13.0/tests/server/server-executeWriteCommand_error-001.phpt b/mongodb-1.14.0/tests/server/server-executeWriteCommand_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-executeWriteCommand_error-001.phpt
rename to mongodb-1.14.0/tests/server/server-executeWriteCommand_error-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-getInfo-001.phpt b/mongodb-1.14.0/tests/server/server-getInfo-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-getInfo-001.phpt
rename to mongodb-1.14.0/tests/server/server-getInfo-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-getLatency-001.phpt b/mongodb-1.14.0/tests/server/server-getLatency-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-getLatency-001.phpt
rename to mongodb-1.14.0/tests/server/server-getLatency-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-getLatency-002.phpt b/mongodb-1.14.0/tests/server/server-getLatency-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-getLatency-002.phpt
rename to mongodb-1.14.0/tests/server/server-getLatency-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server-getServerDescription-001.phpt b/mongodb-1.14.0/tests/server/server-getServerDescription-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-getServerDescription-001.phpt
rename to mongodb-1.14.0/tests/server/server-getServerDescription-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-getTags-001.phpt b/mongodb-1.14.0/tests/server/server-getTags-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-getTags-001.phpt
rename to mongodb-1.14.0/tests/server/server-getTags-001.phpt
diff --git a/mongodb-1.13.0/tests/server/server-getTags-002.phpt b/mongodb-1.14.0/tests/server/server-getTags-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server-getTags-002.phpt
rename to mongodb-1.14.0/tests/server/server-getTags-002.phpt
diff --git a/mongodb-1.13.0/tests/server/server_error-001.phpt b/mongodb-1.14.0/tests/server/server_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/server/server_error-001.phpt
rename to mongodb-1.14.0/tests/server/server_error-001.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-bsonserialize-001.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-bsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-bsonserialize-001.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-bsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-bsonserialize-002.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-bsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-bsonserialize-002.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-bsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-construct-001.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-construct-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-construct-001.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-construct-001.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-debug.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-debug.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-debug.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-debug.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-serialization-001.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-serialization-001.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-serialization-002.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-serialization-002.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-serialization_error-001.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-serialization_error-002.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-set_state-001.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-set_state-001.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-set_state_error-001.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/serverApi/serverApi-var_export-001.phpt b/mongodb-1.14.0/tests/serverApi/serverApi-var_export-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverApi/serverApi-var_export-001.phpt
rename to mongodb-1.14.0/tests/serverApi/serverApi-var_export-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-constants.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-constants.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-constants.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-constants.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-debug-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-debug-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-getHelloResponse-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-getHelloResponse-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-getHelloResponse-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-getHelloResponse-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-getHost-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-getHost-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-getHost-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-getHost-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-getLastUpdateTime-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-getLastUpdateTime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-getLastUpdateTime-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-getLastUpdateTime-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-getLastUpdateTime-002.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-getLastUpdateTime-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-getLastUpdateTime-002.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-getLastUpdateTime-002.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-getPort-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-getPort-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-getPort-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-getPort-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-getRoundTripTime-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-getRoundTripTime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-getRoundTripTime-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-getRoundTripTime-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-getType-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-getType-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-getType-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-getType-001.phpt
diff --git a/mongodb-1.13.0/tests/serverDescription/serverDescription-var_export-001.phpt b/mongodb-1.14.0/tests/serverDescription/serverDescription-var_export-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/serverDescription/serverDescription-var_export-001.phpt
rename to mongodb-1.14.0/tests/serverDescription/serverDescription-var_export-001.phpt
diff --git a/mongodb-1.13.0/tests/session/bug1274-001.phpt b/mongodb-1.14.0/tests/session/bug1274-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/bug1274-001.phpt
rename to mongodb-1.14.0/tests/session/bug1274-001.phpt
diff --git a/mongodb-1.13.0/tests/session/bug1274-002.phpt b/mongodb-1.14.0/tests/session/bug1274-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/bug1274-002.phpt
rename to mongodb-1.14.0/tests/session/bug1274-002.phpt
diff --git a/mongodb-1.13.0/tests/session/bug1274-003.phpt b/mongodb-1.14.0/tests/session/bug1274-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/bug1274-003.phpt
rename to mongodb-1.14.0/tests/session/bug1274-003.phpt
diff --git a/mongodb-1.13.0/tests/session/bug1274-004.phpt b/mongodb-1.14.0/tests/session/bug1274-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/bug1274-004.phpt
rename to mongodb-1.14.0/tests/session/bug1274-004.phpt
diff --git a/mongodb-1.13.0/tests/session/bug1274-005.phpt b/mongodb-1.14.0/tests/session/bug1274-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/bug1274-005.phpt
rename to mongodb-1.14.0/tests/session/bug1274-005.phpt
diff --git a/mongodb-1.13.0/tests/session/bug1274-006.phpt b/mongodb-1.14.0/tests/session/bug1274-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/bug1274-006.phpt
rename to mongodb-1.14.0/tests/session/bug1274-006.phpt
diff --git a/mongodb-1.13.0/tests/session/session-001.phpt b/mongodb-1.14.0/tests/session/session-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-001.phpt
rename to mongodb-1.14.0/tests/session/session-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-002.phpt b/mongodb-1.14.0/tests/session/session-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-002.phpt
rename to mongodb-1.14.0/tests/session/session-002.phpt
diff --git a/mongodb-1.13.0/tests/session/session-003.phpt b/mongodb-1.14.0/tests/session/session-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-003.phpt
rename to mongodb-1.14.0/tests/session/session-003.phpt
diff --git a/mongodb-1.13.0/tests/session/session-004.phpt b/mongodb-1.14.0/tests/session/session-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-004.phpt
rename to mongodb-1.14.0/tests/session/session-004.phpt
diff --git a/mongodb-1.13.0/tests/session/session-005.phpt b/mongodb-1.14.0/tests/session/session-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-005.phpt
rename to mongodb-1.14.0/tests/session/session-005.phpt
diff --git a/mongodb-1.13.0/tests/session/session-advanceClusterTime-001.phpt b/mongodb-1.14.0/tests/session/session-advanceClusterTime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-advanceClusterTime-001.phpt
rename to mongodb-1.14.0/tests/session/session-advanceClusterTime-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-advanceOperationTime-001.phpt b/mongodb-1.14.0/tests/session/session-advanceOperationTime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-advanceOperationTime-001.phpt
rename to mongodb-1.14.0/tests/session/session-advanceOperationTime-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-advanceOperationTime-002.phpt b/mongodb-1.14.0/tests/session/session-advanceOperationTime-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-advanceOperationTime-002.phpt
rename to mongodb-1.14.0/tests/session/session-advanceOperationTime-002.phpt
diff --git a/mongodb-1.13.0/tests/session/session-advanceOperationTime-003.phpt b/mongodb-1.14.0/tests/session/session-advanceOperationTime-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-advanceOperationTime-003.phpt
rename to mongodb-1.14.0/tests/session/session-advanceOperationTime-003.phpt
diff --git a/mongodb-1.13.0/tests/session/session-advanceOperationTime_error-001.phpt b/mongodb-1.14.0/tests/session/session-advanceOperationTime_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-advanceOperationTime_error-001.phpt
rename to mongodb-1.14.0/tests/session/session-advanceOperationTime_error-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-commitTransaction-001.phpt b/mongodb-1.14.0/tests/session/session-commitTransaction-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-commitTransaction-001.phpt
rename to mongodb-1.14.0/tests/session/session-commitTransaction-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-constants.phpt b/mongodb-1.14.0/tests/session/session-constants.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-constants.phpt
rename to mongodb-1.14.0/tests/session/session-constants.phpt
diff --git a/mongodb-1.13.0/tests/session/session-debug-001.phpt b/mongodb-1.14.0/tests/session/session-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-debug-001.phpt
rename to mongodb-1.14.0/tests/session/session-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-debug-002.phpt b/mongodb-1.14.0/tests/session/session-debug-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-debug-002.phpt
rename to mongodb-1.14.0/tests/session/session-debug-002.phpt
diff --git a/mongodb-1.13.0/tests/session/session-debug-003.phpt b/mongodb-1.14.0/tests/session/session-debug-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-debug-003.phpt
rename to mongodb-1.14.0/tests/session/session-debug-003.phpt
diff --git a/mongodb-1.13.0/tests/session/session-debug-004.phpt b/mongodb-1.14.0/tests/session/session-debug-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-debug-004.phpt
rename to mongodb-1.14.0/tests/session/session-debug-004.phpt
diff --git a/mongodb-1.13.0/tests/session/session-debug-005.phpt b/mongodb-1.14.0/tests/session/session-debug-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-debug-005.phpt
rename to mongodb-1.14.0/tests/session/session-debug-005.phpt
diff --git a/mongodb-1.13.0/tests/session/session-debug-006.phpt b/mongodb-1.14.0/tests/session/session-debug-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-debug-006.phpt
rename to mongodb-1.14.0/tests/session/session-debug-006.phpt
diff --git a/mongodb-1.13.0/tests/session/session-debug-007.phpt b/mongodb-1.14.0/tests/session/session-debug-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-debug-007.phpt
rename to mongodb-1.14.0/tests/session/session-debug-007.phpt
diff --git a/mongodb-1.13.0/tests/session/session-endSession-001.phpt b/mongodb-1.14.0/tests/session/session-endSession-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-endSession-001.phpt
rename to mongodb-1.14.0/tests/session/session-endSession-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-endSession-002.phpt b/mongodb-1.14.0/tests/session/session-endSession-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-endSession-002.phpt
rename to mongodb-1.14.0/tests/session/session-endSession-002.phpt
diff --git a/mongodb-1.13.0/tests/session/session-getClusterTime-001.phpt b/mongodb-1.14.0/tests/session/session-getClusterTime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-getClusterTime-001.phpt
rename to mongodb-1.14.0/tests/session/session-getClusterTime-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-getLogicalSessionId-001.phpt b/mongodb-1.14.0/tests/session/session-getLogicalSessionId-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-getLogicalSessionId-001.phpt
rename to mongodb-1.14.0/tests/session/session-getLogicalSessionId-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-getOperationTime-001.phpt b/mongodb-1.14.0/tests/session/session-getOperationTime-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-getOperationTime-001.phpt
rename to mongodb-1.14.0/tests/session/session-getOperationTime-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-getTransactionOptions-001.phpt b/mongodb-1.14.0/tests/session/session-getTransactionOptions-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-getTransactionOptions-001.phpt
rename to mongodb-1.14.0/tests/session/session-getTransactionOptions-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-getTransactionState-001.phpt b/mongodb-1.14.0/tests/session/session-getTransactionState-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-getTransactionState-001.phpt
rename to mongodb-1.14.0/tests/session/session-getTransactionState-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-isDirty-001.phpt b/mongodb-1.14.0/tests/session/session-isDirty-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-isDirty-001.phpt
rename to mongodb-1.14.0/tests/session/session-isDirty-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-isInTransaction-001.phpt b/mongodb-1.14.0/tests/session/session-isInTransaction-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-isInTransaction-001.phpt
rename to mongodb-1.14.0/tests/session/session-isInTransaction-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-startTransaction-001.phpt b/mongodb-1.14.0/tests/session/session-startTransaction-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-startTransaction-001.phpt
rename to mongodb-1.14.0/tests/session/session-startTransaction-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-startTransaction_error-001.phpt b/mongodb-1.14.0/tests/session/session-startTransaction_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-startTransaction_error-001.phpt
rename to mongodb-1.14.0/tests/session/session-startTransaction_error-001.phpt
diff --git a/mongodb-1.13.0/tests/session/session-startTransaction_error-002.phpt b/mongodb-1.14.0/tests/session/session-startTransaction_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-startTransaction_error-002.phpt
rename to mongodb-1.14.0/tests/session/session-startTransaction_error-002.phpt
diff --git a/mongodb-1.13.0/tests/session/session-startTransaction_error-004.phpt b/mongodb-1.14.0/tests/session/session-startTransaction_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-startTransaction_error-004.phpt
rename to mongodb-1.14.0/tests/session/session-startTransaction_error-004.phpt
diff --git a/mongodb-1.13.0/tests/session/session-startTransaction_error-005.phpt b/mongodb-1.14.0/tests/session/session-startTransaction_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-startTransaction_error-005.phpt
rename to mongodb-1.14.0/tests/session/session-startTransaction_error-005.phpt
diff --git a/mongodb-1.13.0/tests/session/session-startTransaction_error-006.phpt b/mongodb-1.14.0/tests/session/session-startTransaction_error-006.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-startTransaction_error-006.phpt
rename to mongodb-1.14.0/tests/session/session-startTransaction_error-006.phpt
diff --git a/mongodb-1.13.0/tests/session/session-startTransaction_error-007.phpt b/mongodb-1.14.0/tests/session/session-startTransaction_error-007.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/session-startTransaction_error-007.phpt
rename to mongodb-1.14.0/tests/session/session-startTransaction_error-007.phpt
diff --git a/mongodb-1.13.0/tests/session/transaction-integration-001.phpt b/mongodb-1.14.0/tests/session/transaction-integration-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/transaction-integration-001.phpt
rename to mongodb-1.14.0/tests/session/transaction-integration-001.phpt
diff --git a/mongodb-1.13.0/tests/session/transaction-integration-002.phpt b/mongodb-1.14.0/tests/session/transaction-integration-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/transaction-integration-002.phpt
rename to mongodb-1.14.0/tests/session/transaction-integration-002.phpt
diff --git a/mongodb-1.13.0/tests/session/transaction-integration-003.phpt b/mongodb-1.14.0/tests/session/transaction-integration-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/transaction-integration-003.phpt
rename to mongodb-1.14.0/tests/session/transaction-integration-003.phpt
diff --git a/mongodb-1.13.0/tests/session/transaction-integration_error-001.phpt b/mongodb-1.14.0/tests/session/transaction-integration_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/transaction-integration_error-001.phpt
rename to mongodb-1.14.0/tests/session/transaction-integration_error-001.phpt
diff --git a/mongodb-1.13.0/tests/session/transaction-integration_error-002.phpt b/mongodb-1.14.0/tests/session/transaction-integration_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/transaction-integration_error-002.phpt
rename to mongodb-1.14.0/tests/session/transaction-integration_error-002.phpt
diff --git a/mongodb-1.13.0/tests/session/transaction-integration_error-003.phpt b/mongodb-1.14.0/tests/session/transaction-integration_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/transaction-integration_error-003.phpt
rename to mongodb-1.14.0/tests/session/transaction-integration_error-003.phpt
diff --git a/mongodb-1.13.0/tests/session/transaction-integration_error-004.phpt b/mongodb-1.14.0/tests/session/transaction-integration_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/session/transaction-integration_error-004.phpt
rename to mongodb-1.14.0/tests/session/transaction-integration_error-004.phpt
diff --git a/mongodb-1.13.0/tests/standalone/bug0166.phpt b/mongodb-1.14.0/tests/standalone/bug0166.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/bug0166.phpt
rename to mongodb-1.14.0/tests/standalone/bug0166.phpt
diff --git a/mongodb-1.13.0/tests/standalone/bug0231.phpt b/mongodb-1.14.0/tests/standalone/bug0231.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/bug0231.phpt
rename to mongodb-1.14.0/tests/standalone/bug0231.phpt
diff --git a/mongodb-1.13.0/tests/standalone/bug0357.phpt b/mongodb-1.14.0/tests/standalone/bug0357.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/bug0357.phpt
rename to mongodb-1.14.0/tests/standalone/bug0357.phpt
diff --git a/mongodb-1.13.0/tests/standalone/bug0545.phpt b/mongodb-1.14.0/tests/standalone/bug0545.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/bug0545.phpt
rename to mongodb-1.14.0/tests/standalone/bug0545.phpt
diff --git a/mongodb-1.13.0/tests/standalone/bug0655.phpt b/mongodb-1.14.0/tests/standalone/bug0655.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/bug0655.phpt
rename to mongodb-1.14.0/tests/standalone/bug0655.phpt
diff --git a/mongodb-1.13.0/tests/standalone/command-aggregate-001.phpt b/mongodb-1.14.0/tests/standalone/command-aggregate-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/command-aggregate-001.phpt
rename to mongodb-1.14.0/tests/standalone/command-aggregate-001.phpt
diff --git a/mongodb-1.13.0/tests/standalone/connectiontimeoutexception-001.phpt b/mongodb-1.14.0/tests/standalone/connectiontimeoutexception-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/connectiontimeoutexception-001.phpt
rename to mongodb-1.14.0/tests/standalone/connectiontimeoutexception-001.phpt
diff --git a/mongodb-1.13.0/tests/standalone/executiontimeoutexception-001.phpt b/mongodb-1.14.0/tests/standalone/executiontimeoutexception-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/executiontimeoutexception-001.phpt
rename to mongodb-1.14.0/tests/standalone/executiontimeoutexception-001.phpt
diff --git a/mongodb-1.13.0/tests/standalone/executiontimeoutexception-002.phpt b/mongodb-1.14.0/tests/standalone/executiontimeoutexception-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/executiontimeoutexception-002.phpt
rename to mongodb-1.14.0/tests/standalone/executiontimeoutexception-002.phpt
diff --git a/mongodb-1.13.0/tests/standalone/manager-as-singleton.phpt b/mongodb-1.14.0/tests/standalone/manager-as-singleton.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/manager-as-singleton.phpt
rename to mongodb-1.14.0/tests/standalone/manager-as-singleton.phpt
diff --git a/mongodb-1.13.0/tests/standalone/query-errors.phpt b/mongodb-1.14.0/tests/standalone/query-errors.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/query-errors.phpt
rename to mongodb-1.14.0/tests/standalone/query-errors.phpt
diff --git a/mongodb-1.13.0/tests/standalone/update-multi-001.phpt b/mongodb-1.14.0/tests/standalone/update-multi-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/update-multi-001.phpt
rename to mongodb-1.14.0/tests/standalone/update-multi-001.phpt
diff --git a/mongodb-1.13.0/tests/standalone/write-error-001.phpt b/mongodb-1.14.0/tests/standalone/write-error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/write-error-001.phpt
rename to mongodb-1.14.0/tests/standalone/write-error-001.phpt
diff --git a/mongodb-1.13.0/tests/standalone/writeresult-isacknowledged-001.phpt b/mongodb-1.14.0/tests/standalone/writeresult-isacknowledged-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/writeresult-isacknowledged-001.phpt
rename to mongodb-1.14.0/tests/standalone/writeresult-isacknowledged-001.phpt
diff --git a/mongodb-1.13.0/tests/standalone/writeresult-isacknowledged-002.phpt b/mongodb-1.14.0/tests/standalone/writeresult-isacknowledged-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/writeresult-isacknowledged-002.phpt
rename to mongodb-1.14.0/tests/standalone/writeresult-isacknowledged-002.phpt
diff --git a/mongodb-1.13.0/tests/standalone/writeresult-isacknowledged-003.phpt b/mongodb-1.14.0/tests/standalone/writeresult-isacknowledged-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/standalone/writeresult-isacknowledged-003.phpt
rename to mongodb-1.14.0/tests/standalone/writeresult-isacknowledged-003.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-constants.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-constants.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-constants.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-constants.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-debug-001.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-debug-001.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-getServers-001.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-getServers-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-getServers-001.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-getServers-001.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-getType-001.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-getType-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-getType-001.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-getType-001.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasReadableServer-001.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasReadableServer-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasReadableServer-001.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasReadableServer-001.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasReadableServer-002.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasReadableServer-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasReadableServer-002.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasReadableServer-002.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasReadableServer_error-001.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasReadableServer_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasReadableServer_error-001.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasReadableServer_error-001.phpt
diff --git a/mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasWritableServer-001.phpt b/mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasWritableServer-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/topologyDescription/topologyDescription-hasWritableServer-001.phpt
rename to mongodb-1.14.0/tests/topologyDescription/topologyDescription-hasWritableServer-001.phpt
diff --git a/mongodb-1.13.0/tests/utils/PHONGO-FIXTURES.json.gz b/mongodb-1.14.0/tests/utils/PHONGO-FIXTURES.json.gz
similarity index 100%
rename from mongodb-1.13.0/tests/utils/PHONGO-FIXTURES.json.gz
rename to mongodb-1.14.0/tests/utils/PHONGO-FIXTURES.json.gz
diff --git a/mongodb-1.13.0/tests/utils/basic-skipif.inc b/mongodb-1.14.0/tests/utils/basic-skipif.inc
similarity index 100%
rename from mongodb-1.13.0/tests/utils/basic-skipif.inc
rename to mongodb-1.14.0/tests/utils/basic-skipif.inc
diff --git a/mongodb-1.13.0/tests/utils/basic.inc b/mongodb-1.14.0/tests/utils/basic.inc
similarity index 67%
rename from mongodb-1.13.0/tests/utils/basic.inc
rename to mongodb-1.14.0/tests/utils/basic.inc
index e438ff3e..67bf687d 100644
--- a/mongodb-1.13.0/tests/utils/basic.inc
+++ b/mongodb-1.14.0/tests/utils/basic.inc
@@ -1,14 +1,12 @@
<?php
require_once __DIR__ . "/" . "tools.php";
define('URI', getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/');
define('MONGO_ORCHESTRATION_URI', getenv('MONGO_ORCHESTRATION_URI') ?: 'http://localhost:8889/v1');
define('DATABASE_NAME', getenv('MONGODB_DATABASE') ?: 'phongo');
define('COLLECTION_NAME', makeCollectionNameFromFilename($_SERVER['SCRIPT_FILENAME']));
define('NS', DATABASE_NAME . '.' . COLLECTION_NAME);
define('SSL_DIR', realpath(getenv('SSL_DIR')));
-
-if (getenv('MOCK_SERVICE_ID')) {
- ini_set('mongodb.mock_service_id', '1');
-}
+define('CSFLE_KEY_VAULT_NS', 'encryption.__keyVault');
+define('CSFLE_LOCAL_KEY', base64_decode('Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk'));
diff --git a/mongodb-1.13.0/tests/utils/classes.inc b/mongodb-1.14.0/tests/utils/classes.inc
similarity index 100%
rename from mongodb-1.13.0/tests/utils/classes.inc
rename to mongodb-1.14.0/tests/utils/classes.inc
diff --git a/mongodb-1.13.0/tests/utils/observer.php b/mongodb-1.14.0/tests/utils/observer.php
similarity index 100%
rename from mongodb-1.13.0/tests/utils/observer.php
rename to mongodb-1.14.0/tests/utils/observer.php
diff --git a/mongodb-1.13.0/tests/utils/skipif.php b/mongodb-1.14.0/tests/utils/skipif.php
similarity index 96%
rename from mongodb-1.13.0/tests/utils/skipif.php
rename to mongodb-1.14.0/tests/utils/skipif.php
index f4848f8b..17c9d353 100644
--- a/mongodb-1.13.0/tests/utils/skipif.php
+++ b/mongodb-1.14.0/tests/utils/skipif.php
@@ -1,481 +1,497 @@
<?php
use MongoDB\Driver\Command;
use MongoDB\Driver\Manager;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Server;
use MongoDB\Driver\Exception\ConnectionException;
use MongoDB\Driver\Exception\RuntimeException;
require_once __DIR__ . '/basic.inc';
require_once __DIR__ . '/tools.php';
/**
* Disables SKIPIF caching (PHP 8.1+).
*/
function disable_skipif_caching()
{
if (PHP_VERSION_ID < 80100) {
return;
}
echo "nocache\n";
}
/**
* Skips the test if the topology is load balanced.
*/
function skip_if_load_balanced()
{
is_load_balanced(URI) and exit('skip topology is load balanced');
}
/**
* Skips the test if the topology is not load balanced.
*/
function skip_if_not_load_balanced()
{
is_load_balanced(URI) or exit('skip topology is not load balanced');
}
/**
* Skips the test if the topology is a sharded cluster.
*/
function skip_if_mongos()
{
is_mongos(URI) and exit('skip topology is a sharded cluster');
}
/**
* Skips the test if the topology contains multiple mongos nodes.
*
* This is particularly useful for tests that rely on configureFailPoint, since
* randomized server selection can interfere with testing.
*/
function skip_if_multiple_mongos()
{
$manager = create_test_manager();
// Ensure SDAM is initialized before calling Manager::getServers()
$manager->selectServer(new ReadPreference('nearest'));
$mongosNodes = array_filter($manager->getServers(), function(Server $server) {
return $server->getType() === Server::TYPE_MONGOS;
});
if (count($mongosNodes) > 1) {
exit('skip topology contains multiple mongos nodes');
}
}
/**
* Skips the test if the topology is not a shard cluster.
*/
function skip_if_not_mongos()
{
is_mongos(URI) or exit('skip topology is not a sharded cluster');
}
function skip_if_not_sharded_cluster_with_replica_set()
{
is_sharded_cluster_with_replica_set(URI) or exit('skip topology is not a sharded cluster with replica set');
}
/**
* Skips the test if the topology is a replica set.
*/
function skip_if_replica_set()
{
is_replica_set(URI) and exit('skip topology is a replica set');
}
/**
* Skips the test if the topology is not a replica set.
*/
function skip_if_not_replica_set()
{
is_replica_set(URI) or exit('skip topology is not a replica set');
}
/**
* Skips the test if the topology is not a replica set or sharded cluster backed by replica sets
*/
function skip_if_not_replica_set_or_sharded_cluster_with_replica_set()
{
is_replica_set(URI) or is_sharded_cluster_with_replica_set(URI) or exit('skip topology is not a replica set or sharded cluster with replica set');
}
function skip_if_no_transactions()
{
if (is_sharded_cluster_with_replica_set(URI)) {
skip_if_server_version('<', '4.2');
} elseif (is_replica_set(URI)) {
skip_if_server_version('<', '4.0');
} else {
exit('skip topology does not support transactions');
}
}
/**
* Skips the test if the topology has no arbiter.
*/
function skip_if_no_arbiter()
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
if (!isset($info['arbiters']) || count($info['arbiters']) < 1) {
exit('skip no arbiters available');
}
}
/**
* Skips the test if the topology has no secondary.
*/
function skip_if_no_secondary()
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
if (!isset($info['hosts']) || count($info['hosts']) < 2) {
exit('skip no secondaries available');
}
}
/**
* Skips the test if the topology does not have enough data carrying nodes
*/
function skip_if_not_enough_data_nodes($requiredNodes, $maxNodeCount = null)
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
$dataNodeCount = isset($info['hosts']) ? count($info['hosts']) : 0;
if ($dataNodeCount < $requiredNodes) {
exit("skip not enough nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
if ($maxNodeCount !== null && $dataNodeCount > $requiredNodes) {
exit("skip too many nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
}
/**
* Skips the test if the topology does not have enough nodes
*/
function skip_if_not_enough_nodes($requiredNodes, $maxNodeCount = null)
{
try {
$primary = get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip primary server is not accessible: ' . $e->getMessage());
}
$info = $primary->getInfo();
$nodeCount =
(isset($info['hosts']) ? count($info['hosts']) : 0) +
(isset($info['arbiters']) ? count($info['arbiters']) : 0);
if ($nodeCount < $requiredNodes) {
exit("skip not enough nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
if ($maxNodeCount !== null && $nodeCount > $requiredNodes) {
exit("skip too many nodes available (wanted: {$requiredNodes}, available: " . count($info['hosts']) . ')');
}
}
/**
* Skips the test if the topology is a standalone.
*/
function skip_if_standalone()
{
is_standalone(URI) and exit('skip topology is a standalone');
}
/**
* Skips the test if the topology is not a standalone.
*/
function skip_if_not_standalone()
{
is_standalone(URI) or exit('skip topology is not a standalone');
}
/**
* Skips the test if the connection string uses SSL.
*/
function skip_if_ssl()
{
is_ssl(URI) and exit('skip URI is using SSL');
}
/**
* Skips the test if the connection string uses SSL.
*/
function skip_if_not_ssl()
{
is_ssl(URI) or exit('skip URI is not using SSL');
}
/**
* Skips the test if no SSL directory has been defined.
*/
function skip_if_no_ssl_dir()
{
$sslDir = getenv('SSL_DIR');
$sslDir !== false or exit('skip SSL_DIR environment variable not set');
$sslDir = realpath($sslDir);
($sslDir !== false && is_dir($sslDir)) or exit('skip SSL_DIR is not a valid directory');
}
/**
* Skips the test if the connection string is using auth.
*/
function skip_if_auth()
{
is_auth(URI) and exit('skip URI is using auth');
}
/**
* Skips the test if the connection string is not using auth.
*/
function skip_if_not_auth()
{
is_auth(URI) or exit('skip URI is not using auth');
}
/**
* Skips the test if the connection string is not using a particular
* authMechanism.
*
* @param string $authMechanism
*/
function skip_if_not_auth_mechanism($authMechanism)
{
$uriAuthMechanism = get_uri_option(URI, 'authMechanism');
if ($uriAuthMechanism === null && $authMechanism !== null) {
exit('skip URI is not using authMechanism');
}
if ($uriAuthMechanism !== $authMechanism) {
exit("skip URI authMechanism is '$uriAuthMechanism' (needed: '$authMechanism')");
}
}
/**
* Skips the test if the server is not accessible.
*/
function skip_if_not_live()
{
try {
get_primary_server(URI);
} catch (ConnectionException $e) {
exit('skip server is not accessible: ' . $e->getMessage());
}
}
/**
* Skips the test if the server version satisfies a comparison.
*
* @see http://php.net/version_compare
* @param string $operator Comparison operator
* @param string $version Version to compare against
*/
function skip_if_server_version($operator, $version)
{
$serverVersion = get_server_version(URI);
if (version_compare($serverVersion, $version, $operator)) {
exit("skip Server version '$serverVersion' $operator '$version'");
}
}
/**
* Skips the test if the PHP version satisfies a comparison.
*
* @see http://php.net/version_compare
* @param string $operator Comparison operator
* @param string $version Version to compare against
*/
function skip_if_php_version($operator, $version)
{
if (version_compare(PHP_VERSION, $version, $operator)) {
exit("skip PHP version '" . PHP_VERSION . "' $operator '$version'");
}
}
/**
* Skips the test if the server not using a particular storage engine.
*
* @param string $storageEngine Storage engine name
*/
function skip_if_not_server_storage_engine($storageEngine)
{
$serverStorageEngine = get_server_storage_engine(URI);
if ($serverStorageEngine !== $storageEngine) {
exit("skip Server storage engine is '$serverStorageEngine' (needed '$storageEngine')");
}
}
/**
* Skips the test if the server does not support the sleep command.
*/
function skip_if_sleep_command_unavailable()
{
if (!command_works(URI, ['sleep' => 1, 'secs' => 1, 'w' => false])) {
exit('skip sleep command not available');
}
}
/**
* Skips the test if the server does not support test commands.
*/
function skip_if_test_commands_disabled()
{
if (!get_server_parameter(URI, 'enableTestCommands')) {
exit('skip test commands are disabled');
}
}
/**
* Skips the test if libmongoc does not support crypto.
*
* If one or more libaries are provided, additionally check that the reported
* library is in that array. Possible values are "libcrypto", "Common Crypto",
* and "CNG".
*
* @param array $libs Optional list of crypto libraries to require
*/
function skip_if_not_libmongoc_crypto(array $libs = [])
{
$lib = get_module_info('libmongoc crypto library');
if ($lib === null) {
exit('skip libmongoc crypto is not enabled');
}
if (!empty($libs) && !in_array($lib, $libs)) {
exit('skip Needs libmongoc crypto library ' . implode(', ', $libs) . ', but found ' . $lib);
}
}
/**
* Skips the test if libmongoc does not support SSL.
*
* If one or more libaries are provided, additionally check that the reported
* library is in that array. Possible values are "OpenSSL", "LibreSSL",
* "Secure Transport", and "Secure Channel".
*
* @param array $libs Optional list of SSL libraries to require
*/
function skip_if_not_libmongoc_ssl(array $libs = [])
{
$lib = get_module_info('libmongoc SSL library');
if ($lib === null) {
exit('skip libmongoc SSL is not enabled');
}
if (!empty($libs) && !in_array($lib, $libs)) {
exit('skip Needs libmongoc SSL library ' . implode(', ', $libs) . ', but found ' . $lib);
}
}
/**
* Skips the test if the driver was not compiled with support for FLE
*/
function skip_if_not_libmongocrypt()
{
$lib = get_module_info('libmongocrypt');
if ($lib === 'disabled') {
exit('skip libmongocrypt is not enabled');
}
}
/**
* Skips the test if the driver was compiled with support for FLE
*/
function skip_if_libmongocrypt()
{
$lib = get_module_info('libmongocrypt');
if ($lib !== 'disabled') {
exit('skip libmongocrypt is enabled');
}
}
/**
* Skips the test if the collection cannot be dropped.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
*/
function skip_if_not_clean($databaseName = DATABASE_NAME, $collectionName = COLLECTION_NAME)
{
try {
drop_collection(URI, $databaseName, $collectionName);
} catch (RuntimeException $e) {
exit("skip Could not drop '$databaseName.$collectionName': " . $e->getMessage());
}
/* Since this function modifies the state of the database, we need it to run
* each time before a test. */
disable_skipif_caching();
}
function skip_if_no_getmore_failpoint()
{
$serverVersion = get_server_version(URI);
if (version_compare($serverVersion, '4.0', '<')) {
exit("skip Server version '$serverVersion' does not support a getMore failpoint'");
}
}
function skip_if_no_failcommand_failpoint()
{
skip_if_test_commands_disabled();
$serverVersion = get_server_version(URI);
if (is_mongos(URI) && version_compare($serverVersion, '4.1.8', '<')) {
exit("skip mongos version '$serverVersion' does not support 'failCommand' failpoint'");
} elseif (version_compare($serverVersion, '4.0', '<')) {
exit("skip mongod version '$serverVersion' does not support 'failCommand' failpoint'");
}
}
function skip_if_no_mongo_orchestration()
{
$ctx = stream_context_create(['http' => ['timeout' => 0.5]]);
$result = @file_get_contents(MONGO_ORCHESTRATION_URI, false, $ctx);
/* Note: file_get_contents emits an E_WARNING on failure, which will be
* caught by the error handler in basic-skipif.inc. In that case, this may
* never be reached. */
if ($result === false) {
exit("skip mongo-orchestration is not accessible: '" . MONGO_ORCHESTRATION_URI . "'");
}
}
function skip_if_appveyor()
{
if (getenv('APPVEYOR')) {
exit('skip Test cannot be run on AppVeyor');
}
}
+
+function skip_if_crypt_shared()
+{
+ // Intentionally ignore empty values for CRYPT_SHARED_LIB_PATH
+ if (getenv('CRYPT_SHARED_LIB_PATH')) {
+ exit('skip crypt_shared is available');
+ }
+}
+
+function skip_if_no_crypt_shared()
+{
+ // Intentionally consider empty values for CRYPT_SHARED_LIB_PATH
+ if ( ! getenv('CRYPT_SHARED_LIB_PATH')) {
+ exit('skip crypt_shared is not available');
+ }
+}
diff --git a/mongodb-1.13.0/tests/utils/tools.php b/mongodb-1.14.0/tests/utils/tools.php
similarity index 98%
rename from mongodb-1.13.0/tests/utils/tools.php
rename to mongodb-1.14.0/tests/utils/tools.php
index bf7184e3..dd8b04e8 100644
--- a/mongodb-1.13.0/tests/utils/tools.php
+++ b/mongodb-1.14.0/tests/utils/tools.php
@@ -1,847 +1,851 @@
<?php
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Command;
use MongoDB\Driver\Manager;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Server;
use MongoDB\Driver\ServerApi;
use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\WriteConcernError;
use MongoDB\Driver\WriteError;
use MongoDB\Driver\WriteResult;
use MongoDB\Driver\Exception\ConnectionException;
use MongoDB\Driver\Exception\RuntimeException;
/**
* Appends an option to a URI string and returns a new URI.
*
* @param string $uri
* @param string $option
* @param string $value
* @return string
*/
function append_uri_option($uri, $option)
{
// Append to existing query string
if (strpos($uri, '?') !== false) {
return $uri . '&' . $option;
}
// Terminate host list and append new query string
if (parse_url($uri, PHP_URL_PATH) === null) {
return $uri . '/?' . $option;
}
// Append query string after terminated host list and possible auth database
return $uri . '?' . $option;
}
/**
* Drops a collection on the primary server.
*
* @param string $uri Connection string
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @throws RuntimeException
*/
function drop_collection($uri, $databaseName, $collectionName)
{
$server = get_primary_server($uri);
$command = new Command(['drop' => $collectionName]);
try {
/* Unless we are dropping a collection within the "local" database,
* which does not support a write concern, we need to use w:majority due
* to the issue explained in SERVER-35613: "drop" uses a two phase
* commit, and due to that, it is possible that a lock can't be acquired
* for a transaction that gets quickly started as the "drop" reaper
* hasn't completed yet. */
$wc = $databaseName === 'local' ? new WriteConcern(1) : new WriteConcern(WriteConcern::MAJORITY);
$server->executeCommand(
$databaseName,
$command,
['writeConcern' => $wc]
);
} catch (RuntimeException $e) {
if ($e->getMessage() !== 'ns not found') {
throw $e;
}
}
}
/**
* Returns the value of a module row from phpinfo(), or null if it's not found.
*
* @param string $row
* @return string|null
*/
function get_module_info($row)
{
ob_start();
phpinfo(INFO_MODULES);
$info = ob_get_clean();
$pattern = sprintf('/^%s([\w ]+)$/m', preg_quote($row . ' => '));
if (preg_match($pattern, $info, $matches) !== 1) {
return null;
}
return $matches[1];
}
function create_test_manager(string $uri = null, array $options = [], array $driverOptions = [])
{
if (getenv('API_VERSION') && ! isset($driverOptions['serverApi'])) {
$driverOptions['serverApi'] = new ServerApi(getenv('API_VERSION'));
}
+ if (getenv('CRYPT_SHARED_LIB_PATH') && ! isset($driverOptions['autoEncryption']['extraOptions']['cryptSharedLibPath'])) {
+ $driverOptions['autoEncryption']['extraOptions']['cryptSharedLibPath'] = getenv('CRYPT_SHARED_LIB_PATH');
+ }
+
return new Manager($uri ?? URI, $options, $driverOptions);
}
/**
* Returns the primary server.
*
* @param string $uri Connection string
* @return Server
* @throws ConnectionException
*/
function get_primary_server($uri)
{
return create_test_manager($uri)->selectServer(new ReadPreference('primary'));
}
/**
* Returns a secondary server.
*
* @param string $uri Connection string
* @return Server
* @throws ConnectionException
*/
function get_secondary_server($uri)
{
return create_test_manager($uri)->selectServer(new ReadPreference('secondary'));
}
/**
* Runs a command and returns whether an exception was thrown or not
*
* @param string $uri Connection string
* @param array|object $commandSpec
* @return bool
* @throws RuntimeException
*/
function command_works($uri, $commandSpec)
{
$command = new Command($commandSpec);
$server = get_primary_server($uri);
try {
$cursor = $server->executeCommand('admin', $command);
return true;
} catch (Exception $e) {
return false;
}
}
/**
* Returns a parameter of the primary server.
*
* @param string $uri Connection string
* @return mixed
* @throws RuntimeException
*/
function get_server_parameter($uri, $parameter)
{
$server = get_primary_server($uri);
$command = new Command(['getParameter' => 1, $parameter => 1]);
$cursor = $server->executeCommand('admin', $command);
return current($cursor->toArray())->$parameter;
}
/**
* Returns the storage engine of the primary server.
*
* @param string $uri Connection string
* @return string
* @throws RuntimeException
*/
function get_server_storage_engine($uri)
{
$server = get_primary_server($uri);
$command = new Command(['serverStatus' => 1]);
$cursor = $server->executeCommand('admin', $command);
return current($cursor->toArray())->storageEngine->name;
}
/**
* Helper to return the version of a specific server.
*
* @param Server $server
* @return string
* @throws RuntimeException
*/
function get_server_version_from_server(Server $server)
{
$command = new Command(['buildInfo' => 1]);
$cursor = $server->executeCommand('admin', $command);
return current($cursor->toArray())->version;
}
/**
* Returns the version of the primary server.
*
* @param string $uri Connection string
* @return string
* @throws RuntimeException
*/
function get_server_version($uri)
{
$server = get_primary_server($uri);
return get_server_version_from_server($server);
}
/**
* Returns the value of a URI option, or null if it's not found.
*
* @param string $uri
* @return string|null
*/
function get_uri_option($uri, $option)
{
$pattern = sprintf('/[?&]%s=([^&]+)/i', preg_quote($option));
if (preg_match($pattern, $uri, $matches) !== 1) {
return null;
}
return $matches[1];
}
/**
* Checks that the topology is load balanced.
*
* @param string $uri
* @return boolean
*/
function is_load_balanced($uri)
{
return get_primary_server($uri)->getType() === Server::TYPE_LOAD_BALANCER;
}
/**
* Checks that the topology is a sharded cluster.
*
* @param string $uri
* @return boolean
*/
function is_mongos($uri)
{
return get_primary_server($uri)->getType() === Server::TYPE_MONGOS;
}
/**
* Checks that the topology is a sharded cluster using a replica set.
*
* Note: only the first shard is checked.
*/
function is_sharded_cluster_with_replica_set($uri)
{
$server = get_primary_server($uri);
if ($server->getType() !== Server::TYPE_MONGOS && $server->getType() !== Server::TYPE_LOAD_BALANCER) {
return false;
}
$cursor = $server->executeQuery('config.shards', new \MongoDB\Driver\Query([], ['limit' => 1]));
$cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
$document = current($cursor->toArray());
if (! $document) {
return false;
}
/**
* Use regular expression to distinguish between standalone or replicaset:
* Without a replicaset: "host" : "localhost:4100"
* With a replicaset: "host" : "dec6d8a7-9bc1-4c0e-960c-615f860b956f/localhost:4400,localhost:4401"
*/
return preg_match('@^.*/.*:\d+@', $document['host']);
}
/**
* Checks that the topology is a replica set.
*
* @param string $uri
* @return boolean
*/
function is_replica_set($uri)
{
if (get_primary_server($uri)->getType() !== Server::TYPE_RS_PRIMARY) {
return false;
}
/* Note: this may return a false negative if replicaSet is specified through
* a TXT record for a mongodb+srv connection string. */
if (get_uri_option($uri, 'replicaSet') === NULL) {
return false;
}
return true;
}
/**
* Checks if the connection string uses authentication.
*
* @param string $uri
* @return boolean
*/
function is_auth($uri)
{
if (stripos($uri, 'authmechanism=') !== false) {
return true;
}
if (strpos($uri, ':') !== false && strpos($uri, '@') !== false) {
return true;
}
return false;
}
/**
* Checks if the connection string uses SSL.
*
* @param string $uri
* @return boolean
*/
function is_ssl($uri)
{
return stripos($uri, 'ssl=true') !== false || stripos($uri, 'tls=true') !== false;
}
/**
* Checks that the topology is a standalone.
*
* @param string $uri
* @return boolean
*/
function is_standalone($uri)
{
return get_primary_server($uri)->getType() === Server::TYPE_STANDALONE;
}
/**
* Converts the server type constant to a string.
*
* @see http://php.net/manual/en/class.mongodb-driver-server.php
* @param integer $type
* @return string
*/
function server_type_as_string($type)
{
switch ($type) {
case Server::TYPE_STANDALONE:
return 'Standalone';
case Server::TYPE_MONGOS:
return 'Mongos';
case Server::TYPE_POSSIBLE_PRIMARY:
return 'PossiblePrimary';
case Server::TYPE_RS_PRIMARY:
return 'RSPrimary';
case Server::TYPE_RS_SECONDARY:
return 'RSSecondary';
case Server::TYPE_RS_ARBITER:
return 'RSArbiter';
case Server::TYPE_RS_OTHER:
return 'RSOther';
case Server::TYPE_RS_GHOST:
return 'RSGhost';
default:
return 'Unknown';
}
}
/**
* Converts an errno number to a string.
*
* @see http://php.net/manual/en/errorfunc.constants.php
* @param integer $errno
* @param string
*/
function errno_as_string($errno)
{
$errors = [
'E_ERROR',
'E_WARNING',
'E_PARSE',
'E_NOTICE',
'E_CORE_ERROR',
'E_CORE_WARNING',
'E_COMPILE_ERROR',
'E_COMPILE_WARNING',
'E_USER_ERROR',
'E_USER_WARNING',
'E_USER_NOTICE',
'E_STRICT',
'E_RECOVERABLE_ERROR',
'E_DEPRECATED',
'E_USER_DEPRECATED',
'E_ALL',
];
foreach ($errors as $error) {
if ($errno === constant($error)) {
return $error;
}
}
return 'Unknown';
}
/**
* Prints a traditional hex dump of byte values and printable characters.
*
* @see http://stackoverflow.com/a/4225813/162228
* @param string $data Binary data
* @param integer $width Bytes displayed per line
*/
function hex_dump($data, $width = 16)
{
static $pad = '.'; // Placeholder for non-printable characters
static $from = '';
static $to = '';
if ($from === '') {
for ($i = 0; $i <= 0xFF; $i++) {
$from .= chr($i);
$to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
}
}
$hex = str_split(bin2hex($data), $width * 2);
$chars = str_split(strtr($data, $from, $to), $width);
$offset = 0;
$length = $width * 3;
foreach ($hex as $i => $line) {
printf("%6X : %-{$length}s [%s]\n", $offset, implode(' ', str_split($line, 2)), $chars[$i]);
$offset += $width;
}
}
/**
* Canonicalizes a JSON string.
*
* @param string $json
* @return string
*/
function json_canonicalize($json)
{
$json = json_encode(json_decode($json));
/* Versions of PHP before 7.1 replace empty JSON keys with "_empty_" when
* decoding to a stdClass (see: https://bugs.php.net/bug.php?id=46600). Work
* around this by replacing "_empty_" keys before returning.
*/
$json = str_replace('"_empty_":', '"":', $json);
/* Canonicalize string values for $numberDouble to ensure they are converted
* the same as number literals in legacy and relaxed output. This is needed
* because the printf format in _bson_as_json_visit_double uses a high level
* of precision and may not produce the exponent notation expected by the
* BSON corpus tests. */
$json = preg_replace_callback(
'/{"\$numberDouble":"(-?\d+(\.\d+([eE]\+\d+)?)?)"}/',
function ($matches) {
return '{"$numberDouble":"' . json_encode(json_decode($matches[1])) . '"}';
},
$json
);
return $json;
}
/**
* Return a collection name to use for the test file.
*
* The filename will be stripped of the base path to the test suite (prefix) as
* well as the PHP file extension (suffix). Special characters (including hyphen
* for shell compatibility) will be replaced with underscores.
*
* @param string $filename
* @return string
*/
function makeCollectionNameFromFilename($filename)
{
$filename = realpath($filename);
$prefix = realpath(dirname(__FILE__) . '/..') . DIRECTORY_SEPARATOR;
$replacements = array(
// Strip test path prefix
sprintf('/^%s/', preg_quote($prefix, '/')) => '',
// Strip file extension suffix
'/\.php$/' => '',
// SKIPIFs add ".skip" between base name and extension
'/\.skip$/' => '',
// Replace special characters with underscores
sprintf('/[%s]/', preg_quote('-$/\\', '/')) => '_',
);
return preg_replace(array_keys($replacements), array_values($replacements), $filename);
}
function NEEDS($configuration) {
if (!constant($configuration)) {
exit("skip -- need '$configuration' defined");
}
}
function SLOW() {
if (getenv("SKIP_SLOW_TESTS")) {
exit("skip SKIP_SLOW_TESTS");
}
}
function loadFixtures(Manager $manager, $dbname = DATABASE_NAME, $collname = COLLECTION_NAME, $filename = null)
{
if (!$filename) {
$filename = "compress.zlib://" . __DIR__ . "/" . "PHONGO-FIXTURES.json.gz";
}
$bulk = new BulkWrite(['ordered' => false]);
$server = $manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
$data = file_get_contents($filename);
$array = json_decode($data);
foreach($array as $document) {
$bulk->insert($document);
}
$retval = $server->executeBulkWrite("$dbname.$collname", $bulk);
if ($retval->getInsertedCount() !== count($array)) {
exit(sprintf('skip Fixtures were not loaded (expected: %d, actual: %d)', $total, $retval->getInsertedCount()));
}
}
function createTemporaryMongoInstance(array $options = [])
{
$id = 'mo_' . COLLECTION_NAME;
$options += [
"name" => "mongod",
"id" => $id,
'procParams' => [
'logpath' => "/tmp/MO/phongo/{$id}.log",
'ipv6' => true,
'setParameter' => [ 'enableTestCommands' => 1 ],
],
];
$opts = array(
"http" => array(
"timeout" => 60,
"method" => "PUT",
"header" => "Accept: application/json\r\n" .
"Content-type: application/x-www-form-urlencoded",
"content" => json_encode($options),
"ignore_errors" => true,
),
);
$ctx = stream_context_create($opts);
$json = file_get_contents(MONGO_ORCHESTRATION_URI . "/servers/$id", false, $ctx);
$result = json_decode($json, true);
/* Failed -- or was already started */
if (!isset($result["mongodb_uri"])) {
destroyTemporaryMongoInstance($id);
throw new Exception("Could not start temporary server instance\n");
} else {
return $result['mongodb_uri'];
}
}
function destroyTemporaryMongoInstance($id = NULL)
{
if ($id == NULL) {
$id = 'mo_' . COLLECTION_NAME;
}
$opts = array(
"http" => array(
"timeout" => 60,
"method" => "DELETE",
"header" => "Accept: application/json\r\n",
"ignore_errors" => true,
),
);
$ctx = stream_context_create($opts);
$json = file_get_contents(MONGO_ORCHESTRATION_URI . "/servers/$id", false, $ctx);
}
/**
* Converts an error level (constant or bitmask) to a string description.
*/
function severityToString(int $severity): string {
static $constants = [
'E_ERROR' => E_ERROR,
'E_WARNING' => E_WARNING,
'E_PARSE' => E_PARSE,
'E_NOTICE' => E_NOTICE,
'E_CORE_ERROR' => E_CORE_ERROR,
'E_CORE_WARNING' => E_CORE_WARNING,
'E_COMPILE_ERROR' => E_COMPILE_ERROR,
'E_COMPILE_WARNING' => E_COMPILE_WARNING,
'E_USER_ERROR' => E_USER_ERROR,
'E_USER_WARNING' => E_USER_WARNING,
'E_USER_NOTICE' => E_USER_NOTICE,
'E_STRICT' => E_STRICT,
'E_RECOVERABLE_ERROR' => E_RECOVERABLE_ERROR,
'E_DEPRECATED' => E_DEPRECATED,
'E_USER_DEPRECATED' => E_USER_DEPRECATED,
// E_ALL is handled separately
];
if ($severity === E_ALL) {
return 'E_ALL';
}
foreach ($constants as $constant => $value) {
if ($severity & $value) {
$matches[] = $constant;
}
}
return empty($matches) ? 'UNKNOWN' : implode('|', $matches);
}
/**
* Expects the callable to raise an error matching the expected severity, which
* may be a constant or bitmask. May optionally expect the error to be raised
* from a particular function. Returns the message from the raised error or
* exception, or an empty string if neither was thrown.
*/
function raises(callable $callable, int $expectedSeverity, string $expectedFromFunction = null): string
{
set_error_handler(function(int $severity, string $message, string $file, int $line) {
throw new ErrorException($message, 0, $severity, $file, $line);
});
try {
call_user_func($callable);
} catch (ErrorException $e) {
if (!($e->getSeverity() & $expectedSeverity)) {
printf("ALMOST: Got %s - expected %s\n", severityToString($e->getSeverity()), severityToString($expectedSeverity));
return $e->getMessage();
}
if ($expectedFromFunction === null) {
printf("OK: Got %s\n", severityToString($e->getSeverity()));
return $e->getMessage();
}
$fromFunction = $e->getTrace()[0]['function'];
if (strcasecmp($fromFunction, $expectedFromFunction) !== 0) {
printf("ALMOST: Got %s - but was raised from %s, not %s\n", errorLevelToString($e->getSeverity()), $fromFunction, $expectedFromFunction);
return $e->getMessage();
}
printf("OK: Got %s raised from %s\n", severityToString($e->getSeverity()), $fromFunction);
return $e->getMessage();
} catch (Throwable $e) {
printf("ALMOST: Got %s - expected %s\n", get_class($e), ErrorException::class);
return $e->getMessage();
} finally {
restore_error_handler();
}
printf("FAILED: Expected %s, but no error raised!\n", ErrorException::class);
return '';
}
/**
* Expects the callable to throw an expected exception. May optionally expect
* the exception to be thrown from a particular function. Returns the message
* from the thrown exception, or an empty string if one was not thrown.
*/
function throws(callable $callable, string $expectedException, string $expectedFromFunction = null): string
{
try {
call_user_func($callable);
} catch (Throwable $e) {
if (!($e instanceof $expectedException)) {
printf("ALMOST: Got %s - expected %s\n", get_class($e), $expectedException);
return $e->getMessage();
}
if ($expectedFromFunction === null) {
printf("OK: Got %s\n", $expectedException);
return $e->getMessage();
}
$fromFunction = $e->getTrace()[0]['function'];
if (strcasecmp($fromFunction, $expectedFromFunction) !== 0) {
printf("ALMOST: Got %s - but was thrown from %s, not %s\n", $expectedException, $fromFunction, $expectedFromFunction);
return $e->getMessage();
}
printf("OK: Got %s thrown from %s\n", $expectedException, $fromFunction);
return $e->getMessage();
}
printf("FAILED: Expected %s, but no exception thrown!\n", $expectedException);
return '';
}
function printServer(Server $server)
{
printf("server: %s:%d\n", $server->getHost(), $server->getPort());
}
function printWriteResult(WriteResult $result, $details = true)
{
printServer($result->getServer());
printf("insertedCount: %d\n", $result->getInsertedCount());
printf("matchedCount: %d\n", $result->getMatchedCount());
printf("modifiedCount: %d\n", $result->getModifiedCount());
printf("upsertedCount: %d\n", $result->getUpsertedCount());
printf("deletedCount: %d\n", $result->getDeletedCount());
foreach ($result->getUpsertedIds() as $index => $id) {
printf("upsertedId[%d]: ", $index);
var_dump($id);
}
$writeConcernError = $result->getWriteConcernError();
printWriteConcernError($writeConcernError ? $writeConcernError : null, $details);
foreach ($result->getWriteErrors() as $writeError) {
printWriteError($writeError);
}
}
function printWriteConcernError(WriteConcernError $error = null, $details)
{
if ($error) {
/* This stuff is generated by the server, no need for us to test it */
if (!$details) {
printf("writeConcernError: %s (%d)\n", $error->getMessage(), $error->getCode());
return;
}
var_dump($error);
printf("writeConcernError.message: %s\n", $error->getMessage());
printf("writeConcernError.code: %d\n", $error->getCode());
printf("writeConcernError.info: ");
var_dump($error->getInfo());
}
}
function printWriteError(WriteError $error)
{
var_dump($error);
printf("writeError[%d].message: %s\n", $error->getIndex(), $error->getMessage());
printf("writeError[%d].code: %d\n", $error->getIndex(), $error->getCode());
}
function getInsertCount($retval) {
return $retval->getInsertedCount();
}
function getModifiedCount($retval) {
return $retval->getModifiedCount();
}
function getDeletedCount($retval) {
return $retval->getDeletedCount();
}
function getUpsertedCount($retval) {
return $retval->getUpsertedCount();
}
function getWriteErrors($retval) {
return (array)$retval->getWriteErrors();
}
function def($arr) {
foreach($arr as $const => $value) {
define($const, getenv("PHONGO_TEST_$const") ?: $value);
}
}
function configureFailPoint(Manager $manager, $failPoint, $mode, array $data = [])
{
$doc = [
'configureFailPoint' => $failPoint,
'mode' => $mode,
];
if ($data) {
$doc['data'] = $data;
}
$cmd = new Command($doc);
$manager->executeCommand('admin', $cmd);
}
function configureTargetedFailPoint(Server $server, $failPoint, $mode, array $data = [])
{
$doc = array(
'configureFailPoint' => $failPoint,
'mode' => $mode,
);
if ($data) {
$doc['data'] = $data;
}
$cmd = new Command($doc);
$server->executeCommand('admin', $cmd);
}
function failMaxTimeMS(Server $server)
{
configureTargetedFailPoint($server, 'maxTimeAlwaysTimeOut', [ 'times' => 1 ]);
}
function toPHP($var, $typemap = array()) {
return MongoDB\BSON\toPHP($var, $typemap);
}
function fromPHP($var) {
return MongoDB\BSON\fromPHP($var);
}
function toJSON($var) {
return MongoDB\BSON\toJSON($var);
}
function toCanonicalExtendedJSON($var) {
return MongoDB\BSON\toCanonicalExtendedJSON($var);
}
function toRelaxedExtendedJSON($var) {
return MongoDB\BSON\toRelaxedExtendedJSON($var);
}
function fromJSON($var) {
return MongoDB\BSON\fromJSON($var);
}
/* Note: this fail point may terminate the mongod process, so you may want to
* use this in conjunction with a throwaway server. */
function failGetMore(Manager $manager)
{
/* We need to do version detection here */
$primary = $manager->selectServer(new ReadPreference('primary'));
$version = get_server_version_from_server($primary);
if (version_compare($version, "4.0", ">=")) {
/* We use 237 here, as that's the same original code that MongoD would
* throw if a cursor had already gone by the time we call getMore. This
* allows us to make things consistent with the getMore OP behaviour
* from previous mongod versions. An errorCode is required here for the
* failPoint to work. */
configureFailPoint($manager, 'failCommand', 'alwaysOn', [ 'errorCode' => 237, 'failCommands' => ['getMore'] ]);
return;
}
throw new Exception("Trying to configure a getMore fail point for a server version ($version) that doesn't support it");
}
diff --git a/mongodb-1.13.0/tests/writeConcern/bug1598-001.phpt b/mongodb-1.14.0/tests/writeConcern/bug1598-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/bug1598-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/bug1598-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/bug1598-002.phpt b/mongodb-1.14.0/tests/writeConcern/bug1598-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/bug1598-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/bug1598-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-002.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-003.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-003.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-003.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-004.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-bsonserialize-004.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-bsonserialize-004.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-constants.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-constants.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-constants.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-constants.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-ctor-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-ctor-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-ctor-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-ctor-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-ctor-002.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-ctor-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-ctor-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-ctor-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-002.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-003.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-003.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-003.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-004.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-004.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-004.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-004.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-005.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-005.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-ctor_error-005.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-ctor_error-005.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-debug-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-debug-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-debug-002.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-debug-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-debug-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-debug-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-debug-003.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-debug-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-debug-003.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-debug-003.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-getjournal-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-getjournal-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-getjournal-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-getjournal-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-getw-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-getw-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-getw-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-getw-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-getwtimeout-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-getwtimeout-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-getwtimeout-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-getwtimeout-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-getwtimeout-002.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-getwtimeout-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-getwtimeout-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-getwtimeout-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-isdefault-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-isdefault-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-isdefault-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-isdefault-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-serialization-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-serialization-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-serialization-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-serialization-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-serialization-002.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-serialization-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-serialization-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-serialization-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-serialization_error-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-serialization_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-serialization_error-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-serialization_error-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-serialization_error-002.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-serialization_error-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-serialization_error-002.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-serialization_error-002.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-set_state-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-set_state-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-set_state-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-set_state-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-set_state_error-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-set_state_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-set_state_error-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-set_state_error-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern-var_export-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern-var_export-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern-var_export-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern-var_export-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcern/writeconcern_error-001.phpt b/mongodb-1.14.0/tests/writeConcern/writeconcern_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcern/writeconcern_error-001.phpt
rename to mongodb-1.14.0/tests/writeConcern/writeconcern_error-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcernError/writeconcernerror-debug-001.phpt b/mongodb-1.14.0/tests/writeConcernError/writeconcernerror-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcernError/writeconcernerror-debug-001.phpt
rename to mongodb-1.14.0/tests/writeConcernError/writeconcernerror-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcernError/writeconcernerror-getcode-001.phpt b/mongodb-1.14.0/tests/writeConcernError/writeconcernerror-getcode-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcernError/writeconcernerror-getcode-001.phpt
rename to mongodb-1.14.0/tests/writeConcernError/writeconcernerror-getcode-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcernError/writeconcernerror-getinfo-001.phpt b/mongodb-1.14.0/tests/writeConcernError/writeconcernerror-getinfo-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcernError/writeconcernerror-getinfo-001.phpt
rename to mongodb-1.14.0/tests/writeConcernError/writeconcernerror-getinfo-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcernError/writeconcernerror-getmessage-001.phpt b/mongodb-1.14.0/tests/writeConcernError/writeconcernerror-getmessage-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcernError/writeconcernerror-getmessage-001.phpt
rename to mongodb-1.14.0/tests/writeConcernError/writeconcernerror-getmessage-001.phpt
diff --git a/mongodb-1.13.0/tests/writeConcernError/writeconcernerror_error-001.phpt b/mongodb-1.14.0/tests/writeConcernError/writeconcernerror_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeConcernError/writeconcernerror_error-001.phpt
rename to mongodb-1.14.0/tests/writeConcernError/writeconcernerror_error-001.phpt
diff --git a/mongodb-1.13.0/tests/writeError/writeerror-debug-001.phpt b/mongodb-1.14.0/tests/writeError/writeerror-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeError/writeerror-debug-001.phpt
rename to mongodb-1.14.0/tests/writeError/writeerror-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/writeError/writeerror-getCode-001.phpt b/mongodb-1.14.0/tests/writeError/writeerror-getCode-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeError/writeerror-getCode-001.phpt
rename to mongodb-1.14.0/tests/writeError/writeerror-getCode-001.phpt
diff --git a/mongodb-1.13.0/tests/writeError/writeerror-getIndex-001.phpt b/mongodb-1.14.0/tests/writeError/writeerror-getIndex-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeError/writeerror-getIndex-001.phpt
rename to mongodb-1.14.0/tests/writeError/writeerror-getIndex-001.phpt
diff --git a/mongodb-1.13.0/tests/writeError/writeerror-getInfo-001.phpt b/mongodb-1.14.0/tests/writeError/writeerror-getInfo-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeError/writeerror-getInfo-001.phpt
rename to mongodb-1.14.0/tests/writeError/writeerror-getInfo-001.phpt
diff --git a/mongodb-1.13.0/tests/writeError/writeerror-getInfo-002.phpt b/mongodb-1.14.0/tests/writeError/writeerror-getInfo-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeError/writeerror-getInfo-002.phpt
rename to mongodb-1.14.0/tests/writeError/writeerror-getInfo-002.phpt
diff --git a/mongodb-1.13.0/tests/writeError/writeerror-getMessage-001.phpt b/mongodb-1.14.0/tests/writeError/writeerror-getMessage-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeError/writeerror-getMessage-001.phpt
rename to mongodb-1.14.0/tests/writeError/writeerror-getMessage-001.phpt
diff --git a/mongodb-1.13.0/tests/writeError/writeerror_error-001.phpt b/mongodb-1.14.0/tests/writeError/writeerror_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeError/writeerror_error-001.phpt
rename to mongodb-1.14.0/tests/writeError/writeerror_error-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/bug0671-003.phpt b/mongodb-1.14.0/tests/writeResult/bug0671-003.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/bug0671-003.phpt
rename to mongodb-1.14.0/tests/writeResult/bug0671-003.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-debug-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-debug-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-debug-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-debug-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-debug-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-debug-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-debug-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-debug-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getdeletedcount-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getdeletedcount-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getdeletedcount-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getdeletedcount-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getdeletedcount-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getdeletedcount-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getdeletedcount-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getdeletedcount-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getinsertedcount-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getinsertedcount-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getinsertedcount-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getinsertedcount-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getinsertedcount-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getinsertedcount-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getinsertedcount-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getinsertedcount-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getmatchedcount-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getmatchedcount-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getmatchedcount-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getmatchedcount-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getmatchedcount-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getmatchedcount-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getmatchedcount-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getmatchedcount-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getmodifiedcount-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getmodifiedcount-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getmodifiedcount-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getmodifiedcount-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getmodifiedcount-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getmodifiedcount-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getmodifiedcount-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getmodifiedcount-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getserver-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getserver-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getserver-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getserver-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getupsertedcount-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getupsertedcount-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getupsertedcount-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getupsertedcount-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getupsertedcount-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getupsertedcount-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getupsertedcount-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getupsertedcount-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getupsertedids-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getupsertedids-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getupsertedids-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getupsertedids-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getupsertedids-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getupsertedids-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getupsertedids-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getupsertedids-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getwriteconcernerror-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getwriteconcernerror-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getwriteerrors-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getwriteerrors-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getwriteerrors-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getwriteerrors-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-getwriteerrors-002.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-getwriteerrors-002.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-getwriteerrors-002.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-getwriteerrors-002.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult-isacknowledged-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult-isacknowledged-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult-isacknowledged-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult-isacknowledged-001.phpt
diff --git a/mongodb-1.13.0/tests/writeResult/writeresult_error-001.phpt b/mongodb-1.14.0/tests/writeResult/writeresult_error-001.phpt
similarity index 100%
rename from mongodb-1.13.0/tests/writeResult/writeresult_error-001.phpt
rename to mongodb-1.14.0/tests/writeResult/writeresult_error-001.phpt
diff --git a/package.xml b/package.xml
index 60897217..6d26c82a 100644
--- a/package.xml
+++ b/package.xml
@@ -1,2863 +1,2878 @@
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.10.13" version="2.1" xmlns="http://pear.php.net/dtd/package-2.1" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.1 http://pear.php.net/dtd/package-2.1.xsd">
<name>mongodb</name>
<channel>pecl.php.net</channel>
<summary>MongoDB driver for PHP</summary>
<description>The purpose of this driver is to provide exceptionally thin glue between MongoDB
and PHP, implementing only fundamental and performance-critical components
necessary to build a fully-functional MongoDB driver.</description>
<lead>
<name>Andreas Braun</name>
<user>alcaeus</user>
<email>alcaeus@php.net</email>
<active>yes</active>
</lead>
<lead>
<name>Jeremy Mikola</name>
<user>jmikola</user>
<email>jmikola@php.net</email>
<active>yes</active>
</lead>
<lead>
<name>Derick Rethans</name>
<user>derick</user>
<email>derick@php.net</email>
<active>no</active>
</lead>
<lead>
<name>Hannes Magnusson</name>
<user>bjori</user>
<email>bjori@php.net</email>
<active>no</active>
</lead>
<developer>
<name>Katherine Walker</name>
<user>kvwalker</user>
<email>kvwalker@php.net</email>
<active>no</active>
</developer>
- <date>2022-03-23</date>
- <time>16:49:06</time>
+ <date>2022-07-16</date>
+ <time>20:55:50</time>
<version>
- <release>1.13.0</release>
- <api>1.13.0</api>
+ <release>1.14.0</release>
+ <api>1.14.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.apache.org/licenses/LICENSE-2.0">Apache License</license>
<notes>
** Bug
- * [PHPC-2013] - RHEL 7.0 and 7.1 builds fail due to incompatible pointer warnings
- * [PHPC-2020] - Validate loadBalanced URI array option
+ * [PHPC-2088] - Memory leak in php_phongo_zval_to_bson_value
+ * [PHPC-2089] - Various bson_value_t memory leaks in ClientEncryption methods
+ * [PHPC-2098] - phongo_clientencryption_init uses wrong signature when compiling without CSFLE
** Epic
- * [PHPC-1150] - Support SDAM Monitoring
+ * [PHPC-2045] - FLE 1.0 Shared Library
+ * [PHPC-2091] - Queryable Encryption Support
** New Feature
- * [PHPC-1805] - Implement ServerDescription class
- * [PHPC-1891] - Implement TopologyDescription class
- * [PHPC-1892] - Define SDAMSubscriber interface
- * [PHPC-1893] - Define SDAM event classes
- * [PHPC-1900] - Allow custom service names with srvServiceName URI option
- * [PHPC-1908] - Allow limiting mongos servers with srvMaxHosts option
+ * [PHPC-1899] - getServerConnectionId for command monitoring events
+ * [PHPC-2005] - Support &apos;let&apos; option for multiple CRUD commands
+ * [PHPC-2049] - BulkWrite and Query support comment option of any type
+ * [PHPC-2085] - autoEncryption options for queryable encryption
+ * [PHPC-2092] - ClientEncryption options for queryable encryption
+ * [PHPC-2096] - Implement Manager::getEncryptedFieldsMap()
+ * [PHPC-2097] - Enable ClientEncryption constructor
** Task
- * [PHPC-1342] - Add documentation warning against the use of duplicate key names
- * [PHPC-1909] - Set minWireVersion to 6 (MongoDB 3.6)
- * [PHPC-1953] - Create tests for event object debug handlers
- * [PHPC-1958] - Ensure that getTopologyId() gives the same result for all SDAM events
- * [PHPC-1959] - Change SDAM event tests to use Manager::addSubscriber()
- * [PHPC-1973] - Bump maxWireVersion to 14 for MongoDB 5.1
- * [PHPC-2008] - writeresult-getserver-002 fails to drop collection in local db on replicaset-auth
- * [PHPC-2012] - Remove extra AX_CHECK_COMPILE_FLAG args
- * [PHPC-2019] - Remove Solaris checks in m4 build scripts
- * [PHPC-2022] - Use mongoc_host_list in event structs
- * [PHPC-2023] - Allow observation of TopologyClosedEvent
- * [PHPC-2028] - Replace PHONGO_ALLOC_OBJECT_T macro with zend_object_alloc
- * [PHPC-2031] - Upgrade libmongoc to 1.21.1 and libmongocrypt to 1.3.2
- * [PHPC-2034] - Bump maxWireVersion for MongoDB 5.2
- * [PHPC-2036] - Remove outdated prose test in causal consistency spec
- * [PHPC-2037] - Remove vim modeline comments
- * [PHPC-2038] - Initialize zval in phongo_clientencryption_init
- * [PHPC-2039] - Remove disabled debugging code in bson.c
- * [PHPC-2040] - Break down php_phongo.c into smaller files
- * [PHPC-2042] - Remove conditional win32/time.h include in UTCDateTime.c
- * [PHPC-2047] - Update load balancer tests to support dedicated load balancer port
- * [PHPC-2073] - Remove test environments and checks for pre-3.6 server versions
- * [PHPC-2074] - Clarify in contributing docs that mongo-orchestration is not required to run tests
+ * [PHPC-2053] - Remove mongodb.mock_service_id INI option
+ * [PHPC-2078] - Allow PECL release-upload.php to verify version constants
+ * [PHPC-2086] - Test against MongoDB 6.0
+ * [PHPC-2090] - Add MongoDB 5.0 to load balancer CI matrix
+ * [PHPC-2099] - Add crypt_shared to CI matrix as an alternative to mongocryptd
+ * [PHPC-2109] - Document Queryable Encryption API as &quot;Public Technical Preview&quot;
** Improvement
- * [PHPC-1647] - Defer to libmongoc for cross-option URI validation
- * [PHPC-1910] - Implement Server::getServerDescription
- * [PHPC-1925] - ServerDescription::getType() should return a string
- * [PHPC-1934] - Check for uninitialized intern in ServerDescription get_properties_hash
- * [PHPC-1950] - Lift restriction on authSource without credentials when set in URI options array
- * [PHPC-2003] - Expose whether a client session is dirty
- * [PHPC-2025] - Support load balancer in ServerDescription and TopologyDescription
- * [PHPC-2026] - Warn if ServerDescription::getLastUpdateTime() must be truncated
- * [PHPC-2030] - Allow observation of commands issued during mongoc_client_destroy()
- * [PHPC-2032] - Report more concise debug info for ended sessions
+ * [PHPC-2087] - Bump maxWireVersion for MongoDB 6.0
+ * [PHPC-2094] - Relay command comment when constructing a cursor
+ * [PHPC-2104] - EncryptOpts queryType should accept a string consistent with queryType in encryptedFields
</notes>
<contents>
<dir name="/">
<file md5sum="c78c5e9b49b67a725e831823492642da" name="scripts/autotools/libbson/CheckAtomics.m4" role="src" />
<file md5sum="24efc529aa9f2b40d80cbec3bb635d01" name="scripts/autotools/libbson/CheckHeaders.m4" role="src" />
<file md5sum="fcce6a6a1e782b4482a50b18f78a2114" name="scripts/autotools/libbson/Endian.m4" role="src" />
<file md5sum="422e66c86688aa02db4c6d98378aa0e2" name="scripts/autotools/libbson/FindDependencies.m4" role="src" />
<file md5sum="0ea5922bfcf826e14a5f3c0a5563e410" name="scripts/autotools/libbson/Versions.m4" role="src" />
<file md5sum="796238ff21022249fc485a8eb53be09e" name="scripts/autotools/libmongoc/CheckCompression.m4" role="src" />
<file md5sum="96ddbeccbaa3c00f367810f56df074e4" name="scripts/autotools/libmongoc/CheckICU.m4" role="src" />
<file md5sum="79ffd99afdc875d93f016f693b787468" name="scripts/autotools/libmongoc/CheckResolv.m4" role="src" />
<file md5sum="1402931faf1e48f2159acbb7f0a36452" name="scripts/autotools/libmongoc/CheckSSL.m4" role="src" />
<file md5sum="39e1c1663469b0d6222b6babd183fb40" name="scripts/autotools/libmongoc/CheckSasl.m4" role="src" />
<file md5sum="2d7d36844c77bceb9da76b448455353d" name="scripts/autotools/libmongoc/FindDependencies.m4" role="src" />
<file md5sum="d429836468174085140a6958c5926402" name="scripts/autotools/libmongoc/PlatformFlags.m4" role="src" />
<file md5sum="08214982201e2c7805b62a3a4ca915a6" name="scripts/autotools/libmongoc/Versions.m4" role="src" />
<file md5sum="76e2c1a2aa19f5fab3661c992ac603fa" name="scripts/autotools/libmongoc/WeakSymbols.m4" role="src" />
<file md5sum="906a71d7858713742f5febc043b9b51b" name="scripts/autotools/libmongocrypt/CheckSSL.m4" role="src" />
- <file md5sum="59f94718c53faf3661bf1a9aadb2991e" name="scripts/autotools/libmongocrypt/Endian.m4" role="src" />
+ <file md5sum="73f7615ca5ccf149594ffef26d9eee3e" name="scripts/autotools/libmongocrypt/Endian.m4" role="src" />
<file md5sum="471ed55586aaeef30e1d54a235133735" name="scripts/autotools/libmongocrypt/Version.m4" role="src" />
<file md5sum="0091c30d8927966e5ba54ce90b62bf6e" name="scripts/autotools/m4/as_var_copy.m4" role="src" />
<file md5sum="8d942f69b5f3c15ecae4b75bb7e80614" name="scripts/autotools/m4/ax_check_compile_flag.m4" role="src" />
<file md5sum="c2221efd4309e58ff7e2ef989c8e8ac4" name="scripts/autotools/m4/ax_prototype.m4" role="src" />
<file md5sum="b5114dfcf027b0f9a47b6e6841015be6" name="scripts/autotools/m4/ax_pthread.m4" role="src" />
<file md5sum="01a9faee79ca2be030b72f2046976b09" name="scripts/autotools/m4/php_mongodb.m4" role="src" />
<file md5sum="ad8d52d54e0f97c0e4e385376ea73bc0" name="scripts/autotools/m4/pkg.m4" role="src" />
<file md5sum="0601fcdfbdc1e25d6f5601cf78693669" name="scripts/autotools/CheckCompiler.m4" role="src" />
<file md5sum="51c4dd11458ad655113dcdb101640b49" name="scripts/autotools/CheckHost.m4" role="src" />
<file md5sum="e6c8420017ff6f2090eccbe800b3ad14" name="scripts/clang-format.sh" role="test" />
<file md5sum="992cbbe1b006fdf00448ed6f106c730c" name="scripts/convert-bson-corpus-tests.php" role="test" />
<file md5sum="a3ee9619493782cf80261595fe7fd9dd" name="scripts/mongo-orchestration.php" role="test" />
- <file md5sum="fb8d8138eb989fe03e2ed7ccac3b7921" name="scripts/update-submodule-sources.php" role="test" />
+ <file md5sum="470a0d6dcdf9553fc90afc5f22365f10" name="scripts/update-submodule-sources.php" role="test" />
<file md5sum="38e98c2bfc7f56dffb9db7b09ade5141" name="src/BSON/Binary.c" role="src" />
<file md5sum="afdb4c218b1832b967dc83b9275109b3" name="src/BSON/BinaryInterface.c" role="src" />
<file md5sum="20874183dc96c87639760ca1a11efb4e" name="src/BSON/DBPointer.c" role="src" />
<file md5sum="5731e850094db36f5232ad2600eb5dbe" name="src/BSON/Decimal128.c" role="src" />
<file md5sum="fe9045fdaf1c04fa2cb1d4c1721c4456" name="src/BSON/Decimal128Interface.c" role="src" />
<file md5sum="60e97c448e99619b273395c7138661c1" name="src/BSON/Int64.c" role="src" />
<file md5sum="3970c46eaf0f8ea0ca67ad79229fc070" name="src/BSON/Javascript.c" role="src" />
<file md5sum="28f0e47660ff76131121e0bf10afa022" name="src/BSON/JavascriptInterface.c" role="src" />
<file md5sum="7314bb17e6770cbc5d848d4c3192c7a3" name="src/BSON/MaxKey.c" role="src" />
<file md5sum="e9296e8b8a30aba292300de75fe6606a" name="src/BSON/MaxKeyInterface.c" role="src" />
<file md5sum="fd48fae3962305ae57f5d5afa3451dbb" name="src/BSON/MinKey.c" role="src" />
<file md5sum="39a764c5bcd276a553c5472283ce3cdd" name="src/BSON/MinKeyInterface.c" role="src" />
<file md5sum="eeee505fb094618d3b5e743bdc3b3e15" name="src/BSON/ObjectId.c" role="src" />
<file md5sum="397725a29c9cc16edbf7c9449898a292" name="src/BSON/ObjectId.h" role="src" />
<file md5sum="5a165c6c79f34f3e6451749dc80df8e9" name="src/BSON/ObjectIdInterface.c" role="src" />
<file md5sum="415e1d9e4a33c1600b251494e7a04b18" name="src/BSON/Persistable.c" role="src" />
<file md5sum="72bb1a49db40a364548960051bcd892f" name="src/BSON/Regex.c" role="src" />
<file md5sum="c30ecde8019c72065e6a059f3666b46f" name="src/BSON/RegexInterface.c" role="src" />
<file md5sum="97eddda27c4a289deb5643c27876ff69" name="src/BSON/Serializable.c" role="src" />
<file md5sum="8eb00e2954e04d252c9ad61d1d0d91e9" name="src/BSON/Symbol.c" role="src" />
<file md5sum="ba5f708808d7dab0e06a56824bfdc8b6" name="src/BSON/Timestamp.c" role="src" />
<file md5sum="5d78979ab806321720326880f10fb1e2" name="src/BSON/TimestampInterface.c" role="src" />
<file md5sum="a768013d507ab726b4de0c2ef44f28aa" name="src/BSON/Type.c" role="src" />
<file md5sum="1dc53b517c53ef57bb6afeb95dc43b2f" name="src/BSON/UTCDateTime.c" role="src" />
<file md5sum="03bb2b27c777674c1f252befa318148e" name="src/BSON/UTCDateTimeInterface.c" role="src" />
<file md5sum="29a5a26c8aea93fc68da6ef8aec1d4e3" name="src/BSON/Undefined.c" role="src" />
<file md5sum="ab50b5d9374db3ac59b898a772e74dfa" name="src/BSON/Unserializable.c" role="src" />
<file md5sum="405d86c89ce754e9d77a23db4b7bfe9e" name="src/BSON/functions.c" role="src" />
<file md5sum="96e2b2aada16d13a3e58834e5384a232" name="src/BSON/functions.h" role="src" />
<file md5sum="b9d87a9dc3b1a8351c0a44c659940cab" name="src/MongoDB/Exception/AuthenticationException.c" role="src" />
<file md5sum="74548742592f4202bbb61a7747ecd678" name="src/MongoDB/Exception/BulkWriteException.c" role="src" />
<file md5sum="e19afc936327ed3572462d048ee7997e" name="src/MongoDB/Exception/CommandException.c" role="src" />
<file md5sum="aee60b2d392bd9213a6d7e4bceaa2a82" name="src/MongoDB/Exception/ConnectionException.c" role="src" />
<file md5sum="7c60c07144f509d2d500ccdcb4de9a80" name="src/MongoDB/Exception/ConnectionTimeoutException.c" role="src" />
<file md5sum="e5cb1c4a9280f1e0f0dc0c711ea8ea99" name="src/MongoDB/Exception/EncryptionException.c" role="src" />
<file md5sum="e62632a8b843dc20d2d5e133370319d5" name="src/MongoDB/Exception/Exception.c" role="src" />
<file md5sum="f47d6e58f9ddccbf3aee5fc3656fbcac" name="src/MongoDB/Exception/ExecutionTimeoutException.c" role="src" />
<file md5sum="8782de57dd76a17b13a26914dd420ab0" name="src/MongoDB/Exception/InvalidArgumentException.c" role="src" />
<file md5sum="851a91b39708007689071a20d727025a" name="src/MongoDB/Exception/LogicException.c" role="src" />
<file md5sum="8f326b44e15fe89bc237b2c6800cea58" name="src/MongoDB/Exception/RuntimeException.c" role="src" />
<file md5sum="5c96b995f505edb36c61a3a8f3195d61" name="src/MongoDB/Exception/SSLConnectionException.c" role="src" />
<file md5sum="d5030f938bb0ed9c5e5e957957cf46d0" name="src/MongoDB/Exception/ServerException.c" role="src" />
<file md5sum="30f24dfa27447dc59598789562447814" name="src/MongoDB/Exception/UnexpectedValueException.c" role="src" />
<file md5sum="80e3bdb8b53b211b9a9def542ac00a90" name="src/MongoDB/Exception/WriteException.c" role="src" />
- <file md5sum="08d5b2e94488f25a7e63c3358aa4b31d" name="src/MongoDB/Monitoring/CommandFailedEvent.c" role="src" />
- <file md5sum="f73d2111cd5221a44faa96e3dcdd9169" name="src/MongoDB/Monitoring/CommandStartedEvent.c" role="src" />
+ <file md5sum="d75616744f23a9505c734bb2db01f8ef" name="src/MongoDB/Monitoring/CommandFailedEvent.c" role="src" />
+ <file md5sum="c2ed9ad13142a44a4fca7ddc5f843c23" name="src/MongoDB/Monitoring/CommandStartedEvent.c" role="src" />
<file md5sum="50cb8481803e057d183cd6d2f6acf399" name="src/MongoDB/Monitoring/CommandSubscriber.c" role="src" />
- <file md5sum="bcc96e558b26dedc27c84401324c3bad" name="src/MongoDB/Monitoring/CommandSucceededEvent.c" role="src" />
+ <file md5sum="fe67854bd2035ca9de69505dbbe6997c" name="src/MongoDB/Monitoring/CommandSucceededEvent.c" role="src" />
<file md5sum="ccd3d921993593b6681b1cf0bd894c51" name="src/MongoDB/Monitoring/SDAMSubscriber.c" role="src" />
<file md5sum="d8a8c7951b2ef5a471b61ace623e65ef" name="src/MongoDB/Monitoring/ServerChangedEvent.c" role="src" />
<file md5sum="474adf321e6df0f19e9a72ee5b25f173" name="src/MongoDB/Monitoring/ServerClosedEvent.c" role="src" />
<file md5sum="e054dd5ba7903f6c014fdc45853aea6d" name="src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.c" role="src" />
<file md5sum="e316e0880df5bd0049cb2818d0146303" name="src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.c" role="src" />
<file md5sum="9729a4e3482684eac938f89a0c58d6c4" name="src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.c" role="src" />
<file md5sum="948e175b3bbd8dfba99508160595ee82" name="src/MongoDB/Monitoring/ServerOpeningEvent.c" role="src" />
<file md5sum="61eac332e392a2b82e809b8ff78121af" name="src/MongoDB/Monitoring/Subscriber.c" role="src" />
<file md5sum="e31280f973092e9eb55403bff8e45ef7" name="src/MongoDB/Monitoring/TopologyChangedEvent.c" role="src" />
<file md5sum="614f6f0e319b31da439c37435c0dafa7" name="src/MongoDB/Monitoring/TopologyClosedEvent.c" role="src" />
<file md5sum="ca2fdcbd1d277b0152c89cbb45bb3adc" name="src/MongoDB/Monitoring/TopologyOpeningEvent.c" role="src" />
<file md5sum="cc3aeca178c0f9b3df384a9ac389b53f" name="src/MongoDB/Monitoring/functions.c" role="src" />
<file md5sum="1f2bab28965c93a8ac7ee6a923fb5f5f" name="src/MongoDB/Monitoring/functions.h" role="src" />
- <file md5sum="25bd3f0dffd3d9b61d491ce16f23358e" name="src/MongoDB/BulkWrite.c" role="src" />
- <file md5sum="84389398b112c7a09ee8f1c8f218ad72" name="src/MongoDB/ClientEncryption.c" role="src" />
- <file md5sum="39019b79a607dbaa734c95f3fa206da9" name="src/MongoDB/ClientEncryption.h" role="src" />
+ <file md5sum="2c98342e2dabb784fec5552f2e2308b7" name="src/MongoDB/BulkWrite.c" role="src" />
+ <file md5sum="a9bf6bf5997d0c0dd43e5e82ac100339" name="src/MongoDB/ClientEncryption.c" role="src" />
+ <file md5sum="160fece5814c42a5379dae4a8686ff67" name="src/MongoDB/ClientEncryption.h" role="src" />
<file md5sum="41517cdf61c91efd359ae8dff544e497" name="src/MongoDB/Command.c" role="src" />
<file md5sum="662e226d6568974d6e40dca03f7cf9a0" name="src/MongoDB/Cursor.c" role="src" />
<file md5sum="b96c7e5787a25dde042893eb3dde62e0" name="src/MongoDB/Cursor.h" role="src" />
<file md5sum="18fd606bc9223f826568f32c13122e0f" name="src/MongoDB/CursorId.c" role="src" />
<file md5sum="63249beb0af413ca7f34095676abe4bc" name="src/MongoDB/CursorInterface.c" role="src" />
- <file md5sum="e5b5dc1d570661b81d88c76fff0de0e5" name="src/MongoDB/Manager.c" role="src" />
- <file md5sum="ef61de949eb4afc2544960c0d7702e94" name="src/MongoDB/Query.c" role="src" />
+ <file md5sum="ad214bdbeb411a190d82707bece02527" name="src/MongoDB/Manager.c" role="src" />
+ <file md5sum="269bf59e2d7537271c40b0c1cb1c6f80" name="src/MongoDB/Query.c" role="src" />
<file md5sum="8f181751d906a6f258b982ab2b2e71e8" name="src/MongoDB/ReadConcern.c" role="src" />
<file md5sum="dfc43f39b619cba2223dfe0ec89a1317" name="src/MongoDB/ReadConcern.h" role="src" />
<file md5sum="a93c01f9bd5e466e0c1e77bd53d21616" name="src/MongoDB/ReadPreference.c" role="src" />
<file md5sum="faeca5d6267879c0680eca37b3004631" name="src/MongoDB/ReadPreference.h" role="src" />
<file md5sum="a258e198dd195d3c72958c9c932828a2" name="src/MongoDB/Server.c" role="src" />
<file md5sum="d88d4c2dbbc0801b2e193add88fbb282" name="src/MongoDB/Server.h" role="src" />
<file md5sum="fdbedd5ba375592924ef9642594dee4f" name="src/MongoDB/ServerApi.c" role="src" />
<file md5sum="db36048a60e83f7b02808097da5f73fc" name="src/MongoDB/ServerDescription.c" role="src" />
<file md5sum="e002fc9dbbbccc3a6139b4b9e412ca88" name="src/MongoDB/ServerDescription.h" role="src" />
<file md5sum="eaaac065f3e662f931a93b159fe13504" name="src/MongoDB/Session.c" role="src" />
<file md5sum="374083edb0982f2547c33e83f4d2ed05" name="src/MongoDB/Session.h" role="src" />
<file md5sum="66b2814a84d0c5e10c2e19fe8b9ff827" name="src/MongoDB/TopologyDescription.c" role="src" />
<file md5sum="9a1687de6465c1eaf5bf325e3ca0ad48" name="src/MongoDB/TopologyDescription.h" role="src" />
<file md5sum="338e4ad14703a5bf7c41ade1064c4772" name="src/MongoDB/WriteConcern.c" role="src" />
<file md5sum="2b08c4db364d4a012ab7b2943fb8e568" name="src/MongoDB/WriteConcern.h" role="src" />
<file md5sum="f25d93e513b68cab0100a982351eec5e" name="src/MongoDB/WriteConcernError.c" role="src" />
<file md5sum="b46861101a81c17fccb3aa38564903cc" name="src/MongoDB/WriteConcernError.h" role="src" />
<file md5sum="c31462424849d03050cb5d9e6985e9ab" name="src/MongoDB/WriteError.c" role="src" />
<file md5sum="fd1faccf09fa47a68bd3ce3e373464fc" name="src/MongoDB/WriteError.h" role="src" />
<file md5sum="3799c93405c1fa842e4a2e7ade43752a" name="src/MongoDB/WriteResult.c" role="src" />
<file md5sum="b993163f17bfcf57e270271b58e05866" name="src/MongoDB/WriteResult.h" role="src" />
<file md5sum="ee59b98c49f5b5ee3c3dd7a4a21c3aca" name="src/contrib/php_array_api.h" role="src" />
- <file md5sum="d36f9ceb3ac1fc1c5a9e5add685cf12a" name="src/libmongoc/src/common/common-b64-private.h" role="src" />
- <file md5sum="66f9014b39f05a20a26d288d51ab5485" name="src/libmongoc/src/common/common-b64.c" role="src" />
+ <file md5sum="ae554c9634ed301b90ab369bd159dd2c" name="src/libmongoc/src/common/common-b64-private.h" role="src" />
+ <file md5sum="42a7d63b8394debccd688fd6d40416e9" name="src/libmongoc/src/common/common-b64.c" role="src" />
<file md5sum="de3c3dfa7949127b9ca6bced2928b728" name="src/libmongoc/src/common/common-config.h" role="src" />
<file md5sum="619956e6cecc5eb8810b568529e2f63a" name="src/libmongoc/src/common/common-config.h.in" role="src" />
<file md5sum="b1207130abc13297c5d711a1974bb2ae" name="src/libmongoc/src/common/common-macros-private.h" role="src" />
- <file md5sum="15b3cf122cbd4a57f4477169f367fde9" name="src/libmongoc/src/common/common-md5-private.h" role="src" />
- <file md5sum="50917245079095c514f4955c8ea62687" name="src/libmongoc/src/common/common-md5.c" role="src" />
- <file md5sum="0918456265baeddaf1234efe7c8ad055" name="src/libmongoc/src/common/common-prelude.h" role="src" />
- <file md5sum="40a58bcc61821c90a05c8d1b296e9b79" name="src/libmongoc/src/common/common-thread-private.h" role="src" />
- <file md5sum="0de9014cf70947409e870b48f28f6fcc" name="src/libmongoc/src/common/common-thread.c" role="src" />
+ <file md5sum="3f6dc080480bf6d13a50afeae819d2f9" name="src/libmongoc/src/common/common-md5-private.h" role="src" />
+ <file md5sum="8d7c13755a982b3518e0d933b6b39697" name="src/libmongoc/src/common/common-md5.c" role="src" />
+ <file md5sum="4f35c951c897704cf4e5e22db6fc98cd" name="src/libmongoc/src/common/common-prelude.h" role="src" />
+ <file md5sum="e5a38dabdb29f75e22f1293019ef23e6" name="src/libmongoc/src/common/common-thread-private.h" role="src" />
+ <file md5sum="3a63154b4251f7ed1f6fc623d1e648d0" name="src/libmongoc/src/common/common-thread.c" role="src" />
<file md5sum="6afe2ac1833309ef5337e5a04945b4d3" name="src/libmongoc/src/kms-message/src/kms_message/kms_b64.h" role="src" />
<file md5sum="d4883934913f8b0693f90207b21bcc8b" name="src/libmongoc/src/kms-message/src/kms_message/kms_caller_identity_request.h" role="src" />
<file md5sum="3a4c30c28593474cb53c81bb30c0b656" name="src/libmongoc/src/kms-message/src/kms_message/kms_decrypt_request.h" role="src" />
<file md5sum="c6dc01b044efe5c7ba582bd36b3f18e0" name="src/libmongoc/src/kms-message/src/kms_message/kms_encrypt_request.h" role="src" />
<file md5sum="9463d1727695035852304d5947d2e86a" name="src/libmongoc/src/kms-message/src/kms_message/kms_message.h" role="src" />
<file md5sum="d00d408056f02b5ad2bd515e6dda4450" name="src/libmongoc/src/kms-message/src/kms_message/kms_message_defines.h" role="src" />
<file md5sum="a3bc2896fca774b80db0c60cdd1ecb60" name="src/libmongoc/src/kms-message/src/kms_message/kms_request.h" role="src" />
<file md5sum="771832eae920dc27ee493a736dcd0f07" name="src/libmongoc/src/kms-message/src/kms_message/kms_request_opt.h" role="src" />
<file md5sum="5341a53253bb71fdde40ef2733eed413" name="src/libmongoc/src/kms-message/src/kms_message/kms_response.h" role="src" />
<file md5sum="5d8416124f251cd69c9b6c37305aed1e" name="src/libmongoc/src/kms-message/src/kms_message/kms_response_parser.h" role="src" />
<file md5sum="001504937a1c62a19d6c1b56fe353eb1" name="src/libmongoc/src/kms-message/src/hexlify.c" role="src" />
<file md5sum="3ae9830c7804a56d602283845ed86651" name="src/libmongoc/src/kms-message/src/hexlify.h" role="src" />
<file md5sum="e8a52f0b2bc3e28f7c64f0a777ce3770" name="src/libmongoc/src/kms-message/src/kms_b64.c" role="src" />
<file md5sum="9cb501a5bfed23a74f5e38be89c1a6d5" name="src/libmongoc/src/kms-message/src/kms_caller_identity_request.c" role="src" />
<file md5sum="9c64a953bbdfa8ba90cbdc1a1d4519c9" name="src/libmongoc/src/kms-message/src/kms_crypto.h" role="src" />
<file md5sum="f4c1b39c72e5f25c7660bd86d87ca85e" name="src/libmongoc/src/kms-message/src/kms_crypto_apple.c" role="src" />
<file md5sum="32436c05f4a3e55cd176a882e21e13ad" name="src/libmongoc/src/kms-message/src/kms_crypto_libcrypto.c" role="src" />
<file md5sum="74b56cf66ea6e9cff053efb192a29add" name="src/libmongoc/src/kms-message/src/kms_crypto_none.c" role="src" />
<file md5sum="37f833a2d0dbb40323de0ddbacd461d6" name="src/libmongoc/src/kms-message/src/kms_crypto_windows.c" role="src" />
<file md5sum="9142dedbdc54951149219e8d7d733e36" name="src/libmongoc/src/kms-message/src/kms_decrypt_request.c" role="src" />
<file md5sum="69ec5d3da1ee1f8d3185854c883cd707" name="src/libmongoc/src/kms-message/src/kms_encrypt_request.c" role="src" />
<file md5sum="2a7f41d0b533d839384c449f05db13c5" name="src/libmongoc/src/kms-message/src/kms_kv_list.c" role="src" />
<file md5sum="69e374f65d9b21695d194e3495941f37" name="src/libmongoc/src/kms-message/src/kms_kv_list.h" role="src" />
<file md5sum="c2189649bce27380a9b07897662901e0" name="src/libmongoc/src/kms-message/src/kms_message.c" role="src" />
<file md5sum="47167d6a5e423a441d7df65d9feda9d7" name="src/libmongoc/src/kms-message/src/kms_message_private.h" role="src" />
<file md5sum="e470c7dcd696d7c4a2f401d23e93a218" name="src/libmongoc/src/kms-message/src/kms_port.c" role="src" />
<file md5sum="52247eca34cb25b7d80aad345e393e81" name="src/libmongoc/src/kms-message/src/kms_port.h" role="src" />
<file md5sum="f38035514480120b10b4bcb2c334e2a0" name="src/libmongoc/src/kms-message/src/kms_request.c" role="src" />
<file md5sum="0e650d43199b0e12ffb08b38f54c9b90" name="src/libmongoc/src/kms-message/src/kms_request_opt.c" role="src" />
<file md5sum="4c851b149d17a8d3818de213af8f2d06" name="src/libmongoc/src/kms-message/src/kms_request_opt_private.h" role="src" />
- <file md5sum="888bf715d142e373232463eccf0dffcf" name="src/libmongoc/src/kms-message/src/kms_request_str.c" role="src" />
+ <file md5sum="1972356299fd9636a5438f644ad4bfb7" name="src/libmongoc/src/kms-message/src/kms_request_str.c" role="src" />
<file md5sum="7d8d321cf69c6316096ca2aab4c9728c" name="src/libmongoc/src/kms-message/src/kms_request_str.h" role="src" />
<file md5sum="ea5d236af2499b31ad2d6b8820376313" name="src/libmongoc/src/kms-message/src/kms_response.c" role="src" />
<file md5sum="2253d59b564ae589d7f0bc6c41626ec2" name="src/libmongoc/src/kms-message/src/kms_response_parser.c" role="src" />
<file md5sum="dff15b5018efb6269a2a0269c5ddb798" name="src/libmongoc/src/kms-message/src/sort.c" role="src" />
<file md5sum="18f9bd055f6a60e7702603b6b8bf07d5" name="src/libmongoc/src/kms-message/src/sort.h" role="src" />
<file md5sum="889d90340a7b3210d087b2a2f02699cf" name="src/libmongoc/src/libbson/src/bson/bcon.c" role="src" />
<file md5sum="af5d3c6890b4fec8709a349289f8f9d3" name="src/libmongoc/src/libbson/src/bson/bcon.h" role="src" />
<file md5sum="d6e124824ed51206dcab5ddf67bc230e" name="src/libmongoc/src/libbson/src/bson/bson-atomic.c" role="src" />
<file md5sum="8d34494ea96177002420f9aeea1fd7e0" name="src/libmongoc/src/libbson/src/bson/bson-atomic.h" role="src" />
<file md5sum="ef3d475df2f82f4fdd78daaf6d754a35" name="src/libmongoc/src/libbson/src/bson/bson-clock.c" role="src" />
<file md5sum="941aa21f16b18e768fd8072a15a4da71" name="src/libmongoc/src/libbson/src/bson/bson-clock.h" role="src" />
- <file md5sum="c6a908f8f5612d723e3f81d8a4eb08bd" name="src/libmongoc/src/libbson/src/bson/bson-compat.h" role="src" />
+ <file md5sum="20ac103c272aa836071037072df5b34b" name="src/libmongoc/src/libbson/src/bson/bson-cmp.h" role="src" />
+ <file md5sum="25c9beaee5c3bc71f85fc9f3bdf0cb90" name="src/libmongoc/src/libbson/src/bson/bson-compat.h" role="src" />
<file md5sum="0462387cd269514d5e9742b02860cbd3" name="src/libmongoc/src/libbson/src/bson/bson-config.h" role="src" />
<file md5sum="1ebb885e9482b3e8d3afaef498ccf209" name="src/libmongoc/src/libbson/src/bson/bson-config.h.in" role="src" />
<file md5sum="61e6cd1fe450560f487cabbb69c8de40" name="src/libmongoc/src/libbson/src/bson/bson-context-private.h" role="src" />
<file md5sum="2e0640f2ec04abc1210d976393e960b5" name="src/libmongoc/src/libbson/src/bson/bson-context.c" role="src" />
<file md5sum="1a25c8d61105c7da95a9563835b8bc3a" name="src/libmongoc/src/libbson/src/bson/bson-context.h" role="src" />
- <file md5sum="5840b8ec20580e9fd360a86fbb37baaf" name="src/libmongoc/src/libbson/src/bson/bson-decimal128.c" role="src" />
+ <file md5sum="6ce55ee2de3f8ae9b0e4b248898462e1" name="src/libmongoc/src/libbson/src/bson/bson-decimal128.c" role="src" />
<file md5sum="6700198519a93ee85b8c95bcddfced30" name="src/libmongoc/src/libbson/src/bson/bson-decimal128.h" role="src" />
<file md5sum="07b4f9d909657026cc8261d63084d67b" name="src/libmongoc/src/libbson/src/bson/bson-endian.h" role="src" />
<file md5sum="4f643560fbb549b900ea02d2a7b34484" name="src/libmongoc/src/libbson/src/bson/bson-error.c" role="src" />
<file md5sum="5ee55f4f9a3401900b82a0381ab8f2a8" name="src/libmongoc/src/libbson/src/bson/bson-error.h" role="src" />
<file md5sum="6910b34f7cf6d0b522f548aa2599b490" name="src/libmongoc/src/libbson/src/bson/bson-iso8601-private.h" role="src" />
<file md5sum="4d80e24fadedcfce63799efad8333489" name="src/libmongoc/src/libbson/src/bson/bson-iso8601.c" role="src" />
- <file md5sum="e726ae34c8b34e8ab7e414032791160b" name="src/libmongoc/src/libbson/src/bson/bson-iter.c" role="src" />
+ <file md5sum="17e413e088efb3f098579468b58cbac2" name="src/libmongoc/src/libbson/src/bson/bson-iter.c" role="src" />
<file md5sum="1d7b25e4b7051c95da6dda05e8703894" name="src/libmongoc/src/libbson/src/bson/bson-iter.h" role="src" />
<file md5sum="037b65f0f7695a6c779bda5a108b708a" name="src/libmongoc/src/libbson/src/bson/bson-json-private.h" role="src" />
- <file md5sum="fbf8b4e7a5a9a15ff1e804c1608137ea" name="src/libmongoc/src/libbson/src/bson/bson-json.c" role="src" />
+ <file md5sum="9ebd2b162b5d2d52bf3d27afd52134fb" name="src/libmongoc/src/libbson/src/bson/bson-json.c" role="src" />
<file md5sum="cbb1cff3aaa7472a50bb185a455f6544" name="src/libmongoc/src/libbson/src/bson/bson-json.h" role="src" />
<file md5sum="5addb8761faac2e8d52f4ded8ecdc0c0" name="src/libmongoc/src/libbson/src/bson/bson-keys.c" role="src" />
<file md5sum="e1973fc044b52bfc2bb35b440350d228" name="src/libmongoc/src/libbson/src/bson/bson-keys.h" role="src" />
<file md5sum="8dd1917f2dea0d985a707db37494ae78" name="src/libmongoc/src/libbson/src/bson/bson-macros.h" role="src" />
- <file md5sum="69c9a5bd0fcdeacffadb994c6d2e9e57" name="src/libmongoc/src/libbson/src/bson/bson-md5.c" role="src" />
+ <file md5sum="ee97c0e463270be3c97207a3555c7fb4" name="src/libmongoc/src/libbson/src/bson/bson-md5.c" role="src" />
<file md5sum="64bfaad7b9c371ac3cc5b19ae0d88fb5" name="src/libmongoc/src/libbson/src/bson/bson-md5.h" role="src" />
<file md5sum="e1ab64fb2919ea159ad8d72a29f5b544" name="src/libmongoc/src/libbson/src/bson/bson-memory.c" role="src" />
<file md5sum="a50cea3f9a11bd1a11448b2b865b656e" name="src/libmongoc/src/libbson/src/bson/bson-memory.h" role="src" />
<file md5sum="8301daa3ba4306b2a89af70c619aa209" name="src/libmongoc/src/libbson/src/bson/bson-oid.c" role="src" />
<file md5sum="2e25ec392f12cf4afd970fff2bedacd4" name="src/libmongoc/src/libbson/src/bson/bson-oid.h" role="src" />
<file md5sum="1cf75fbb62bcbe7bfed5906fce7bd0cd" name="src/libmongoc/src/libbson/src/bson/bson-prelude.h" role="src" />
<file md5sum="9173795c678991efc29bec5c95e402b4" name="src/libmongoc/src/libbson/src/bson/bson-private.h" role="src" />
<file md5sum="b351f160949566778783d1ba7a5b4d60" name="src/libmongoc/src/libbson/src/bson/bson-reader.c" role="src" />
<file md5sum="eda7ef0c3380276709b2f8e833867689" name="src/libmongoc/src/libbson/src/bson/bson-reader.h" role="src" />
<file md5sum="fc1eb647810867d1db76dccb3ea3b663" name="src/libmongoc/src/libbson/src/bson/bson-string.c" role="src" />
<file md5sum="84bb7fecb29271e3a8fdc145cb33a77b" name="src/libmongoc/src/libbson/src/bson/bson-string.h" role="src" />
<file md5sum="f80c7197ff122c24f1a2642b083fb523" name="src/libmongoc/src/libbson/src/bson/bson-timegm-private.h" role="src" />
<file md5sum="cf1148af5b260d787b5a8de5ba82de77" name="src/libmongoc/src/libbson/src/bson/bson-timegm.c" role="src" />
<file md5sum="89ccd18b278677e3f25297a8c3171624" name="src/libmongoc/src/libbson/src/bson/bson-types.h" role="src" />
<file md5sum="4b3ce4f29b9b19e9db849d4a674ad3e4" name="src/libmongoc/src/libbson/src/bson/bson-utf8.c" role="src" />
<file md5sum="f23b07d93c8c65df5c0142f8ede21612" name="src/libmongoc/src/libbson/src/bson/bson-utf8.h" role="src" />
<file md5sum="5db2801d1c52e5027937dd5facab1b3d" name="src/libmongoc/src/libbson/src/bson/bson-value.c" role="src" />
<file md5sum="6d175e5373d24e3f403416b7871be3ca" name="src/libmongoc/src/libbson/src/bson/bson-value.h" role="src" />
<file md5sum="0bcfe98e683ae4fa5a6321fd6cafd9cd" name="src/libmongoc/src/libbson/src/bson/bson-version-functions.c" role="src" />
<file md5sum="0f7724eca64476682b9fd7f7a970cc04" name="src/libmongoc/src/libbson/src/bson/bson-version-functions.h" role="src" />
- <file md5sum="3f9e5f3a1d5482d58d08929e98b22e96" name="src/libmongoc/src/libbson/src/bson/bson-version.h" role="src" />
+ <file md5sum="fbe89a524c34b6505d28d262f1668c08" name="src/libmongoc/src/libbson/src/bson/bson-version.h" role="src" />
<file md5sum="1f473fea4d18c65e7bb00be8bf2e841c" name="src/libmongoc/src/libbson/src/bson/bson-version.h.in" role="src" />
<file md5sum="61ba6f5aa4028b691ee22ea27eb3c3c5" name="src/libmongoc/src/libbson/src/bson/bson-writer.c" role="src" />
<file md5sum="05d85f6ccc42974bc14cf0eab289ebce" name="src/libmongoc/src/libbson/src/bson/bson-writer.h" role="src" />
- <file md5sum="42ab62f44421b55736ca0e26e656ae9c" name="src/libmongoc/src/libbson/src/bson/bson.c" role="src" />
- <file md5sum="30bce06980f59cd0b2785119a75fe3cf" name="src/libmongoc/src/libbson/src/bson/bson.h" role="src" />
- <file md5sum="cc8e625953a6cdb6147172f86f8d0c20" name="src/libmongoc/src/libbson/src/jsonsl/jsonsl.c" role="src" />
+ <file md5sum="dcb5fe9e70f2da897b36a3acf705760f" name="src/libmongoc/src/libbson/src/bson/bson.c" role="src" />
+ <file md5sum="776f296d33d19560b03d6287457c8c8b" name="src/libmongoc/src/libbson/src/bson/bson.h" role="src" />
+ <file md5sum="802636f9a4c2fc47e32ce86bbdbc8a1f" name="src/libmongoc/src/libbson/src/jsonsl/jsonsl.c" role="src" />
<file md5sum="cc4d69576f4fe9b87cd116d399309454" name="src/libmongoc/src/libbson/src/jsonsl/jsonsl.h" role="src" />
<file md5sum="715a53b77739b4f6d87b7236792b3501" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate-private.h" role="src" />
<file md5sum="648dc84b316f30cfee1e349d23d0cbe4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-aggregate.c" role="src" />
- <file md5sum="d9a75b51a24fee7ec1199d905d143a92" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h" role="src" />
- <file md5sum="e9893c44b0a5074b8c98a95813540151" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c" role="src" />
- <file md5sum="790a6172ae0da5905bbbc0dc1c1afd32" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h" role="src" />
+ <file md5sum="d1661d443992a339ecf57515faa12b41" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm-private.h" role="src" />
+ <file md5sum="9d1591efbb707732db5b79a95a9b6e0b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.c" role="src" />
+ <file md5sum="5763bc790fd6953c53f7f47e17d5df9a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-apm.h" role="src" />
<file md5sum="02429f357ecd89327482930aec8bf34b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-array-private.h" role="src" />
<file md5sum="475df6bf5cd4e55e0d4b26db29ea71fc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-array.c" role="src" />
- <file md5sum="766374d866c30f32a4e5a313494d7cce" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h" role="src" />
- <file md5sum="d39616bfb99494f48a63d8de5f59d9e7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c" role="src" />
+ <file md5sum="032e0543a66478717d9f0cc009f6d2d5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h" role="src" />
+ <file md5sum="ae9e1b28b9d5e4ddcb8aeaf6bc9a1799" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-cmd.c" role="src" />
<file md5sum="6117af585e6f280e22535fee10458148" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async-private.h" role="src" />
<file md5sum="73f6de02c9db4135e7e7c355ae1a2c40" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-async.c" role="src" />
<file md5sum="5e7c0de09a22745fce5b273d8e9e964c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer-private.h" role="src" />
<file md5sum="f4b3b177551d2703d24cd5be1add89e6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-buffer.c" role="src" />
- <file md5sum="d099437d7ea96ce3115170be386adceb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h" role="src" />
- <file md5sum="190e9e9843d5449a86ff5a6a14cb8737" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c" role="src" />
- <file md5sum="f403a3a84cde66d80a223638f14f5f9f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h" role="src" />
- <file md5sum="178d695599ed8eb98de6672aff1ca0bc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h" role="src" />
- <file md5sum="98e5ebfb273118744c8c808dd362f7b1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c" role="src" />
+ <file md5sum="91c1eb3d729658aa2223afa012309d89" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h" role="src" />
+ <file md5sum="a0d5c66a07f40582d709114bd20ce896" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.c" role="src" />
+ <file md5sum="c7c58cc72c027d23d5d0cef20474d61b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-bulk-operation.h" role="src" />
+ <file md5sum="2d04c728cb978fe554324bf674ca5279" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream-private.h" role="src" />
+ <file md5sum="f8c3c90c2c2e161795d0711593fbd379" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.c" role="src" />
<file md5sum="a28176a567c6cd9b3e06246256c7ac7d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-change-stream.h" role="src" />
<file md5sum="dd048997f3230e0f019ad17ecfcf9dfd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool-private.h" role="src" />
<file md5sum="b72259ca1a8d2cac04b988e34eed3346" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.c" role="src" />
<file md5sum="b7ec158f7e0c1f298aefaa9bdeb41563" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-pool.h" role="src" />
- <file md5sum="14b66b6f1433f8dd36dad38102f12dac" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h" role="src" />
+ <file md5sum="6594c96f504877379fc444fd9609eab7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-private.h" role="src" />
<file md5sum="be1f432f9f37b512ecd98c1c21e6ff05" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session-private.h" role="src" />
<file md5sum="0de5b07694d64591f176f100e4557810" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.c" role="src" />
<file md5sum="3d591f816481c1584c3aa1f870b42aea" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-session.h" role="src" />
<file md5sum="829e08021e4b012a3df657e9d3745aed" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption-private.h" role="src" />
- <file md5sum="8dfb1264e95c1ca51d236703979fe590" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c" role="src" />
- <file md5sum="b5be0a43bc59dc23fea512cd25d3fbf7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h" role="src" />
- <file md5sum="28b37e67f9e183c94496ed239ceb1cc4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c" role="src" />
+ <file md5sum="c436df25d2dcd7dcfad5eddffa618eaa" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.c" role="src" />
+ <file md5sum="a02ca1d756716401ffa4a0917954f948" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client-side-encryption.h" role="src" />
+ <file md5sum="657db5e6a985b8d62d23a5748d95d63d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.c" role="src" />
<file md5sum="a1b1212bb6ae352f4d6cd67651bf4990" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-client.h" role="src" />
<file md5sum="ea98e4e4ae56c176e8286f3373b93872" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws-private.h" role="src" />
- <file md5sum="b33a55893a9031048815f4bf7bde06fe" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c" role="src" />
+ <file md5sum="20875c545605f6107bd107846f3aa81f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-aws.c" role="src" />
<file md5sum="abc87a40623b01a2848a13483f55c0eb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h" role="src" />
<file md5sum="6ceb56409fb779b40887d8c597ae585d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c" role="src" />
- <file md5sum="ebd5c2aba2df20f73a0a663726e4fcec" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h" role="src" />
+ <file md5sum="6aa7369d453417d5eaed2770a120def3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-private.h" role="src" />
<file md5sum="7b7c909f1fa7029ea48d4d06e18c23a1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h" role="src" />
<file md5sum="9c05f27fa8164bfdb5b9d9d2afd7c8ec" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c" role="src" />
<file md5sum="820290eb3904bfc15d4b8bd246407472" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h" role="src" />
<file md5sum="9d09cad4e1c89c4f22540ecbf58b6f8a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c" role="src" />
- <file md5sum="d43168f26bc6f50b83858fa904b54f39" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c" role="src" />
+ <file md5sum="f732dc1d65598a7faf8281fbb748006f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cluster.c" role="src" />
<file md5sum="83eee40cd11208e81a44593e173464a7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd-private.h" role="src" />
- <file md5sum="e2a1834c201488ad8d5d16992dc58ae0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c" role="src" />
+ <file md5sum="23deef6bb237afa225e3a65fefa65f13" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cmd.c" role="src" />
<file md5sum="7be3fb1fffde65a0a4f9864cc666585f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection-private.h" role="src" />
- <file md5sum="280ac84e5c3a1220231e5aa073043e9c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c" role="src" />
+ <file md5sum="058de46d0122e5593df5dff1372d89ac" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.c" role="src" />
<file md5sum="2cea9224f2c11ca0048d3faf871f3e43" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-collection.h" role="src" />
<file md5sum="51a5f2b055faf65386ed28d537af94e2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression-private.h" role="src" />
<file md5sum="c8efb75e7a6278b654502ad1f16b5e50" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-compression.c" role="src" />
<file md5sum="d347554bc29b7c2687a51c2ac01b355e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h" role="src" />
<file md5sum="2626cb59611d7ff06184fdf3d59deff7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in" role="src" />
<file md5sum="83b01f3ae0287022e4c5b4dbe0512904" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters-private.h" role="src" />
<file md5sum="0e75630e4d381fba80801afc10811173" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.c" role="src" />
<file md5sum="04d57743da7337aaec4dfe958a5742b7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-counters.defs" role="src" />
- <file md5sum="d1111578a21c720b026904bb1e3ae223" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h" role="src" />
- <file md5sum="c25a245ac4db12e014ddd4bfe67bf27b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c" role="src" />
+ <file md5sum="bb35d3ae73856a1c28afdd2df9b87617" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt-private.h" role="src" />
+ <file md5sum="9bee074297289bd16e303afa883cda18" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypt.c" role="src" />
<file md5sum="92fd26e85664f6c9d2d369c0fadc025b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h" role="src" />
<file md5sum="4962154517e614c682f72ec91a2dfb21" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-cng.c" role="src" />
<file md5sum="b3e1538050bff40cd2232ccc57978580" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h" role="src" />
<file md5sum="05bc88780422e1fecf959938dba4f37c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c" role="src" />
<file md5sum="b8182112c242fe00bfb665e7b7af8d09" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h" role="src" />
<file md5sum="45f55e6aa1c9ca8dd427bd45c28f50ed" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c" role="src" />
<file md5sum="d917683855b94173416b062df755d960" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto-private.h" role="src" />
<file md5sum="2dc0df9846f851aead72d9fd4d734760" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-crypto.c" role="src" />
<file md5sum="f1f255dcc6c9c9abc06423b00553a660" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-array.c" role="src" />
<file md5sum="f39ea72235be77d77a30ad06c15be5b4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-change-stream.c" role="src" />
<file md5sum="13772036c14fa28597bae438270f5494" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd-deprecated.c" role="src" />
<file md5sum="34522fc38976abd9e0ea6fbfce136a98" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-cmd.c" role="src" />
<file md5sum="436a0c9fea83bc37dfde5b82044db2de" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-cmd.c" role="src" />
<file md5sum="d4664b89578808b1581a6a971e47f49e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find-opquery.c" role="src" />
<file md5sum="7f05b5ea17fabe3535bc9bff4287c694" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-find.c" role="src" />
- <file md5sum="1eb05f279e142f8ba2d98234dc65bf9c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c" role="src" />
+ <file md5sum="cface98993658381c76763fb15f5fe21" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-legacy.c" role="src" />
<file md5sum="ada83d26ea3f38bde4ee190b94ef4823" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor-private.h" role="src" />
- <file md5sum="2fb83683c83eac38e3aa32052b38736c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c" role="src" />
+ <file md5sum="46a181c825c1c3fa7048bcb25bbaa443" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.c" role="src" />
<file md5sum="ab02e4cb247e4dedbf49e30b4b02e193" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cursor.h" role="src" />
<file md5sum="cf20c0277c2b973281325739721d635b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus-private.h" role="src" />
- <file md5sum="5c67ae23fe25b60c480c4955af75dfe2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c" role="src" />
- <file md5sum="31a9b3420812c03b4446dd9ab13f222d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h" role="src" />
- <file md5sum="46104d074e3c88a22e968d7148d6f22a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c" role="src" />
+ <file md5sum="d162f9049a2ed66800dca95c43026719" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-cyrus.c" role="src" />
+ <file md5sum="22937a27e0b5553f0324a434a800319c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database-private.h" role="src" />
+ <file md5sum="a46074b4638c9c62a586e7def650d60c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.c" role="src" />
<file md5sum="8b34d317248c622bf08e1fe26dddf437" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-database.h" role="src" />
<file md5sum="28d90894b4e7c78bef2b1ca1834d0fcb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-errno-private.h" role="src" />
- <file md5sum="768d0fbe35f8ba072ca468716d6bfe98" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h" role="src" />
+ <file md5sum="d9e745f42abbf1f2852f6fb09b489948" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error-private.h" role="src" />
<file md5sum="7958f96545cdfd6141f233b92f446cf7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.c" role="src" />
<file md5sum="f40e2b5ae830e43faf63d180d2e55b6b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-error.h" role="src" />
<file md5sum="1ba39aca81a5d25857b77542e307b97b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h" role="src" />
<file md5sum="d0253ef5feb5587064d86eeb19577a1c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.c" role="src" />
<file md5sum="4baf895100d5eeffe2fde56396a06b08" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-find-and-modify.h" role="src" />
<file md5sum="75af2dc3e1069036fb8d78c1a94ca3c8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags-private.h" role="src" />
<file md5sum="dcb65a56ce1b685779763817f44c5581" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-flags.h" role="src" />
<file md5sum="678c516515546e641e5eca6cfce0ee48" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map-private.h" role="src" />
<file md5sum="cd7f1914be3de0388504ac87a199e0d2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-generation-map.c" role="src" />
<file md5sum="61a20bbf13213628a988af242bec479b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file-private.h" role="src" />
<file md5sum="a805e8f77e86cb9b806c48b6677a8ec8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-file.c" role="src" />
<file md5sum="58fcf3011bfd394f310f3daa9594855b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket-private.h" role="src" />
<file md5sum="916ebb08602002a944ccb104b02f8ca4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c" role="src" />
<file md5sum="9ae55fdb24c8d042514b4beaeffbbc37" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-bucket.h" role="src" />
<file md5sum="952b93d5ee76b7402ea500906809161b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h" role="src" />
<file md5sum="8597d29f134e6d78cb6a34ea74423bab" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c" role="src" />
<file md5sum="869dae5d01adf048bb1299cca4afba84" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h" role="src" />
<file md5sum="282f5e691bb325deb6b8891eb13149f2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h" role="src" />
<file md5sum="6f0ed4d860816a02bfd98c9b50340227" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c" role="src" />
<file md5sum="3b932d73546d72dae9fcb918c41de57d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h" role="src" />
<file md5sum="c03dd7e85d3095caf235744ebb562a0e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h" role="src" />
<file md5sum="3a40c1bac045fbcf2cc6cfa985be4c56" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.c" role="src" />
<file md5sum="4391ad3ca3396e9fc9b4c0c4e5772bfb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-file.h" role="src" />
<file md5sum="ef7007f002b46c8354fee538e885de40" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs-private.h" role="src" />
<file md5sum="8a825992520617af35e9bddb0aabe9c6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.c" role="src" />
<file md5sum="d20582bf915d78253359a937ed28bbea" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-gridfs.h" role="src" />
<file md5sum="bbc260b536678d5331744aee0c186256" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h" role="src" />
<file md5sum="67039f2c6bc58df9e35fcb0cab2c2dbc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h" role="src" />
- <file md5sum="1814373012d79db5741434170a2b6fee" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h" role="src" />
+ <file md5sum="ddeb85cede4d3ca8a0e920210f380e09" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake-private.h" role="src" />
<file md5sum="5bfc06e8d27d29ccc1b8417c83caf86c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.c" role="src" />
<file md5sum="fa8bc2ce220ac698bc154b1b245750cd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-handshake.h" role="src" />
<file md5sum="7c57b5152a74508c5ff78f14b2f1ffea" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list-private.h" role="src" />
<file md5sum="48b031f3f051bfd4c8f014a1f8a6aa86" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.c" role="src" />
<file md5sum="5e2da30e912e909ed594a59683833f7d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-host-list.h" role="src" />
<file md5sum="c1934ce90e02b46a05a9a4751dbc0262" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-http-private.h" role="src" />
<file md5sum="552f945bb02a4c698a66608dd30f1fe1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-http.c" role="src" />
<file md5sum="5ac6b6febc5f47878215fbc74bd44de7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.c" role="src" />
<file md5sum="dad1a4af8adf72a13809fd6c1c10afee" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-index.h" role="src" />
<file md5sum="9a065aa2944698f9d0f64496cd59c8bd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.c" role="src" />
<file md5sum="747ea7ab1744daf2a7e42508780575b1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-init.h" role="src" />
<file md5sum="3502d9809ba3e5866ce10037c4b3563c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt-private.h" role="src" />
- <file md5sum="3177cbfad1c5079952840fbb4c4dfbe4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c" role="src" />
+ <file md5sum="876b6f1e5f466e54aceee02c9d157b21" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-interrupt.c" role="src" />
<file md5sum="c3d4de8405f528f15caf2ab7f847ca12" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-iovec.h" role="src" />
<file md5sum="c06c20bc7e775d6d8bced165cd04f8ee" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl-private.h" role="src" />
<file md5sum="0c90387fd3fe9289c20cf4354d6bd87e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-libressl.c" role="src" />
<file md5sum="8c0701b9c767f009ba52d7231059d12b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h" role="src" />
<file md5sum="54d78d18718c9b8705de0862b931f476" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c" role="src" />
<file md5sum="88813fcf803fccf84966f26431b3b71a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-list-private.h" role="src" />
<file md5sum="ab4d31b167f229b490faf5b71a714339" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-list.c" role="src" />
<file md5sum="be914702b66b1e1b8582cb9277239001" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-log-private.h" role="src" />
<file md5sum="7df5c2164e44e9f2697de0833ceb53cf" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.c" role="src" />
<file md5sum="1c741c1aed2b563cacb6bced8e97d0b0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-log.h" role="src" />
<file md5sum="439f25680fbc4c8a7542502287e3675e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-macros.h" role="src" />
<file md5sum="5a3506bda8c1638be4b76999c3c50f12" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h" role="src" />
<file md5sum="e3555fc6a1007c07d55f4f210097d689" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-op.c" role="src" />
<file md5sum="dd1d23edde3907521792649267b48bc3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher-private.h" role="src" />
<file md5sum="cf91b7fcfb80ccaa33329d6bf14f8fbc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.c" role="src" />
<file md5sum="30f6ed82f9988d2e4485e6fd23632d02" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-matcher.h" role="src" />
<file md5sum="86736045e6dcc91d8c525c87720b2911" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp-private.h" role="src" />
<file md5sum="cc510669bc8cdbfab031f54e143085e2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-memcmp.c" role="src" />
<file md5sum="a5d748bdf1c4b5cb845c6a81370d7961" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache-private.h" role="src" />
<file md5sum="f2c3545733f228d2457f64373ee5831b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ocsp-cache.c" role="src" />
<file md5sum="14f209fb86ed514cdde4b187d35ac83b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opcode.h" role="src" />
<file md5sum="810df1337011be8f15d0719f1e03d798" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl-private.h" role="src" />
- <file md5sum="e429f31c6f1d66a0ac819f2a27adee72" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c" role="src" />
+ <file md5sum="c97609309a855c14971439e231564b96" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-openssl.c" role="src" />
<file md5sum="eb42adc455bdb25e9180243e56cdd812" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.c" role="src" />
<file md5sum="f90b93bf8d4e15329353b361b19eb1e5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-optional.h" role="src" />
<file md5sum="eb48d60cbcae6ce34b3b1b3edc3b9e73" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers-private.h" role="src" />
<file md5sum="abae85a1d96099484ea092abd7459a6a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-helpers.c" role="src" />
- <file md5sum="6ac236f005b1b09c334689d9257aef04" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h" role="src" />
- <file md5sum="cfb8187dc6e8a2f3d6a700cb435792fa" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c" role="src" />
+ <file md5sum="7bb07cd240da256213763b38662e68a8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts-private.h" role="src" />
+ <file md5sum="76d46d049601504c6c84e9828c490e22" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-opts.c" role="src" />
<file md5sum="a5a16bf330ec389692145c0a0f796d40" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-prelude.h" role="src" />
<file md5sum="9d479bd2f13f239d558616322f8b4fb6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue-private.h" role="src" />
<file md5sum="7da2ed3fabbeee9a88c7ddeab9f11a20" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-queue.c" role="src" />
<file md5sum="fa9297dcbff7191c36b6fb2b2a5a9c91" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-cng.c" role="src" />
<file md5sum="b8818c8c7c155272ab33a04dfb0c464c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c" role="src" />
<file md5sum="12887a2170ee9f8678c22675ac706b03" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-openssl.c" role="src" />
<file md5sum="d665e822fefc6c01c4dd9ee4d1a02f2b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand-private.h" role="src" />
<file md5sum="41c7cd3177c60893f4eec6b144ceedc9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rand.h" role="src" />
<file md5sum="a9abe88c57feeade91e4617b1582ea84" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern-private.h" role="src" />
<file md5sum="f877494d6f2aacb31a7aab8f2e46c911" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.c" role="src" />
<file md5sum="6e1554a4f43b405f70bbf2c59ead73dd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-concern.h" role="src" />
<file md5sum="a200756c4228fc0675ab5e7057546068" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h" role="src" />
<file md5sum="26b9e46531eb411d8100ce1244e17bde" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.c" role="src" />
<file md5sum="39494b56050754f341ac9e1aa259b8a6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-read-prefs.h" role="src" />
- <file md5sum="14d70d8935bf21f4c3239e45d86f4e6e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h" role="src" />
- <file md5sum="4346415ce0acd31256f6c337054946b8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c" role="src" />
+ <file md5sum="33d60ed21bc64c6e1cc9494d107025ca" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc-private.h" role="src" />
+ <file md5sum="6d90e88047851f0f504c52907aedf661" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-rpc.c" role="src" />
<file md5sum="02680a898c086020b12d6efdcefaef1b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl-private.h" role="src" />
<file md5sum="f12439745ff93ee7d533b34cdfd76fdf" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sasl.c" role="src" />
<file md5sum="fb161be2bdaf05d53d5e8e4bb4760b0a" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram-private.h" role="src" />
- <file md5sum="0dd217d6feb694507b2c572b4f2e0762" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c" role="src" />
+ <file md5sum="f7842ee5740acf137690fa31ca9dbdd8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c" role="src" />
<file md5sum="b2795ae4c107dbbc11aa3d97d0c61d84" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h" role="src" />
<file md5sum="7091fbaa03b9dcfd7f2c26a798ab0ad8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-channel.c" role="src" />
<file md5sum="a6abefa0bc83ec37be8176b2df7de977" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h" role="src" />
<file md5sum="791823b6db4e4901f985450b553a65ca" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-secure-transport.c" role="src" />
<file md5sum="b3dc46ca7adc34861ea6e9c45e50b05b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api-private.h" role="src" />
<file md5sum="af60f4e10e4dc9c35f421a5601169d4d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.c" role="src" />
<file md5sum="78dfc9819e8f8bc83a71b53404eadf3c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-api.h" role="src" />
- <file md5sum="e49225578378e16850bb21e4027e25b0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h" role="src" />
- <file md5sum="fb336c049ea18c8b2826ddaa9a859bdf" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c" role="src" />
+ <file md5sum="27aa28f9017c93311e669e2c6db3e401" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description-private.h" role="src" />
+ <file md5sum="ace41c33630c5d4560302e3603a6395b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.c" role="src" />
<file md5sum="cc8bf5c6bc4fdc600a2455ea4c236259" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-description.h" role="src" />
<file md5sum="e75b07c14e3879fb67832dd839de29e0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor-private.h" role="src" />
- <file md5sum="2b970c294a8f7ee7d4e0f0c2b93bb649" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c" role="src" />
+ <file md5sum="ffac50798d7ab58ec36a4079761d6199" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-monitor.c" role="src" />
<file md5sum="63f17f6ae6d2f79dcbdf2113c7db20fb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream-private.h" role="src" />
<file md5sum="f1af771373ac1bdcb03a6fbb6358e74d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-server-stream.c" role="src" />
<file md5sum="cede4eeffec68b7ada9b86cf41955c74" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-set-private.h" role="src" />
<file md5sum="e273f247bdd66f3e66dd96c218b01d9c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-set.c" role="src" />
<file md5sum="bd017efd5e6206fb55a3ac7306a95f24" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared-private.h" role="src" />
<file md5sum="bcd3b9c778ecf5639a06be567674d340" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-shared.c" role="src" />
<file md5sum="37376243128180b5b0d7eacef659f3d6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket-private.h" role="src" />
<file md5sum="16b1377ba13959205b9ee171e49edeb1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c" role="src" />
<file md5sum="3f61c4bf2a022ee0a3d85154a5bee770" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.h" role="src" />
<file md5sum="41500393a9c5ffdb8cc7c66c4a1960c0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl-private.h" role="src" />
<file md5sum="b463a4cff8d5d424c62c726aaa657982" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.c" role="src" />
<file md5sum="42c133e3ad18a70058177091190401fd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ssl.h" role="src" />
<file md5sum="cc755861d5be912193591ad063bcad48" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi-private.h" role="src" />
<file md5sum="11a45877cdfc2df905aa0d162bb493b7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-sspi.c" role="src" />
<file md5sum="cc3fc77850ae4bea293bd74b4cf60a04" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.c" role="src" />
<file md5sum="9b245df6c45d411766be5f7290e8da04" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-buffered.h" role="src" />
<file md5sum="f25a6cc9eeb840f34847f81cc2f36b60" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.c" role="src" />
<file md5sum="4ce12f6db0b74f55d3c49c34332b6f7d" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-file.h" role="src" />
<file md5sum="dc85d644079ad2e79d9d9dbe49facf10" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download-private.h" role="src" />
<file md5sum="131246e2d632381ce14d72fdbb1b3f21" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-download.c" role="src" />
<file md5sum="7c0cce0559efc51ffe81a5465aa41484" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload-private.h" role="src" />
<file md5sum="b2eb639aae1caed00f7032b27e73cfbd" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs-upload.c" role="src" />
<file md5sum="d247dac07fdfffa79422f0682f546a77" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c" role="src" />
<file md5sum="f66d645623c5b2ba02e6afe1cc0b00df" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h" role="src" />
<file md5sum="fa30b8c754b1523186b0c0c19bf017dc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-private.h" role="src" />
<file md5sum="3dbc0c52c735d318b3efbedb25a6005e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.c" role="src" />
<file md5sum="c25f4029b8bbb9990ffe947511a4d534" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-socket.h" role="src" />
<file md5sum="90ec84cb182c98c7fc8fa8af0e85bdf0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h" role="src" />
<file md5sum="116918bf8bb96c6f9165c13a4c1096a7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c" role="src" />
<file md5sum="986de196a5775636248360a89ac342ce" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h" role="src" />
<file md5sum="3fd16580fa667309339b94b19a396b9e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h" role="src" />
<file md5sum="f72dd2878dcd9333a138e6c62adcd971" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c" role="src" />
<file md5sum="377279ab2c57036be34ac0b8684d74c8" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h" role="src" />
- <file md5sum="98c94302efb2e4d3198d9de9390c00b6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c" role="src" />
+ <file md5sum="c3fbdc385987825a68b3e0903cbfb6b6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c" role="src" />
<file md5sum="d304866f9dfa3e2372b0e94abf58452f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h" role="src" />
<file md5sum="cfdd7f4e9b7619ec17a2af509ca99714" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h" role="src" />
<file md5sum="8df0fd4f5dc00181e9ebbe3eef3f321e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h" role="src" />
<file md5sum="f5bff5eaedc38a85fd334045e0f95b31" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c" role="src" />
<file md5sum="a548717b6ae53390c8f44dcb02c5af18" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h" role="src" />
<file md5sum="0d18b0e579e693ff1e484632a7ffbe3c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h" role="src" />
<file md5sum="6c7f4e134ef9fbe5ece63ede7b34e618" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c" role="src" />
<file md5sum="db9560efe8c38948cf3d0935566475c4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h" role="src" />
<file md5sum="b4c2290ab76580b8428b18ada4760f53" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.c" role="src" />
<file md5sum="7cf653c627cc7708161dbb9c2cad7f1e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream-tls.h" role="src" />
<file md5sum="77d9779c925cbdcc010c708ceff13495" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.c" role="src" />
<file md5sum="e8a3b99226da0b724dd3e01f845f3207" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-stream.h" role="src" />
<file md5sum="b5ceb7c14c3ca2c2407d80a2db2d28d0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-thread-private.h" role="src" />
<file md5sum="3773c7ef3ac14e7f138fdb1182f91e80" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout-private.h" role="src" />
<file md5sum="eb72065aec6b9338f3300f5ab638f375" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-timeout.c" role="src" />
<file md5sum="acaa4ec85c67a8aa87a89c11da253c3c" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring-private.h" role="src" />
- <file md5sum="5d151338cb01096ebbef9d961bd98ae2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c" role="src" />
+ <file md5sum="d1b0ca2df72570ae85f381f44b0f60ef" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c" role="src" />
<file md5sum="395d5e3342ba5a943413926f65ccc9a1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h" role="src" />
<file md5sum="9e33bee391288851c85bbf348c5a6056" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c" role="src" />
<file md5sum="c8960b386615370139dcb753f6006fb3" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description-private.h" role="src" />
<file md5sum="00c18293e63fa882bafaed3d94216534" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.c" role="src" />
<file md5sum="7216b55e1e9684b298b54af143edd9a6" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-description.h" role="src" />
- <file md5sum="4030cc8fd66093079f6ad356582490c0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h" role="src" />
- <file md5sum="ef81ed481d1c1290f10e4e54db2980da" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h" role="src" />
- <file md5sum="0e0c077ce62414d05e9c775f48a533d5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c" role="src" />
- <file md5sum="47c012bf597764130b7da8501e0227f1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c" role="src" />
+ <file md5sum="8464bacb4133ebea8922453ec604e420" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-private.h" role="src" />
+ <file md5sum="dae9f14b2f40ac1fe61198ac520524f5" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h" role="src" />
+ <file md5sum="2f9ba4197a35a1df2211e3151b142c8f" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology-scanner.c" role="src" />
+ <file md5sum="bf17f81fa9747f880db1f02a5368f9aa" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-topology.c" role="src" />
<file md5sum="74353ddb00d3f8a4d5423dc86a5be7e0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-trace-private.h" role="src" />
<file md5sum="10fbbc3cf1ba5c22883635e3bca4d2d0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool-private.h" role="src" />
<file md5sum="e34b16cbe4d47974b6bb9182c4b605bb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-ts-pool.c" role="src" />
<file md5sum="2d0158d029d00435eaf3b98fdd9f1c3b" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri-private.h" role="src" />
<file md5sum="00ebae12fca5c180c653f10da08ff6dc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.c" role="src" />
<file md5sum="ec8a82d2d8c002b1517fee400464e7cc" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-uri.h" role="src" />
- <file md5sum="b415b8bf55bcb220c31f0db30b6422f4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h" role="src" />
- <file md5sum="fbca4cc6014a2272f04607ed27d04a29" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c" role="src" />
+ <file md5sum="c2fbfa5cb28235b0235d355d3e2f9049" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util-private.h" role="src" />
+ <file md5sum="426122cb2a580eeee61f464a2f252af2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-util.c" role="src" />
<file md5sum="5c7c2a82e500e9a518fa596ff9c44021" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.c" role="src" />
<file md5sum="c7cfe57411c17d6d3028ee180f1772e9" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version-functions.h" role="src" />
- <file md5sum="98de9dc51da20da2e319c0c437c89019" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h" role="src" />
+ <file md5sum="839dcf21047aa510e7a92cbb18767841" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h" role="src" />
<file md5sum="ff10fb268641d60f7b14f911208fb2b1" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in" role="src" />
<file md5sum="0808798e16ae4d6d7d8d01df40a54052" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy-private.h" role="src" />
- <file md5sum="6130f80234c368dcb70cf713b8effbc4" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c" role="src" />
- <file md5sum="ee107bf849dd6644a6453a395651c2d0" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h" role="src" />
- <file md5sum="c526d42415961800fb727d241b4863ea" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c" role="src" />
+ <file md5sum="4b4ba286a42b6dc608ef9c3ca91d2db2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-legacy.c" role="src" />
+ <file md5sum="b986ee1c5694198a047a01c6e83283cb" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command-private.h" role="src" />
+ <file md5sum="b825c116424dbaa798d1ac585187add2" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-command.c" role="src" />
<file md5sum="e5bce2b46dbf04b76fe5485db9de7e4e" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern-private.h" role="src" />
<file md5sum="2b01095b4919618f6d33b2c418c29455" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.c" role="src" />
<file md5sum="d777c85e5593d047218fef92f7ab5434" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc-write-concern.h" role="src" />
<file md5sum="22b9dfd9aacdbca888e8fb7a71dfe4f7" name="src/libmongoc/src/libmongoc/src/mongoc/mongoc.h" role="src" />
<file md5sum="f3e25b8f4865b4ff5ce5830870d8cec5" name="src/libmongoc/src/libmongoc/src/mongoc/op-compressed.def" role="src" />
<file md5sum="ed1890accd7d9a1426fdac121ed42ad4" name="src/libmongoc/src/libmongoc/src/mongoc/op-delete.def" role="src" />
<file md5sum="9af88adf2ef432761bbe81db2f9bdce7" name="src/libmongoc/src/libmongoc/src/mongoc/op-get-more.def" role="src" />
<file md5sum="242fff22640f143ae262e363e8552a7e" name="src/libmongoc/src/libmongoc/src/mongoc/op-header.def" role="src" />
<file md5sum="2efe34631dd0d540d0f1d2fdb2d57813" name="src/libmongoc/src/libmongoc/src/mongoc/op-insert.def" role="src" />
<file md5sum="79ab986cb49a47e7c9bccdc4005a9697" name="src/libmongoc/src/libmongoc/src/mongoc/op-kill-cursors.def" role="src" />
<file md5sum="7e1f1d29f10ca2b86aed48b4071b9800" name="src/libmongoc/src/libmongoc/src/mongoc/op-msg.def" role="src" />
<file md5sum="a986d22cb495d652dc6059d722bb3266" name="src/libmongoc/src/libmongoc/src/mongoc/op-query.def" role="src" />
<file md5sum="f82bc931404ce00b318675126572d667" name="src/libmongoc/src/libmongoc/src/mongoc/op-reply-header.def" role="src" />
<file md5sum="dd22bb15cb70d35fe25192f0f304871b" name="src/libmongoc/src/libmongoc/src/mongoc/op-reply.def" role="src" />
<file md5sum="03c6179a4fe8b51c606b03a763529d55" name="src/libmongoc/src/libmongoc/src/mongoc/op-update.def" role="src" />
<file md5sum="28e467e1c2bfe811edfcfc86662f3987" name="src/libmongoc/src/libmongoc/src/mongoc/utlist.h" role="src" />
- <file md5sum="4dc406b7d1b6e49c22eee2e01177c195" name="src/libmongoc/src/zlib-1.2.11/adler32.c" role="src" />
- <file md5sum="bca8dc2f982dfce8944aec9f4a83626c" name="src/libmongoc/src/zlib-1.2.11/compress.c" role="src" />
- <file md5sum="f9a17af8e4efe8019fca94827ea1c0db" name="src/libmongoc/src/zlib-1.2.11/crc32.c" role="src" />
- <file md5sum="f28d16b67efecdfafa0d816a7d982124" name="src/libmongoc/src/zlib-1.2.11/crc32.h" role="src" />
- <file md5sum="9e645d2cc17f3e324028b90d25edc969" name="src/libmongoc/src/zlib-1.2.11/deflate.c" role="src" />
- <file md5sum="c5839b3f66d79c5aa0daa5062de59bd5" name="src/libmongoc/src/zlib-1.2.11/deflate.h" role="src" />
- <file md5sum="29d02cff161bde3e4e717b25a2ab7050" name="src/libmongoc/src/zlib-1.2.11/gzclose.c" role="src" />
- <file md5sum="de472a3069a84c6e6b1eb083c3f91b53" name="src/libmongoc/src/zlib-1.2.11/gzguts.h" role="src" />
- <file md5sum="2c08acd5014596272031fdd1a36d0f1c" name="src/libmongoc/src/zlib-1.2.11/gzlib.c" role="src" />
- <file md5sum="a2a2f3a65c2891b1a8cf98be9b499e96" name="src/libmongoc/src/zlib-1.2.11/gzread.c" role="src" />
- <file md5sum="92c3520553ac47aaa67f36ac9a571761" name="src/libmongoc/src/zlib-1.2.11/gzwrite.c" role="src" />
- <file md5sum="f2adcadab3504b146be9c4928821f233" name="src/libmongoc/src/zlib-1.2.11/infback.c" role="src" />
- <file md5sum="20d7b26f5ae64f4e8501f846beab550c" name="src/libmongoc/src/zlib-1.2.11/inffast.c" role="src" />
- <file md5sum="f3669099d3f571dbc0426401ed5f50e3" name="src/libmongoc/src/zlib-1.2.11/inffast.h" role="src" />
- <file md5sum="7fa3e91804601b6618c915b76a8dc332" name="src/libmongoc/src/zlib-1.2.11/inffixed.h" role="src" />
- <file md5sum="c892c303a1be104ed0efb628e18ed85a" name="src/libmongoc/src/zlib-1.2.11/inflate.c" role="src" />
- <file md5sum="12c1f3adaf005c8a4cfb629f2e266d30" name="src/libmongoc/src/zlib-1.2.11/inflate.h" role="src" />
- <file md5sum="34a634c4c6e1de2e357f18c170e6b96c" name="src/libmongoc/src/zlib-1.2.11/inftrees.c" role="src" />
- <file md5sum="ec87be89b9bcca8ced80a70f857e823b" name="src/libmongoc/src/zlib-1.2.11/inftrees.h" role="src" />
- <file md5sum="fddcbf441ed0140dec23927ee34de9a7" name="src/libmongoc/src/zlib-1.2.11/trees.c" role="src" />
- <file md5sum="51fdcb3e2ccf60ca13c06920c89296a3" name="src/libmongoc/src/zlib-1.2.11/trees.h" role="src" />
- <file md5sum="dc210f08738914519d15edf1bb6e5141" name="src/libmongoc/src/zlib-1.2.11/uncompr.c" role="src" />
- <file md5sum="66c6b3953f574eca8b709dd5f6865745" name="src/libmongoc/src/zlib-1.2.11/zconf.h" role="src" />
- <file md5sum="66c6b3953f574eca8b709dd5f6865745" name="src/libmongoc/src/zlib-1.2.11/zconf.h.in" role="src" />
- <file md5sum="0338828e9d00c94645648b1517108324" name="src/libmongoc/src/zlib-1.2.11/zlib.h" role="src" />
- <file md5sum="69d0e0950d3ab5c1938d8566257c33a3" name="src/libmongoc/src/zlib-1.2.11/zutil.c" role="src" />
- <file md5sum="b8a47cd8873cbfa8daf689f88dd62f75" name="src/libmongoc/src/zlib-1.2.11/zutil.h" role="src" />
+ <file md5sum="4dc406b7d1b6e49c22eee2e01177c195" name="src/libmongoc/src/zlib-1.2.12/adler32.c" role="src" />
+ <file md5sum="bca8dc2f982dfce8944aec9f4a83626c" name="src/libmongoc/src/zlib-1.2.12/compress.c" role="src" />
+ <file md5sum="bc9da84ad46376bc0c3717daa806d097" name="src/libmongoc/src/zlib-1.2.12/crc32.c" role="src" />
+ <file md5sum="0ce0ac9394905aa53ed0a915620d9e5d" name="src/libmongoc/src/zlib-1.2.12/crc32.h" role="src" />
+ <file md5sum="ced86fdeacf259b3fce1a0339f1d5167" name="src/libmongoc/src/zlib-1.2.12/deflate.c" role="src" />
+ <file md5sum="34da0cf83aa75e62309aab91253fa63d" name="src/libmongoc/src/zlib-1.2.12/deflate.h" role="src" />
+ <file md5sum="29d02cff161bde3e4e717b25a2ab7050" name="src/libmongoc/src/zlib-1.2.12/gzclose.c" role="src" />
+ <file md5sum="db97f959e6b95017fd036d805c9a23c3" name="src/libmongoc/src/zlib-1.2.12/gzguts.h" role="src" />
+ <file md5sum="3f9383498e257c650cc91782d9e57383" name="src/libmongoc/src/zlib-1.2.12/gzlib.c" role="src" />
+ <file md5sum="62ce9507c5a1d2b271b588f1742499e9" name="src/libmongoc/src/zlib-1.2.12/gzread.c" role="src" />
+ <file md5sum="88662ce74bc97f8d01ebb886e8c13c11" name="src/libmongoc/src/zlib-1.2.12/gzwrite.c" role="src" />
+ <file md5sum="2d98b4e9d15a2ec3ce110466cab1402d" name="src/libmongoc/src/zlib-1.2.12/infback.c" role="src" />
+ <file md5sum="4942f8c7c85dca21c18812163e2f9530" name="src/libmongoc/src/zlib-1.2.12/inffast.c" role="src" />
+ <file md5sum="f3669099d3f571dbc0426401ed5f50e3" name="src/libmongoc/src/zlib-1.2.12/inffast.h" role="src" />
+ <file md5sum="7fa3e91804601b6618c915b76a8dc332" name="src/libmongoc/src/zlib-1.2.12/inffixed.h" role="src" />
+ <file md5sum="cf91c5b70bf9828bf0e6eceb226da32b" name="src/libmongoc/src/zlib-1.2.12/inflate.c" role="src" />
+ <file md5sum="819fb5556d0c65ba2577ee379b4641c0" name="src/libmongoc/src/zlib-1.2.12/inflate.h" role="src" />
+ <file md5sum="1618e07c0b945202be074a7ec9c39c72" name="src/libmongoc/src/zlib-1.2.12/inftrees.c" role="src" />
+ <file md5sum="ec87be89b9bcca8ced80a70f857e823b" name="src/libmongoc/src/zlib-1.2.12/inftrees.h" role="src" />
+ <file md5sum="53ac3bbd056e76a84602008f0980b883" name="src/libmongoc/src/zlib-1.2.12/trees.c" role="src" />
+ <file md5sum="51fdcb3e2ccf60ca13c06920c89296a3" name="src/libmongoc/src/zlib-1.2.12/trees.h" role="src" />
+ <file md5sum="dc210f08738914519d15edf1bb6e5141" name="src/libmongoc/src/zlib-1.2.12/uncompr.c" role="src" />
+ <file md5sum="66c6b3953f574eca8b709dd5f6865745" name="src/libmongoc/src/zlib-1.2.12/zconf.h.in" role="src" />
+ <file md5sum="d3e8793e6d1b7c77d2a7732246f14063" name="src/libmongoc/src/zlib-1.2.12/zlib.h" role="src" />
+ <file md5sum="0e761e9849f6031abcb9df5aa53b1d63" name="src/libmongoc/src/zlib-1.2.12/zutil.c" role="src" />
+ <file md5sum="3bb15310e32649d4ecdcff5c1a1ea0ef" name="src/libmongoc/src/zlib-1.2.12/zutil.h" role="src" />
<file md5sum="801dd41ee3301f2e0385658e8d409cb0" name="src/libmongocrypt-compat/mongocrypt/mongocrypt.h" role="src" />
- <file md5sum="94b739a5ca4735c9efbef6c7c29c8e60" name="src/libmongocrypt-compat/mongocrypt-export.h" role="src" />
+ <file md5sum="f22eebcf8eeea32715bac7c95e704d09" name="src/libmongocrypt-compat/mongocrypt-export.h" role="src" />
<file md5sum="ffc011eff957abdff3b1b2dc3360c9ff" name="src/libmongocrypt/kms-message/src/kms_message/kms_azure_request.h" role="src" />
<file md5sum="178bd08ac73470d35b4986e388085161" name="src/libmongocrypt/kms-message/src/kms_message/kms_b64.h" role="src" />
<file md5sum="39ee9cf46b0439403a0f7c8073f583d5" name="src/libmongocrypt/kms-message/src/kms_message/kms_caller_identity_request.h" role="src" />
<file md5sum="8ebc97b8d9401873858ade801e9feb35" name="src/libmongocrypt/kms-message/src/kms_message/kms_decrypt_request.h" role="src" />
<file md5sum="d0fed9c2821dff65ae9dc6879ee881b6" name="src/libmongocrypt/kms-message/src/kms_message/kms_encrypt_request.h" role="src" />
<file md5sum="610a7df9b3f166d1173a890a19784b84" name="src/libmongocrypt/kms-message/src/kms_message/kms_gcp_request.h" role="src" />
<file md5sum="320d3ed66a12df7b88f3e2aacfd1f26d" name="src/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h" role="src" />
<file md5sum="a1eb97816ae793c9701208349233eb12" name="src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h" role="src" />
<file md5sum="0cd5c466ec235998c2a758540154ed75" name="src/libmongocrypt/kms-message/src/kms_message/kms_kmip_response_parser.h" role="src" />
<file md5sum="c1a35d0b49f3f920d16ffc84f4d8e373" name="src/libmongocrypt/kms-message/src/kms_message/kms_message.h" role="src" />
<file md5sum="cfef23bb3ac62cf8d3fbd8e08015f0c0" name="src/libmongocrypt/kms-message/src/kms_message/kms_message_defines.h" role="src" />
<file md5sum="5663ee4fe8bcca2dc395cd5be3617b44" name="src/libmongocrypt/kms-message/src/kms_message/kms_request.h" role="src" />
<file md5sum="ad85fcbd4c473f138818a4bd9e7f0815" name="src/libmongocrypt/kms-message/src/kms_message/kms_request_opt.h" role="src" />
<file md5sum="209083716262424fab84d670209755c8" name="src/libmongocrypt/kms-message/src/kms_message/kms_response.h" role="src" />
<file md5sum="36754553406792f1c571ec1133d76785" name="src/libmongocrypt/kms-message/src/kms_message/kms_response_parser.h" role="src" />
<file md5sum="e87486a63aa846e479f3bf1af7380038" name="src/libmongocrypt/kms-message/src/hexlify.c" role="src" />
<file md5sum="60664bb6d46c14b4eea28f15e6a082e5" name="src/libmongocrypt/kms-message/src/hexlify.h" role="src" />
<file md5sum="1e4af07511a196a91fd60a0e24a6e158" name="src/libmongocrypt/kms-message/src/kms_azure_request.c" role="src" />
<file md5sum="7ea85b23709fab14de6e2ac7f5ba66f2" name="src/libmongocrypt/kms-message/src/kms_b64.c" role="src" />
<file md5sum="29d5db2215a92ef6121c729f6c75ee00" name="src/libmongocrypt/kms-message/src/kms_caller_identity_request.c" role="src" />
<file md5sum="32b4b23b26fceaed3874af2f4a012f68" name="src/libmongocrypt/kms-message/src/kms_crypto.h" role="src" />
<file md5sum="d23244b72417192b5a8f6d2afed4410a" name="src/libmongocrypt/kms-message/src/kms_crypto_apple.c" role="src" />
<file md5sum="d6ef24b2ededc8139cd4137397325368" name="src/libmongocrypt/kms-message/src/kms_crypto_libcrypto.c" role="src" />
<file md5sum="1636e264b74abccf68fcf0df1806fbe3" name="src/libmongocrypt/kms-message/src/kms_crypto_none.c" role="src" />
<file md5sum="6c2dd3a27026c65f88694d615fe7d0a9" name="src/libmongocrypt/kms-message/src/kms_crypto_windows.c" role="src" />
<file md5sum="aba07d5c53233adfe5d8928b5ef92e06" name="src/libmongocrypt/kms-message/src/kms_decrypt_request.c" role="src" />
<file md5sum="65692a06262c9889f7ce0ae81928d390" name="src/libmongocrypt/kms-message/src/kms_encrypt_request.c" role="src" />
<file md5sum="d353001a1f4139bfae3631f2cd41b4e8" name="src/libmongocrypt/kms-message/src/kms_endian_private.h" role="src" />
<file md5sum="9e2953c624d8a37b2cabc3358d54db4a" name="src/libmongocrypt/kms-message/src/kms_gcp_request.c" role="src" />
<file md5sum="593d915279b88dcc90ccdc13562ade1d" name="src/libmongocrypt/kms-message/src/kms_kmip_item_type_private.h" role="src" />
<file md5sum="598d5fa1534ca2a169440f56ae8853d6" name="src/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c" role="src" />
<file md5sum="9a659b418853e5b1895776b46fef7870" name="src/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h" role="src" />
<file md5sum="e854b55dc5e3bc8c377435246a8ac843" name="src/libmongocrypt/kms-message/src/kms_kmip_request.c" role="src" />
<file md5sum="5cf970d24111daf63277cc3c49425938" name="src/libmongocrypt/kms-message/src/kms_kmip_response.c" role="src" />
<file md5sum="470eb89defd7c4d57636938192192e89" name="src/libmongocrypt/kms-message/src/kms_kmip_response_parser.c" role="src" />
<file md5sum="f64765a9c63171b8aa2c5fd7de738072" name="src/libmongocrypt/kms-message/src/kms_kmip_response_parser_private.h" role="src" />
<file md5sum="21898fd3923dfa059f2139a555643e14" name="src/libmongocrypt/kms-message/src/kms_kmip_result_reason_private.h" role="src" />
<file md5sum="8f826227b67ce2503aeb359cea5a3402" name="src/libmongocrypt/kms-message/src/kms_kmip_result_status_private.h" role="src" />
<file md5sum="ec4325cc2b8516ba039d41b922e78e82" name="src/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h" role="src" />
<file md5sum="2a7f41d0b533d839384c449f05db13c5" name="src/libmongocrypt/kms-message/src/kms_kv_list.c" role="src" />
<file md5sum="69e374f65d9b21695d194e3495941f37" name="src/libmongocrypt/kms-message/src/kms_kv_list.h" role="src" />
<file md5sum="c2189649bce27380a9b07897662901e0" name="src/libmongocrypt/kms-message/src/kms_message.c" role="src" />
<file md5sum="1a522b4a4306818d69b41961575dcc4f" name="src/libmongocrypt/kms-message/src/kms_message_private.h" role="src" />
<file md5sum="f27094bd3cd0c6174a279875623af84e" name="src/libmongocrypt/kms-message/src/kms_port.c" role="src" />
<file md5sum="52247eca34cb25b7d80aad345e393e81" name="src/libmongocrypt/kms-message/src/kms_port.h" role="src" />
- <file md5sum="2b999b9501258a2aaa8989b5af4a1f9a" name="src/libmongocrypt/kms-message/src/kms_request.c" role="src" />
+ <file md5sum="1d8e512d5de303c6f1ca58a86dd63108" name="src/libmongocrypt/kms-message/src/kms_request.c" role="src" />
<file md5sum="fd15be17d87fa70a2bab1a0309b71b82" name="src/libmongocrypt/kms-message/src/kms_request_opt.c" role="src" />
<file md5sum="c7079940f8096ea3bce05d343de44481" name="src/libmongocrypt/kms-message/src/kms_request_opt_private.h" role="src" />
<file md5sum="888bf715d142e373232463eccf0dffcf" name="src/libmongocrypt/kms-message/src/kms_request_str.c" role="src" />
<file md5sum="8943a55e4b590e6aaf6e7df818922699" name="src/libmongocrypt/kms-message/src/kms_request_str.h" role="src" />
<file md5sum="92b75e5851d90b8d28949ef18417c789" name="src/libmongocrypt/kms-message/src/kms_response.c" role="src" />
- <file md5sum="fbeb43438b539423d1ba7ea55f8fc545" name="src/libmongocrypt/kms-message/src/kms_response_parser.c" role="src" />
+ <file md5sum="30c3fa5f1f0e858b67dc38a8167abf75" name="src/libmongocrypt/kms-message/src/kms_response_parser.c" role="src" />
<file md5sum="dff15b5018efb6269a2a0269c5ddb798" name="src/libmongocrypt/kms-message/src/sort.c" role="src" />
<file md5sum="18f9bd055f6a60e7702603b6b8bf07d5" name="src/libmongocrypt/kms-message/src/sort.h" role="src" />
- <file md5sum="7199d9d1b761dd3e7bb98dd5872fe4dd" name="src/libmongocrypt/src/crypto/cng.c" role="src" />
- <file md5sum="7cdc2caf59a0624bf98b339d944a84c8" name="src/libmongocrypt/src/crypto/commoncrypto.c" role="src" />
- <file md5sum="fdc1e194924183150c685cf8f884e23f" name="src/libmongocrypt/src/crypto/libcrypto.c" role="src" />
- <file md5sum="e66c0b266bc841431bc251bc5f0044e8" name="src/libmongocrypt/src/crypto/none.c" role="src" />
+ <file md5sum="83f860b3d45e64845025303af0d02ae9" name="src/libmongocrypt/src/crypto/cng.c" role="src" />
+ <file md5sum="32e59c12404db9389170e80290986620" name="src/libmongocrypt/src/crypto/commoncrypto.c" role="src" />
+ <file md5sum="4cb47e0e038839aa99e3504fa875ccad" name="src/libmongocrypt/src/crypto/libcrypto.c" role="src" />
+ <file md5sum="87a5b5ee7b2c9406a1243b7f9fc3d592" name="src/libmongocrypt/src/crypto/none.c" role="src" />
<file md5sum="2678e814143dfde62c0bdf8ee7ddab28" name="src/libmongocrypt/src/mlib/error.h" role="src" />
<file md5sum="8e0b42bcd1eaa9a8ac1f31283d162cab" name="src/libmongocrypt/src/mlib/path.h" role="src" />
- <file md5sum="16eb747980bd3f1e69cbb8498c35765f" name="src/libmongocrypt/src/mlib/str.h" role="src" />
+ <file md5sum="4fe4e0a7fe2604ad823d5e5db6acbf84" name="src/libmongocrypt/src/mlib/str.h" role="src" />
<file md5sum="19cde120e49273bc0197da1656a0fba3" name="src/libmongocrypt/src/mlib/thread.h" role="src" />
<file md5sum="0f4e6528293d8a8ef1e2cd3771a67053" name="src/libmongocrypt/src/mlib/user-check.h" role="src" />
<file md5sum="9c0cd74b3c026396ed50fd40839c1a26" name="src/libmongocrypt/src/mlib/windows-lean.h" role="src" />
- <file md5sum="b89f9a8d3dee058a2b6d56375b698343" name="src/libmongocrypt/src/os_posix/os_dll.c" role="src" />
+ <file md5sum="2d6090641939ae5871ff6f65ebc8af03" name="src/libmongocrypt/src/os_posix/os_dll.c" role="src" />
<file md5sum="39a4c1f631e35ead04f8ba13a11bba65" name="src/libmongocrypt/src/os_posix/os_mutex.c" role="src" />
- <file md5sum="838723a785bd5f1ff1b6ccd8928daca4" name="src/libmongocrypt/src/os_win/os_dll.c" role="src" />
+ <file md5sum="abe887e20e284f0c2c8392ba71bec212" name="src/libmongocrypt/src/os_win/os_dll.c" role="src" />
<file md5sum="f95d328d2484c7369dc938a5366cf846" name="src/libmongocrypt/src/os_win/os_mutex.c" role="src" />
- <file md5sum="9bf1794f8ac3532ea4ffd96ae52888ae" name="src/libmongocrypt/src/mongo_csfle-v1.h" role="src" />
+ <file md5sum="f694b6cf21dd356e54a9382a62ad5073" name="src/libmongocrypt/src/mc-efc-private.h" role="src" />
+ <file md5sum="2d68fe017d5d6c1902bf191c596e1f51" name="src/libmongocrypt/src/mc-efc.c" role="src" />
+ <file md5sum="250cdd4170f052cfd92d223f5d660fd4" name="src/libmongocrypt/src/mc-fle-blob-subtype-private.h" role="src" />
+ <file md5sum="92e5efc20d877826512bc11b8fb58959" name="src/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h" role="src" />
+ <file md5sum="2c971bccc9f632e5533a3acaa8756e23" name="src/libmongocrypt/src/mc-fle2-encryption-placeholder.c" role="src" />
+ <file md5sum="4255e16ee9bbcb4e60d83039b3d8ac82" name="src/libmongocrypt/src/mc-fle2-find-equality-payload-private.h" role="src" />
+ <file md5sum="2405d8ba0c56f8d78726d19951238aef" name="src/libmongocrypt/src/mc-fle2-find-equality-payload.c" role="src" />
+ <file md5sum="843545837428c4a8a5640c71e1a19cd8" name="src/libmongocrypt/src/mc-fle2-insert-update-payload-private.h" role="src" />
+ <file md5sum="dfff0397d3de9df6f170830e238f4f3c" name="src/libmongocrypt/src/mc-fle2-insert-update-payload.c" role="src" />
+ <file md5sum="cb575a9863a6bcce26779eff0d533fc8" name="src/libmongocrypt/src/mc-fle2-payload-ieev-private.h" role="src" />
+ <file md5sum="7c302dd11b21f1f953763cbffa1b965a" name="src/libmongocrypt/src/mc-fle2-payload-ieev.c" role="src" />
+ <file md5sum="104cdb62d6e993735f47b2e4d2a2b54f" name="src/libmongocrypt/src/mc-fle2-payload-uev-private.h" role="src" />
+ <file md5sum="a4102787b874275c3bc044f34121dbdc" name="src/libmongocrypt/src/mc-fle2-payload-uev.c" role="src" />
+ <file md5sum="b7d9797fe2f5e71f4b0dc23e980e4576" name="src/libmongocrypt/src/mc-tokens-private.h" role="src" />
+ <file md5sum="8afc1e61fe19f629ead3416274218052" name="src/libmongocrypt/src/mc-tokens.c" role="src" />
+ <file md5sum="e4de9003ee36be8f111db29ad64ba468" name="src/libmongocrypt/src/mongo_crypt-v1.h" role="src" />
<file md5sum="34e15d89ffa2a308ea86b1ae2cb0088f" name="src/libmongocrypt/src/mongocrypt-binary-private.h" role="src" />
<file md5sum="b81c6d7cb5e9526df940d94c813284e9" name="src/libmongocrypt/src/mongocrypt-binary.c" role="src" />
- <file md5sum="0a81f609be9fa064a2747ce49f9d9295" name="src/libmongocrypt/src/mongocrypt-buffer-private.h" role="src" />
- <file md5sum="12cb785445ab7d10ef0e5409e8827da5" name="src/libmongocrypt/src/mongocrypt-buffer.c" role="src" />
+ <file md5sum="42ece81fc2701afc4eae81e131684f40" name="src/libmongocrypt/src/mongocrypt-buffer-private.h" role="src" />
+ <file md5sum="f18d6cfcc2c16aef3c0d644786c24a15" name="src/libmongocrypt/src/mongocrypt-buffer.c" role="src" />
<file md5sum="b5e9bc242b7d785f6c293d875c2d3c71" name="src/libmongocrypt/src/mongocrypt-cache-collinfo-private.h" role="src" />
<file md5sum="48c5eb499d93bd2e230d38b78515deaa" name="src/libmongocrypt/src/mongocrypt-cache-collinfo.c" role="src" />
<file md5sum="1b4df4f22323d029c972086c956926d4" name="src/libmongocrypt/src/mongocrypt-cache-key-private.h" role="src" />
<file md5sum="21c432424e1a3160a71c8daa03a64cb5" name="src/libmongocrypt/src/mongocrypt-cache-key.c" role="src" />
<file md5sum="b2bfeff59a23a567715a46b7f1e56b8f" name="src/libmongocrypt/src/mongocrypt-cache-oauth-private.h" role="src" />
<file md5sum="6a6bdd6ae519a198bd9cc38fd3d66187" name="src/libmongocrypt/src/mongocrypt-cache-oauth.c" role="src" />
<file md5sum="56a3c0f20b220f11a18965282facea22" name="src/libmongocrypt/src/mongocrypt-cache-private.h" role="src" />
<file md5sum="cf785575cca4c00c45dac5de2251c0c3" name="src/libmongocrypt/src/mongocrypt-cache.c" role="src" />
- <file md5sum="3ee978103ce2a2f53b87f03b5bf9c12f" name="src/libmongocrypt/src/mongocrypt-ciphertext-private.h" role="src" />
- <file md5sum="bdecd2c011f4f816c8660e3324115ca1" name="src/libmongocrypt/src/mongocrypt-ciphertext.c" role="src" />
+ <file md5sum="6893303c75e1ec5dc113343f1321e4f3" name="src/libmongocrypt/src/mongocrypt-ciphertext-private.h" role="src" />
+ <file md5sum="4c321bf7eec124147ac02494f4c2815e" name="src/libmongocrypt/src/mongocrypt-ciphertext.c" role="src" />
<file md5sum="e4ef675e85348b5ec19de83aede925ee" name="src/libmongocrypt/src/mongocrypt-compat.h" role="src" />
- <file md5sum="b13ae1e7606af6047d74166b4ef2495f" name="src/libmongocrypt/src/mongocrypt-config.h" role="src" />
- <file md5sum="6f51385c8021d849d4338bec0a8d0afc" name="src/libmongocrypt/src/mongocrypt-config.h.in" role="src" />
- <file md5sum="4b9f7565a5cefe8a40c6c65f196c7b59" name="src/libmongocrypt/src/mongocrypt-crypto-private.h" role="src" />
- <file md5sum="fbdf3042130dc80240c5c73b127f2d9d" name="src/libmongocrypt/src/mongocrypt-crypto.c" role="src" />
- <file md5sum="e262ada6e5d2d7bc646c620069302722" name="src/libmongocrypt/src/mongocrypt-ctx-datakey.c" role="src" />
- <file md5sum="502f446a79814987c271a6baa18b50d2" name="src/libmongocrypt/src/mongocrypt-ctx-decrypt.c" role="src" />
- <file md5sum="ea86fe107be10e7948b71dce661d548b" name="src/libmongocrypt/src/mongocrypt-ctx-encrypt.c" role="src" />
- <file md5sum="10c2dfeacad9be275f71912a6d0f5ec2" name="src/libmongocrypt/src/mongocrypt-ctx-private.h" role="src" />
- <file md5sum="297ba78f17e16f5b7d971b358c9f0b80" name="src/libmongocrypt/src/mongocrypt-ctx.c" role="src" />
- <file md5sum="27ad6650139510beb8165907458c615b" name="src/libmongocrypt/src/mongocrypt-dll-private.h" role="src" />
+ <file md5sum="ecfa49d93c8f8d4afaa7b82ae026b83d" name="src/libmongocrypt/src/mongocrypt-config.h" role="src" />
+ <file md5sum="da03665c049ef6d8f82f588830c73532" name="src/libmongocrypt/src/mongocrypt-config.h.in" role="src" />
+ <file md5sum="a419aaa20a0cfebff63417a0892c9135" name="src/libmongocrypt/src/mongocrypt-crypto-private.h" role="src" />
+ <file md5sum="18c63c35633d4918bd00c15e83cb4e81" name="src/libmongocrypt/src/mongocrypt-crypto.c" role="src" />
+ <file md5sum="54f37187a3a413c6566742b709635147" name="src/libmongocrypt/src/mongocrypt-ctx-datakey.c" role="src" />
+ <file md5sum="66523b5b915d923130b2d48371bc2102" name="src/libmongocrypt/src/mongocrypt-ctx-decrypt.c" role="src" />
+ <file md5sum="3ec888b9ef01f99cb899b2d3df76702e" name="src/libmongocrypt/src/mongocrypt-ctx-encrypt.c" role="src" />
+ <file md5sum="171b8ecd544439a672e599433e45360a" name="src/libmongocrypt/src/mongocrypt-ctx-private.h" role="src" />
+ <file md5sum="67ac8babb28bf5474c915e7d3fcf0b35" name="src/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c" role="src" />
+ <file md5sum="de6ed4b2f4e090d6f9db7c3c563b9a32" name="src/libmongocrypt/src/mongocrypt-ctx.c" role="src" />
+ <file md5sum="d2cbe53994a61fdd62863e20fdc0a151" name="src/libmongocrypt/src/mongocrypt-dll-private.h" role="src" />
+ <file md5sum="c3ace88b6cc17f54ae9df0bd33379ee9" name="src/libmongocrypt/src/mongocrypt-endian-private.h" role="src" />
<file md5sum="4fb2bf18afde014629d7b1df81572dfa" name="src/libmongocrypt/src/mongocrypt-endpoint-private.h" role="src" />
<file md5sum="8168656596c38d21c201c95080311b71" name="src/libmongocrypt/src/mongocrypt-endpoint.c" role="src" />
<file md5sum="92add912564fdbe450689d91b2590d9c" name="src/libmongocrypt/src/mongocrypt-kek-private.h" role="src" />
<file md5sum="7b9ff46d60ade202961a7c7b33b3532c" name="src/libmongocrypt/src/mongocrypt-kek.c" role="src" />
- <file md5sum="527813694437bfcb77a3bad1740fa2ec" name="src/libmongocrypt/src/mongocrypt-key-broker-private.h" role="src" />
- <file md5sum="456ed3802e13cf774b38fec713e50eab" name="src/libmongocrypt/src/mongocrypt-key-broker.c" role="src" />
+ <file md5sum="ebd86b723cb37e05bb2165f27943e490" name="src/libmongocrypt/src/mongocrypt-key-broker-private.h" role="src" />
+ <file md5sum="30f011326d906565095ec2d6164c0c84" name="src/libmongocrypt/src/mongocrypt-key-broker.c" role="src" />
<file md5sum="91c5a372f6acc679feb1dd22dab38b3f" name="src/libmongocrypt/src/mongocrypt-key-private.h" role="src" />
- <file md5sum="0c4d0412192d819be45437de6d89569e" name="src/libmongocrypt/src/mongocrypt-key.c" role="src" />
- <file md5sum="b2ca40703288e618e2ae607d541700fe" name="src/libmongocrypt/src/mongocrypt-kms-ctx-private.h" role="src" />
- <file md5sum="120e8aaf6ca0f00cac0cd6871a31ca41" name="src/libmongocrypt/src/mongocrypt-kms-ctx.c" role="src" />
+ <file md5sum="f0d53ea3d979d5a95e31db6734668f01" name="src/libmongocrypt/src/mongocrypt-key.c" role="src" />
+ <file md5sum="31994844ef9d230448258e43a02e361e" name="src/libmongocrypt/src/mongocrypt-kms-ctx-private.h" role="src" />
+ <file md5sum="b9e56e36283d4f8a90da0abf5159764a" name="src/libmongocrypt/src/mongocrypt-kms-ctx.c" role="src" />
<file md5sum="811275f18e5aee6299146b79a08a0542" name="src/libmongocrypt/src/mongocrypt-log-private.h" role="src" />
- <file md5sum="791498257b4fc5601a91792bdc55c2cc" name="src/libmongocrypt/src/mongocrypt-log.c" role="src" />
- <file md5sum="0453849c026e5fd24e80ad50c1aef528" name="src/libmongocrypt/src/mongocrypt-marking-private.h" role="src" />
- <file md5sum="2993cd22ed2359e653f753f6a6c7ee16" name="src/libmongocrypt/src/mongocrypt-marking.c" role="src" />
- <file md5sum="de4411fc003a25f9dbcc9d3f8fe80c2c" name="src/libmongocrypt/src/mongocrypt-mutex-private.h" role="src" />
- <file md5sum="c5b7d9a9d433425cd2d720f8a901c7b1" name="src/libmongocrypt/src/mongocrypt-opts-private.h" role="src" />
- <file md5sum="0b92bfc935d47233603d982e00bdc3f8" name="src/libmongocrypt/src/mongocrypt-opts.c" role="src" />
- <file md5sum="32f72f2c7d8fc8a57ecd5a39c1d78a4d" name="src/libmongocrypt/src/mongocrypt-private.h" role="src" />
+ <file md5sum="47bad524d2263980e61b1420f107d211" name="src/libmongocrypt/src/mongocrypt-log.c" role="src" />
+ <file md5sum="403bf17890ed48f4a24f0719e9e6e772" name="src/libmongocrypt/src/mongocrypt-marking-private.h" role="src" />
+ <file md5sum="89e5142cd74cddf8335a3afaa3bcd7cb" name="src/libmongocrypt/src/mongocrypt-marking.c" role="src" />
+ <file md5sum="2cdb9a473c8d0152408ebad61511c30b" name="src/libmongocrypt/src/mongocrypt-mutex-private.h" role="src" />
+ <file md5sum="467efa76d745388915a3298e37dfb6bd" name="src/libmongocrypt/src/mongocrypt-opts-private.h" role="src" />
+ <file md5sum="df5bf5d2068c3760fd6c1582b025800b" name="src/libmongocrypt/src/mongocrypt-opts.c" role="src" />
+ <file md5sum="4b29f5a862bd04f19421b2c2c6e9d03f" name="src/libmongocrypt/src/mongocrypt-private.h" role="src" />
<file md5sum="1ba59cdac21a95f2b2adf02b651dd952" name="src/libmongocrypt/src/mongocrypt-status-private.h" role="src" />
<file md5sum="3c8dfcd10882c001534fe287ba2d0744" name="src/libmongocrypt/src/mongocrypt-status.c" role="src" />
- <file md5sum="c532c0d6ed2d0d97df2ac1b2bb01f469" name="src/libmongocrypt/src/mongocrypt-traverse-util-private.h" role="src" />
- <file md5sum="93bf9b4cec817a1b527ddcaf1ee4f812" name="src/libmongocrypt/src/mongocrypt-traverse-util.c" role="src" />
+ <file md5sum="361ea881b77e184c171a0d2ef378a772" name="src/libmongocrypt/src/mongocrypt-traverse-util-private.h" role="src" />
+ <file md5sum="0d4d2d2feea178a5cfe96744ea402c71" name="src/libmongocrypt/src/mongocrypt-traverse-util.c" role="src" />
<file md5sum="05c50f0b644756e3d2e40f3e3242c5fd" name="src/libmongocrypt/src/mongocrypt-util-private.h" role="src" />
<file md5sum="58cf61bd5459d0685e7829c8680f1aaf" name="src/libmongocrypt/src/mongocrypt-util.c" role="src" />
- <file md5sum="3f1b175cdaa9cb1157444f76e84cd2aa" name="src/libmongocrypt/src/mongocrypt.c" role="src" />
- <file md5sum="5d5c64d1dc85ed14116a0dd7507fb504" name="src/libmongocrypt/src/mongocrypt.h" role="src" />
- <file md5sum="1c86beb27422a7fdbd5a656bd785c273" name="src/libmongocrypt/src/mongocrypt.h.in" role="src" />
- <file md5sum="8dadbeb3ae0d6e8cf2c8b7df7a24ec0b" name="src/LIBMONGOCRYPT_VERSION_CURRENT" role="src" />
- <file md5sum="b01d92c0fadad032b18541b9cf71061c" name="src/LIBMONGOC_VERSION_CURRENT" role="src" />
- <file md5sum="ec7c7268228fb4ce9e41507d3c1bbc25" name="src/phongo_apm.c" role="src" />
+ <file md5sum="c06449943153aef9d3e50287fadee233" name="src/libmongocrypt/src/mongocrypt.c" role="src" />
+ <file md5sum="ad8ad594f2c7658090ace6c5c3a62600" name="src/libmongocrypt/src/mongocrypt.h" role="src" />
+ <file md5sum="803e3564c7d54bc317c74860da9cb559" name="src/LIBMONGOCRYPT_VERSION_CURRENT" role="src" />
+ <file md5sum="1ba5dbefafd34745177b51409f15afb6" name="src/LIBMONGOC_VERSION_CURRENT" role="src" />
+ <file md5sum="83dfa6f16d0bdd52e8021660aec33a1e" name="src/phongo_apm.c" role="src" />
<file md5sum="77a9ea21f15bc0112af0540372bbb10f" name="src/phongo_apm.h" role="src" />
<file md5sum="1d1ab42a1177faeb4f06a4ff3428d8db" name="src/phongo_bson.c" role="src" />
<file md5sum="10d7fa5ef5c64a01cabd548b7e71fef4" name="src/phongo_bson.h" role="src" />
- <file md5sum="3aec47c3d88894dd86653475ba6dc712" name="src/phongo_bson_encode.c" role="src" />
+ <file md5sum="36e5c0c61e76e0b787a4f809531fc8db" name="src/phongo_bson_encode.c" role="src" />
<file md5sum="5318a01c78fe27a1567f66d09fc87e8a" name="src/phongo_bson_encode.h" role="src" />
<file md5sum="6453bc69bde12bc20c2f268f671dd28b" name="src/phongo_classes.h" role="src" />
- <file md5sum="1746081a1aec4b78e492381b4253f7f6" name="src/phongo_client.c" role="src" />
+ <file md5sum="55327d7c0b14ea74b97ee1829a05b92f" name="src/phongo_client.c" role="src" />
<file md5sum="1e53a91f977a06878a8d68d769e3eac9" name="src/phongo_client.h" role="src" />
<file md5sum="a008716fd427c048f4fc952e3503ebc4" name="src/phongo_compat.c" role="src" />
<file md5sum="67bce0014d8765d3fefc3573acd7adc2" name="src/phongo_compat.h" role="src" />
<file md5sum="f06e720068afa4d263aaefe6c68f5efb" name="src/phongo_error.c" role="src" />
<file md5sum="136d20717f05027d7b90dd327460cbaf" name="src/phongo_error.h" role="src" />
- <file md5sum="b79f2fd89df437644ebc935d3f7da28e" name="src/phongo_execute.c" role="src" />
+ <file md5sum="34c3bdfc0b5b90f53b49feda24093467" name="src/phongo_execute.c" role="src" />
<file md5sum="edcaff696c46e8d86b4bfb82afa944eb" name="src/phongo_execute.h" role="src" />
- <file md5sum="01fc6f8e57bf12bd2f6b2a7021a819a3" name="src/phongo_ini.c" role="src" />
+ <file md5sum="bd05c3c2def7ecbc9c0009dbc6a01ffb" name="src/phongo_ini.c" role="src" />
<file md5sum="6c4fdb6112eb54d2cc89abeae499630f" name="src/phongo_ini.h" role="src" />
- <file md5sum="0ff01adac3d2c2a3e4f5b1ae7b5f6877" name="src/phongo_structs.h" role="src" />
+ <file md5sum="2aa42b093004a2c3616a4b531a8fd145" name="src/phongo_structs.h" role="src" />
<file md5sum="0be03ab06536bfe3bed1c60832d9623f" name="src/phongo_util.c" role="src" />
<file md5sum="d18cbbc1f0fb6015c452b74d2165dbd1" name="src/phongo_util.h" role="src" />
- <file md5sum="78a17be7d97c69f434d836ffebeb55b3" name="src/phongo_version.h" role="src" />
<file md5sum="ca2c5031647b050893a81fef62317af2" name="tests/apm/bug0950-001.phpt" role="test" />
<file md5sum="c57aecc8032252158a190e7e10270417" name="tests/apm/bug0950-002.phpt" role="test" />
<file md5sum="9ee1bcb875babea7612bf831f108eb6d" name="tests/apm/commandFailedEvent-001.phpt" role="test" />
<file md5sum="5267ddfa53b8ee6c786c950e29e1808c" name="tests/apm/commandFailedEvent-002.phpt" role="test" />
- <file md5sum="ea20ae402869d360bbf2c7dcc9e740c2" name="tests/apm/commandFailedEvent-debug-001.phpt" role="test" />
+ <file md5sum="5896f75b067f16eb1629909aaf7672d7" name="tests/apm/commandFailedEvent-debug-001.phpt" role="test" />
<file md5sum="5ee004ab5b1703aa00a2ef35767e2837" name="tests/apm/commandFailedEvent-getReply-001.phpt" role="test" />
+ <file md5sum="2bcc88476508a5333cabedfc2750f56f" name="tests/apm/commandFailedEvent-getServerConnectionId-001.phpt" role="test" />
+ <file md5sum="29dff8c2354b01d12ff0119156330bb4" name="tests/apm/commandFailedEvent-getServerConnectionId-002.phpt" role="test" />
<file md5sum="d95da38cbecdecd04107722de552f099" name="tests/apm/commandFailedEvent-getServiceId-001.phpt" role="test" />
<file md5sum="59a7eea238c21c7fcd7d95342f6d14ed" name="tests/apm/commandFailedEvent-getServiceId-002.phpt" role="test" />
<file md5sum="e0abc3a888f028ee72dd1142523dd511" name="tests/apm/commandStartedEvent-001.phpt" role="test" />
<file md5sum="26294cdbe7578806d138b4a5ac445512" name="tests/apm/commandStartedEvent-002.phpt" role="test" />
- <file md5sum="a84cad5b5225c55bd08fa8edcc6665cc" name="tests/apm/commandStartedEvent-debug-001.phpt" role="test" />
+ <file md5sum="a28cf6b599861f65a2f7820fce3392b1" name="tests/apm/commandStartedEvent-debug-001.phpt" role="test" />
+ <file md5sum="f298faffe84612200578edfded5c7961" name="tests/apm/commandStartedEvent-getServerConnectionId-001.phpt" role="test" />
+ <file md5sum="eb6dded71c3fe0757e1d312d6a2341db" name="tests/apm/commandStartedEvent-getServerConnectionId-002.phpt" role="test" />
<file md5sum="2efc2678d58fdb5fca68c6985d3fe3fd" name="tests/apm/commandStartedEvent-getServiceId-001.phpt" role="test" />
<file md5sum="c7429a87f93581dff47305bf4131171e" name="tests/apm/commandStartedEvent-getServiceId-002.phpt" role="test" />
<file md5sum="9f529376edb9f66409f91d5230d521e2" name="tests/apm/commandSucceededEvent-001.phpt" role="test" />
<file md5sum="8f10fc1f4932f3e65d8e3fce952bb15b" name="tests/apm/commandSucceededEvent-002.phpt" role="test" />
- <file md5sum="5d851446a3015daffaf842fc87a2de62" name="tests/apm/commandSucceededEvent-debug-001.phpt" role="test" />
+ <file md5sum="919fbebc3ac1aefcf25640c7e758d485" name="tests/apm/commandSucceededEvent-debug-001.phpt" role="test" />
+ <file md5sum="e45d9482b994c272a088319ca9e27700" name="tests/apm/commandSucceededEvent-getServerConnectionId-001.phpt" role="test" />
+ <file md5sum="ec26b1c16bd72c574d0a69aafc7a2157" name="tests/apm/commandSucceededEvent-getServerConnectionId-002.phpt" role="test" />
<file md5sum="e5f7d842a2bd1f1df4515534a567a407" name="tests/apm/commandSucceededEvent-getServiceId-001.phpt" role="test" />
<file md5sum="9be8be033e66fa07907935142670f2d8" name="tests/apm/commandSucceededEvent-getServiceId-002.phpt" role="test" />
<file md5sum="3e1e7674a4c01c8c57cdaf378655d1d6" name="tests/apm/monitoring-addSubscriber-001.phpt" role="test" />
<file md5sum="63cce7df4352b6f96dda09e9f0ae85ca" name="tests/apm/monitoring-addSubscriber-002.phpt" role="test" />
<file md5sum="58956419747418a41465fded0466b612" name="tests/apm/monitoring-addSubscriber-003.phpt" role="test" />
<file md5sum="560368f53701ebd1565badaa4cba3f83" name="tests/apm/monitoring-addSubscriber-004.phpt" role="test" />
<file md5sum="716845017e446303a39d968f773649d1" name="tests/apm/monitoring-removeSubscriber-001.phpt" role="test" />
<file md5sum="d9df59c5dfd66e0be123831e79cfe009" name="tests/apm/monitoring-removeSubscriber-002.phpt" role="test" />
<file md5sum="9fc0cc57de28c7c927aee7ba0f746687" name="tests/apm/serverChangedEvent-001.phpt" role="test" />
<file md5sum="45af08eb3b36b3c67dc9a2cce119cac6" name="tests/apm/serverClosedEvent-001.phpt" role="test" />
<file md5sum="91dcb096b1025f0979ce29676446ba42" name="tests/apm/serverHeartbeatFailedEvent-001.phpt" role="test" />
<file md5sum="9d50aac0a474fa62702f305d7deac176" name="tests/apm/serverHeartbeatStartedEvent-001.phpt" role="test" />
<file md5sum="d5912d918a99a72382a4b86910ded322" name="tests/apm/serverHeartbeatSucceededEvent-001.phpt" role="test" />
<file md5sum="dd3da20b90a02fc91570cf93df197c0b" name="tests/apm/serverOpeningEvent-001.phpt" role="test" />
<file md5sum="51b96829647749816cacfbe94c217f8a" name="tests/apm/topologyChangedEvent-001.phpt" role="test" />
<file md5sum="a5ce87b8ccca2c98b4322a06a23aeaa6" name="tests/apm/topologyClosedEvent-001.phpt" role="test" />
<file md5sum="6d95ae9d8775b9708e7b345661bc9ee5" name="tests/apm/topologyOpeningEvent-001.phpt" role="test" />
<file md5sum="3f8dcd773327b14ee445ef51bde6c21c" name="tests/apm/topologyOpeningEvent-002.phpt" role="test" />
<file md5sum="baa3d7edf68691614eadee83b7708638" name="tests/bson-corpus/array-decodeError-001.phpt" role="test" />
<file md5sum="eec94d5ab15a126f72a30b2b79306ce9" name="tests/bson-corpus/array-decodeError-002.phpt" role="test" />
<file md5sum="6d18f10c0068020a9d6a48f8d84414b9" name="tests/bson-corpus/array-decodeError-003.phpt" role="test" />
<file md5sum="98d114d97f7e23b40a83908a6bb796f5" name="tests/bson-corpus/array-valid-001.phpt" role="test" />
<file md5sum="d4a761de533a0712a8bbc852b154076c" name="tests/bson-corpus/array-valid-002.phpt" role="test" />
<file md5sum="c465ab144497f93ed869057cc2abb304" name="tests/bson-corpus/array-valid-003.phpt" role="test" />
<file md5sum="aae5943c9338ef5f953332c685f81d57" name="tests/bson-corpus/array-valid-004.phpt" role="test" />
<file md5sum="54dd965efb05d28d8fd2e908333e0810" name="tests/bson-corpus/array-valid-005.phpt" role="test" />
<file md5sum="d807b5a839294209cc4dc11a7529249d" name="tests/bson-corpus/binary-decodeError-001.phpt" role="test" />
<file md5sum="0a9f951a09caabfbc75ecb326c227811" name="tests/bson-corpus/binary-decodeError-002.phpt" role="test" />
<file md5sum="5b77030b5ebae42e37aca99ef3821116" name="tests/bson-corpus/binary-decodeError-003.phpt" role="test" />
<file md5sum="40c878a95d22ed3155a9f234cfbf9c9c" name="tests/bson-corpus/binary-decodeError-004.phpt" role="test" />
<file md5sum="0d0015a55c033db887b0ff045f1347e1" name="tests/bson-corpus/binary-decodeError-005.phpt" role="test" />
<file md5sum="14774d1f29828780b0766476b4dd37a5" name="tests/bson-corpus/binary-parseError-001.phpt" role="test" />
<file md5sum="522004a8e00d656e77572ea5fdcca2c6" name="tests/bson-corpus/binary-parseError-002.phpt" role="test" />
<file md5sum="6f3b84da88b0b33ad66c1e86c2905458" name="tests/bson-corpus/binary-parseError-003.phpt" role="test" />
<file md5sum="eb55593431d6bddd64f25be7d43d6ef0" name="tests/bson-corpus/binary-parseError-004.phpt" role="test" />
<file md5sum="c54515e589c765e5e07ffbe5787472b7" name="tests/bson-corpus/binary-parseError-005.phpt" role="test" />
<file md5sum="dae4f19c166a8f2f3ca5ad05bab8ab8b" name="tests/bson-corpus/binary-valid-001.phpt" role="test" />
<file md5sum="d113ebef12ab87e860079a78ed90dd6a" name="tests/bson-corpus/binary-valid-002.phpt" role="test" />
<file md5sum="ea9b49e5334a6d0dfb02676fed32f1c6" name="tests/bson-corpus/binary-valid-003.phpt" role="test" />
<file md5sum="4664b9940a9a42330a286cfaa4be8d3a" name="tests/bson-corpus/binary-valid-004.phpt" role="test" />
<file md5sum="ec4ee1c5c365cbe03cf767d1b9feb1f1" name="tests/bson-corpus/binary-valid-005.phpt" role="test" />
<file md5sum="4b915c50885402aef86cb5bf6cd781e5" name="tests/bson-corpus/binary-valid-006.phpt" role="test" />
<file md5sum="65524ba0237dc7292908c02bd60bab55" name="tests/bson-corpus/binary-valid-007.phpt" role="test" />
<file md5sum="a1974955b3013148af357575dadbd42a" name="tests/bson-corpus/binary-valid-008.phpt" role="test" />
<file md5sum="8ed7e75059848bb2fa8dae968b3165b4" name="tests/bson-corpus/binary-valid-009.phpt" role="test" />
<file md5sum="ec668b2d309bde01d389f375173c4237" name="tests/bson-corpus/binary-valid-010.phpt" role="test" />
<file md5sum="59f90daf0580a24e4e2a7adc25339fb5" name="tests/bson-corpus/binary-valid-011.phpt" role="test" />
<file md5sum="e34a0a285fb2cf5c3b31b68ba8d64b60" name="tests/bson-corpus/binary-valid-012.phpt" role="test" />
<file md5sum="a4015fa1fd13d04c2624314693aa79f0" name="tests/bson-corpus/binary-valid-013.phpt" role="test" />
<file md5sum="8c555f641e62f188c760ea259fa0905b" name="tests/bson-corpus/boolean-decodeError-001.phpt" role="test" />
<file md5sum="81399e6126c3c56fe847ae51d1ac5321" name="tests/bson-corpus/boolean-decodeError-002.phpt" role="test" />
<file md5sum="5219cd5251957aecac799dd3756902bc" name="tests/bson-corpus/boolean-valid-001.phpt" role="test" />
<file md5sum="adc8666825689f459d7369276f93aa77" name="tests/bson-corpus/boolean-valid-002.phpt" role="test" />
<file md5sum="07ce410a97dbe7fdc9f5bdb36f6d565d" name="tests/bson-corpus/code-decodeError-001.phpt" role="test" />
<file md5sum="75a6535d50dad93710f03f085e63a4a2" name="tests/bson-corpus/code-decodeError-002.phpt" role="test" />
<file md5sum="6eb0eafd83bcb0534ab4194cee305a97" name="tests/bson-corpus/code-decodeError-003.phpt" role="test" />
<file md5sum="0cfa9c4f0a74d15f202c757980a906a7" name="tests/bson-corpus/code-decodeError-004.phpt" role="test" />
<file md5sum="e667e4a51dc0168c571198f989ef779a" name="tests/bson-corpus/code-decodeError-005.phpt" role="test" />
<file md5sum="7504b851a985838f5e72219cd52e325b" name="tests/bson-corpus/code-decodeError-006.phpt" role="test" />
<file md5sum="be44ea4b2585d4c835e16c48fcf38e13" name="tests/bson-corpus/code-decodeError-007.phpt" role="test" />
<file md5sum="7057b47d0b9af05a56f9d10c29180046" name="tests/bson-corpus/code-valid-001.phpt" role="test" />
<file md5sum="1aeda4cf9b01aaf44da141c159355353" name="tests/bson-corpus/code-valid-002.phpt" role="test" />
<file md5sum="a622d156ef6459b4f1198f29d196dc64" name="tests/bson-corpus/code-valid-003.phpt" role="test" />
<file md5sum="b8715bcfe56a16c54563decb94652dac" name="tests/bson-corpus/code-valid-004.phpt" role="test" />
<file md5sum="79a555c483b2cad930b2469adf3465b2" name="tests/bson-corpus/code-valid-005.phpt" role="test" />
<file md5sum="81a20ddf7b39fd77d035abd711603ca4" name="tests/bson-corpus/code-valid-006.phpt" role="test" />
<file md5sum="7cbb03c444968469684d43b617a651c9" name="tests/bson-corpus/code_w_scope-decodeError-001.phpt" role="test" />
<file md5sum="90b2b80ca43b71c65db39d2bac6e0d08" name="tests/bson-corpus/code_w_scope-decodeError-002.phpt" role="test" />
<file md5sum="0977a3a73073fef3a88bc60fa63624c2" name="tests/bson-corpus/code_w_scope-decodeError-003.phpt" role="test" />
<file md5sum="82fd83d89a738bff8ed74b3f1afa32c6" name="tests/bson-corpus/code_w_scope-decodeError-004.phpt" role="test" />
<file md5sum="cd9130276550b837ee5c15a2cbfa85df" name="tests/bson-corpus/code_w_scope-decodeError-005.phpt" role="test" />
<file md5sum="7a0fe48f99f58fb05fd5a937ae23c585" name="tests/bson-corpus/code_w_scope-decodeError-006.phpt" role="test" />
<file md5sum="96b9583e3fecc7ca67df568726c39b62" name="tests/bson-corpus/code_w_scope-decodeError-007.phpt" role="test" />
<file md5sum="8341838b0a95b053f7a82d457c34a539" name="tests/bson-corpus/code_w_scope-decodeError-008.phpt" role="test" />
<file md5sum="0e85755385c1d1b7daa3ec469cfc27eb" name="tests/bson-corpus/code_w_scope-decodeError-009.phpt" role="test" />
<file md5sum="1a9fb68565a64903639f1b3c1bc9d543" name="tests/bson-corpus/code_w_scope-decodeError-010.phpt" role="test" />
<file md5sum="27fb6ca6fc059f12566888eeb335154f" name="tests/bson-corpus/code_w_scope-decodeError-011.phpt" role="test" />
<file md5sum="17f3a5eba8cdd56ce2f73d781575d8ff" name="tests/bson-corpus/code_w_scope-valid-001.phpt" role="test" />
<file md5sum="7cc17cee915c73328f77579db2eb8b32" name="tests/bson-corpus/code_w_scope-valid-002.phpt" role="test" />
<file md5sum="f2516438c2f05da6a05ca66e50f488d5" name="tests/bson-corpus/code_w_scope-valid-003.phpt" role="test" />
<file md5sum="4dc3544ace08e85e90315fa7aa9a5bd7" name="tests/bson-corpus/code_w_scope-valid-004.phpt" role="test" />
<file md5sum="ea1dad39a5e650989bde4cce50b6912c" name="tests/bson-corpus/code_w_scope-valid-005.phpt" role="test" />
<file md5sum="a5e367bba0680e4f5c0232fa99ff5830" name="tests/bson-corpus/datetime-decodeError-001.phpt" role="test" />
<file md5sum="4a64a9e7365127a23315db6d1ad4b45e" name="tests/bson-corpus/datetime-valid-001.phpt" role="test" />
<file md5sum="89cecd3e5fc22f38695b071d0592d20b" name="tests/bson-corpus/datetime-valid-002.phpt" role="test" />
<file md5sum="5142efd68b779142234912f9130a893a" name="tests/bson-corpus/datetime-valid-003.phpt" role="test" />
<file md5sum="82be9c1517e9ac71980d5dd1e63692a1" name="tests/bson-corpus/datetime-valid-004.phpt" role="test" />
<file md5sum="b9b2985697d4018a5349f26b6a2189fa" name="tests/bson-corpus/datetime-valid-005.phpt" role="test" />
<file md5sum="3ad3e33946bfc413e1671eee8b1a56af" name="tests/bson-corpus/dbpointer-decodeError-001.phpt" role="test" />
<file md5sum="3dc01fb79532e373dd3a4b0ceaa2b70c" name="tests/bson-corpus/dbpointer-decodeError-002.phpt" role="test" />
<file md5sum="9262cfd01cf672724ac59995be78e54b" name="tests/bson-corpus/dbpointer-decodeError-003.phpt" role="test" />
<file md5sum="4466fd41c0a2cd02530821f7c6794655" name="tests/bson-corpus/dbpointer-decodeError-004.phpt" role="test" />
<file md5sum="e2309452e28485a05226c6b72842f2fc" name="tests/bson-corpus/dbpointer-decodeError-005.phpt" role="test" />
<file md5sum="68b0583db17d887509f8c3a88b234348" name="tests/bson-corpus/dbpointer-decodeError-006.phpt" role="test" />
<file md5sum="1c5600661ffa39dba86dfe6abc2df5c7" name="tests/bson-corpus/dbpointer-valid-001.phpt" role="test" />
<file md5sum="609cf521db0f3b398885c64633cd4cb0" name="tests/bson-corpus/dbpointer-valid-002.phpt" role="test" />
<file md5sum="27e0dab75f44c055149387169ebbdca3" name="tests/bson-corpus/dbpointer-valid-003.phpt" role="test" />
<file md5sum="69b6af5f6fb37408ac4b5268a9709463" name="tests/bson-corpus/dbref-valid-001.phpt" role="test" />
<file md5sum="c4d059e997c1d804e0472c4307b45eea" name="tests/bson-corpus/dbref-valid-002.phpt" role="test" />
<file md5sum="0aa924cb47180b3e8d5a5dddb781d5b6" name="tests/bson-corpus/dbref-valid-003.phpt" role="test" />
<file md5sum="d82fabf93ab940d550b8b3b43985740c" name="tests/bson-corpus/dbref-valid-004.phpt" role="test" />
<file md5sum="af733d65729db7d267ba44333e087f7c" name="tests/bson-corpus/dbref-valid-005.phpt" role="test" />
<file md5sum="964d823680ff081351b44b1210f85938" name="tests/bson-corpus/dbref-valid-006.phpt" role="test" />
<file md5sum="50fdfd40d749b7faa722388a8719be35" name="tests/bson-corpus/dbref-valid-007.phpt" role="test" />
<file md5sum="46e2f6615d23e0e93d831feece91edb8" name="tests/bson-corpus/dbref-valid-008.phpt" role="test" />
<file md5sum="f497c15e3c5d4f91bb5e4b811d0f626a" name="tests/bson-corpus/dbref-valid-009.phpt" role="test" />
<file md5sum="181777f44bb24d2d123b78e1f951cc48" name="tests/bson-corpus/decimal128-1-valid-001.phpt" role="test" />
<file md5sum="05636e1736addca153d9cb2296279e6c" name="tests/bson-corpus/decimal128-1-valid-002.phpt" role="test" />
<file md5sum="9093cb6ea89b3aee8f8455c6c68f6793" name="tests/bson-corpus/decimal128-1-valid-003.phpt" role="test" />
<file md5sum="53aa5f575355bd3223e915f3a337cb5f" name="tests/bson-corpus/decimal128-1-valid-004.phpt" role="test" />
<file md5sum="2685f03107eefd6486f9b390b4fa6ab8" name="tests/bson-corpus/decimal128-1-valid-005.phpt" role="test" />
<file md5sum="46437b3d39725d2bfaa6be64f2d593b4" name="tests/bson-corpus/decimal128-1-valid-006.phpt" role="test" />
<file md5sum="515c2938f91bfe74a4b8f95da78d9821" name="tests/bson-corpus/decimal128-1-valid-007.phpt" role="test" />
<file md5sum="c024cb4305dac855b8af9c7b74958c36" name="tests/bson-corpus/decimal128-1-valid-008.phpt" role="test" />
<file md5sum="20ec3b4074921e7e910887fb75af5d42" name="tests/bson-corpus/decimal128-1-valid-009.phpt" role="test" />
<file md5sum="0737fe57984b0da8c73c1f72e23ece55" name="tests/bson-corpus/decimal128-1-valid-010.phpt" role="test" />
<file md5sum="6bd52fe6e3790c7c8a33ef5ee047ba75" name="tests/bson-corpus/decimal128-1-valid-011.phpt" role="test" />
<file md5sum="3223159cc842967a3599de2fe101ee54" name="tests/bson-corpus/decimal128-1-valid-012.phpt" role="test" />
<file md5sum="4dc802e60530028adc8d5c8ded3c569a" name="tests/bson-corpus/decimal128-1-valid-013.phpt" role="test" />
<file md5sum="9f64ff435e0f0f85ac4fcc85634a83d7" name="tests/bson-corpus/decimal128-1-valid-014.phpt" role="test" />
<file md5sum="4e3083d4c813fab736ed3b7542a7cdcc" name="tests/bson-corpus/decimal128-1-valid-015.phpt" role="test" />
<file md5sum="0152c6c8f959dfde6d1f70da8c7c3fe6" name="tests/bson-corpus/decimal128-1-valid-016.phpt" role="test" />
<file md5sum="febdbd923021222449042454301b1a47" name="tests/bson-corpus/decimal128-1-valid-017.phpt" role="test" />
<file md5sum="26bf546e763fc1772b40095d85b1fe7e" name="tests/bson-corpus/decimal128-1-valid-018.phpt" role="test" />
<file md5sum="4133cc0a34fe402ef3c343087cb3b862" name="tests/bson-corpus/decimal128-1-valid-019.phpt" role="test" />
<file md5sum="527ee9d3c8c22374136f31a84f1f3afe" name="tests/bson-corpus/decimal128-1-valid-020.phpt" role="test" />
<file md5sum="ae47f2b1197250d42b0a374643ec3fd8" name="tests/bson-corpus/decimal128-1-valid-021.phpt" role="test" />
<file md5sum="c141d9d9681098aa090bd9956cb41028" name="tests/bson-corpus/decimal128-1-valid-022.phpt" role="test" />
<file md5sum="0cac88fcc47e16f1ea3c2d7a79607b94" name="tests/bson-corpus/decimal128-1-valid-023.phpt" role="test" />
<file md5sum="b197806633c40722bf483c22bb5bbc14" name="tests/bson-corpus/decimal128-1-valid-024.phpt" role="test" />
<file md5sum="1c6b0566a8cc2a347a322cab39aad81b" name="tests/bson-corpus/decimal128-1-valid-025.phpt" role="test" />
<file md5sum="b6b92d177c102dfee5354f783ba14a34" name="tests/bson-corpus/decimal128-1-valid-026.phpt" role="test" />
<file md5sum="91cb770554b1cc1dd0ca604f605b3904" name="tests/bson-corpus/decimal128-1-valid-027.phpt" role="test" />
<file md5sum="8350180d7ce47e9046331a0a74947c92" name="tests/bson-corpus/decimal128-1-valid-028.phpt" role="test" />
<file md5sum="d8c763344490fc19e1487c5bbe3a3e87" name="tests/bson-corpus/decimal128-1-valid-029.phpt" role="test" />
<file md5sum="77b646bf805652b4bc5e4c9935bb7a72" name="tests/bson-corpus/decimal128-1-valid-030.phpt" role="test" />
<file md5sum="29a4bd0d922f58d564d81c1f2cfee38a" name="tests/bson-corpus/decimal128-1-valid-031.phpt" role="test" />
<file md5sum="9ce50bb8fc905b7687ec3491d11560c7" name="tests/bson-corpus/decimal128-1-valid-032.phpt" role="test" />
<file md5sum="4b246fa8bb1355f0af82432efd65381c" name="tests/bson-corpus/decimal128-1-valid-033.phpt" role="test" />
<file md5sum="d3ab028c37d49a5882b7d0b3620d5444" name="tests/bson-corpus/decimal128-1-valid-034.phpt" role="test" />
<file md5sum="e36d9ad83dc52f209fbcd1b8b2c0fa2d" name="tests/bson-corpus/decimal128-1-valid-035.phpt" role="test" />
<file md5sum="bdbb2f3244bf9668cbcc1831c2999415" name="tests/bson-corpus/decimal128-1-valid-036.phpt" role="test" />
<file md5sum="a5c00e87e229cb3edabf431255a01fda" name="tests/bson-corpus/decimal128-1-valid-037.phpt" role="test" />
<file md5sum="c50985ab0b18d1ba4f40a5564e060beb" name="tests/bson-corpus/decimal128-1-valid-038.phpt" role="test" />
<file md5sum="b3c90cc2433a2d92ae2bae0b82459fdc" name="tests/bson-corpus/decimal128-1-valid-039.phpt" role="test" />
<file md5sum="f1ed2912db6a1af78f89f37eb2b28c72" name="tests/bson-corpus/decimal128-1-valid-040.phpt" role="test" />
<file md5sum="1a2fe9d1b42589351ff104f1591c6df4" name="tests/bson-corpus/decimal128-1-valid-041.phpt" role="test" />
<file md5sum="9a604049ea1265a20aae18aa0748ce60" name="tests/bson-corpus/decimal128-1-valid-042.phpt" role="test" />
<file md5sum="ed0f14a2df766171c95646afb73cbcf4" name="tests/bson-corpus/decimal128-1-valid-043.phpt" role="test" />
<file md5sum="0b038d9214ecdc4bb4cf5dca3f5bbbe8" name="tests/bson-corpus/decimal128-1-valid-044.phpt" role="test" />
<file md5sum="0f1af353b9da41f863dc760a7cfa9bb2" name="tests/bson-corpus/decimal128-1-valid-045.phpt" role="test" />
<file md5sum="03fbda063ba4dff9d85daa5cae771007" name="tests/bson-corpus/decimal128-1-valid-046.phpt" role="test" />
<file md5sum="e11b787f18052f0bb45d131a5f421016" name="tests/bson-corpus/decimal128-1-valid-047.phpt" role="test" />
<file md5sum="890ae8f1bd849c64dc212f0217a592cc" name="tests/bson-corpus/decimal128-1-valid-048.phpt" role="test" />
<file md5sum="6f3417465de2d6041accdf6d36983ed1" name="tests/bson-corpus/decimal128-1-valid-049.phpt" role="test" />
<file md5sum="a856a4e669ee0ca37abc26e8d4d7be3a" name="tests/bson-corpus/decimal128-1-valid-050.phpt" role="test" />
<file md5sum="c9fd1a8621d8d298a2a1ff46ce6fc2c4" name="tests/bson-corpus/decimal128-1-valid-051.phpt" role="test" />
<file md5sum="152855c622ca0f557268a43b5f33b9af" name="tests/bson-corpus/decimal128-1-valid-052.phpt" role="test" />
<file md5sum="f6be60d8df2faf214807026292b248fa" name="tests/bson-corpus/decimal128-1-valid-053.phpt" role="test" />
<file md5sum="4b0c216290010189cd5bdd34e6d20ab4" name="tests/bson-corpus/decimal128-1-valid-054.phpt" role="test" />
<file md5sum="c7c4cd25bb866dc7c31070b6925e295b" name="tests/bson-corpus/decimal128-1-valid-055.phpt" role="test" />
<file md5sum="64964fbbc267b35685f1228631834737" name="tests/bson-corpus/decimal128-1-valid-056.phpt" role="test" />
<file md5sum="04356b1831da8db1f176384482b33d3a" name="tests/bson-corpus/decimal128-2-valid-001.phpt" role="test" />
<file md5sum="c602b99310f55634e40dcc39dac6e939" name="tests/bson-corpus/decimal128-2-valid-002.phpt" role="test" />
<file md5sum="d4502c76bca1329d850d68832a2e7100" name="tests/bson-corpus/decimal128-2-valid-003.phpt" role="test" />
<file md5sum="dc5f8337029e4603a29e3e159abeb80a" name="tests/bson-corpus/decimal128-2-valid-004.phpt" role="test" />
<file md5sum="28eace8c67cc6c1e476b5055c23436b3" name="tests/bson-corpus/decimal128-2-valid-005.phpt" role="test" />
<file md5sum="7ddbeb89d56d31392ae60f8fa89101df" name="tests/bson-corpus/decimal128-2-valid-006.phpt" role="test" />
<file md5sum="728c35f1a068c4ae897f0492813f7f88" name="tests/bson-corpus/decimal128-2-valid-007.phpt" role="test" />
<file md5sum="ae211145f5b65359814225f1e9f857c9" name="tests/bson-corpus/decimal128-2-valid-008.phpt" role="test" />
<file md5sum="f7ccd654f0b66977e43c2beb9355f7d7" name="tests/bson-corpus/decimal128-2-valid-009.phpt" role="test" />
<file md5sum="48e39888de51d58169d405da6c02100d" name="tests/bson-corpus/decimal128-2-valid-010.phpt" role="test" />
<file md5sum="abcd6dce99a5878b0d828a5033a94ce0" name="tests/bson-corpus/decimal128-2-valid-011.phpt" role="test" />
<file md5sum="d73fc290bfe6a7cd3b6d1ff2d9058b3d" name="tests/bson-corpus/decimal128-2-valid-012.phpt" role="test" />
<file md5sum="c1a1bc361109c4e13fc609ffa720f7cd" name="tests/bson-corpus/decimal128-2-valid-013.phpt" role="test" />
<file md5sum="48d975b96f3ba6f03e1cb584a1eb778c" name="tests/bson-corpus/decimal128-2-valid-014.phpt" role="test" />
<file md5sum="5612753bed0a1957ebf7450c0ca61750" name="tests/bson-corpus/decimal128-2-valid-015.phpt" role="test" />
<file md5sum="0da73f1b93da8e714e0be3c6ed96e930" name="tests/bson-corpus/decimal128-2-valid-016.phpt" role="test" />
<file md5sum="b89faae69d2c310e3fbdacbc59d56be5" name="tests/bson-corpus/decimal128-2-valid-017.phpt" role="test" />
<file md5sum="6f82366fee736c5e1855aaea543f199c" name="tests/bson-corpus/decimal128-2-valid-018.phpt" role="test" />
<file md5sum="847c0cdf22d49c1ac2fa8d6a94998023" name="tests/bson-corpus/decimal128-2-valid-019.phpt" role="test" />
<file md5sum="d20bbf92de57c759be535f0f5726f9a9" name="tests/bson-corpus/decimal128-2-valid-020.phpt" role="test" />
<file md5sum="c0e82e9808daadfc4ddf66b5c5c4305f" name="tests/bson-corpus/decimal128-2-valid-021.phpt" role="test" />
<file md5sum="418a169d42a9f21299563ac66f68347e" name="tests/bson-corpus/decimal128-2-valid-022.phpt" role="test" />
<file md5sum="a6f2d6747a39f50a4d429a680b99fd6d" name="tests/bson-corpus/decimal128-2-valid-023.phpt" role="test" />
<file md5sum="a416f9b9750e34139eb58b7aef38402f" name="tests/bson-corpus/decimal128-2-valid-024.phpt" role="test" />
<file md5sum="711450c2690746ed5eae3d4640a28f9c" name="tests/bson-corpus/decimal128-2-valid-025.phpt" role="test" />
<file md5sum="4490e63afd6b0d198564b6a261b99b03" name="tests/bson-corpus/decimal128-2-valid-026.phpt" role="test" />
<file md5sum="eb7946eb347a9ef05c9e91ffcddfa133" name="tests/bson-corpus/decimal128-2-valid-027.phpt" role="test" />
<file md5sum="697e1da9a9a12a7953c7e5b5041dd597" name="tests/bson-corpus/decimal128-2-valid-028.phpt" role="test" />
<file md5sum="7747df1c67053a9d2c27e68bf662acb0" name="tests/bson-corpus/decimal128-2-valid-029.phpt" role="test" />
<file md5sum="2af7e14d59fd78f19955a9bfb1f46793" name="tests/bson-corpus/decimal128-2-valid-030.phpt" role="test" />
<file md5sum="044bb1532b756f91eb120961b609ddf8" name="tests/bson-corpus/decimal128-2-valid-031.phpt" role="test" />
<file md5sum="881ba5eab7f3e5a983ae78abd599e471" name="tests/bson-corpus/decimal128-2-valid-032.phpt" role="test" />
<file md5sum="357a3bfda8af22a07727a8f61b75e162" name="tests/bson-corpus/decimal128-2-valid-033.phpt" role="test" />
<file md5sum="cc4e62ea75c4e530cbf570ff29b01b68" name="tests/bson-corpus/decimal128-2-valid-034.phpt" role="test" />
<file md5sum="34a105ed800d5e7aa13522a55a436dae" name="tests/bson-corpus/decimal128-2-valid-035.phpt" role="test" />
<file md5sum="886a19018d5cc2f9101ade92ad839bc9" name="tests/bson-corpus/decimal128-2-valid-036.phpt" role="test" />
<file md5sum="4e5034286f541608d2b33aca6398de73" name="tests/bson-corpus/decimal128-2-valid-037.phpt" role="test" />
<file md5sum="e7252e40e67cd60d20b4718b4ba16ef6" name="tests/bson-corpus/decimal128-2-valid-038.phpt" role="test" />
<file md5sum="88b0173e05e093415083fd17406a8ae0" name="tests/bson-corpus/decimal128-2-valid-039.phpt" role="test" />
<file md5sum="fa82cc3d5be493a3ceb4fb38d6ab5267" name="tests/bson-corpus/decimal128-2-valid-040.phpt" role="test" />
<file md5sum="6445671c388fcc71180edc0e1461b3c6" name="tests/bson-corpus/decimal128-2-valid-041.phpt" role="test" />
<file md5sum="c011244d5ed85adc0eeb6bc411af3c77" name="tests/bson-corpus/decimal128-2-valid-042.phpt" role="test" />
<file md5sum="4b8cba61113053325624423f840d07eb" name="tests/bson-corpus/decimal128-2-valid-043.phpt" role="test" />
<file md5sum="7a3c43634667f64b0aae7075ef914682" name="tests/bson-corpus/decimal128-2-valid-044.phpt" role="test" />
<file md5sum="2647d390ceb2f81e710d82ddfd6f273c" name="tests/bson-corpus/decimal128-2-valid-045.phpt" role="test" />
<file md5sum="32f6abc6b58082c2141dc989ea349413" name="tests/bson-corpus/decimal128-2-valid-046.phpt" role="test" />
<file md5sum="c1bd96d2b8138ab299c29b6c266902da" name="tests/bson-corpus/decimal128-2-valid-047.phpt" role="test" />
<file md5sum="186bb114d5f3779a85561740bfa29240" name="tests/bson-corpus/decimal128-2-valid-048.phpt" role="test" />
<file md5sum="6ba6548ec25416196d36a08c8f3b7580" name="tests/bson-corpus/decimal128-2-valid-049.phpt" role="test" />
<file md5sum="ff01a7097f7c877f1943be959b80d5a3" name="tests/bson-corpus/decimal128-2-valid-050.phpt" role="test" />
<file md5sum="5381add30710b641345b8840d4f1bf84" name="tests/bson-corpus/decimal128-2-valid-051.phpt" role="test" />
<file md5sum="629f2c56cfbe2189fc29254bccb9b8e0" name="tests/bson-corpus/decimal128-2-valid-052.phpt" role="test" />
<file md5sum="ffdc837fb21ddf93f9709e8026652299" name="tests/bson-corpus/decimal128-2-valid-053.phpt" role="test" />
<file md5sum="a5878447b4e32364db64a9c93ec616e9" name="tests/bson-corpus/decimal128-2-valid-054.phpt" role="test" />
<file md5sum="a347cbdede675a48cc41badbfd7effd5" name="tests/bson-corpus/decimal128-2-valid-055.phpt" role="test" />
<file md5sum="50f429ef36974fc3d059ddb2328eedf0" name="tests/bson-corpus/decimal128-2-valid-056.phpt" role="test" />
<file md5sum="fe656db3f0c621a0f5eb94e7502864bf" name="tests/bson-corpus/decimal128-2-valid-057.phpt" role="test" />
<file md5sum="c92ffd0a1692916593ee2de9c9c6ac1f" name="tests/bson-corpus/decimal128-2-valid-058.phpt" role="test" />
<file md5sum="4ac8e7078192e42e4dc1dde944eed7bc" name="tests/bson-corpus/decimal128-2-valid-059.phpt" role="test" />
<file md5sum="f360ee5a9a26ac96fc5ee0e3ce50b3ef" name="tests/bson-corpus/decimal128-2-valid-060.phpt" role="test" />
<file md5sum="33226378bb0c279966d0ae98fb27554e" name="tests/bson-corpus/decimal128-2-valid-061.phpt" role="test" />
<file md5sum="7e42b5aa22e28785d76ceb0a5ade97e9" name="tests/bson-corpus/decimal128-2-valid-062.phpt" role="test" />
<file md5sum="15e05bb7d4de9bae7f1458343f36ac9f" name="tests/bson-corpus/decimal128-2-valid-063.phpt" role="test" />
<file md5sum="a6c6678dd5348816a61a41e4ec61a2ff" name="tests/bson-corpus/decimal128-2-valid-064.phpt" role="test" />
<file md5sum="cc05c7dac8a0ead9c46fe0a07d5c2164" name="tests/bson-corpus/decimal128-2-valid-065.phpt" role="test" />
<file md5sum="724100276a42dfd27b388a0e5efd498d" name="tests/bson-corpus/decimal128-2-valid-066.phpt" role="test" />
<file md5sum="e8f0fa361241363f50577d75b4e24f8d" name="tests/bson-corpus/decimal128-2-valid-067.phpt" role="test" />
<file md5sum="b07a18bd07d2bd0250fc41d84ef5d28d" name="tests/bson-corpus/decimal128-2-valid-068.phpt" role="test" />
<file md5sum="05f2f595336abe5c6c3c6e98a603ad12" name="tests/bson-corpus/decimal128-2-valid-069.phpt" role="test" />
<file md5sum="7be5fb3d2518b48762881731f8a1f809" name="tests/bson-corpus/decimal128-2-valid-070.phpt" role="test" />
<file md5sum="13752ade9b1d44648cee82acf78cee64" name="tests/bson-corpus/decimal128-2-valid-071.phpt" role="test" />
<file md5sum="ccd99d2d5a6246938d36cda50b0f449b" name="tests/bson-corpus/decimal128-2-valid-072.phpt" role="test" />
<file md5sum="3bfda7788aa33c8a06240871205d1e32" name="tests/bson-corpus/decimal128-2-valid-073.phpt" role="test" />
<file md5sum="72f72f8f249af0832bb8151a1cf59691" name="tests/bson-corpus/decimal128-2-valid-074.phpt" role="test" />
<file md5sum="1cffcc11e66c884ab0ff66081144baa8" name="tests/bson-corpus/decimal128-2-valid-075.phpt" role="test" />
<file md5sum="0283d995acec4a7952db741948162b53" name="tests/bson-corpus/decimal128-2-valid-076.phpt" role="test" />
<file md5sum="37f207b92b34d178dedbdf196a45dcb9" name="tests/bson-corpus/decimal128-2-valid-077.phpt" role="test" />
<file md5sum="9bcf356999f0bd8767261d8cee6567aa" name="tests/bson-corpus/decimal128-2-valid-078.phpt" role="test" />
<file md5sum="eff95b6516b729ec80ab27634b047b3b" name="tests/bson-corpus/decimal128-2-valid-079.phpt" role="test" />
<file md5sum="1535c9542ab51ce947a0229844cb1159" name="tests/bson-corpus/decimal128-2-valid-080.phpt" role="test" />
<file md5sum="72c8f9b3f1bbc3793b3897dcde98b185" name="tests/bson-corpus/decimal128-2-valid-081.phpt" role="test" />
<file md5sum="988358edc755774da91ae8e036e6f330" name="tests/bson-corpus/decimal128-2-valid-082.phpt" role="test" />
<file md5sum="8449063868c7078c844ea0353e12392d" name="tests/bson-corpus/decimal128-2-valid-083.phpt" role="test" />
<file md5sum="7901409614d56e86835d97755efbe927" name="tests/bson-corpus/decimal128-2-valid-084.phpt" role="test" />
<file md5sum="ea1abfd069a7ff24e447d996a404c63d" name="tests/bson-corpus/decimal128-2-valid-085.phpt" role="test" />
<file md5sum="3de31217d54f56be403267f41e238c2b" name="tests/bson-corpus/decimal128-2-valid-086.phpt" role="test" />
<file md5sum="21ea0d67772ba21de38876206877bf0e" name="tests/bson-corpus/decimal128-2-valid-087.phpt" role="test" />
<file md5sum="0bb26a44c2ae2be22e40d67c1cb90735" name="tests/bson-corpus/decimal128-2-valid-088.phpt" role="test" />
<file md5sum="3ad70a2f5233190c7ff8f5a0026d3fb6" name="tests/bson-corpus/decimal128-2-valid-089.phpt" role="test" />
<file md5sum="f78064a6d145e66d31391ff75ca14ef0" name="tests/bson-corpus/decimal128-2-valid-090.phpt" role="test" />
<file md5sum="85e01784b2fb103853cb8c7977c2b1b2" name="tests/bson-corpus/decimal128-2-valid-091.phpt" role="test" />
<file md5sum="e13bdd974d4e91009b78d29b47311be6" name="tests/bson-corpus/decimal128-2-valid-092.phpt" role="test" />
<file md5sum="98f340f6aea75095cacc28742e26ed0f" name="tests/bson-corpus/decimal128-2-valid-093.phpt" role="test" />
<file md5sum="db659d84605259969ecc0c4f0bf1ef77" name="tests/bson-corpus/decimal128-2-valid-094.phpt" role="test" />
<file md5sum="135e22cdba09010b35357fd83e69fa25" name="tests/bson-corpus/decimal128-2-valid-095.phpt" role="test" />
<file md5sum="43df03f766d7b73d20dfa628ce5a2789" name="tests/bson-corpus/decimal128-2-valid-096.phpt" role="test" />
<file md5sum="2544c121493bc6e1be45cddadcdd793e" name="tests/bson-corpus/decimal128-2-valid-097.phpt" role="test" />
<file md5sum="fa5b88bf5b1200657210163e663eac89" name="tests/bson-corpus/decimal128-2-valid-098.phpt" role="test" />
<file md5sum="988a407e1ef6cf8be8bf9224d7829c26" name="tests/bson-corpus/decimal128-2-valid-099.phpt" role="test" />
<file md5sum="4633926740b6ece1fd8fd201756ea9fc" name="tests/bson-corpus/decimal128-2-valid-100.phpt" role="test" />
<file md5sum="b5b21dd5f96c6df2f09e50636daef584" name="tests/bson-corpus/decimal128-2-valid-101.phpt" role="test" />
<file md5sum="406e01276827c3c0d895010f3854139a" name="tests/bson-corpus/decimal128-2-valid-102.phpt" role="test" />
<file md5sum="cbf91ab43a1b6bcd7646b1e8a7a32bea" name="tests/bson-corpus/decimal128-2-valid-103.phpt" role="test" />
<file md5sum="a57767b902c18f5ad1f511525dc8a934" name="tests/bson-corpus/decimal128-2-valid-104.phpt" role="test" />
<file md5sum="1f51031dd6120fc0f5d53ca13d0d251f" name="tests/bson-corpus/decimal128-2-valid-105.phpt" role="test" />
<file md5sum="b9fc4a6691c7954606553eaacfc98242" name="tests/bson-corpus/decimal128-2-valid-106.phpt" role="test" />
<file md5sum="91e279e096b4956b3e20d2157cf029e0" name="tests/bson-corpus/decimal128-2-valid-107.phpt" role="test" />
<file md5sum="f036833d51808c4ccc06b1d7342e75b1" name="tests/bson-corpus/decimal128-2-valid-108.phpt" role="test" />
<file md5sum="0a5f5986b4cef6f9a1c3f24796f655cc" name="tests/bson-corpus/decimal128-2-valid-109.phpt" role="test" />
<file md5sum="850c8371885e621a14319ef30823d63f" name="tests/bson-corpus/decimal128-2-valid-110.phpt" role="test" />
<file md5sum="3fc1076c5a759a62967e96bbda826ba4" name="tests/bson-corpus/decimal128-2-valid-111.phpt" role="test" />
<file md5sum="d33e2438cc5472883744d8e8d2635f71" name="tests/bson-corpus/decimal128-2-valid-112.phpt" role="test" />
<file md5sum="1c228103737aad44f12952ba13fb766c" name="tests/bson-corpus/decimal128-2-valid-113.phpt" role="test" />
<file md5sum="7a91a010680b55ffd726167f65c24904" name="tests/bson-corpus/decimal128-2-valid-114.phpt" role="test" />
<file md5sum="5667a619383ec4ae4312efcbf2c180d1" name="tests/bson-corpus/decimal128-2-valid-115.phpt" role="test" />
<file md5sum="c903782b8f4f6fafa969cafed31706ba" name="tests/bson-corpus/decimal128-2-valid-116.phpt" role="test" />
<file md5sum="2ecb80aadb80f03f2f6cfbab84749edd" name="tests/bson-corpus/decimal128-2-valid-117.phpt" role="test" />
<file md5sum="3dd542b557928081c036f533fe08e210" name="tests/bson-corpus/decimal128-2-valid-118.phpt" role="test" />
<file md5sum="625df8840a9c21b552a8ab79c6589c56" name="tests/bson-corpus/decimal128-2-valid-119.phpt" role="test" />
<file md5sum="26315b63c5ea5b2db2adc50b0e29f3a1" name="tests/bson-corpus/decimal128-2-valid-120.phpt" role="test" />
<file md5sum="ae0105879adf90c711100e546e32651f" name="tests/bson-corpus/decimal128-2-valid-121.phpt" role="test" />
<file md5sum="8a43675ce7fe983a84260dc6a966ed68" name="tests/bson-corpus/decimal128-2-valid-122.phpt" role="test" />
<file md5sum="024f18433a8c496375e6edea22b8706c" name="tests/bson-corpus/decimal128-2-valid-123.phpt" role="test" />
<file md5sum="5a0bc26b9750cf4b9904ca95035f4b32" name="tests/bson-corpus/decimal128-2-valid-124.phpt" role="test" />
<file md5sum="050ed6d772a24839576f3328291c91a2" name="tests/bson-corpus/decimal128-2-valid-125.phpt" role="test" />
<file md5sum="2ddad0fc63699392f4285ec09a848ac4" name="tests/bson-corpus/decimal128-2-valid-126.phpt" role="test" />
<file md5sum="c2458fd81ddd17872b43abaf00dbc20d" name="tests/bson-corpus/decimal128-2-valid-127.phpt" role="test" />
<file md5sum="5dd76e53120dc0a64a44d1932d18ef32" name="tests/bson-corpus/decimal128-2-valid-128.phpt" role="test" />
<file md5sum="64bd7100ad022fc085878fcb7ee41afe" name="tests/bson-corpus/decimal128-2-valid-129.phpt" role="test" />
<file md5sum="51406de0787a60e2e582e595b33badeb" name="tests/bson-corpus/decimal128-2-valid-130.phpt" role="test" />
<file md5sum="6623372f0b8e66d9585146e83ff917e8" name="tests/bson-corpus/decimal128-2-valid-131.phpt" role="test" />
<file md5sum="6257c6e4a35f5f2998f8e4435125bb91" name="tests/bson-corpus/decimal128-2-valid-132.phpt" role="test" />
<file md5sum="f393c373126f675d3905decc7f231c85" name="tests/bson-corpus/decimal128-2-valid-133.phpt" role="test" />
<file md5sum="c77aab4153ccb5a16264456ea6edded5" name="tests/bson-corpus/decimal128-2-valid-134.phpt" role="test" />
<file md5sum="ffb34dbc7f6a1a8acd512754d6e79cfa" name="tests/bson-corpus/decimal128-2-valid-135.phpt" role="test" />
<file md5sum="30ed4be2378b33db1d04b2917462cd76" name="tests/bson-corpus/decimal128-2-valid-136.phpt" role="test" />
<file md5sum="f18ba4545e1204135c615b308447d47e" name="tests/bson-corpus/decimal128-2-valid-137.phpt" role="test" />
<file md5sum="f0b3ab11a0a9ba9d40871e90de34b41d" name="tests/bson-corpus/decimal128-2-valid-138.phpt" role="test" />
<file md5sum="6a35e965d7ce6fd40fc0e7fc2c091289" name="tests/bson-corpus/decimal128-2-valid-139.phpt" role="test" />
<file md5sum="e6c010be7ed3d416e8089a959c8d745e" name="tests/bson-corpus/decimal128-2-valid-140.phpt" role="test" />
<file md5sum="c7f1126b2fb28dabee45846d260f05e0" name="tests/bson-corpus/decimal128-2-valid-141.phpt" role="test" />
<file md5sum="214afec9481b343a3feea6095cf7010f" name="tests/bson-corpus/decimal128-2-valid-142.phpt" role="test" />
<file md5sum="c6a9455454bbab3d6d4ac0193c304eeb" name="tests/bson-corpus/decimal128-2-valid-143.phpt" role="test" />
<file md5sum="bdba88fe0455d32178c4fc9dfe010335" name="tests/bson-corpus/decimal128-2-valid-144.phpt" role="test" />
<file md5sum="449afdc4b473224d9295b96a861e6915" name="tests/bson-corpus/decimal128-2-valid-145.phpt" role="test" />
<file md5sum="6e08ddf23c007cdf28d3ac57086d0fc0" name="tests/bson-corpus/decimal128-2-valid-146.phpt" role="test" />
<file md5sum="be920f0f728e6073e95ee1d64b0ef2bf" name="tests/bson-corpus/decimal128-2-valid-147.phpt" role="test" />
<file md5sum="cff7c99da96a2a5aaee956966d7eda61" name="tests/bson-corpus/decimal128-2-valid-148.phpt" role="test" />
<file md5sum="45bfc06f06be2d4c43d65ccf2510e793" name="tests/bson-corpus/decimal128-2-valid-149.phpt" role="test" />
<file md5sum="bdd47e2a97678678839e6f79399fbf13" name="tests/bson-corpus/decimal128-2-valid-150.phpt" role="test" />
<file md5sum="7226fcbe4f4592f55bf2b682c1bf5fe1" name="tests/bson-corpus/decimal128-2-valid-151.phpt" role="test" />
<file md5sum="0c82fef60426d39a15def51b7979e58a" name="tests/bson-corpus/decimal128-2-valid-152.phpt" role="test" />
<file md5sum="4fbf1e19d7f6df8dd99e1b001ab29aaf" name="tests/bson-corpus/decimal128-2-valid-153.phpt" role="test" />
<file md5sum="437693ec37fb699fd461a15ab03d6958" name="tests/bson-corpus/decimal128-2-valid-154.phpt" role="test" />
<file md5sum="04d19a4f052153ce438e7392fbede2ae" name="tests/bson-corpus/decimal128-2-valid-155.phpt" role="test" />
<file md5sum="83636b3c914c03294084335baad24308" name="tests/bson-corpus/decimal128-2-valid-156.phpt" role="test" />
<file md5sum="baed618c203d6939f981d76c52398e18" name="tests/bson-corpus/decimal128-2-valid-157.phpt" role="test" />
<file md5sum="d663958a9a04af4d7f440f6fbf01f218" name="tests/bson-corpus/decimal128-3-valid-001.phpt" role="test" />
<file md5sum="ecc07dbedc7fef899e29469b6d69cc77" name="tests/bson-corpus/decimal128-3-valid-002.phpt" role="test" />
<file md5sum="a335969c0bdbd3b2f293d6b190060607" name="tests/bson-corpus/decimal128-3-valid-003.phpt" role="test" />
<file md5sum="78595b3c17c04f349cff845cb9d9b297" name="tests/bson-corpus/decimal128-3-valid-004.phpt" role="test" />
<file md5sum="76b9fc8c1090c8a11663f918dca8db90" name="tests/bson-corpus/decimal128-3-valid-005.phpt" role="test" />
<file md5sum="ee876344d7b9dee33b3e8733f453e33a" name="tests/bson-corpus/decimal128-3-valid-006.phpt" role="test" />
<file md5sum="9cff4e8d62ddf9cc9e9ca3fe5c41b1e3" name="tests/bson-corpus/decimal128-3-valid-007.phpt" role="test" />
<file md5sum="91d898997cfe79ffee8379062559ea38" name="tests/bson-corpus/decimal128-3-valid-008.phpt" role="test" />
<file md5sum="169ca1653e767baaa0237566c7c83202" name="tests/bson-corpus/decimal128-3-valid-009.phpt" role="test" />
<file md5sum="4a86dffa38699350595f14cce92658e4" name="tests/bson-corpus/decimal128-3-valid-010.phpt" role="test" />
<file md5sum="08f15de590c2637d5b802a9290459121" name="tests/bson-corpus/decimal128-3-valid-011.phpt" role="test" />
<file md5sum="1d079a21207368445051a74f01a196bb" name="tests/bson-corpus/decimal128-3-valid-012.phpt" role="test" />
<file md5sum="5e85a73cee90262e146277cc095161a2" name="tests/bson-corpus/decimal128-3-valid-013.phpt" role="test" />
<file md5sum="bd803feb1215caf7264f07f4f13e9eeb" name="tests/bson-corpus/decimal128-3-valid-014.phpt" role="test" />
<file md5sum="a509970a1a2ac408f6352ba5a5d809db" name="tests/bson-corpus/decimal128-3-valid-015.phpt" role="test" />
<file md5sum="917dfdf1917ae90ca441f46797a0b36f" name="tests/bson-corpus/decimal128-3-valid-016.phpt" role="test" />
<file md5sum="b8c7e09412bf0009202af0f94cd8f4c2" name="tests/bson-corpus/decimal128-3-valid-017.phpt" role="test" />
<file md5sum="bc1c8501be2e8e5605efff6f9a5cfee8" name="tests/bson-corpus/decimal128-3-valid-018.phpt" role="test" />
<file md5sum="45efaf007818f2ab4ee9092497541cf1" name="tests/bson-corpus/decimal128-3-valid-019.phpt" role="test" />
<file md5sum="70281fc36152213a418150b2b5403eed" name="tests/bson-corpus/decimal128-3-valid-020.phpt" role="test" />
<file md5sum="df9b4abbb00157a20e7eb1515e1b92d2" name="tests/bson-corpus/decimal128-3-valid-021.phpt" role="test" />
<file md5sum="000060f6cb4188e439bacf6f05390406" name="tests/bson-corpus/decimal128-3-valid-022.phpt" role="test" />
<file md5sum="81f305b3f256dccab1ad47ffbacc5a0e" name="tests/bson-corpus/decimal128-3-valid-023.phpt" role="test" />
<file md5sum="bb8b21b4cff570a41127872a21cfbe1e" name="tests/bson-corpus/decimal128-3-valid-024.phpt" role="test" />
<file md5sum="4dd8129b25ba91c3d8b39061a2586e85" name="tests/bson-corpus/decimal128-3-valid-025.phpt" role="test" />
<file md5sum="15c58ac7ae27b71d678eb272134d4ac3" name="tests/bson-corpus/decimal128-3-valid-026.phpt" role="test" />
<file md5sum="c0092a6dbe98463d593560951b9ffcf8" name="tests/bson-corpus/decimal128-3-valid-027.phpt" role="test" />
<file md5sum="037a779426adf3a0bd0c142461fe1a40" name="tests/bson-corpus/decimal128-3-valid-028.phpt" role="test" />
<file md5sum="71b808193d118e1f2584196053f0572f" name="tests/bson-corpus/decimal128-3-valid-029.phpt" role="test" />
<file md5sum="5bdc09c50157a4c6da25cc1fbd89ca86" name="tests/bson-corpus/decimal128-3-valid-030.phpt" role="test" />
<file md5sum="617a9aa32ddafab1040d42299b4a569c" name="tests/bson-corpus/decimal128-3-valid-031.phpt" role="test" />
<file md5sum="aa944ceab34cf6a7212d3dfb1acbac1b" name="tests/bson-corpus/decimal128-3-valid-032.phpt" role="test" />
<file md5sum="293cc8ca7e1ac2882f792e03296dccb5" name="tests/bson-corpus/decimal128-3-valid-033.phpt" role="test" />
<file md5sum="caa1404d8010c57a2c44879e7d6a6cef" name="tests/bson-corpus/decimal128-3-valid-034.phpt" role="test" />
<file md5sum="14f7ca7e55262fbf31ae07ed24e80ef9" name="tests/bson-corpus/decimal128-3-valid-035.phpt" role="test" />
<file md5sum="a6ff5bda0b279be4bd8b8683df768392" name="tests/bson-corpus/decimal128-3-valid-036.phpt" role="test" />
<file md5sum="57d2969629d1259ecd78cf5dbb3a8480" name="tests/bson-corpus/decimal128-3-valid-037.phpt" role="test" />
<file md5sum="39fa63f7acc6f875df47208ee5ff8780" name="tests/bson-corpus/decimal128-3-valid-038.phpt" role="test" />
<file md5sum="e489ba54d002683333a38b3d3ae3a68c" name="tests/bson-corpus/decimal128-3-valid-039.phpt" role="test" />
<file md5sum="45a147ada15a6cd19d4b1f5d84c61f3b" name="tests/bson-corpus/decimal128-3-valid-040.phpt" role="test" />
<file md5sum="a50b5de4fc6b56718b73dc3eeaf90d84" name="tests/bson-corpus/decimal128-3-valid-041.phpt" role="test" />
<file md5sum="eb0bfd58f7e7c150ae6ba8a8cc694bf2" name="tests/bson-corpus/decimal128-3-valid-042.phpt" role="test" />
<file md5sum="de7928d46237131c3f62a0cdea6302ff" name="tests/bson-corpus/decimal128-3-valid-043.phpt" role="test" />
<file md5sum="ba4a91f8f44c2fe060585dfd0fe55541" name="tests/bson-corpus/decimal128-3-valid-044.phpt" role="test" />
<file md5sum="201ab1261f9e00ad51e34ff7cbac385d" name="tests/bson-corpus/decimal128-3-valid-045.phpt" role="test" />
<file md5sum="73cd0ab3b85b7876b62dafcc6b47862a" name="tests/bson-corpus/decimal128-3-valid-046.phpt" role="test" />
<file md5sum="e9fc32da279c5eb92658689a10235399" name="tests/bson-corpus/decimal128-3-valid-047.phpt" role="test" />
<file md5sum="ea0c1bd4adcc97adea6060fe037a39ff" name="tests/bson-corpus/decimal128-3-valid-048.phpt" role="test" />
<file md5sum="583fb51b1b9edd2fe6d762fa4e1f080f" name="tests/bson-corpus/decimal128-3-valid-049.phpt" role="test" />
<file md5sum="3f34801e62a987e85f69ed36161263e3" name="tests/bson-corpus/decimal128-3-valid-050.phpt" role="test" />
<file md5sum="175917a95c4bb895a655dd34a5c45241" name="tests/bson-corpus/decimal128-3-valid-051.phpt" role="test" />
<file md5sum="da519fcd6365dfa317b47361ee5803aa" name="tests/bson-corpus/decimal128-3-valid-052.phpt" role="test" />
<file md5sum="d092cedcd919cdb4058bd3ae510fd1ad" name="tests/bson-corpus/decimal128-3-valid-053.phpt" role="test" />
<file md5sum="e850354f3236c861c6da9705f1486972" name="tests/bson-corpus/decimal128-3-valid-054.phpt" role="test" />
<file md5sum="bfe45e890c0fdb6ed790fb3a498d6af9" name="tests/bson-corpus/decimal128-3-valid-055.phpt" role="test" />
<file md5sum="5d501aee839b508cf2ef6295514ca94f" name="tests/bson-corpus/decimal128-3-valid-056.phpt" role="test" />
<file md5sum="12491275e5ec45c85a7b1df192bd4f3f" name="tests/bson-corpus/decimal128-3-valid-057.phpt" role="test" />
<file md5sum="14931a4e58c5ab8ac0fded043e177ea0" name="tests/bson-corpus/decimal128-3-valid-058.phpt" role="test" />
<file md5sum="89e0b5c575e0a05183d4083475a9e1e6" name="tests/bson-corpus/decimal128-3-valid-059.phpt" role="test" />
<file md5sum="1a1bcd12962fc1d18765b78d160cae45" name="tests/bson-corpus/decimal128-3-valid-060.phpt" role="test" />
<file md5sum="bff26b7bb5f5f026c1bef71daac5471a" name="tests/bson-corpus/decimal128-3-valid-061.phpt" role="test" />
<file md5sum="c424ce2eeb8b3e9d731268e2ecb586c8" name="tests/bson-corpus/decimal128-3-valid-062.phpt" role="test" />
<file md5sum="f9810126ba6338721bf810fc2f7df13c" name="tests/bson-corpus/decimal128-3-valid-063.phpt" role="test" />
<file md5sum="75dbcf3f9d389f3d01d3783d3a717312" name="tests/bson-corpus/decimal128-3-valid-064.phpt" role="test" />
<file md5sum="1962c74102261ec0275d1979f8b08a36" name="tests/bson-corpus/decimal128-3-valid-065.phpt" role="test" />
<file md5sum="4f880060a5188ef62155d868f1cfc1ed" name="tests/bson-corpus/decimal128-3-valid-066.phpt" role="test" />
<file md5sum="34dee229164dbb8d587755108dc3add6" name="tests/bson-corpus/decimal128-3-valid-067.phpt" role="test" />
<file md5sum="0481384bfb647021ec33ff435b5a16fc" name="tests/bson-corpus/decimal128-3-valid-068.phpt" role="test" />
<file md5sum="0ccf9fbb134c0f197c9427258ad9cf9a" name="tests/bson-corpus/decimal128-3-valid-069.phpt" role="test" />
<file md5sum="ebe453e7e8dafdb214cfbece655f3ba1" name="tests/bson-corpus/decimal128-3-valid-070.phpt" role="test" />
<file md5sum="e03aeca7a1854f872b573a6459237add" name="tests/bson-corpus/decimal128-3-valid-071.phpt" role="test" />
<file md5sum="ccc504adf424fa6c243daef5bbd14587" name="tests/bson-corpus/decimal128-3-valid-072.phpt" role="test" />
<file md5sum="cc1ad4185d5c5f656b0a897138532398" name="tests/bson-corpus/decimal128-3-valid-073.phpt" role="test" />
<file md5sum="c192e80107cd9d875fa116e476023243" name="tests/bson-corpus/decimal128-3-valid-074.phpt" role="test" />
<file md5sum="02156edeedc363f26d852f984f8212b4" name="tests/bson-corpus/decimal128-3-valid-075.phpt" role="test" />
<file md5sum="95aad9442987108e0b4cce2e4721899e" name="tests/bson-corpus/decimal128-3-valid-076.phpt" role="test" />
<file md5sum="8cb6067468db7aa9830d7e67b31e5049" name="tests/bson-corpus/decimal128-3-valid-077.phpt" role="test" />
<file md5sum="1d65b3edbf22c5db259eb2f3f03eb27c" name="tests/bson-corpus/decimal128-3-valid-078.phpt" role="test" />
<file md5sum="0feb8079732e1ad8a7c32976eb395a0f" name="tests/bson-corpus/decimal128-3-valid-079.phpt" role="test" />
<file md5sum="9c3a99144f631018d8bb67fd90fc11b0" name="tests/bson-corpus/decimal128-3-valid-080.phpt" role="test" />
<file md5sum="3f1a36b46cf7cc8a5cfe31d704f47c20" name="tests/bson-corpus/decimal128-3-valid-081.phpt" role="test" />
<file md5sum="93fe3ed288ee37162e75724e69258c3d" name="tests/bson-corpus/decimal128-3-valid-082.phpt" role="test" />
<file md5sum="857d01afef9513a561e89e65ecc3be65" name="tests/bson-corpus/decimal128-3-valid-083.phpt" role="test" />
<file md5sum="418e701672877a981f29a252d18649b7" name="tests/bson-corpus/decimal128-3-valid-084.phpt" role="test" />
<file md5sum="e0bd1763ce58b81b4b642ce7d847760d" name="tests/bson-corpus/decimal128-3-valid-085.phpt" role="test" />
<file md5sum="f8219f82f090ab31c72990f3e69f7de9" name="tests/bson-corpus/decimal128-3-valid-086.phpt" role="test" />
<file md5sum="135c5def9e53d1330e40d0c9db005f82" name="tests/bson-corpus/decimal128-3-valid-087.phpt" role="test" />
<file md5sum="eae1e8e58678ebc4900e1e76d8b707f7" name="tests/bson-corpus/decimal128-3-valid-088.phpt" role="test" />
<file md5sum="9da9ebdb272e62cd49ad55c953d2f585" name="tests/bson-corpus/decimal128-3-valid-089.phpt" role="test" />
<file md5sum="1b0308b459131414d4fdcbb83ce644be" name="tests/bson-corpus/decimal128-3-valid-090.phpt" role="test" />
<file md5sum="f6831b6281b8792c73c5e7e1a62f8d09" name="tests/bson-corpus/decimal128-3-valid-091.phpt" role="test" />
<file md5sum="f7f4ddb3747783588da39fcbbf877c7f" name="tests/bson-corpus/decimal128-3-valid-092.phpt" role="test" />
<file md5sum="9d931b0e25e8c506eb100ffcd40a81d2" name="tests/bson-corpus/decimal128-3-valid-093.phpt" role="test" />
<file md5sum="5569a2c40ab01148442a3e10317013f7" name="tests/bson-corpus/decimal128-3-valid-094.phpt" role="test" />
<file md5sum="6ded8b0607a78b0af47c70b5e40fa553" name="tests/bson-corpus/decimal128-3-valid-095.phpt" role="test" />
<file md5sum="87f2b78c9bde6247cd0e5df3b8974e13" name="tests/bson-corpus/decimal128-3-valid-096.phpt" role="test" />
<file md5sum="12c9214689823bd5e5185a9e70efc367" name="tests/bson-corpus/decimal128-3-valid-097.phpt" role="test" />
<file md5sum="a03dee4e37647a6d75d47e129c21e5ff" name="tests/bson-corpus/decimal128-3-valid-098.phpt" role="test" />
<file md5sum="1e40eaebd2f828048b3d2527cc28215a" name="tests/bson-corpus/decimal128-3-valid-099.phpt" role="test" />
<file md5sum="15f98c55d09d08ceefe37625e7968450" name="tests/bson-corpus/decimal128-3-valid-100.phpt" role="test" />
<file md5sum="86d1d02e3200ef3e6cb0ec6d56dffa7a" name="tests/bson-corpus/decimal128-3-valid-101.phpt" role="test" />
<file md5sum="ce2282f2a0b6a3a5dec57975a245a45e" name="tests/bson-corpus/decimal128-3-valid-102.phpt" role="test" />
<file md5sum="89ac6a9b7144480acf3a4d2e206d84a8" name="tests/bson-corpus/decimal128-3-valid-103.phpt" role="test" />
<file md5sum="7ee902971ee8a202a473da731afb9cfe" name="tests/bson-corpus/decimal128-3-valid-104.phpt" role="test" />
<file md5sum="aac8ebf753b56938213af2bc26bfe8e4" name="tests/bson-corpus/decimal128-3-valid-105.phpt" role="test" />
<file md5sum="77d21e1be55cc8a0455fb10831a345a5" name="tests/bson-corpus/decimal128-3-valid-106.phpt" role="test" />
<file md5sum="fc3e6cc66bf666004b1694d691fcef25" name="tests/bson-corpus/decimal128-3-valid-107.phpt" role="test" />
<file md5sum="c9857e3a53e2b492d4649fad34114fdc" name="tests/bson-corpus/decimal128-3-valid-108.phpt" role="test" />
<file md5sum="4acaf250c963be852e98e56858a02e0c" name="tests/bson-corpus/decimal128-3-valid-109.phpt" role="test" />
<file md5sum="086e06d076ced5b52258b2a33771c183" name="tests/bson-corpus/decimal128-3-valid-110.phpt" role="test" />
<file md5sum="8d91b9a7cb540d4387a505f58574108e" name="tests/bson-corpus/decimal128-3-valid-111.phpt" role="test" />
<file md5sum="34e1796deebbc24b7f5126d3fa76f492" name="tests/bson-corpus/decimal128-3-valid-112.phpt" role="test" />
<file md5sum="6876f7d97b31d9de1c5ef80cb2da3e46" name="tests/bson-corpus/decimal128-3-valid-113.phpt" role="test" />
<file md5sum="78db49b179f3aa2adf753ef414af4b07" name="tests/bson-corpus/decimal128-3-valid-114.phpt" role="test" />
<file md5sum="85077ceb495972ce1666ce2ca6bff241" name="tests/bson-corpus/decimal128-3-valid-115.phpt" role="test" />
<file md5sum="25d5f3a37400b59d830548d0b19f7167" name="tests/bson-corpus/decimal128-3-valid-116.phpt" role="test" />
<file md5sum="7bd291561573e8b297a283f71d0f833c" name="tests/bson-corpus/decimal128-3-valid-117.phpt" role="test" />
<file md5sum="3018d5985b433ad8327198371b274b69" name="tests/bson-corpus/decimal128-3-valid-118.phpt" role="test" />
<file md5sum="ab9e8e91b98e0f778fcdeb46ea0dba7a" name="tests/bson-corpus/decimal128-3-valid-119.phpt" role="test" />
<file md5sum="7245422896d49aa46f13d735bf1f0b60" name="tests/bson-corpus/decimal128-3-valid-120.phpt" role="test" />
<file md5sum="be7cc343096711e5c603aeb5bf9c8e1e" name="tests/bson-corpus/decimal128-3-valid-121.phpt" role="test" />
<file md5sum="fde4542bd5195f65a89f87fe592f5b68" name="tests/bson-corpus/decimal128-3-valid-122.phpt" role="test" />
<file md5sum="5784f8917972cf55088e0187fbee9eda" name="tests/bson-corpus/decimal128-3-valid-123.phpt" role="test" />
<file md5sum="4f8fbc6b7ddc23a24d9465cb3b65c935" name="tests/bson-corpus/decimal128-3-valid-124.phpt" role="test" />
<file md5sum="31740f132c125df94563a23df30f4062" name="tests/bson-corpus/decimal128-3-valid-125.phpt" role="test" />
<file md5sum="e905661301fb137f8e8af2022b094c8b" name="tests/bson-corpus/decimal128-3-valid-126.phpt" role="test" />
<file md5sum="d7f206136f1eeaa187435a8de879fe9b" name="tests/bson-corpus/decimal128-3-valid-127.phpt" role="test" />
<file md5sum="fd5d03e6d489d9483e0211e89d112db9" name="tests/bson-corpus/decimal128-3-valid-128.phpt" role="test" />
<file md5sum="1d8882fe77db8d8e9ff668d55c1aa7cc" name="tests/bson-corpus/decimal128-3-valid-129.phpt" role="test" />
<file md5sum="d192443cdd874b506af216c18260692e" name="tests/bson-corpus/decimal128-3-valid-130.phpt" role="test" />
<file md5sum="b9ebf345c533fe2fb31e3a976c5a2586" name="tests/bson-corpus/decimal128-3-valid-131.phpt" role="test" />
<file md5sum="2da4817354b049bf98d75f5cffb50df8" name="tests/bson-corpus/decimal128-3-valid-132.phpt" role="test" />
<file md5sum="c55b4edfaae4da641cbef9e43ae27749" name="tests/bson-corpus/decimal128-3-valid-133.phpt" role="test" />
<file md5sum="716b0e43ec01e9bdb8f1d07cb95d2d47" name="tests/bson-corpus/decimal128-3-valid-134.phpt" role="test" />
<file md5sum="4311a8f3f7f03b83bc8aa50c3b41a7b3" name="tests/bson-corpus/decimal128-3-valid-135.phpt" role="test" />
<file md5sum="f02d6dba5d13a1a553f4df0325ce8c95" name="tests/bson-corpus/decimal128-3-valid-136.phpt" role="test" />
<file md5sum="b427a8b34df8dfea8b658f0e397e6410" name="tests/bson-corpus/decimal128-3-valid-137.phpt" role="test" />
<file md5sum="412109a5ad9bace87a5e548320c95b63" name="tests/bson-corpus/decimal128-3-valid-138.phpt" role="test" />
<file md5sum="24b1923c0de2c035767ca0c2413a6877" name="tests/bson-corpus/decimal128-3-valid-139.phpt" role="test" />
<file md5sum="86d1daec5860decc7fed2c0d24a72010" name="tests/bson-corpus/decimal128-3-valid-140.phpt" role="test" />
<file md5sum="9df0580b1518470f5071f83d5b5907e4" name="tests/bson-corpus/decimal128-3-valid-141.phpt" role="test" />
<file md5sum="96d326ae41086e9e82a065ac0c2a5470" name="tests/bson-corpus/decimal128-3-valid-142.phpt" role="test" />
<file md5sum="dca7cd61fc27d3993dd2702d1078ccea" name="tests/bson-corpus/decimal128-3-valid-143.phpt" role="test" />
<file md5sum="2104f5bea79ea21b06ad36af1fef34f5" name="tests/bson-corpus/decimal128-3-valid-144.phpt" role="test" />
<file md5sum="db364e0176cd7bb05ca67aaea34c07ec" name="tests/bson-corpus/decimal128-3-valid-145.phpt" role="test" />
<file md5sum="041e861f5feabee285641bede7658962" name="tests/bson-corpus/decimal128-3-valid-146.phpt" role="test" />
<file md5sum="51277ab6f97e3f621cb44ce6ac3079b1" name="tests/bson-corpus/decimal128-3-valid-147.phpt" role="test" />
<file md5sum="9c0090cb83d66cb6779cfad5fbe2aeb5" name="tests/bson-corpus/decimal128-3-valid-148.phpt" role="test" />
<file md5sum="6b60295daa8dc395222a709fac2dbe69" name="tests/bson-corpus/decimal128-3-valid-149.phpt" role="test" />
<file md5sum="4848a67e7d194c36c2559bf4f16a75fa" name="tests/bson-corpus/decimal128-3-valid-150.phpt" role="test" />
<file md5sum="c7ab36909fd42b42ef9cfe62055ae48e" name="tests/bson-corpus/decimal128-3-valid-151.phpt" role="test" />
<file md5sum="8095127bc9738bdc43d73d620ec60085" name="tests/bson-corpus/decimal128-3-valid-152.phpt" role="test" />
<file md5sum="8c0516cd86dba89635450c4c2f16a1c8" name="tests/bson-corpus/decimal128-3-valid-153.phpt" role="test" />
<file md5sum="0b2d7af4fa199f375f7f7559e40c8437" name="tests/bson-corpus/decimal128-3-valid-154.phpt" role="test" />
<file md5sum="e4913bfa055eec06944d154c22254e34" name="tests/bson-corpus/decimal128-3-valid-155.phpt" role="test" />
<file md5sum="1bbb49f4acb8e747c671bec4ded1625b" name="tests/bson-corpus/decimal128-3-valid-156.phpt" role="test" />
<file md5sum="2055c345977112555436fd1032088550" name="tests/bson-corpus/decimal128-3-valid-157.phpt" role="test" />
<file md5sum="aee3703ff7f9d3574999ed4192ee5a7b" name="tests/bson-corpus/decimal128-3-valid-158.phpt" role="test" />
<file md5sum="6c44c9da5be7d14d7e1e64df0c05ab50" name="tests/bson-corpus/decimal128-3-valid-159.phpt" role="test" />
<file md5sum="fc733a47ea1bca924b7758b142feb60f" name="tests/bson-corpus/decimal128-3-valid-160.phpt" role="test" />
<file md5sum="9a1bc4666bf48a3f186158a275da92ee" name="tests/bson-corpus/decimal128-3-valid-161.phpt" role="test" />
<file md5sum="28ea08eae3926df32eac21f9c4fcf9f5" name="tests/bson-corpus/decimal128-3-valid-162.phpt" role="test" />
<file md5sum="c977800cce3174c016215be8b13895b8" name="tests/bson-corpus/decimal128-3-valid-163.phpt" role="test" />
<file md5sum="1205216679be2c1ef9701e5cdca89af3" name="tests/bson-corpus/decimal128-3-valid-164.phpt" role="test" />
<file md5sum="f5c5d28cb2c3e25959bcd8b8cfb18067" name="tests/bson-corpus/decimal128-3-valid-165.phpt" role="test" />
<file md5sum="57dfdcde16d01df36704cc544ccab7a9" name="tests/bson-corpus/decimal128-3-valid-166.phpt" role="test" />
<file md5sum="cb7888fb2fe79a6e4a4a24638ab3d6cb" name="tests/bson-corpus/decimal128-3-valid-167.phpt" role="test" />
<file md5sum="fc0ef710100ec9c010cab2b48bac6ad9" name="tests/bson-corpus/decimal128-3-valid-168.phpt" role="test" />
<file md5sum="ab255604f85bb4de07795ef64f5f52ff" name="tests/bson-corpus/decimal128-3-valid-169.phpt" role="test" />
<file md5sum="4c37d21a51e323aa2f5a9ce057370dfb" name="tests/bson-corpus/decimal128-3-valid-170.phpt" role="test" />
<file md5sum="e8004efddcf823a90d8866b01fe47484" name="tests/bson-corpus/decimal128-3-valid-171.phpt" role="test" />
<file md5sum="b5cd969bf4aa15beb8fd9d86da5e2c6b" name="tests/bson-corpus/decimal128-3-valid-172.phpt" role="test" />
<file md5sum="8e791e98d3e9d8b929aa776689060e73" name="tests/bson-corpus/decimal128-3-valid-173.phpt" role="test" />
<file md5sum="1a0aab89867a192127bee79116325b87" name="tests/bson-corpus/decimal128-3-valid-174.phpt" role="test" />
<file md5sum="92ee0cde9906482b7ba70af64b7db652" name="tests/bson-corpus/decimal128-3-valid-175.phpt" role="test" />
<file md5sum="47d81bd68b7d6cf7400e7bc7800b802f" name="tests/bson-corpus/decimal128-3-valid-176.phpt" role="test" />
<file md5sum="e9d3ecff8a2629451dfbd6ce8433ad16" name="tests/bson-corpus/decimal128-3-valid-177.phpt" role="test" />
<file md5sum="e2006319591744837f5c63c889a33a64" name="tests/bson-corpus/decimal128-3-valid-178.phpt" role="test" />
<file md5sum="31151203e48881eddcf122554c0066e2" name="tests/bson-corpus/decimal128-3-valid-179.phpt" role="test" />
<file md5sum="accf0f5388ceca4eeb1e353a58652381" name="tests/bson-corpus/decimal128-3-valid-180.phpt" role="test" />
<file md5sum="88889b93a559042a1d36b4613cb6e9d5" name="tests/bson-corpus/decimal128-3-valid-181.phpt" role="test" />
<file md5sum="8c394b5ae827d370d63336e610c82914" name="tests/bson-corpus/decimal128-3-valid-182.phpt" role="test" />
<file md5sum="37076846368569fc63d33fdb88a1b54d" name="tests/bson-corpus/decimal128-3-valid-183.phpt" role="test" />
<file md5sum="8eae26029ee22ecb86f41f180a5ca116" name="tests/bson-corpus/decimal128-3-valid-184.phpt" role="test" />
<file md5sum="31d3465dee3f4f873a2f07a9f7e5cbb1" name="tests/bson-corpus/decimal128-3-valid-185.phpt" role="test" />
<file md5sum="c20fffbdac614f64cdf9e0c0a4031ed5" name="tests/bson-corpus/decimal128-3-valid-186.phpt" role="test" />
<file md5sum="e661acef71d97e07e5e014db6b35882c" name="tests/bson-corpus/decimal128-3-valid-187.phpt" role="test" />
<file md5sum="868e5c102d17283c5d409860fccbfa4e" name="tests/bson-corpus/decimal128-3-valid-188.phpt" role="test" />
<file md5sum="bbea4f1602b3984917476d1e690ad295" name="tests/bson-corpus/decimal128-3-valid-189.phpt" role="test" />
<file md5sum="c4124a2fef2a6756a445119f5c9e87eb" name="tests/bson-corpus/decimal128-3-valid-190.phpt" role="test" />
<file md5sum="1947f48464ce9e2cf13063c8177c2242" name="tests/bson-corpus/decimal128-3-valid-191.phpt" role="test" />
<file md5sum="d18377558e6bd3ec8873415db1385f01" name="tests/bson-corpus/decimal128-3-valid-192.phpt" role="test" />
<file md5sum="4610f63580b90439588bafb24b7e3aec" name="tests/bson-corpus/decimal128-3-valid-193.phpt" role="test" />
<file md5sum="e2a0c6f4fca7db4fa4c246140e626dfa" name="tests/bson-corpus/decimal128-3-valid-194.phpt" role="test" />
<file md5sum="61fd9c77baa3e055a3dd1d583c735ad8" name="tests/bson-corpus/decimal128-3-valid-195.phpt" role="test" />
<file md5sum="a2dd41853291597b6e8a42659556f5ae" name="tests/bson-corpus/decimal128-3-valid-196.phpt" role="test" />
<file md5sum="fa0bf2f4dd8eef8f6e01fbc6ae34fbe4" name="tests/bson-corpus/decimal128-3-valid-197.phpt" role="test" />
<file md5sum="7d155cbc68bb1d0811799b8b956ea349" name="tests/bson-corpus/decimal128-3-valid-198.phpt" role="test" />
<file md5sum="8da630bd40cea241eaded08f2f0c85b7" name="tests/bson-corpus/decimal128-3-valid-199.phpt" role="test" />
<file md5sum="d18dada8921aa158fbd3c7f8ca7e5311" name="tests/bson-corpus/decimal128-3-valid-200.phpt" role="test" />
<file md5sum="d5c7a07be870a2ef38072661d54e96f8" name="tests/bson-corpus/decimal128-3-valid-201.phpt" role="test" />
<file md5sum="958fe772e4105738c3fdec3f12626e91" name="tests/bson-corpus/decimal128-3-valid-202.phpt" role="test" />
<file md5sum="7d26387b1ce9f36475e82b961132fe20" name="tests/bson-corpus/decimal128-3-valid-203.phpt" role="test" />
<file md5sum="10cff8b9ca7de0a9f65aa07637f1fbe1" name="tests/bson-corpus/decimal128-3-valid-204.phpt" role="test" />
<file md5sum="c48e34f0cd62955e21eb7eb4e91bc2e6" name="tests/bson-corpus/decimal128-3-valid-205.phpt" role="test" />
<file md5sum="d9756c9baeb4f4a380e06979e89ba8c6" name="tests/bson-corpus/decimal128-3-valid-206.phpt" role="test" />
<file md5sum="065368cc47839cb8f09fc29ef5be3356" name="tests/bson-corpus/decimal128-3-valid-207.phpt" role="test" />
<file md5sum="88e8a54b62e646b8f0018cebd13c91ce" name="tests/bson-corpus/decimal128-3-valid-208.phpt" role="test" />
<file md5sum="2a8907082d7e1562502089d3780da0da" name="tests/bson-corpus/decimal128-3-valid-209.phpt" role="test" />
<file md5sum="024b2807906b89941d8cb6cc7edcfa35" name="tests/bson-corpus/decimal128-3-valid-210.phpt" role="test" />
<file md5sum="a7a55d1d5240dfe00797f948a9b4ff14" name="tests/bson-corpus/decimal128-3-valid-211.phpt" role="test" />
<file md5sum="a90fa6dfcf451b906ef8dc4de0320e8c" name="tests/bson-corpus/decimal128-3-valid-212.phpt" role="test" />
<file md5sum="18e2d5bc2b07741bab2528993d781314" name="tests/bson-corpus/decimal128-3-valid-213.phpt" role="test" />
<file md5sum="37b0645de83b792bf815ad23103ab566" name="tests/bson-corpus/decimal128-3-valid-214.phpt" role="test" />
<file md5sum="4b9ffd465539a046a3cb246224d72f95" name="tests/bson-corpus/decimal128-3-valid-215.phpt" role="test" />
<file md5sum="984d8afafc82fad297461ba62cd8ac1d" name="tests/bson-corpus/decimal128-3-valid-216.phpt" role="test" />
<file md5sum="e3cc278118c21d942fc1ae11b687648b" name="tests/bson-corpus/decimal128-3-valid-217.phpt" role="test" />
<file md5sum="1173a48f6361e2de3dd61e6338ac788f" name="tests/bson-corpus/decimal128-3-valid-218.phpt" role="test" />
<file md5sum="96f2a2a5fe40e0c7c250b9ecc8348957" name="tests/bson-corpus/decimal128-3-valid-219.phpt" role="test" />
<file md5sum="dac9801678b61c05275f890be26ed6fa" name="tests/bson-corpus/decimal128-3-valid-220.phpt" role="test" />
<file md5sum="fa7d9008c0ce8501b8dd88c6f1979629" name="tests/bson-corpus/decimal128-3-valid-221.phpt" role="test" />
<file md5sum="7e4ebd6890f9f7a826fd305308d14391" name="tests/bson-corpus/decimal128-3-valid-222.phpt" role="test" />
<file md5sum="5062c83925f58f0a6862aa55b1a51ef3" name="tests/bson-corpus/decimal128-3-valid-223.phpt" role="test" />
<file md5sum="3bb84b7df212ca8940660ebe7d874a59" name="tests/bson-corpus/decimal128-3-valid-224.phpt" role="test" />
<file md5sum="74bf40280e720d2c4d2c4cac267fdad2" name="tests/bson-corpus/decimal128-3-valid-225.phpt" role="test" />
<file md5sum="b29d6344aa7230063e17e18a5a8afcdf" name="tests/bson-corpus/decimal128-3-valid-226.phpt" role="test" />
<file md5sum="534c33801721b90c1a05de585b27c346" name="tests/bson-corpus/decimal128-3-valid-227.phpt" role="test" />
<file md5sum="e8e1217c0cfcae77f1475428e2864833" name="tests/bson-corpus/decimal128-3-valid-228.phpt" role="test" />
<file md5sum="55c36373b5bb97d9458583e40c679154" name="tests/bson-corpus/decimal128-3-valid-229.phpt" role="test" />
<file md5sum="2b3a49f63c44e233a069c2cfc5ab6418" name="tests/bson-corpus/decimal128-3-valid-230.phpt" role="test" />
<file md5sum="7c7557f76a059b2702dd51658fb9b5fe" name="tests/bson-corpus/decimal128-3-valid-231.phpt" role="test" />
<file md5sum="b520fa6b84bd9f1ccae80fcb451d71b1" name="tests/bson-corpus/decimal128-3-valid-232.phpt" role="test" />
<file md5sum="9d29422ba6241564eaddded8d407dedf" name="tests/bson-corpus/decimal128-3-valid-233.phpt" role="test" />
<file md5sum="dacc33bbee339c26e7de1cda145afd02" name="tests/bson-corpus/decimal128-3-valid-234.phpt" role="test" />
<file md5sum="a70f999ff669cdba90b3010f0d6c3d88" name="tests/bson-corpus/decimal128-3-valid-235.phpt" role="test" />
<file md5sum="bc46984804f3efd6a5d727b012a4ef5c" name="tests/bson-corpus/decimal128-3-valid-236.phpt" role="test" />
<file md5sum="a4e1ecaa13dd625af1df3785ec5fb7d0" name="tests/bson-corpus/decimal128-3-valid-237.phpt" role="test" />
<file md5sum="a9563619eeb12e76dadb211e6e411096" name="tests/bson-corpus/decimal128-3-valid-238.phpt" role="test" />
<file md5sum="b2483a48520d01b99ee3782a545f620e" name="tests/bson-corpus/decimal128-3-valid-239.phpt" role="test" />
<file md5sum="beb70a804e04565272f7bcacdf106fdd" name="tests/bson-corpus/decimal128-3-valid-240.phpt" role="test" />
<file md5sum="0f3b075ad241dbb48003cc1ae4c5546d" name="tests/bson-corpus/decimal128-3-valid-241.phpt" role="test" />
<file md5sum="aa8d6423927cd6fa40dd0b0f750ab5cb" name="tests/bson-corpus/decimal128-3-valid-242.phpt" role="test" />
<file md5sum="d52a67c83822741cb3d4b3eef7c5bcb3" name="tests/bson-corpus/decimal128-3-valid-243.phpt" role="test" />
<file md5sum="fe2289f275359d280f1247ae727b842e" name="tests/bson-corpus/decimal128-3-valid-244.phpt" role="test" />
<file md5sum="9e5227bb6e0c2b52b6a466ac207c52ee" name="tests/bson-corpus/decimal128-3-valid-245.phpt" role="test" />
<file md5sum="7c7b2f334c3deb4c8520819a6a5c0753" name="tests/bson-corpus/decimal128-3-valid-246.phpt" role="test" />
<file md5sum="c2a4dee2ffb3ac99cf322056b216e1bf" name="tests/bson-corpus/decimal128-3-valid-247.phpt" role="test" />
<file md5sum="de365973ac696e0dbd2e920242bf7027" name="tests/bson-corpus/decimal128-3-valid-248.phpt" role="test" />
<file md5sum="2f2a7f8a47f0798bad07ff58d4f79cdd" name="tests/bson-corpus/decimal128-3-valid-249.phpt" role="test" />
<file md5sum="20bcbbdd59af956c90a49096feda241d" name="tests/bson-corpus/decimal128-3-valid-250.phpt" role="test" />
<file md5sum="4fc937ac01a41825a9de95a1aaef3626" name="tests/bson-corpus/decimal128-3-valid-251.phpt" role="test" />
<file md5sum="0bdd8aff5c0ecfff015e057ec783eb54" name="tests/bson-corpus/decimal128-3-valid-252.phpt" role="test" />
<file md5sum="8171b181ce1f3714b85fa4794a89f277" name="tests/bson-corpus/decimal128-3-valid-253.phpt" role="test" />
<file md5sum="d04d9efcc3f8855b83933dd3b3bc7048" name="tests/bson-corpus/decimal128-3-valid-254.phpt" role="test" />
<file md5sum="53ee0eaacdd78867ec0e7ed8971429a7" name="tests/bson-corpus/decimal128-3-valid-255.phpt" role="test" />
<file md5sum="3cee9acb77277efee148bdbe8d223dfa" name="tests/bson-corpus/decimal128-3-valid-256.phpt" role="test" />
<file md5sum="789c791120cc609ede0737b7c23c85c5" name="tests/bson-corpus/decimal128-3-valid-257.phpt" role="test" />
<file md5sum="3d98bb4cbf4deca3dbebca3c2dfd2172" name="tests/bson-corpus/decimal128-3-valid-258.phpt" role="test" />
<file md5sum="f236ad31e12561372e2eb1c5d422d433" name="tests/bson-corpus/decimal128-3-valid-259.phpt" role="test" />
<file md5sum="6b536b709b52a15a444876ba78d8386b" name="tests/bson-corpus/decimal128-3-valid-260.phpt" role="test" />
<file md5sum="977f9734739aa26baecfd42aa11d0563" name="tests/bson-corpus/decimal128-3-valid-261.phpt" role="test" />
<file md5sum="b20fadb42701697d312a405454d3897d" name="tests/bson-corpus/decimal128-3-valid-262.phpt" role="test" />
<file md5sum="cc1d280c45c19a0a4a99095ccb1057ee" name="tests/bson-corpus/decimal128-3-valid-263.phpt" role="test" />
<file md5sum="5396c314de1ee3d03222dd54730d8cea" name="tests/bson-corpus/decimal128-3-valid-264.phpt" role="test" />
<file md5sum="53355bc837a9e55bb89235c4a4dccebc" name="tests/bson-corpus/decimal128-3-valid-265.phpt" role="test" />
<file md5sum="b5f3ee35ca6330dc3fe7d36247329b19" name="tests/bson-corpus/decimal128-3-valid-266.phpt" role="test" />
<file md5sum="1caf657e84d75ec2da12cbdd694ed7cd" name="tests/bson-corpus/decimal128-3-valid-267.phpt" role="test" />
<file md5sum="91b7a0d88d47c52ff8c7fb90096ede50" name="tests/bson-corpus/decimal128-3-valid-268.phpt" role="test" />
<file md5sum="e8c6b1bff14070cb676c2f979b3b4e96" name="tests/bson-corpus/decimal128-3-valid-269.phpt" role="test" />
<file md5sum="c6146dad6e717e10b5bf49d19bd2db89" name="tests/bson-corpus/decimal128-3-valid-270.phpt" role="test" />
<file md5sum="a4209116538d9925a17136840c078d7e" name="tests/bson-corpus/decimal128-3-valid-271.phpt" role="test" />
<file md5sum="6410e5f72cfd14259830104c5c091139" name="tests/bson-corpus/decimal128-3-valid-272.phpt" role="test" />
<file md5sum="bd929e4791beeb33dbcae622f4626d04" name="tests/bson-corpus/decimal128-3-valid-273.phpt" role="test" />
<file md5sum="1760c2f0b0439badf8bea9d0c97b4bb9" name="tests/bson-corpus/decimal128-3-valid-274.phpt" role="test" />
<file md5sum="413c3fb29c57a6bb541a3208dfa5b0b5" name="tests/bson-corpus/decimal128-3-valid-275.phpt" role="test" />
<file md5sum="e94d822420eb0fcb1c4284555472f753" name="tests/bson-corpus/decimal128-3-valid-276.phpt" role="test" />
<file md5sum="851f35f08adee1669ee5aea2372bd1d3" name="tests/bson-corpus/decimal128-3-valid-277.phpt" role="test" />
<file md5sum="a5f96574b6b9757c43b66c78d8fd4192" name="tests/bson-corpus/decimal128-3-valid-278.phpt" role="test" />
<file md5sum="9a5b2ff83d46cea8ba921d741cab8ebd" name="tests/bson-corpus/decimal128-3-valid-279.phpt" role="test" />
<file md5sum="554928efc3695a2d4f5633d0b5d8ff1c" name="tests/bson-corpus/decimal128-3-valid-280.phpt" role="test" />
<file md5sum="beb3f30d75efb68b5f28bdea472f7de2" name="tests/bson-corpus/decimal128-3-valid-281.phpt" role="test" />
<file md5sum="cc5d33541c74b05f6baae0f9716cddfe" name="tests/bson-corpus/decimal128-3-valid-282.phpt" role="test" />
<file md5sum="ba3e10638dfebdb19cbd26a1a0f9fc8d" name="tests/bson-corpus/decimal128-3-valid-283.phpt" role="test" />
<file md5sum="2049b5bdb6e19ffb1596e99760be5910" name="tests/bson-corpus/decimal128-3-valid-284.phpt" role="test" />
<file md5sum="5c4dca60c9d1ade7ce30db60850d1462" name="tests/bson-corpus/decimal128-3-valid-285.phpt" role="test" />
<file md5sum="d4d643d1edee4c50e649692e26d7091a" name="tests/bson-corpus/decimal128-3-valid-286.phpt" role="test" />
<file md5sum="ad4a1ea5243f7c668fe1c709c7d35817" name="tests/bson-corpus/decimal128-3-valid-287.phpt" role="test" />
<file md5sum="8d8d837be562a71df83c5824e2f85d5d" name="tests/bson-corpus/decimal128-3-valid-288.phpt" role="test" />
<file md5sum="aede3884fcb665e586b415cabb1445c7" name="tests/bson-corpus/decimal128-3-valid-289.phpt" role="test" />
<file md5sum="382d05d15d18d9c982ee2bca7eb5c635" name="tests/bson-corpus/decimal128-3-valid-290.phpt" role="test" />
<file md5sum="f60413673f1660b677ae8266c8752d04" name="tests/bson-corpus/decimal128-3-valid-291.phpt" role="test" />
<file md5sum="04e0bf0b3d2e94c840709ee5b78e5c41" name="tests/bson-corpus/decimal128-3-valid-292.phpt" role="test" />
<file md5sum="ae8b9bea995be967a10013d3737e839b" name="tests/bson-corpus/decimal128-3-valid-293.phpt" role="test" />
<file md5sum="068c95a87a1fcf669a844e22295cae66" name="tests/bson-corpus/decimal128-3-valid-294.phpt" role="test" />
<file md5sum="e22e8042b8962529fe11556cdcf3f4bb" name="tests/bson-corpus/decimal128-3-valid-295.phpt" role="test" />
<file md5sum="cd3d4a2f108de6a94e832fc9f325b6b8" name="tests/bson-corpus/decimal128-3-valid-296.phpt" role="test" />
<file md5sum="722074da871f776a7963fbbe499d52b0" name="tests/bson-corpus/decimal128-3-valid-297.phpt" role="test" />
<file md5sum="a5bf581446b1e605ea2083eb87238d59" name="tests/bson-corpus/decimal128-3-valid-298.phpt" role="test" />
<file md5sum="7daf264958ffe34c085fa056b8f1fcde" name="tests/bson-corpus/decimal128-3-valid-299.phpt" role="test" />
<file md5sum="6c3b1b7b6475db6e258143c22cfdf823" name="tests/bson-corpus/decimal128-3-valid-300.phpt" role="test" />
<file md5sum="5696d287145bf434b3b4fa2b43e7519d" name="tests/bson-corpus/decimal128-3-valid-301.phpt" role="test" />
<file md5sum="4a7acee19c691e605b29a1ffe0d6d928" name="tests/bson-corpus/decimal128-3-valid-302.phpt" role="test" />
<file md5sum="1229842a762826af288b5ebdd895821b" name="tests/bson-corpus/decimal128-3-valid-303.phpt" role="test" />
<file md5sum="5680e250968906159a0379273ae5037e" name="tests/bson-corpus/decimal128-3-valid-304.phpt" role="test" />
<file md5sum="03d614a59d978304368b78eba1307bc2" name="tests/bson-corpus/decimal128-3-valid-305.phpt" role="test" />
<file md5sum="f56eda4c9bfb24077dff037a5fbdc971" name="tests/bson-corpus/decimal128-3-valid-306.phpt" role="test" />
<file md5sum="10c8c645114891728a44d4c55d3985ef" name="tests/bson-corpus/decimal128-3-valid-307.phpt" role="test" />
<file md5sum="d9d947e4778922f209b5164a63762252" name="tests/bson-corpus/decimal128-3-valid-308.phpt" role="test" />
<file md5sum="ba047e7921fca83be0bbf1ffb9ff32e6" name="tests/bson-corpus/decimal128-4-parseError-001.phpt" role="test" />
<file md5sum="96c4e11223d6a702ce7c160d7f33ec6e" name="tests/bson-corpus/decimal128-4-parseError-002.phpt" role="test" />
<file md5sum="2975e7043d01c304620a4a635c1df627" name="tests/bson-corpus/decimal128-4-parseError-003.phpt" role="test" />
<file md5sum="66ee3e45b68893588ae091b3da40b1c9" name="tests/bson-corpus/decimal128-4-parseError-004.phpt" role="test" />
<file md5sum="5f79cc977af6f42f0d16e23b6b78787a" name="tests/bson-corpus/decimal128-4-parseError-005.phpt" role="test" />
<file md5sum="905801853974398dd4df272c70db9f1f" name="tests/bson-corpus/decimal128-4-parseError-006.phpt" role="test" />
<file md5sum="930136040e99d94cac48f2dc1ea1b4ec" name="tests/bson-corpus/decimal128-4-parseError-007.phpt" role="test" />
<file md5sum="d200890cddd844aa3e417afdfaf66258" name="tests/bson-corpus/decimal128-4-parseError-008.phpt" role="test" />
<file md5sum="6929f5e4aa871b5568760bc96d01963f" name="tests/bson-corpus/decimal128-4-parseError-009.phpt" role="test" />
<file md5sum="14a207527ae35bbbf707219236f86f63" name="tests/bson-corpus/decimal128-4-parseError-010.phpt" role="test" />
<file md5sum="9828ca9e0e1d1af8bba3896ad969cbdc" name="tests/bson-corpus/decimal128-4-parseError-011.phpt" role="test" />
<file md5sum="eeb65b1dc4411a057e3437efd758cad5" name="tests/bson-corpus/decimal128-4-parseError-012.phpt" role="test" />
<file md5sum="ba731b0fd3b5e6f12980c65d3cd4c8c2" name="tests/bson-corpus/decimal128-4-parseError-013.phpt" role="test" />
<file md5sum="e185b77c3f7e11690bd948cff345f6a2" name="tests/bson-corpus/decimal128-4-parseError-014.phpt" role="test" />
<file md5sum="9c019336f3754089c347f727e81fa529" name="tests/bson-corpus/decimal128-4-parseError-015.phpt" role="test" />
<file md5sum="0eee95f4870d4d75daeba9d37a74a3da" name="tests/bson-corpus/decimal128-4-parseError-016.phpt" role="test" />
<file md5sum="9d327df701b1303cf8562508d1b73cc6" name="tests/bson-corpus/decimal128-4-parseError-017.phpt" role="test" />
<file md5sum="1ba071fa83d1712f9e18182a7c609d08" name="tests/bson-corpus/decimal128-4-parseError-018.phpt" role="test" />
<file md5sum="2e18b7b9617a104ca7944660cfbe7d31" name="tests/bson-corpus/decimal128-4-parseError-019.phpt" role="test" />
<file md5sum="54546dd203137c1ad0a58c5fd0144e7f" name="tests/bson-corpus/decimal128-4-parseError-020.phpt" role="test" />
<file md5sum="267a1f9db0dffd911c013dbdf7c1b7c3" name="tests/bson-corpus/decimal128-4-valid-001.phpt" role="test" />
<file md5sum="cb76c65de06c5493f91c2754bbaafe37" name="tests/bson-corpus/decimal128-4-valid-002.phpt" role="test" />
<file md5sum="632de2625b3d216e256d0ed592280201" name="tests/bson-corpus/decimal128-4-valid-003.phpt" role="test" />
<file md5sum="e49f627b6184b691e5bfe8e7abe13188" name="tests/bson-corpus/decimal128-4-valid-004.phpt" role="test" />
<file md5sum="29db50bbea92d96c66ee22b25937455c" name="tests/bson-corpus/decimal128-4-valid-005.phpt" role="test" />
<file md5sum="9c5d97a72c8d46d95fdd525fe4aa52aa" name="tests/bson-corpus/decimal128-4-valid-006.phpt" role="test" />
<file md5sum="4bdcc386968fb2f93abc39b0f9545d28" name="tests/bson-corpus/decimal128-4-valid-007.phpt" role="test" />
<file md5sum="c12b60332cdde3ee04f03e8850373696" name="tests/bson-corpus/decimal128-4-valid-008.phpt" role="test" />
<file md5sum="3d2d79a674331cfa01096813cac3b226" name="tests/bson-corpus/decimal128-4-valid-009.phpt" role="test" />
<file md5sum="5b142aac0ad0f00783cff7cbe7d996cb" name="tests/bson-corpus/decimal128-4-valid-010.phpt" role="test" />
<file md5sum="743051a9c45eefeb32cad44c6f9e9c91" name="tests/bson-corpus/decimal128-4-valid-011.phpt" role="test" />
<file md5sum="9d6f0169fd3f09984f3de067bebdba78" name="tests/bson-corpus/decimal128-4-valid-012.phpt" role="test" />
<file md5sum="943f97ece6a0843090c5baff1f2b730e" name="tests/bson-corpus/decimal128-4-valid-013.phpt" role="test" />
<file md5sum="a9981c958bf5491b6dae949026d66059" name="tests/bson-corpus/decimal128-5-valid-001.phpt" role="test" />
<file md5sum="a26800c0358caddea1d5b1dd9bd2ae23" name="tests/bson-corpus/decimal128-5-valid-002.phpt" role="test" />
<file md5sum="f4021d7ebe7eb3f6ee75091ce54a4f68" name="tests/bson-corpus/decimal128-5-valid-003.phpt" role="test" />
<file md5sum="e43383cbcb3d75e7cd967f3c9a159be8" name="tests/bson-corpus/decimal128-5-valid-004.phpt" role="test" />
<file md5sum="82d8c7463f9b98b6353f26b1a5ee030d" name="tests/bson-corpus/decimal128-5-valid-005.phpt" role="test" />
<file md5sum="f08c46d33cc7c52db54da0593e95a973" name="tests/bson-corpus/decimal128-5-valid-006.phpt" role="test" />
<file md5sum="8039d96c7d86bb021ab99e8ad40a0bff" name="tests/bson-corpus/decimal128-5-valid-007.phpt" role="test" />
<file md5sum="7e93f1c90e8a00bb6a3cd41da71fbd43" name="tests/bson-corpus/decimal128-5-valid-008.phpt" role="test" />
<file md5sum="338aaf0050fc9cb9236786de6b9095e7" name="tests/bson-corpus/decimal128-5-valid-009.phpt" role="test" />
<file md5sum="16673c8e4bd1edf82aafc281ba129efc" name="tests/bson-corpus/decimal128-5-valid-010.phpt" role="test" />
<file md5sum="1b0e168e873836f80595d1921ac43966" name="tests/bson-corpus/decimal128-5-valid-011.phpt" role="test" />
<file md5sum="ae4d358af4acaf73b54d796f9366d7c5" name="tests/bson-corpus/decimal128-5-valid-012.phpt" role="test" />
<file md5sum="e3e7a0daecdb0b5907859fe56431df3b" name="tests/bson-corpus/decimal128-5-valid-013.phpt" role="test" />
<file md5sum="b330fc71b0066b4e4c59a9fd564aa8fe" name="tests/bson-corpus/decimal128-5-valid-014.phpt" role="test" />
<file md5sum="a97fe0bb194ceeaa8de509adf29630e7" name="tests/bson-corpus/decimal128-5-valid-015.phpt" role="test" />
<file md5sum="cd2a754a2d5a82ed673e420b2d7b88f7" name="tests/bson-corpus/decimal128-5-valid-016.phpt" role="test" />
<file md5sum="1e6e680849fd7e36d378e728bbdb9b66" name="tests/bson-corpus/decimal128-5-valid-017.phpt" role="test" />
<file md5sum="ab93ba16758f68d9a3193911e6964e65" name="tests/bson-corpus/decimal128-5-valid-018.phpt" role="test" />
<file md5sum="80e5967f9738487686a86f10f15fa885" name="tests/bson-corpus/decimal128-5-valid-019.phpt" role="test" />
<file md5sum="f9e7a91beedf969e6df1a615e86558e6" name="tests/bson-corpus/decimal128-5-valid-020.phpt" role="test" />
<file md5sum="21d50833e7c999721d5d4306ad92a3fa" name="tests/bson-corpus/decimal128-5-valid-021.phpt" role="test" />
<file md5sum="909e2f48ca4706b4205a28e74d508b9e" name="tests/bson-corpus/decimal128-5-valid-022.phpt" role="test" />
<file md5sum="609cb491c2c160fb06497b0f23d96af7" name="tests/bson-corpus/decimal128-5-valid-023.phpt" role="test" />
<file md5sum="3e51831c477d2d2f943146e7ce786965" name="tests/bson-corpus/decimal128-5-valid-024.phpt" role="test" />
<file md5sum="942ed4fe72753a9ee4756afcb4fedba4" name="tests/bson-corpus/decimal128-5-valid-025.phpt" role="test" />
<file md5sum="5263e2388ae94ecbb529230d3b667717" name="tests/bson-corpus/decimal128-5-valid-026.phpt" role="test" />
<file md5sum="361cdf8640e57a9ac09c2b918f80f0b9" name="tests/bson-corpus/decimal128-5-valid-027.phpt" role="test" />
<file md5sum="698706c741e1d89a22b25eb8793fa3ce" name="tests/bson-corpus/decimal128-5-valid-028.phpt" role="test" />
<file md5sum="e08c868e027f85b3008abcc956f3b4a4" name="tests/bson-corpus/decimal128-5-valid-029.phpt" role="test" />
<file md5sum="ea64febefabfdbe88108852ab13201bb" name="tests/bson-corpus/decimal128-5-valid-030.phpt" role="test" />
<file md5sum="d82056149a3a7002513310b8a0632dc2" name="tests/bson-corpus/decimal128-5-valid-031.phpt" role="test" />
<file md5sum="e9fa637af0ebcb17267ae42644920bbb" name="tests/bson-corpus/decimal128-5-valid-032.phpt" role="test" />
<file md5sum="bc92c06a9cf332e2c730bb9f7c83268d" name="tests/bson-corpus/decimal128-5-valid-033.phpt" role="test" />
<file md5sum="5a59091bb3b1dedc267eaf79d38df0d3" name="tests/bson-corpus/decimal128-5-valid-034.phpt" role="test" />
<file md5sum="7af0fd92fc11417588602082e983ed83" name="tests/bson-corpus/decimal128-5-valid-035.phpt" role="test" />
<file md5sum="eae7b3bfba7cb6b5018f91cb6bf9c4da" name="tests/bson-corpus/decimal128-5-valid-036.phpt" role="test" />
<file md5sum="414c76669d00becc64246e97b2f70fb4" name="tests/bson-corpus/decimal128-5-valid-037.phpt" role="test" />
<file md5sum="e2941a8be7889c48461634da9f27c152" name="tests/bson-corpus/decimal128-5-valid-038.phpt" role="test" />
<file md5sum="d634cabc36938736e3fb5b1d5766c6c5" name="tests/bson-corpus/decimal128-5-valid-039.phpt" role="test" />
<file md5sum="1159c39b074979355f046ab2057576ea" name="tests/bson-corpus/decimal128-5-valid-040.phpt" role="test" />
<file md5sum="6b501682a22836cb221dc871d270227c" name="tests/bson-corpus/decimal128-5-valid-041.phpt" role="test" />
<file md5sum="ac354fc02b2c70cb3078f56a2e488761" name="tests/bson-corpus/decimal128-5-valid-042.phpt" role="test" />
<file md5sum="774b092064286ca4a12d87c2801a8f8c" name="tests/bson-corpus/decimal128-5-valid-043.phpt" role="test" />
<file md5sum="9498fcc098d04af6bc18ff3226421492" name="tests/bson-corpus/decimal128-5-valid-044.phpt" role="test" />
<file md5sum="d043cd280ec38491680b757f1095b2bc" name="tests/bson-corpus/decimal128-5-valid-045.phpt" role="test" />
<file md5sum="7e6fc4384daac7ba63fa15438487183e" name="tests/bson-corpus/decimal128-5-valid-046.phpt" role="test" />
<file md5sum="bf9017a27ab1056fd2156596fa5fa773" name="tests/bson-corpus/decimal128-5-valid-047.phpt" role="test" />
<file md5sum="d6e8383e3e9edbc8e3a9f7ea7880a29d" name="tests/bson-corpus/decimal128-5-valid-048.phpt" role="test" />
<file md5sum="518f3be51879acb708aadd12c0a4bc43" name="tests/bson-corpus/decimal128-5-valid-049.phpt" role="test" />
<file md5sum="9b815092dfc93cc3b95f5d613ec7edb1" name="tests/bson-corpus/decimal128-5-valid-050.phpt" role="test" />
<file md5sum="af44e5ac84c9bceff73bf490cd1a1f10" name="tests/bson-corpus/decimal128-5-valid-051.phpt" role="test" />
<file md5sum="7f039c3a7b0bcc30eeadebb7a88d7551" name="tests/bson-corpus/decimal128-5-valid-052.phpt" role="test" />
<file md5sum="ab8715e9de548d75ec5b634bfe09f983" name="tests/bson-corpus/decimal128-5-valid-053.phpt" role="test" />
<file md5sum="bf0236d0ef1475d10aaae9e5a781b2c2" name="tests/bson-corpus/decimal128-5-valid-054.phpt" role="test" />
<file md5sum="dc5c1657c93563731615c01fc00b20aa" name="tests/bson-corpus/decimal128-5-valid-055.phpt" role="test" />
<file md5sum="572c6bb3906cc8677d57a358a28a1eec" name="tests/bson-corpus/decimal128-5-valid-056.phpt" role="test" />
<file md5sum="10e8bd72db4fbf06371338e2156e020b" name="tests/bson-corpus/decimal128-5-valid-057.phpt" role="test" />
<file md5sum="29619b121f1e1cc80daf7b25e3c23734" name="tests/bson-corpus/decimal128-5-valid-058.phpt" role="test" />
<file md5sum="5fc14e28dd477b9760dff8c29e776327" name="tests/bson-corpus/decimal128-5-valid-059.phpt" role="test" />
<file md5sum="88585d3700d3313283f7ea87692c5314" name="tests/bson-corpus/decimal128-5-valid-060.phpt" role="test" />
<file md5sum="c2d8e3bd56e0bb7da2981c89a47f74dd" name="tests/bson-corpus/decimal128-5-valid-061.phpt" role="test" />
<file md5sum="dabbfbbb9c8a0dffe1190b6206414465" name="tests/bson-corpus/decimal128-5-valid-062.phpt" role="test" />
<file md5sum="f6e59ace820732da155936b82850c1ed" name="tests/bson-corpus/decimal128-5-valid-063.phpt" role="test" />
<file md5sum="45cc1964d3fd051a506b64c1bf145fb6" name="tests/bson-corpus/decimal128-5-valid-064.phpt" role="test" />
<file md5sum="bdb105435ff7bc5b5c900bbe02894c28" name="tests/bson-corpus/decimal128-5-valid-065.phpt" role="test" />
<file md5sum="9bdbed82d0a59f1200c405f7f06a2405" name="tests/bson-corpus/decimal128-5-valid-066.phpt" role="test" />
<file md5sum="bb317bfec39ac48ba2ee3671ecdd3c65" name="tests/bson-corpus/decimal128-5-valid-067.phpt" role="test" />
<file md5sum="9d619c3b0719e7e6075adddc0ea9dbfd" name="tests/bson-corpus/decimal128-6-parseError-001.phpt" role="test" />
<file md5sum="5e5e28715e20456528ad5de48bd7349e" name="tests/bson-corpus/decimal128-6-parseError-002.phpt" role="test" />
<file md5sum="0bcacd7da821fef56d8133be73d34e3f" name="tests/bson-corpus/decimal128-6-parseError-003.phpt" role="test" />
<file md5sum="b330cdf56d272be270e82e2341aff1f4" name="tests/bson-corpus/decimal128-6-parseError-004.phpt" role="test" />
<file md5sum="087821837bfc5cc35f93663233652f5e" name="tests/bson-corpus/decimal128-6-parseError-005.phpt" role="test" />
<file md5sum="b7ff0e65afd02d5000989e467d212c51" name="tests/bson-corpus/decimal128-6-parseError-006.phpt" role="test" />
<file md5sum="32b737ae134b0641800c408a9bc4f4fc" name="tests/bson-corpus/decimal128-6-parseError-007.phpt" role="test" />
<file md5sum="722f4553265a2f16492fedd8cadf5dea" name="tests/bson-corpus/decimal128-6-parseError-008.phpt" role="test" />
<file md5sum="2e6d342b33ad7b6fa79067ccf36a2a9e" name="tests/bson-corpus/decimal128-6-parseError-009.phpt" role="test" />
<file md5sum="da34bfaf1576dc9a3a0c7152ab17551e" name="tests/bson-corpus/decimal128-6-parseError-010.phpt" role="test" />
<file md5sum="86ce002a308067909f42b96eb21308b2" name="tests/bson-corpus/decimal128-6-parseError-011.phpt" role="test" />
<file md5sum="6addc588a3cbc00449082c46a2e121db" name="tests/bson-corpus/decimal128-6-parseError-012.phpt" role="test" />
<file md5sum="473b1b080710a4937c2d7b1586ee40b3" name="tests/bson-corpus/decimal128-6-parseError-013.phpt" role="test" />
<file md5sum="dd0898b2e0802cb47b30753e9da159e3" name="tests/bson-corpus/decimal128-6-parseError-014.phpt" role="test" />
<file md5sum="58eb765b37e2e284a67383aaf3359788" name="tests/bson-corpus/decimal128-6-parseError-015.phpt" role="test" />
<file md5sum="7f360fae68599d98fff6b09d9e2ea8d0" name="tests/bson-corpus/decimal128-6-parseError-016.phpt" role="test" />
<file md5sum="be7a3fadb14f640d88c8423932975813" name="tests/bson-corpus/decimal128-6-parseError-017.phpt" role="test" />
<file md5sum="7a0603436c1795a2a1613a83f90901b7" name="tests/bson-corpus/decimal128-6-parseError-018.phpt" role="test" />
<file md5sum="7d1dccee0bd183c2baf5c9e0c90e6fbb" name="tests/bson-corpus/decimal128-6-parseError-019.phpt" role="test" />
<file md5sum="b979e1cff5d7aac6ac47239fa21baa72" name="tests/bson-corpus/decimal128-6-parseError-020.phpt" role="test" />
<file md5sum="08834e4aa640b820ef329690c28ba6ca" name="tests/bson-corpus/decimal128-6-parseError-021.phpt" role="test" />
<file md5sum="df16fe00ed13b38e8d7c648bd6d89c97" name="tests/bson-corpus/decimal128-6-parseError-022.phpt" role="test" />
<file md5sum="26b48d1f949d0e3aed0b9dedfc185afd" name="tests/bson-corpus/decimal128-6-parseError-023.phpt" role="test" />
<file md5sum="1078595f5fac6bee1267b4d263c6c8cb" name="tests/bson-corpus/decimal128-6-parseError-024.phpt" role="test" />
<file md5sum="e047a839813f6d9e94bae49691dd6701" name="tests/bson-corpus/decimal128-6-parseError-025.phpt" role="test" />
<file md5sum="12a013fe95a88779c348c4cb773115ad" name="tests/bson-corpus/decimal128-6-parseError-026.phpt" role="test" />
<file md5sum="354ff6b5d986470794f59886b683ac70" name="tests/bson-corpus/decimal128-6-parseError-027.phpt" role="test" />
<file md5sum="3ef809210e108a7dc60645c4140f07f9" name="tests/bson-corpus/decimal128-6-parseError-028.phpt" role="test" />
<file md5sum="50f7c0c8c816658e51a3946671bc02b4" name="tests/bson-corpus/decimal128-6-parseError-029.phpt" role="test" />
<file md5sum="93988289538ba9bebb3c9130d0287dd0" name="tests/bson-corpus/decimal128-6-parseError-030.phpt" role="test" />
<file md5sum="6bd10e968b1852735c6047be0e22e523" name="tests/bson-corpus/decimal128-6-parseError-031.phpt" role="test" />
<file md5sum="739125a03b1d42ac4f928dfd98a3f306" name="tests/bson-corpus/decimal128-7-parseError-001.phpt" role="test" />
<file md5sum="3e70c7fd9860e1b557c951895227973b" name="tests/bson-corpus/decimal128-7-parseError-002.phpt" role="test" />
<file md5sum="5680032198806e7625acfcdb227dc67a" name="tests/bson-corpus/decimal128-7-parseError-003.phpt" role="test" />
<file md5sum="bf63ba62a9265425b447d7285f045b28" name="tests/bson-corpus/decimal128-7-parseError-004.phpt" role="test" />
<file md5sum="9319f1a49ec2f2449283c2fd44d8275a" name="tests/bson-corpus/decimal128-7-parseError-005.phpt" role="test" />
<file md5sum="770cd1d3f59b161db855c5838fad7390" name="tests/bson-corpus/decimal128-7-parseError-006.phpt" role="test" />
<file md5sum="0dd5f74d70bd4d09fefaccc0ae3b326c" name="tests/bson-corpus/decimal128-7-parseError-007.phpt" role="test" />
<file md5sum="aec5da5a25c84f34b33d65f347a83c10" name="tests/bson-corpus/decimal128-7-parseError-008.phpt" role="test" />
<file md5sum="ab4f84a31f21de6c7a5a75381d8a8760" name="tests/bson-corpus/decimal128-7-parseError-009.phpt" role="test" />
<file md5sum="e6c669fe4746f25af030f19ca2efe96f" name="tests/bson-corpus/decimal128-7-parseError-010.phpt" role="test" />
<file md5sum="1c512a25e6b3b5eeb7efb02607c01351" name="tests/bson-corpus/decimal128-7-parseError-011.phpt" role="test" />
<file md5sum="5ec3a512414e516a23691ed7ce9c8409" name="tests/bson-corpus/decimal128-7-parseError-012.phpt" role="test" />
<file md5sum="83e1d3549c3e354b4ef47b3a97a42304" name="tests/bson-corpus/decimal128-7-parseError-013.phpt" role="test" />
<file md5sum="d5a3fe0a6355b408d2b5b1e82164dc06" name="tests/bson-corpus/decimal128-7-parseError-014.phpt" role="test" />
<file md5sum="03c2144e7ed68d510609d1882a0d3fb5" name="tests/bson-corpus/decimal128-7-parseError-015.phpt" role="test" />
<file md5sum="5bc01966bae4d9965ca5ab8e64d55d21" name="tests/bson-corpus/decimal128-7-parseError-016.phpt" role="test" />
<file md5sum="19e0f71895b66144e92440e3dcd0ff23" name="tests/bson-corpus/decimal128-7-parseError-017.phpt" role="test" />
<file md5sum="2f9e63cdb60253c97b4a1b709a35b6be" name="tests/bson-corpus/decimal128-7-parseError-018.phpt" role="test" />
<file md5sum="aeaa29b049aae5916bb8cccc8d47e7e8" name="tests/bson-corpus/decimal128-7-parseError-019.phpt" role="test" />
<file md5sum="b103339bc111045d962a5da60907a954" name="tests/bson-corpus/decimal128-7-parseError-020.phpt" role="test" />
<file md5sum="77c0d904a85bc98f4c0d60637a167d59" name="tests/bson-corpus/decimal128-7-parseError-021.phpt" role="test" />
<file md5sum="526a91c29eedfb7e792e31284bce93c2" name="tests/bson-corpus/decimal128-7-parseError-022.phpt" role="test" />
<file md5sum="7fad1b695028cee5b3524ae7795671dd" name="tests/bson-corpus/decimal128-7-parseError-023.phpt" role="test" />
<file md5sum="a284eeae3ac0dc6913c5028765472178" name="tests/bson-corpus/decimal128-7-parseError-024.phpt" role="test" />
<file md5sum="de5e0cfba4ba4e4db4dc6f9bac610bf3" name="tests/bson-corpus/decimal128-7-parseError-025.phpt" role="test" />
<file md5sum="5e8f71033a1f75d2caad14db4806d8b7" name="tests/bson-corpus/decimal128-7-parseError-026.phpt" role="test" />
<file md5sum="3e9808fa4362a86083025c8418b6b300" name="tests/bson-corpus/decimal128-7-parseError-027.phpt" role="test" />
<file md5sum="46c182f2fb62174dbe5ad42d52b1230d" name="tests/bson-corpus/decimal128-7-parseError-028.phpt" role="test" />
<file md5sum="3df633a71755c619e70d3961f3ed778d" name="tests/bson-corpus/decimal128-7-parseError-029.phpt" role="test" />
<file md5sum="7f7590bd2c639fb10e553ea2f1e40a97" name="tests/bson-corpus/decimal128-7-parseError-030.phpt" role="test" />
<file md5sum="b827cc6fea8a64cc770452afa2cb45cb" name="tests/bson-corpus/decimal128-7-parseError-031.phpt" role="test" />
<file md5sum="98f885b5d4b9333ea213f4be4f8ddca6" name="tests/bson-corpus/decimal128-7-parseError-032.phpt" role="test" />
<file md5sum="546c9fa342e790e86e34f6b5c6de3b84" name="tests/bson-corpus/decimal128-7-parseError-033.phpt" role="test" />
<file md5sum="2b073b2ea1bc7fd605780f947ceac75e" name="tests/bson-corpus/decimal128-7-parseError-034.phpt" role="test" />
<file md5sum="9e92800972333c69386eb81e0e3d8ec9" name="tests/bson-corpus/decimal128-7-parseError-035.phpt" role="test" />
<file md5sum="ac308002b7f73ff45b68ce36b38a7275" name="tests/bson-corpus/decimal128-7-parseError-036.phpt" role="test" />
<file md5sum="a10da36d1c1c27079c245ad31d2bce08" name="tests/bson-corpus/decimal128-7-parseError-037.phpt" role="test" />
<file md5sum="c11703f2e41a1e40e993465cc1f5a865" name="tests/bson-corpus/decimal128-7-parseError-038.phpt" role="test" />
<file md5sum="ef094591196f8a16df0cfeb14d7fa8fd" name="tests/bson-corpus/decimal128-7-parseError-039.phpt" role="test" />
<file md5sum="d44551a47e6182cf4c22245df9a49863" name="tests/bson-corpus/decimal128-7-parseError-040.phpt" role="test" />
<file md5sum="bfd6aefac1a28c8f5a576f646d1c8f4b" name="tests/bson-corpus/decimal128-7-parseError-041.phpt" role="test" />
<file md5sum="5e667f745c3bf9dc68b4878a6de2ca7f" name="tests/bson-corpus/decimal128-7-parseError-042.phpt" role="test" />
<file md5sum="e8eb51d644cc1ad01df9f2fe5f8d615c" name="tests/bson-corpus/decimal128-7-parseError-043.phpt" role="test" />
<file md5sum="d0ab46feebf5f41b736c28c25be9c41d" name="tests/bson-corpus/decimal128-7-parseError-044.phpt" role="test" />
<file md5sum="5195470ca981d3b793e4dc7ae16c7b80" name="tests/bson-corpus/decimal128-7-parseError-045.phpt" role="test" />
<file md5sum="5ed083d6153fb2be44b2bdd69cb3ad66" name="tests/bson-corpus/decimal128-7-parseError-046.phpt" role="test" />
<file md5sum="b90aad87eb6e3fdc0f7069a6217bdeb6" name="tests/bson-corpus/decimal128-7-parseError-047.phpt" role="test" />
<file md5sum="24a773cfb9b0f6d19d2f5d23e2d4734f" name="tests/bson-corpus/decimal128-7-parseError-048.phpt" role="test" />
<file md5sum="d49c37b3be2913bbf9e94460aaa6dea5" name="tests/bson-corpus/decimal128-7-parseError-049.phpt" role="test" />
<file md5sum="a8e25353f491c8abcd83ecb445cdbef7" name="tests/bson-corpus/decimal128-7-parseError-050.phpt" role="test" />
<file md5sum="7d957b915a4677d1a743b82ed69b8399" name="tests/bson-corpus/decimal128-7-parseError-051.phpt" role="test" />
<file md5sum="a6c028651988ac5aef2583662d03606d" name="tests/bson-corpus/decimal128-7-parseError-052.phpt" role="test" />
<file md5sum="8b9d5a234c5003562c06a22a6055b9a9" name="tests/bson-corpus/decimal128-7-parseError-053.phpt" role="test" />
<file md5sum="db576d750b955b8133bc3a3ca17b268d" name="tests/bson-corpus/decimal128-7-parseError-054.phpt" role="test" />
<file md5sum="0fe5c131ea839136dbe43eb34956ddea" name="tests/bson-corpus/decimal128-7-parseError-055.phpt" role="test" />
<file md5sum="c8a6b9a6dc2b7fd0859748bf004444ad" name="tests/bson-corpus/decimal128-7-parseError-056.phpt" role="test" />
<file md5sum="e6317794fe425616e7384eaee73d508d" name="tests/bson-corpus/decimal128-7-parseError-057.phpt" role="test" />
<file md5sum="ae9adaf19631cf1b0fc10f5ef2d73fc9" name="tests/bson-corpus/decimal128-7-parseError-058.phpt" role="test" />
<file md5sum="de4ea2c89f6188610d9b754bbe699a64" name="tests/bson-corpus/decimal128-7-parseError-059.phpt" role="test" />
<file md5sum="2ab16b6b73a8fd7a26850ed267dc7839" name="tests/bson-corpus/decimal128-7-parseError-060.phpt" role="test" />
<file md5sum="e9243a30ec1d8601e3349c95a52bb281" name="tests/bson-corpus/decimal128-7-parseError-061.phpt" role="test" />
<file md5sum="deb3afb234ab883875f98adae9ac22c7" name="tests/bson-corpus/decimal128-7-parseError-062.phpt" role="test" />
<file md5sum="7f9efd9d04a8f1dc79a5b0b89fd01591" name="tests/bson-corpus/decimal128-7-parseError-063.phpt" role="test" />
<file md5sum="6e2d1fd08e5c5119473aec4a053a8b28" name="tests/bson-corpus/decimal128-7-parseError-064.phpt" role="test" />
<file md5sum="f01b69a5459752b843c52b2bfa3abe94" name="tests/bson-corpus/decimal128-7-parseError-065.phpt" role="test" />
<file md5sum="5f9f1ec42e3cb971c969c02e21861d35" name="tests/bson-corpus/decimal128-7-parseError-066.phpt" role="test" />
<file md5sum="5f35e09da70142bacb52211bc1c56723" name="tests/bson-corpus/decimal128-7-parseError-067.phpt" role="test" />
<file md5sum="670bba129ff3d44ebcaa75bb1eef54db" name="tests/bson-corpus/decimal128-7-parseError-068.phpt" role="test" />
<file md5sum="9822ce5f455adcb099fb8608ec00447e" name="tests/bson-corpus/decimal128-7-parseError-069.phpt" role="test" />
<file md5sum="3d91bc48b724ce35db3d8ee571201bef" name="tests/bson-corpus/decimal128-7-parseError-070.phpt" role="test" />
<file md5sum="4e27519c86e60695762547d22250a30d" name="tests/bson-corpus/decimal128-7-parseError-071.phpt" role="test" />
<file md5sum="2ad0c662a34e4860d591491568519e0c" name="tests/bson-corpus/decimal128-7-parseError-072.phpt" role="test" />
<file md5sum="8cb216dfac5cb18d1dc67b217b03a75f" name="tests/bson-corpus/decimal128-7-parseError-073.phpt" role="test" />
<file md5sum="102157c1968d887e482664937712f960" name="tests/bson-corpus/decimal128-7-parseError-074.phpt" role="test" />
<file md5sum="1383c9faaea4308830abf57c319d1416" name="tests/bson-corpus/decimal128-7-parseError-075.phpt" role="test" />
<file md5sum="bdc6b09eadb365c1ca90fa5abdcdcb72" name="tests/bson-corpus/decimal128-7-parseError-076.phpt" role="test" />
<file md5sum="fcb39e6d22bec7ae00715559c73d4021" name="tests/bson-corpus/decimal128-7-parseError-077.phpt" role="test" />
<file md5sum="883d74890811efba08b9bdcd00427933" name="tests/bson-corpus/decimal128-7-parseError-078.phpt" role="test" />
<file md5sum="b70276e215fe563edbb78b9ab826ac94" name="tests/bson-corpus/decimal128-7-parseError-079.phpt" role="test" />
<file md5sum="b566a55c4f0abf20272a8a5d7a7b0f86" name="tests/bson-corpus/decimal128-7-parseError-080.phpt" role="test" />
<file md5sum="87ad9d946c27e3f9dc0ce27d677603ee" name="tests/bson-corpus/document-decodeError-001.phpt" role="test" />
<file md5sum="19e200efa9c259f932e3b39b5414a9bd" name="tests/bson-corpus/document-decodeError-002.phpt" role="test" />
<file md5sum="4e0ee9b29c76b02780ac778f592a593a" name="tests/bson-corpus/document-decodeError-003.phpt" role="test" />
<file md5sum="4d54871d349fce471b2c04fb0315e283" name="tests/bson-corpus/document-decodeError-004.phpt" role="test" />
<file md5sum="c2afc444b968e7ed5206f630e7993387" name="tests/bson-corpus/document-valid-001.phpt" role="test" />
<file md5sum="9cb19864efff5132349002ceb3e91528" name="tests/bson-corpus/document-valid-002.phpt" role="test" />
<file md5sum="a0a053cd67c7dc2f17e5f7c78b2a8a3c" name="tests/bson-corpus/document-valid-003.phpt" role="test" />
<file md5sum="80bbe3b442ad0b02cb210ffdc084864c" name="tests/bson-corpus/document-valid-004.phpt" role="test" />
<file md5sum="5142ac41c9250459ba4f6d764e09f235" name="tests/bson-corpus/document-valid-005.phpt" role="test" />
<file md5sum="e15dd26f6396cae98bd71bc84b5e4485" name="tests/bson-corpus/document-valid-006.phpt" role="test" />
<file md5sum="dc115c6f84cfae3ee540db465c94d592" name="tests/bson-corpus/document-valid-007.phpt" role="test" />
<file md5sum="0e5e1939db94932d718a38b4ef0ab08a" name="tests/bson-corpus/double-decodeError-001.phpt" role="test" />
<file md5sum="cc38451861a9bdd440f141a9603d1c1e" name="tests/bson-corpus/double-valid-001.phpt" role="test" />
<file md5sum="695dd4b6ffe5752e635432f770112bbc" name="tests/bson-corpus/double-valid-002.phpt" role="test" />
<file md5sum="543c768616786e182f8a87808846c29d" name="tests/bson-corpus/double-valid-003.phpt" role="test" />
<file md5sum="3cf794c41b81ab6f675943418935fa74" name="tests/bson-corpus/double-valid-004.phpt" role="test" />
<file md5sum="fe3240831666b15e23036505dea59fa1" name="tests/bson-corpus/double-valid-005.phpt" role="test" />
<file md5sum="a224706dad0bf59ce12314a13678af78" name="tests/bson-corpus/double-valid-006.phpt" role="test" />
<file md5sum="8b867ea6bc23c98544e8257d7d8e4c92" name="tests/bson-corpus/double-valid-007.phpt" role="test" />
<file md5sum="804d48af76d2c76fd53627d49d7f2646" name="tests/bson-corpus/double-valid-008.phpt" role="test" />
<file md5sum="3e130f6f9ab3c4a0b6fd22cc2becefa6" name="tests/bson-corpus/double-valid-009.phpt" role="test" />
<file md5sum="604baeed341001363b5715e61056040a" name="tests/bson-corpus/double-valid-010.phpt" role="test" />
<file md5sum="fe54c7d3d75bdf528166ba26f76ef679" name="tests/bson-corpus/double-valid-011.phpt" role="test" />
<file md5sum="545898bdb556531e6f9d11da3ad5978b" name="tests/bson-corpus/double-valid-012.phpt" role="test" />
<file md5sum="c91a4bce14361c34ea741952eb2175be" name="tests/bson-corpus/int32-decodeError-001.phpt" role="test" />
<file md5sum="bd86a89e3e55ba3cc1bfc52f8d51c063" name="tests/bson-corpus/int32-valid-001.phpt" role="test" />
<file md5sum="a7f0ad32a306d3ff6a9e41243bbb1cf7" name="tests/bson-corpus/int32-valid-002.phpt" role="test" />
<file md5sum="5265e1dce0b39e9dd7d3eb28a2614cfe" name="tests/bson-corpus/int32-valid-003.phpt" role="test" />
<file md5sum="e860de8b786fc849832bb01181722e1d" name="tests/bson-corpus/int32-valid-004.phpt" role="test" />
<file md5sum="005f05207b42f0455548cc888b19d589" name="tests/bson-corpus/int32-valid-005.phpt" role="test" />
<file md5sum="0fe33cf3e05061a31ffc678969983d9c" name="tests/bson-corpus/int64-decodeError-001.phpt" role="test" />
<file md5sum="13bfcaf74f3aa1263c628e038ebf0ac6" name="tests/bson-corpus/int64-valid-001.phpt" role="test" />
<file md5sum="049fe2eaa155c9cb71d413c2f40b62b7" name="tests/bson-corpus/int64-valid-002.phpt" role="test" />
<file md5sum="fc58ac268c43443c5698d44bbf9986ac" name="tests/bson-corpus/int64-valid-003.phpt" role="test" />
<file md5sum="9e42448859f7314fcc95d46beb7b41ca" name="tests/bson-corpus/int64-valid-004.phpt" role="test" />
<file md5sum="7666e8e6e7cbc76a9ffcda2e8c41c972" name="tests/bson-corpus/int64-valid-005.phpt" role="test" />
<file md5sum="96c7d0d8dbfd8d3dbc184c71041bd085" name="tests/bson-corpus/maxkey-valid-001.phpt" role="test" />
<file md5sum="db4dfaef00c528351f9d0a79d49272c5" name="tests/bson-corpus/minkey-valid-001.phpt" role="test" />
<file md5sum="665af9df9c8f5436de98687e38505328" name="tests/bson-corpus/multi-type-deprecated-valid-001.phpt" role="test" />
<file md5sum="6575ecdd677d4e7d92da396f18004a36" name="tests/bson-corpus/multi-type-valid-001.phpt" role="test" />
<file md5sum="eecaba36153f53bde14086766ffa357b" name="tests/bson-corpus/null-valid-001.phpt" role="test" />
<file md5sum="fbacc7ed40542cb9572c2bb2a8493412" name="tests/bson-corpus/oid-decodeError-001.phpt" role="test" />
<file md5sum="d79850b753f362e9737a8e01d8a44f2f" name="tests/bson-corpus/oid-valid-001.phpt" role="test" />
<file md5sum="e523c3765b1c8911b90cc1d879926195" name="tests/bson-corpus/oid-valid-002.phpt" role="test" />
<file md5sum="af1f12a17a2ca6e4212a2b8380ea31e9" name="tests/bson-corpus/oid-valid-003.phpt" role="test" />
<file md5sum="3cf5f7b152a8003003b3c2d690c3303b" name="tests/bson-corpus/regex-decodeError-001.phpt" role="test" />
<file md5sum="e97a4abf7777aac9cb3ce9f8722d0453" name="tests/bson-corpus/regex-decodeError-002.phpt" role="test" />
<file md5sum="0e015c17579a3feed38e1e188dc7ff07" name="tests/bson-corpus/regex-valid-001.phpt" role="test" />
<file md5sum="9f3a43c96ad794fff3f75e0a6ecbdada" name="tests/bson-corpus/regex-valid-002.phpt" role="test" />
<file md5sum="a19498c0bc21109fd0ec0f810fc9ee2d" name="tests/bson-corpus/regex-valid-003.phpt" role="test" />
<file md5sum="46f7833cc33761cff91b356e4334463b" name="tests/bson-corpus/regex-valid-004.phpt" role="test" />
<file md5sum="7615e5b9e497d6e8456d375bc1b6910b" name="tests/bson-corpus/regex-valid-005.phpt" role="test" />
<file md5sum="4ffd5048962a95eb4562fce7501172f7" name="tests/bson-corpus/regex-valid-006.phpt" role="test" />
<file md5sum="86a99dccea9fd693a5b04ad5b2c01540" name="tests/bson-corpus/regex-valid-007.phpt" role="test" />
<file md5sum="802a0163c6f4fa8d95e94dc16f94f960" name="tests/bson-corpus/regex-valid-008.phpt" role="test" />
<file md5sum="6557f635e166a9c648e6b75dc5f843e0" name="tests/bson-corpus/regex-valid-009.phpt" role="test" />
<file md5sum="4898fc40b2f51bbba71363a14daab010" name="tests/bson-corpus/string-decodeError-001.phpt" role="test" />
<file md5sum="280e883246a2fc2c030af330a8c4da96" name="tests/bson-corpus/string-decodeError-002.phpt" role="test" />
<file md5sum="71c126e1ee7dd0bb5d9d45946cf121f4" name="tests/bson-corpus/string-decodeError-003.phpt" role="test" />
<file md5sum="73afd75be29fecc6e512f5d7e07010d9" name="tests/bson-corpus/string-decodeError-004.phpt" role="test" />
<file md5sum="9e98c7b6d20ef1dec8fd719435c6cdfd" name="tests/bson-corpus/string-decodeError-005.phpt" role="test" />
<file md5sum="123a6dcad2408ad25b64e22001c86dde" name="tests/bson-corpus/string-decodeError-006.phpt" role="test" />
<file md5sum="f87222f2d3962ee60d538b7cd3309826" name="tests/bson-corpus/string-decodeError-007.phpt" role="test" />
<file md5sum="cd090432ec5b22617da3c15fae13be95" name="tests/bson-corpus/string-valid-001.phpt" role="test" />
<file md5sum="61d943d946c7727fa1939033f388a11b" name="tests/bson-corpus/string-valid-002.phpt" role="test" />
<file md5sum="3ac03f27d856eee9ad8937fdcfc899d2" name="tests/bson-corpus/string-valid-003.phpt" role="test" />
<file md5sum="d52070fed1cb99e9afd091c80bca6a1c" name="tests/bson-corpus/string-valid-004.phpt" role="test" />
<file md5sum="695929957ffb4fe7947e575d5235c8b5" name="tests/bson-corpus/string-valid-005.phpt" role="test" />
<file md5sum="2df5ab655b2a343ff9d742de3dbfe976" name="tests/bson-corpus/string-valid-006.phpt" role="test" />
<file md5sum="e84799c6f81901ac9d3ddf95a60df0fb" name="tests/bson-corpus/string-valid-007.phpt" role="test" />
<file md5sum="830eb608ffd3b6585639f518eeed862b" name="tests/bson-corpus/symbol-decodeError-001.phpt" role="test" />
<file md5sum="0ab4d25eb7621d0a3da5a0d7d00359c5" name="tests/bson-corpus/symbol-decodeError-002.phpt" role="test" />
<file md5sum="b3a8d860d2a1836a8ebbb608e1193283" name="tests/bson-corpus/symbol-decodeError-003.phpt" role="test" />
<file md5sum="bd5f73305b311b05e59e75423648dbb1" name="tests/bson-corpus/symbol-decodeError-004.phpt" role="test" />
<file md5sum="3b9ae0fb4b4f1dc2b9ea00ef617de89f" name="tests/bson-corpus/symbol-decodeError-005.phpt" role="test" />
<file md5sum="6890f411db7f5ea2c4c49efd9208a396" name="tests/bson-corpus/symbol-decodeError-006.phpt" role="test" />
<file md5sum="4fd326563d72bbd45b0e00c82f353a7b" name="tests/bson-corpus/symbol-decodeError-007.phpt" role="test" />
<file md5sum="7d95d4e791eadb0a4046aae7f03f5bbe" name="tests/bson-corpus/symbol-valid-001.phpt" role="test" />
<file md5sum="b0bb8ae42ee2cf53e4cda0c89fd1bda0" name="tests/bson-corpus/symbol-valid-002.phpt" role="test" />
<file md5sum="142070c493226d39a9841548057b9267" name="tests/bson-corpus/symbol-valid-003.phpt" role="test" />
<file md5sum="44002e1290f035dd5fa28105b0dd2151" name="tests/bson-corpus/symbol-valid-004.phpt" role="test" />
<file md5sum="ee611d73c4222f696e08d5e0165ca062" name="tests/bson-corpus/symbol-valid-005.phpt" role="test" />
<file md5sum="30d1b68d8dff83d027dc4fd701223f22" name="tests/bson-corpus/symbol-valid-006.phpt" role="test" />
<file md5sum="a1543108e6f297ee2f7cf6381339309a" name="tests/bson-corpus/timestamp-decodeError-001.phpt" role="test" />
<file md5sum="77004f6708d4f044c123334ab683fee3" name="tests/bson-corpus/timestamp-valid-001.phpt" role="test" />
<file md5sum="e5045dceeea21b4557008b944d2f8456" name="tests/bson-corpus/timestamp-valid-002.phpt" role="test" />
<file md5sum="46d59f37bff62adeba220a24c4f40444" name="tests/bson-corpus/timestamp-valid-003.phpt" role="test" />
<file md5sum="0f24703e16e6d58a54e0d1458421ed04" name="tests/bson-corpus/timestamp-valid-004.phpt" role="test" />
<file md5sum="a5746762b1f83f18dd08b3af2a79bd82" name="tests/bson-corpus/top-decodeError-001.phpt" role="test" />
<file md5sum="5a74dcc8e1f00e3d61b8d532e394fa4a" name="tests/bson-corpus/top-decodeError-002.phpt" role="test" />
<file md5sum="2eebd24618df5f979d21bc03000ec9fb" name="tests/bson-corpus/top-decodeError-003.phpt" role="test" />
<file md5sum="fdcc239654abfb36fdf13b1098c77130" name="tests/bson-corpus/top-decodeError-004.phpt" role="test" />
<file md5sum="711fea55b27b2786267454fda85ff66c" name="tests/bson-corpus/top-decodeError-005.phpt" role="test" />
<file md5sum="67ca5cd050fc16f6be3b3414368c2e0c" name="tests/bson-corpus/top-decodeError-006.phpt" role="test" />
<file md5sum="93ad41d55ec7e4f707f3d14b42f8e547" name="tests/bson-corpus/top-decodeError-007.phpt" role="test" />
<file md5sum="31dc1b6892344a4d37f32cb103631b91" name="tests/bson-corpus/top-decodeError-008.phpt" role="test" />
<file md5sum="1ac72fa2caa70252323a7390e90f4af9" name="tests/bson-corpus/top-decodeError-009.phpt" role="test" />
<file md5sum="2953c32452de2afa6cd31d8377a7eafb" name="tests/bson-corpus/top-decodeError-010.phpt" role="test" />
<file md5sum="6fc36bb32a3209c6218c2240de2eb15f" name="tests/bson-corpus/top-decodeError-011.phpt" role="test" />
<file md5sum="abf592b4ca9282c12a83de8a8da98409" name="tests/bson-corpus/top-decodeError-012.phpt" role="test" />
<file md5sum="ee5382fc1a0b4f995464f3976b98760f" name="tests/bson-corpus/top-decodeError-013.phpt" role="test" />
<file md5sum="2b2a3ba8d74fc26bbc451ea95e8961c9" name="tests/bson-corpus/top-decodeError-014.phpt" role="test" />
<file md5sum="48020b621a91d5798a64a3093002e4cb" name="tests/bson-corpus/top-decodeError-015.phpt" role="test" />
<file md5sum="e4fae2f12a561bd3ffb82ef693900a72" name="tests/bson-corpus/top-parseError-001.phpt" role="test" />
<file md5sum="9cd08fb16dfb481d6a30391b521d6926" name="tests/bson-corpus/top-parseError-002.phpt" role="test" />
<file md5sum="6767ba1deaad7cc658ebdb9d34b35ccd" name="tests/bson-corpus/top-parseError-003.phpt" role="test" />
<file md5sum="203ca09e6fcd6186e025fdf713529773" name="tests/bson-corpus/top-parseError-004.phpt" role="test" />
<file md5sum="14907ac9f9578344f895e192a3072cf4" name="tests/bson-corpus/top-parseError-005.phpt" role="test" />
<file md5sum="57f4f24b244817c15cf329e985905e35" name="tests/bson-corpus/top-parseError-006.phpt" role="test" />
<file md5sum="d51577a319f459bb1ca2d5e8974f2b0a" name="tests/bson-corpus/top-parseError-007.phpt" role="test" />
<file md5sum="5003d0478689f52a901bdb5c8f97a7ab" name="tests/bson-corpus/top-parseError-008.phpt" role="test" />
<file md5sum="ec23c3b3fa83d23338f1225b4ff97266" name="tests/bson-corpus/top-parseError-009.phpt" role="test" />
<file md5sum="b162f2cb67f78f60dc2be04d7e1850a3" name="tests/bson-corpus/top-parseError-010.phpt" role="test" />
<file md5sum="f6c561717161fef888831a004208b889" name="tests/bson-corpus/top-parseError-011.phpt" role="test" />
<file md5sum="6c203c59e320c264bd8a77dcad85c78f" name="tests/bson-corpus/top-parseError-012.phpt" role="test" />
<file md5sum="e0aa94e3b0d53dea52514e97d81bb533" name="tests/bson-corpus/top-parseError-013.phpt" role="test" />
<file md5sum="355204a85d99f71ba5191d6ab3d4c25a" name="tests/bson-corpus/top-parseError-014.phpt" role="test" />
<file md5sum="eb8e0bc7482afd8d028d242b7eed55a1" name="tests/bson-corpus/top-parseError-015.phpt" role="test" />
<file md5sum="21a6da95073beac6597ec25a1e8f1f50" name="tests/bson-corpus/top-parseError-016.phpt" role="test" />
<file md5sum="ef3937e1fac5136b3fb5b89d4b84e58b" name="tests/bson-corpus/top-parseError-017.phpt" role="test" />
<file md5sum="1fa01faebe457ce15d2fa145a1387b16" name="tests/bson-corpus/top-parseError-018.phpt" role="test" />
<file md5sum="4fb0b73c21bc7759ea406486d7af54eb" name="tests/bson-corpus/top-parseError-019.phpt" role="test" />
<file md5sum="aaafb808ced03bf16d7b459b2c03b513" name="tests/bson-corpus/top-parseError-020.phpt" role="test" />
<file md5sum="3585b33df743cd164de84bab95887006" name="tests/bson-corpus/top-parseError-021.phpt" role="test" />
<file md5sum="a0d66550a5fe08352448e581c841e820" name="tests/bson-corpus/top-parseError-022.phpt" role="test" />
<file md5sum="5a572d1c94b46570970c8e24362a680b" name="tests/bson-corpus/top-parseError-023.phpt" role="test" />
<file md5sum="972d38422efd928c9a0abe7fa6ec3bbc" name="tests/bson-corpus/top-parseError-024.phpt" role="test" />
<file md5sum="0b91fe79c2fae913a941179a7d4637ac" name="tests/bson-corpus/top-parseError-025.phpt" role="test" />
<file md5sum="ff22a84cb2cd8a79eb737e2cf891a028" name="tests/bson-corpus/top-parseError-026.phpt" role="test" />
<file md5sum="a4baa8f4b94c682bc97fefa232ccda88" name="tests/bson-corpus/top-parseError-027.phpt" role="test" />
<file md5sum="e11c66523dc4c6c4cb145ef20d93648d" name="tests/bson-corpus/top-parseError-028.phpt" role="test" />
<file md5sum="a604b56dbbd486175ea60d2d3d012ba2" name="tests/bson-corpus/top-parseError-029.phpt" role="test" />
<file md5sum="8a13c440f47575e00d3236e12adcce7c" name="tests/bson-corpus/top-parseError-030.phpt" role="test" />
<file md5sum="e334df950ab8061f120169f73f7df38a" name="tests/bson-corpus/top-parseError-031.phpt" role="test" />
<file md5sum="0444895204cdd4fb7c9a0b9205e6771b" name="tests/bson-corpus/top-parseError-032.phpt" role="test" />
<file md5sum="ad149adbdb84c23e408b8ee48a18682d" name="tests/bson-corpus/top-parseError-033.phpt" role="test" />
<file md5sum="8e523e50fdab6b4f9c234f2da8dee443" name="tests/bson-corpus/top-parseError-034.phpt" role="test" />
<file md5sum="5c548ed88b10bd221e005d716fe3838b" name="tests/bson-corpus/top-parseError-035.phpt" role="test" />
<file md5sum="3728c8281b5ad85fa8061144c9c16248" name="tests/bson-corpus/top-parseError-036.phpt" role="test" />
<file md5sum="710b55a4cbb613984b6e7e363a73d5ee" name="tests/bson-corpus/top-parseError-037.phpt" role="test" />
<file md5sum="44bcdd8c877aa1edb9912bdf7a41177c" name="tests/bson-corpus/top-parseError-038.phpt" role="test" />
<file md5sum="9913de14e00404a200e386ff25b1737f" name="tests/bson-corpus/top-parseError-039.phpt" role="test" />
<file md5sum="518e955449095c0064f8ae0ce6c61d17" name="tests/bson-corpus/top-parseError-040.phpt" role="test" />
<file md5sum="879e82251a2d8f6696947af913df789c" name="tests/bson-corpus/top-parseError-041.phpt" role="test" />
<file md5sum="5194cd6fc21f532371f0b6d3579af422" name="tests/bson-corpus/top-parseError-042.phpt" role="test" />
<file md5sum="582edbb14368ab63af4329ddbf5532c1" name="tests/bson-corpus/top-parseError-043.phpt" role="test" />
<file md5sum="f3bd75e918f0ba2b3d63ce05fafd30d3" name="tests/bson-corpus/top-parseError-044.phpt" role="test" />
<file md5sum="d127bb81fc985a32b18f4fbf562ca6e8" name="tests/bson-corpus/top-valid-001.phpt" role="test" />
<file md5sum="8a40ba6371deed0938490606bf3efe55" name="tests/bson-corpus/top-valid-002.phpt" role="test" />
<file md5sum="d5a07aa241ff80ff6d6558c3ecbe0425" name="tests/bson-corpus/top-valid-003.phpt" role="test" />
<file md5sum="f11a8a52803e238ce58fbc7ed7973927" name="tests/bson-corpus/top-valid-004.phpt" role="test" />
<file md5sum="a5c0bf78a37a5b4cc6b4c766f5720315" name="tests/bson-corpus/undefined-valid-001.phpt" role="test" />
<file md5sum="e0f562832e47bd59cecc7e99aa443e5a" name="tests/bson/bson-binary-001.phpt" role="test" />
<file md5sum="8e80fa7d54ec086c48315cac29f9e739" name="tests/bson/bson-binary-clone-001.phpt" role="test" />
<file md5sum="78c016cd924e363fb8433ce673a76b6a" name="tests/bson/bson-binary-compare-001.phpt" role="test" />
<file md5sum="6eb6c83707dd7be5c718fa13b0427d6c" name="tests/bson/bson-binary-compare-002.phpt" role="test" />
<file md5sum="58e5df014bd86dd8f1313b3fb734a7ce" name="tests/bson/bson-binary-get_properties-001.phpt" role="test" />
<file md5sum="c61e1c8e4c5327f87674314fde6b5d2f" name="tests/bson/bson-binary-get_properties-002.phpt" role="test" />
<file md5sum="a89324b72c9dbfffca5008d9563565c8" name="tests/bson/bson-binary-jsonserialize-001.phpt" role="test" />
<file md5sum="f09168841e8c1c8c75f785705ea5867d" name="tests/bson/bson-binary-jsonserialize-002.phpt" role="test" />
<file md5sum="3bf4748a5513a5aa255a38ada3f49cf6" name="tests/bson/bson-binary-serialization-001.phpt" role="test" />
<file md5sum="1c5030867786be34d289e795e28003c3" name="tests/bson/bson-binary-serialization-002.phpt" role="test" />
<file md5sum="2f8b8545ec69b155f55d1195187a4cd2" name="tests/bson/bson-binary-serialization_error-001.phpt" role="test" />
<file md5sum="423c959fe88b78ade73303c8467779b6" name="tests/bson/bson-binary-serialization_error-002.phpt" role="test" />
<file md5sum="f0e0c245cad638edebd3b4d50c890d93" name="tests/bson/bson-binary-serialization_error-003.phpt" role="test" />
<file md5sum="dc34ba6f912c1684bc6873e3a13c12fb" name="tests/bson/bson-binary-serialization_error-004.phpt" role="test" />
<file md5sum="2bd6ceb365ce5548ce1694081584cd7c" name="tests/bson/bson-binary-serialization_error-005.phpt" role="test" />
<file md5sum="11d3d828f528c119653974af5973baaf" name="tests/bson/bson-binary-serialization_error-006.phpt" role="test" />
<file md5sum="4a4275ac852b7457302ddcb2fdce7544" name="tests/bson/bson-binary-set_state-001.phpt" role="test" />
<file md5sum="b7e5915d1450ca8cb5a5e547ca9160b5" name="tests/bson/bson-binary-set_state_error-001.phpt" role="test" />
<file md5sum="4afee01d63968922b4a6642e7bbb401f" name="tests/bson/bson-binary-set_state_error-002.phpt" role="test" />
<file md5sum="ede14af86e066f7e7a2e1f8fb95deef5" name="tests/bson/bson-binary-set_state_error-003.phpt" role="test" />
<file md5sum="2079c2a8ebed8e51c12a0fab40e42ab3" name="tests/bson/bson-binary-tostring-001.phpt" role="test" />
<file md5sum="07d22be75bb9a7f92a0a70f3e517f43d" name="tests/bson/bson-binary_error-001.phpt" role="test" />
<file md5sum="e19b6d29cb9a0b089ec60d677518b336" name="tests/bson/bson-binary_error-002.phpt" role="test" />
<file md5sum="81379b32b0d5a89ab8a6ff0ac0adadba" name="tests/bson/bson-binary_error-003.phpt" role="test" />
<file md5sum="c06ae96a6cc67f60cbf53231b7a2143f" name="tests/bson/bson-binary_error-004.phpt" role="test" />
<file md5sum="fe638f713510cf803847a14a9109e6e7" name="tests/bson/bson-binaryinterface-001.phpt" role="test" />
<file md5sum="27af38a0c4f8c69764813d35839bf850" name="tests/bson/bson-dbpointer-001.phpt" role="test" />
<file md5sum="a9eb173b6168b52f6f36a3c1ad230e03" name="tests/bson/bson-dbpointer-002.phpt" role="test" />
<file md5sum="3b065984d845826addd19b9a6af03f61" name="tests/bson/bson-dbpointer-clone-001.phpt" role="test" />
<file md5sum="d583aaa6c756bd85fbc18a1aea0c8375" name="tests/bson/bson-dbpointer-compare-001.phpt" role="test" />
<file md5sum="54a92286eef293b765b118e13c4c35c6" name="tests/bson/bson-dbpointer-get_properties-001.phpt" role="test" />
<file md5sum="7eb0a24e6d9fdb5ba682ed5b56d4e903" name="tests/bson/bson-dbpointer-get_properties-002.phpt" role="test" />
<file md5sum="080fc12205c5e3b7faac905c1492d430" name="tests/bson/bson-dbpointer-jsonserialize-001.phpt" role="test" />
<file md5sum="b95771b72feed9e472fe3e8a208c6dc6" name="tests/bson/bson-dbpointer-jsonserialize-003.phpt" role="test" />
<file md5sum="0f8f37f38dc30236b58b2678bdabe8af" name="tests/bson/bson-dbpointer-serialization-001.phpt" role="test" />
<file md5sum="28bc72c2fc1f76d9ce4dca837b0467a9" name="tests/bson/bson-dbpointer-serialization-002.phpt" role="test" />
<file md5sum="572f5c184c8048a12f9a633a4f5b5161" name="tests/bson/bson-dbpointer-serialization_error-001.phpt" role="test" />
<file md5sum="6fcad6bde701b86b793b70d802110843" name="tests/bson/bson-dbpointer-serialization_error-002.phpt" role="test" />
<file md5sum="058d75bfbff3fcb9960c59165ff3f0fe" name="tests/bson/bson-dbpointer-serialization_error-003.phpt" role="test" />
<file md5sum="820c28cd63ded636b5b94d5e7734c201" name="tests/bson/bson-dbpointer-serialization_error-004.phpt" role="test" />
<file md5sum="9967c68c7c6be7228d00469feb0a1a44" name="tests/bson/bson-dbpointer-tostring-001.phpt" role="test" />
<file md5sum="8586d0a798025c589314ec96271f8ee1" name="tests/bson/bson-dbpointer_error-002.phpt" role="test" />
<file md5sum="1b07dc40c0327eaa948a01415e80156e" name="tests/bson/bson-decimal128-001.phpt" role="test" />
<file md5sum="aa1a54f32962e51878159b0b3f25a83a" name="tests/bson/bson-decimal128-002.phpt" role="test" />
<file md5sum="b17b174c54b38e37a407f8fb35aff65e" name="tests/bson/bson-decimal128-003.phpt" role="test" />
<file md5sum="b6d96feed66dfb73e8220e48e58337a1" name="tests/bson/bson-decimal128-004.phpt" role="test" />
<file md5sum="0f6988e90559d6d9f1a55d433bd02e8a" name="tests/bson/bson-decimal128-clone-001.phpt" role="test" />
<file md5sum="49024c33887fe583b96d02a37d826015" name="tests/bson/bson-decimal128-get_properties-001.phpt" role="test" />
<file md5sum="2078cc54b51b316910e7724a9fd6a346" name="tests/bson/bson-decimal128-get_properties-002.phpt" role="test" />
<file md5sum="b82e77c47a326ab042f1e35ec4725e51" name="tests/bson/bson-decimal128-jsonserialize-001.phpt" role="test" />
<file md5sum="cb0996f5695a326193b01373d57a81fb" name="tests/bson/bson-decimal128-jsonserialize-002.phpt" role="test" />
<file md5sum="f890cf6437b01948782d18fe3ecba422" name="tests/bson/bson-decimal128-serialization-001.phpt" role="test" />
<file md5sum="04decbf536c9fb60e5fcce1619ffc27b" name="tests/bson/bson-decimal128-serialization-002.phpt" role="test" />
<file md5sum="c21c6db23fc38a3c0de719c18aba9ed2" name="tests/bson/bson-decimal128-serialization_error-001.phpt" role="test" />
<file md5sum="cdb1ef626a0bc629ba8816d145055383" name="tests/bson/bson-decimal128-serialization_error-002.phpt" role="test" />
<file md5sum="90b4715e5ccade6479572b1cbd4e3fff" name="tests/bson/bson-decimal128-serialization_error-003.phpt" role="test" />
<file md5sum="d79ccabd6541bb758d0848bfe7e8fd7d" name="tests/bson/bson-decimal128-serialization_error-004.phpt" role="test" />
<file md5sum="3a8bcad13be933556fd0967a643293ac" name="tests/bson/bson-decimal128-set_state-001.phpt" role="test" />
<file md5sum="067e89686f1af0fc9281ae7b7fa55559" name="tests/bson/bson-decimal128-set_state_error-001.phpt" role="test" />
<file md5sum="95f6be0b00844003690b270087c7e8e0" name="tests/bson/bson-decimal128-set_state_error-002.phpt" role="test" />
<file md5sum="38e7320acc411dc19c200dcf4cf9fb24" name="tests/bson/bson-decimal128_error-001.phpt" role="test" />
<file md5sum="0f4dea68cea5e1b9ec5ea0bbb7e407e1" name="tests/bson/bson-decimal128_error-002.phpt" role="test" />
<file md5sum="a7dbd531a5dace1341acdf77d3821da3" name="tests/bson/bson-decimal128interface-001.phpt" role="test" />
<file md5sum="5b89a145ad1ee8e366a33c3728b1c1d3" name="tests/bson/bson-decode-001.phpt" role="test" />
<file md5sum="905e2cad0ed091633aa74ea6b3d74368" name="tests/bson/bson-decode-002.phpt" role="test" />
<file md5sum="20d31f08c1bde121119b5643be855f54" name="tests/bson/bson-encode-001.phpt" role="test" />
<file md5sum="6eefc04d2279aa541e60a1bf5a41191a" name="tests/bson/bson-encode-002.phpt" role="test" />
<file md5sum="72beb42baef8a97bb7d58355c916ceeb" name="tests/bson/bson-encode-003.phpt" role="test" />
<file md5sum="1fef8ca07ced691be09475c7726dbfcc" name="tests/bson/bson-encode-004.phpt" role="test" />
<file md5sum="abdb12bec880f1f67021fd671fd59b64" name="tests/bson/bson-encode-005.phpt" role="test" />
<file md5sum="e78affed774e0b3614d96c5455d064d1" name="tests/bson/bson-fromJSON-001.phpt" role="test" />
<file md5sum="cd3f89d1b4b926f9508c1f004244a677" name="tests/bson/bson-fromJSON-002.phpt" role="test" />
<file md5sum="5c1d857130788502f6e046a4e5594fba" name="tests/bson/bson-fromJSON-003.phpt" role="test" />
<file md5sum="0235d0d88aa6b8fe6959933b36285145" name="tests/bson/bson-fromJSON_error-001.phpt" role="test" />
<file md5sum="862d5db78dee4d2e6595d2a689d62ef1" name="tests/bson/bson-fromPHP-001.phpt" role="test" />
<file md5sum="e58fb5b6e7c422388074f9841cebd526" name="tests/bson/bson-fromPHP-002.phpt" role="test" />
<file md5sum="6b7dbfd1365adb626abb6a7b22c2e947" name="tests/bson/bson-fromPHP-003.phpt" role="test" />
<file md5sum="76871342b7809aa430fe465dd43361ca" name="tests/bson/bson-fromPHP-005.phpt" role="test" />
<file md5sum="46e2008dccd4677d517ad689ecdb2026" name="tests/bson/bson-fromPHP-006.phpt" role="test" />
<file md5sum="bbadfc7ced5da4ba1bd6652e924f96f1" name="tests/bson/bson-fromPHP_error-001.phpt" role="test" />
<file md5sum="5c886d755cd88364f0c8db69fbf3c940" name="tests/bson/bson-fromPHP_error-002.phpt" role="test" />
<file md5sum="e98523783e7330f32c8201f73c6dcc28" name="tests/bson/bson-fromPHP_error-003.phpt" role="test" />
<file md5sum="f68179caed6ca457d1da808d14cd6c65" name="tests/bson/bson-fromPHP_error-004.phpt" role="test" />
<file md5sum="9b9f0a2f33494c53a9b2ae310a58c005" name="tests/bson/bson-fromPHP_error-005.phpt" role="test" />
<file md5sum="88cad2d0e67050d76fb23a190d7a0e98" name="tests/bson/bson-fromPHP_error-006.phpt" role="test" />
<file md5sum="f73ab14963ae08f0dc674c3b5590ede5" name="tests/bson/bson-fromPHP_error-007.phpt" role="test" />
<file md5sum="247839625266088bbe2470e69cba29b6" name="tests/bson/bson-fromPHP_error-008.phpt" role="test" />
<file md5sum="3f7453d6f12a51683d5378cea4a3c920" name="tests/bson/bson-generate-document-id.phpt" role="test" />
<file md5sum="5bfed445a47856619e5e4ee5966bd531" name="tests/bson/bson-int64-001.phpt" role="test" />
<file md5sum="905baa0034820cce55b12c0fed1ac310" name="tests/bson/bson-int64-002.phpt" role="test" />
<file md5sum="4931c15064094b59d41951e0f2b63bc8" name="tests/bson/bson-int64-003.phpt" role="test" />
<file md5sum="5c9d668ca892566a55d86240786397fa" name="tests/bson/bson-int64-clone-001.phpt" role="test" />
<file md5sum="3e9447dc7f3c1f1d40741b8585fe7807" name="tests/bson/bson-int64-compare-001.phpt" role="test" />
<file md5sum="c213fa3095e2825c4743677d746b1439" name="tests/bson/bson-int64-debug-001.phpt" role="test" />
<file md5sum="9cf48adc54bdbcbcecb5a2d9fd7c83c5" name="tests/bson/bson-int64-get_properties-001.phpt" role="test" />
<file md5sum="4900dd4d57070508e00217e51f470024" name="tests/bson/bson-int64-get_properties-002.phpt" role="test" />
<file md5sum="3e267e9d9f2bd1c6e3cf496dc153291c" name="tests/bson/bson-int64-jsonserialize-001.phpt" role="test" />
<file md5sum="63787c977cac21d00f57d7c280b7ab7e" name="tests/bson/bson-int64-jsonserialize-002.phpt" role="test" />
<file md5sum="2195d40c9cf84278e7182207908c664f" name="tests/bson/bson-int64-serialization-001.phpt" role="test" />
<file md5sum="d949a276c2060299628270411eb360f0" name="tests/bson/bson-int64-serialization-002.phpt" role="test" />
<file md5sum="bc9c651613dac4502de4a08d990e3351" name="tests/bson/bson-int64-serialization_error-001.phpt" role="test" />
<file md5sum="dbb974929ac4bc20457bf78398539883" name="tests/bson/bson-int64-serialization_error-002.phpt" role="test" />
<file md5sum="3a1a4984bb7403742709524fca696869" name="tests/bson/bson-int64-serialization_error-003.phpt" role="test" />
<file md5sum="c80708f2b1967d38447882afbb649820" name="tests/bson/bson-int64-serialization_error-004.phpt" role="test" />
<file md5sum="d3d5527a1ed2efe91fa1772c9f4b9698" name="tests/bson/bson-int64-tostring-001.phpt" role="test" />
<file md5sum="a5e58f843937879d0919b476d879644a" name="tests/bson/bson-int64_error-001.phpt" role="test" />
<file md5sum="a46d3047cc8115fcccb300a9ccab9247" name="tests/bson/bson-javascript-001.phpt" role="test" />
<file md5sum="9c91bd749fd0ab27a36d14394a5e424b" name="tests/bson/bson-javascript-002.phpt" role="test" />
<file md5sum="04404d6096ed38ec3796730bbb5261c3" name="tests/bson/bson-javascript-clone-001.phpt" role="test" />
<file md5sum="97e60e9d937e0545fdd93efbc9f78c7f" name="tests/bson/bson-javascript-compare-001.phpt" role="test" />
<file md5sum="6fa03185f5a88f493df843621065aeb9" name="tests/bson/bson-javascript-compare-002.phpt" role="test" />
<file md5sum="3567bceb79c30dfd50838a0267a69c62" name="tests/bson/bson-javascript-getCode-001.phpt" role="test" />
<file md5sum="540de5d9a88362eb9f00555a1fb35597" name="tests/bson/bson-javascript-getScope-001.phpt" role="test" />
<file md5sum="e25c7ca28f41bf8785962a44c62b2159" name="tests/bson/bson-javascript-get_properties-001.phpt" role="test" />
<file md5sum="d422d8249db5a52a19a9fb2bf3e2b631" name="tests/bson/bson-javascript-get_properties-002.phpt" role="test" />
<file md5sum="b56136e8638788b0e72210ae82293c4a" name="tests/bson/bson-javascript-jsonserialize-001.phpt" role="test" />
<file md5sum="08155bf6625a0317d0daebba81670fcc" name="tests/bson/bson-javascript-jsonserialize-002.phpt" role="test" />
<file md5sum="bcb35c9e2daccee18c6fca9c8008712c" name="tests/bson/bson-javascript-jsonserialize-003.phpt" role="test" />
<file md5sum="e41434375ce47d77b71716fadf06c735" name="tests/bson/bson-javascript-jsonserialize-004.phpt" role="test" />
<file md5sum="84d099b0a16b379db8bbc4776a6610a9" name="tests/bson/bson-javascript-serialization-001.phpt" role="test" />
<file md5sum="14689ce4b1ba7f8b8105efb1598acb21" name="tests/bson/bson-javascript-serialization-002.phpt" role="test" />
<file md5sum="e377451b43f8831e68bfaf694a077789" name="tests/bson/bson-javascript-serialization_error-001.phpt" role="test" />
<file md5sum="a36384592b77821182cf5e7dac8623d8" name="tests/bson/bson-javascript-serialization_error-002.phpt" role="test" />
<file md5sum="3b9e8d0e09c9ca728a33ad59e5f2aaf6" name="tests/bson/bson-javascript-serialization_error-003.phpt" role="test" />
<file md5sum="08d397211436ce1bec9279a6921e3d58" name="tests/bson/bson-javascript-serialization_error-004.phpt" role="test" />
<file md5sum="c74d17bca1b3648fcaef53c5358d4f6e" name="tests/bson/bson-javascript-serialization_error-005.phpt" role="test" />
<file md5sum="a52c6ffac00f34fb356481a38aa50931" name="tests/bson/bson-javascript-serialization_error-006.phpt" role="test" />
<file md5sum="8b7ae41cc5888baaa121061c665ba301" name="tests/bson/bson-javascript-set_state-001.phpt" role="test" />
<file md5sum="d649a395f0abcd4c41dc59f9344f0a89" name="tests/bson/bson-javascript-set_state_error-001.phpt" role="test" />
<file md5sum="e43106245c7f106bc8b60b5a2249980d" name="tests/bson/bson-javascript-set_state_error-002.phpt" role="test" />
<file md5sum="64930970a2085d8c4d5e43d267dc5b13" name="tests/bson/bson-javascript-set_state_error-003.phpt" role="test" />
<file md5sum="4a853962f168d677f3e9c2087766fa29" name="tests/bson/bson-javascript-tostring-001.phpt" role="test" />
<file md5sum="d33b6fabee6b27aa845112710e0f043e" name="tests/bson/bson-javascript_error-001.phpt" role="test" />
<file md5sum="ebee3faf0213cdf7df62dd289a481297" name="tests/bson/bson-javascript_error-002.phpt" role="test" />
<file md5sum="be5b6f9751e312da5ff4d4331e307642" name="tests/bson/bson-javascript_error-003.phpt" role="test" />
<file md5sum="91e37d158699b239d09f45bac8b3a237" name="tests/bson/bson-javascriptinterface-001.phpt" role="test" />
<file md5sum="8443b87ea871db9861558e6979ff0db6" name="tests/bson/bson-maxkey-001.phpt" role="test" />
<file md5sum="e1179648520ecb6cf347e2e82826b4df" name="tests/bson/bson-maxkey-clone-001.phpt" role="test" />
<file md5sum="1640c877e8ffab77ca2a49939721f325" name="tests/bson/bson-maxkey-compare-001.phpt" role="test" />
<file md5sum="4314312c271b5c33f53a4d3887a683b0" name="tests/bson/bson-maxkey-jsonserialize-001.phpt" role="test" />
<file md5sum="b21da8686270aac6b81ec28467ed1144" name="tests/bson/bson-maxkey-jsonserialize-002.phpt" role="test" />
<file md5sum="352380ab948329003bccd5c12397be34" name="tests/bson/bson-maxkey-serialization-001.phpt" role="test" />
<file md5sum="2c7974d5284754b25e129f32b2700dfa" name="tests/bson/bson-maxkey-serialization-002.phpt" role="test" />
<file md5sum="ea86c16672ce4ca92a750eb7de2837e5" name="tests/bson/bson-maxkey-set_state-001.phpt" role="test" />
<file md5sum="d4a47acb431463b7f01c83e5db2f2d3d" name="tests/bson/bson-maxkey_error-001.phpt" role="test" />
<file md5sum="d9a42b06a0a7d9b8103ffee8a638c7b5" name="tests/bson/bson-maxkeyinterface-001.phpt" role="test" />
<file md5sum="a472b29a2cbc7ae8065ca1129ec5f699" name="tests/bson/bson-minkey-001.phpt" role="test" />
<file md5sum="2215a249b4334d774b4d9ab2e075ce72" name="tests/bson/bson-minkey-clone-001.phpt" role="test" />
<file md5sum="cab9d17b350f7ff0fb3930aa298f626a" name="tests/bson/bson-minkey-compare-001.phpt" role="test" />
<file md5sum="6b2c6c29ac2dbc4f91392779b99d562c" name="tests/bson/bson-minkey-jsonserialize-001.phpt" role="test" />
<file md5sum="2f29f939846864d23b0bd7fd3896301a" name="tests/bson/bson-minkey-jsonserialize-002.phpt" role="test" />
<file md5sum="dbc4b2a7f6d42a017a0004bc95552ac3" name="tests/bson/bson-minkey-serialization-001.phpt" role="test" />
<file md5sum="98b0d2775839d019bbaaae5abafa63cb" name="tests/bson/bson-minkey-serialization-002.phpt" role="test" />
<file md5sum="74201982485a724a0822cc2f2093cb75" name="tests/bson/bson-minkey-set_state-001.phpt" role="test" />
<file md5sum="64d66ab2ebc01d4b1c271079bb94db72" name="tests/bson/bson-minkey_error-001.phpt" role="test" />
<file md5sum="0a45023579316c69f78806f230ba106c" name="tests/bson/bson-minkeyinterface-001.phpt" role="test" />
<file md5sum="2f8619f0b382f91b183575db2a09fa68" name="tests/bson/bson-objectid-001.phpt" role="test" />
<file md5sum="d1eae72097de3d1e1bd0ef60f4e35cd6" name="tests/bson/bson-objectid-002.phpt" role="test" />
<file md5sum="c994597716974e44d2586b1fd6abe4a8" name="tests/bson/bson-objectid-003.phpt" role="test" />
<file md5sum="b9a3a09dd645ff06e975d192c34ad587" name="tests/bson/bson-objectid-004.phpt" role="test" />
<file md5sum="75e3621029ca645e2a5bfc69f32f2fd8" name="tests/bson/bson-objectid-clone-001.phpt" role="test" />
<file md5sum="a777ad1f36f9f3ab61a31848e29fbda3" name="tests/bson/bson-objectid-compare-001.phpt" role="test" />
<file md5sum="45a5c909f831527ec527dc6dff83a41d" name="tests/bson/bson-objectid-compare-002.phpt" role="test" />
<file md5sum="5f4fc31b72fbf2946cabfbe801e1f8e5" name="tests/bson/bson-objectid-getTimestamp-001.phpt" role="test" />
<file md5sum="04c2bfef7d149d82b796f8257ae8d1ee" name="tests/bson/bson-objectid-getTimestamp-002.phpt" role="test" />
<file md5sum="cae2d6ff62f134db503c739f79da7516" name="tests/bson/bson-objectid-get_properties-001.phpt" role="test" />
<file md5sum="ce20450b15ec7489bc67392e0af50231" name="tests/bson/bson-objectid-get_properties-002.phpt" role="test" />
<file md5sum="2927bb3a1e8581dada0e53f8c701f30d" name="tests/bson/bson-objectid-jsonserialize-001.phpt" role="test" />
<file md5sum="582dc76cd110aac0e0cb8c299e70d076" name="tests/bson/bson-objectid-jsonserialize-002.phpt" role="test" />
<file md5sum="664772c1486cea5290f9365595b7dd19" name="tests/bson/bson-objectid-serialization-001.phpt" role="test" />
<file md5sum="e75f9416725745ea9a3890a3519f8ff3" name="tests/bson/bson-objectid-serialization-002.phpt" role="test" />
<file md5sum="8cd579253bc676cc7d159dd1bb05b950" name="tests/bson/bson-objectid-serialization_error-001.phpt" role="test" />
<file md5sum="50e1b000a0b30447487e3b3f7dd055db" name="tests/bson/bson-objectid-serialization_error-002.phpt" role="test" />
<file md5sum="9a62434ef2614a0da99c6202fa0e3e4c" name="tests/bson/bson-objectid-serialization_error-003.phpt" role="test" />
<file md5sum="ff253046c0960900411875db4800a0bd" name="tests/bson/bson-objectid-serialization_error-004.phpt" role="test" />
<file md5sum="5d2fd4b95c5120b2f79599dab1d8611f" name="tests/bson/bson-objectid-set_state-001.phpt" role="test" />
<file md5sum="3667bbb9e3faffc2665641488e24cb93" name="tests/bson/bson-objectid-set_state_error-001.phpt" role="test" />
<file md5sum="4d7026a6b49e6f5d40d51a1003a251b6" name="tests/bson/bson-objectid-set_state_error-002.phpt" role="test" />
<file md5sum="dc3e069b4e1039311345171358f3d795" name="tests/bson/bson-objectid-tostring_error-001.phpt" role="test" />
<file md5sum="76ef9f4ba753e7ff3cbbf1a7181a70f1" name="tests/bson/bson-objectid_error-001.phpt" role="test" />
<file md5sum="cdb174d464441a4a3ab142b0d27429ec" name="tests/bson/bson-objectid_error-002.phpt" role="test" />
<file md5sum="556a89c07ebc69c629010a8381f918d3" name="tests/bson/bson-objectid_error-003.phpt" role="test" />
<file md5sum="94512cbf7a26273ee3b7191601600674" name="tests/bson/bson-objectidinterface-001.phpt" role="test" />
<file md5sum="6794691cba0bd0a8d005c10c46c670a3" name="tests/bson/bson-regex-001.phpt" role="test" />
<file md5sum="c6d502bd80b12b49bb86ca15cd80cb5d" name="tests/bson/bson-regex-002.phpt" role="test" />
<file md5sum="4eeeb040d3e3d2e90011e4d82ffadf5c" name="tests/bson/bson-regex-003.phpt" role="test" />
<file md5sum="511347e513bdf3bc2ae37aa34b146c01" name="tests/bson/bson-regex-004.phpt" role="test" />
<file md5sum="c5aeef20912e9660c5b9b9916e6061ed" name="tests/bson/bson-regex-005.phpt" role="test" />
<file md5sum="a785e64f4e65f7497852e29719da7e1c" name="tests/bson/bson-regex-clone-001.phpt" role="test" />
<file md5sum="6f0accb9c2f47fd13f287b115e1fdb69" name="tests/bson/bson-regex-compare-001.phpt" role="test" />
<file md5sum="78e0fcaa87dc451f34f9ef119e1bd274" name="tests/bson/bson-regex-compare-002.phpt" role="test" />
<file md5sum="7b006f20fc2ac164fb4bdce2846da38b" name="tests/bson/bson-regex-get_properties-001.phpt" role="test" />
<file md5sum="6324a488905bb05b3d2e75375c69d88a" name="tests/bson/bson-regex-get_properties-002.phpt" role="test" />
<file md5sum="6fa2a0677b01b0c63ac9e75d7189de73" name="tests/bson/bson-regex-jsonserialize-001.phpt" role="test" />
<file md5sum="b74df13ee5230ede71e1c6dab4439d2f" name="tests/bson/bson-regex-jsonserialize-002.phpt" role="test" />
<file md5sum="8a6b9554bdd5e55d0e7854e439d18925" name="tests/bson/bson-regex-jsonserialize-003.phpt" role="test" />
<file md5sum="ccb43fb3fe648baec71fc2ec79dcbbf4" name="tests/bson/bson-regex-jsonserialize-004.phpt" role="test" />
<file md5sum="34f6961089d1acb9e5d314d2f6a81262" name="tests/bson/bson-regex-serialization-001.phpt" role="test" />
<file md5sum="25b4eb60c948d48451d6d6ce0998f260" name="tests/bson/bson-regex-serialization-002.phpt" role="test" />
<file md5sum="f406a56c1cf8016d5fd0d0ecd6604bd0" name="tests/bson/bson-regex-serialization-003.phpt" role="test" />
<file md5sum="9a37fd5ae1e62311bd1e1fea9a9a84bd" name="tests/bson/bson-regex-serialization-004.phpt" role="test" />
<file md5sum="d986deafead8ca9b484dcc0eed24a934" name="tests/bson/bson-regex-serialization-005.phpt" role="test" />
<file md5sum="8a5a3cb2f10225728a903c66dcd47eb1" name="tests/bson/bson-regex-serialization-006.phpt" role="test" />
<file md5sum="5dd1e154925bebbe66ead1fe352f77bf" name="tests/bson/bson-regex-serialization_error-001.phpt" role="test" />
<file md5sum="66256509949ea548032fe13a35feafa5" name="tests/bson/bson-regex-serialization_error-002.phpt" role="test" />
<file md5sum="bfe0313e242a67e11776d51c2c953b2d" name="tests/bson/bson-regex-serialization_error-003.phpt" role="test" />
<file md5sum="d573dfe08ae5a6abc5e49492714b61d3" name="tests/bson/bson-regex-serialization_error-004.phpt" role="test" />
<file md5sum="1761af9218ff1583f51133d4f0cdcb19" name="tests/bson/bson-regex-set_state-001.phpt" role="test" />
<file md5sum="ab56bd68ecf9ea5717facbaa141db1b5" name="tests/bson/bson-regex-set_state-002.phpt" role="test" />
<file md5sum="fdd23b37dd05d0c7b626bf7192073a26" name="tests/bson/bson-regex-set_state_error-001.phpt" role="test" />
<file md5sum="780b53cc64a01a8d0a74f3cd49563d2e" name="tests/bson/bson-regex-set_state_error-002.phpt" role="test" />
<file md5sum="f86befb012d028c7552ea505725dd6e9" name="tests/bson/bson-regex_error-001.phpt" role="test" />
<file md5sum="009697ca0ba2befc6b308d59fd304b11" name="tests/bson/bson-regex_error-002.phpt" role="test" />
<file md5sum="e8851dee3b4a2cb27016935a7c4fe549" name="tests/bson/bson-regex_error-003.phpt" role="test" />
<file md5sum="b3c02b3eb309f7bbf5a33523a120b43f" name="tests/bson/bson-regexinterface-001.phpt" role="test" />
<file md5sum="b5f7d02fbf62cf6d5bece75e3f82359d" name="tests/bson/bson-symbol-001.phpt" role="test" />
<file md5sum="c49005d1f3a31ba63334439927aa8842" name="tests/bson/bson-symbol-clone-001.phpt" role="test" />
<file md5sum="a55dbbc77a3a9221810c032f38d25005" name="tests/bson/bson-symbol-compare-001.phpt" role="test" />
<file md5sum="e0b90e25e3507d77a97b7463ab76c0d4" name="tests/bson/bson-symbol-get_properties-001.phpt" role="test" />
<file md5sum="0648e9bf022072d2eb9343fb99f30a0a" name="tests/bson/bson-symbol-get_properties-002.phpt" role="test" />
<file md5sum="218eba280d32b6bbe135d24fb530ecb1" name="tests/bson/bson-symbol-jsonserialize-001.phpt" role="test" />
<file md5sum="890793b8dfd3ef59c89b90b5f063acaf" name="tests/bson/bson-symbol-jsonserialize-002.phpt" role="test" />
<file md5sum="403d81de0a50fbb4d660b2c065771906" name="tests/bson/bson-symbol-serialization-001.phpt" role="test" />
<file md5sum="2be0f0a6d09b6e4107616bf4670e5637" name="tests/bson/bson-symbol-serialization-002.phpt" role="test" />
<file md5sum="555b678e5bbe48dbfb15bb93347d4417" name="tests/bson/bson-symbol-serialization_error-001.phpt" role="test" />
<file md5sum="b7237ee2d7d9f6b613a48c502199c2ea" name="tests/bson/bson-symbol-serialization_error-002.phpt" role="test" />
<file md5sum="f9e39cd91cf14f5d0dbc126334a83200" name="tests/bson/bson-symbol-serialization_error-003.phpt" role="test" />
<file md5sum="a61f0474d24c9949b187722437dc2b5c" name="tests/bson/bson-symbol-serialization_error-004.phpt" role="test" />
<file md5sum="5753cdf389e2e3cb769eaa272f4a285e" name="tests/bson/bson-symbol-tostring-001.phpt" role="test" />
<file md5sum="92583aa0415496caf1876468b4814b84" name="tests/bson/bson-symbol_error-001.phpt" role="test" />
<file md5sum="5b5b7584c59afc95c82f798c4405d0e9" name="tests/bson/bson-timestamp-001.phpt" role="test" />
<file md5sum="94cee14f3d06ab8085f06c241a976589" name="tests/bson/bson-timestamp-002.phpt" role="test" />
<file md5sum="a0763909d65abab501df3471d9cf0009" name="tests/bson/bson-timestamp-003.phpt" role="test" />
<file md5sum="3932a3692389d969ee55de22034324b1" name="tests/bson/bson-timestamp-004.phpt" role="test" />
<file md5sum="db926cded84f832c39e527d5fcdadcbb" name="tests/bson/bson-timestamp-005.phpt" role="test" />
<file md5sum="d537ba65e693c20ae7ef9373a10c7b9a" name="tests/bson/bson-timestamp-clone-001.phpt" role="test" />
<file md5sum="bf27f37b85d838f7f3601f1733674ebe" name="tests/bson/bson-timestamp-compare-001.phpt" role="test" />
<file md5sum="8d390960f78a0d4c874f1a9bea6f60e1" name="tests/bson/bson-timestamp-getIncrement-001.phpt" role="test" />
<file md5sum="dbc98d4c863f2edbd470a744569b8ebc" name="tests/bson/bson-timestamp-getTimestamp-001.phpt" role="test" />
<file md5sum="70cbe569659d4cd104ded6f0b3954697" name="tests/bson/bson-timestamp-get_properties-001.phpt" role="test" />
<file md5sum="1cb51102b60c196d34c7c1588b91ae78" name="tests/bson/bson-timestamp-get_properties-002.phpt" role="test" />
<file md5sum="4ff5e264bb118d99302fb918e2b54ea4" name="tests/bson/bson-timestamp-jsonserialize-001.phpt" role="test" />
<file md5sum="c4ed3bdd884202c20cf3dfb199f765a2" name="tests/bson/bson-timestamp-jsonserialize-002.phpt" role="test" />
<file md5sum="5828245cb8bc389dbcc1625087637662" name="tests/bson/bson-timestamp-serialization-001.phpt" role="test" />
<file md5sum="b8c8c61075957d65caab2df3b217c4bd" name="tests/bson/bson-timestamp-serialization-002.phpt" role="test" />
<file md5sum="417881d8826b15f7c2e0df3dd386efef" name="tests/bson/bson-timestamp-serialization-003.phpt" role="test" />
<file md5sum="e4ffb218da3ca4e4947c577eb9ac7b1b" name="tests/bson/bson-timestamp-serialization-004.phpt" role="test" />
<file md5sum="6187a9a761acda7f751591d944dd890f" name="tests/bson/bson-timestamp-serialization_error-001.phpt" role="test" />
<file md5sum="7b0f7e61ca04c299c65b9c7861d61e01" name="tests/bson/bson-timestamp-serialization_error-002.phpt" role="test" />
<file md5sum="ddbdf01400527236bc45326ec0558c5d" name="tests/bson/bson-timestamp-serialization_error-003.phpt" role="test" />
<file md5sum="cb50b8e81cae55ecec85b029dc91b124" name="tests/bson/bson-timestamp-serialization_error-004.phpt" role="test" />
<file md5sum="359692a518cea16106f34a999305c280" name="tests/bson/bson-timestamp-serialization_error-005.phpt" role="test" />
<file md5sum="bc0dd3d46bff61f1b84a18a70dabe480" name="tests/bson/bson-timestamp-serialization_error-006.phpt" role="test" />
<file md5sum="b3774e8fb79913b09eaec9294ae00128" name="tests/bson/bson-timestamp-serialization_error-007.phpt" role="test" />
<file md5sum="8533a6a30fa1ee5e6be11c81b2629f95" name="tests/bson/bson-timestamp-serialization_error-008.phpt" role="test" />
<file md5sum="7a13dad169f79e7cda4ab3c7a8e2dc1f" name="tests/bson/bson-timestamp-set_state-001.phpt" role="test" />
<file md5sum="2137458362aca8c1a3d8f6224c438d9e" name="tests/bson/bson-timestamp-set_state-002.phpt" role="test" />
<file md5sum="8baeba2ddc938df88ba34a03ba47d1d1" name="tests/bson/bson-timestamp-set_state_error-001.phpt" role="test" />
<file md5sum="73a5d3cebea540001cba1b80f1febc52" name="tests/bson/bson-timestamp-set_state_error-002.phpt" role="test" />
<file md5sum="c37df82f2051521242f1dbc7ae1a9ecd" name="tests/bson/bson-timestamp-set_state_error-003.phpt" role="test" />
<file md5sum="d7176a251bfc6af5b814cc7a52a8f4b3" name="tests/bson/bson-timestamp-set_state_error-004.phpt" role="test" />
<file md5sum="6ca746014810084f9fe6cc45bb431ed6" name="tests/bson/bson-timestamp_error-001.phpt" role="test" />
<file md5sum="69daf6c7b6567dfbce4f64a6a77075a5" name="tests/bson/bson-timestamp_error-002.phpt" role="test" />
<file md5sum="c6a934138c3573ae650ea666baa809c5" name="tests/bson/bson-timestamp_error-003.phpt" role="test" />
<file md5sum="6b62f4f50fb29c882e769710d62b1f72" name="tests/bson/bson-timestamp_error-004.phpt" role="test" />
<file md5sum="4345c7e61bb3f6eadf294f1d29d5c4df" name="tests/bson/bson-timestamp_error-005.phpt" role="test" />
<file md5sum="a708297bd4537aecac1efe8868cabf7e" name="tests/bson/bson-timestamp_error-006.phpt" role="test" />
<file md5sum="304b9fe634cafb1fb611d793197f60ec" name="tests/bson/bson-timestampinterface-001.phpt" role="test" />
<file md5sum="a82ec1fe251bc4a7ce713735ae9a28b2" name="tests/bson/bson-toCanonicalJSON-001.phpt" role="test" />
<file md5sum="22321d5aa441679bfb9f60ea930228a6" name="tests/bson/bson-toCanonicalJSON-002.phpt" role="test" />
<file md5sum="5b5fa3d5a61d2646ff9f82003e83f222" name="tests/bson/bson-toCanonicalJSON_error-001.phpt" role="test" />
<file md5sum="7349eb21455138d4d5d40891a0f9f837" name="tests/bson/bson-toCanonicalJSON_error-002.phpt" role="test" />
<file md5sum="47b89324f7c19952f8fa6e977a0a0e75" name="tests/bson/bson-toCanonicalJSON_error-003.phpt" role="test" />
<file md5sum="acf0303d524300ae52812f4c04c446a5" name="tests/bson/bson-toJSON-001.phpt" role="test" />
<file md5sum="44357d5f0079f8c53f3b5d0d1671d0b4" name="tests/bson/bson-toJSON-002.phpt" role="test" />
<file md5sum="4680a3b31b66615db2875e3d794dcffd" name="tests/bson/bson-toJSON-003.phpt" role="test" />
<file md5sum="1534bb66792c42334a3ccf580da1c97b" name="tests/bson/bson-toJSON_error-001.phpt" role="test" />
<file md5sum="47271f6e4dded5ff20f04c88b2e53b8f" name="tests/bson/bson-toJSON_error-002.phpt" role="test" />
<file md5sum="3c2ca8258b3b64d53a74040675a9ead7" name="tests/bson/bson-toJSON_error-003.phpt" role="test" />
<file md5sum="c2c8b44aec6dbc4a7649394607b7aed4" name="tests/bson/bson-toPHP-001.phpt" role="test" />
<file md5sum="902453975c62deb1601d90f88778f45b" name="tests/bson/bson-toPHP-002.phpt" role="test" />
<file md5sum="28758ff54b0ba60b172bceb762710e60" name="tests/bson/bson-toPHP-003.phpt" role="test" />
<file md5sum="f1528de440af64af3ad2c64680b5d24f" name="tests/bson/bson-toPHP-004.phpt" role="test" />
<file md5sum="429cf2a3dd16f54a2688043e97598348" name="tests/bson/bson-toPHP-006.phpt" role="test" />
<file md5sum="a0b49d8b87a293efe7aa38950455b894" name="tests/bson/bson-toPHP-007.phpt" role="test" />
<file md5sum="d25d75d37d7252171a7349a3c9103760" name="tests/bson/bson-toPHP-008.phpt" role="test" />
<file md5sum="8dea2bcca14169ded2315c3c69986465" name="tests/bson/bson-toPHP-009.phpt" role="test" />
<file md5sum="1f4802a3e561debbb3ae5e08125bfb86" name="tests/bson/bson-toPHP-010.phpt" role="test" />
<file md5sum="138a7e09fdce8d44d6719a76d95d6baa" name="tests/bson/bson-toPHP-011.phpt" role="test" />
<file md5sum="b4c90232aff25ed3b7e28f1ba052c35d" name="tests/bson/bson-toPHP-012.phpt" role="test" />
<file md5sum="aeb50a7ff8e6e5e241630ca2d6835536" name="tests/bson/bson-toPHP_error-001.phpt" role="test" />
<file md5sum="26629fc4af47f1878838edb4f4b161f3" name="tests/bson/bson-toPHP_error-002.phpt" role="test" />
<file md5sum="8df28633d423cf82f5f4b08b65395b78" name="tests/bson/bson-toPHP_error-003.phpt" role="test" />
<file md5sum="a4c73580f29357adf4c4cff62f265d2a" name="tests/bson/bson-toPHP_error-004.phpt" role="test" />
<file md5sum="f6e156c4ae00827bc071e1f039e83b3d" name="tests/bson/bson-toPHP_error-005.phpt" role="test" />
<file md5sum="393e6cd0dc25441afd9802e361ffb900" name="tests/bson/bson-toPHP_error-006.phpt" role="test" />
<file md5sum="28afbfd1d34a8531e28c70c1d1b8c277" name="tests/bson/bson-toRelaxedJSON-001.phpt" role="test" />
<file md5sum="53e31eb8338e3fbfc680fa7561c9cba3" name="tests/bson/bson-toRelaxedJSON-002.phpt" role="test" />
<file md5sum="05af402e9c41fdc20e1840183dfc3ead" name="tests/bson/bson-toRelaxedJSON_error-001.phpt" role="test" />
<file md5sum="7e5f4a45d2bbb48e823ae6ee1b244c6c" name="tests/bson/bson-toRelaxedJSON_error-002.phpt" role="test" />
<file md5sum="6832130f3ad0ff88be298675a6ac2fd8" name="tests/bson/bson-toRelaxedJSON_error-003.phpt" role="test" />
<file md5sum="522c1e36a572c3a8a9835683b3fb4d60" name="tests/bson/bson-undefined-001.phpt" role="test" />
<file md5sum="2e2f8ed13b02d8631b8137568ae5b50b" name="tests/bson/bson-undefined-clone-001.phpt" role="test" />
<file md5sum="dc74e078f67345758dbb837e9d1f0f6e" name="tests/bson/bson-undefined-compare-001.phpt" role="test" />
<file md5sum="286eaff5b548beb827ac4e7641bf0cf8" name="tests/bson/bson-undefined-jsonserialize-001.phpt" role="test" />
<file md5sum="8c8a718f141b1a455d12e3e4395b638f" name="tests/bson/bson-undefined-jsonserialize-002.phpt" role="test" />
<file md5sum="e8f9d2ea7cfa8130a5e2370a89dd4bad" name="tests/bson/bson-undefined-serialization-001.phpt" role="test" />
<file md5sum="81eac679b3b83eec0f290d9724ea9856" name="tests/bson/bson-undefined-serialization-002.phpt" role="test" />
<file md5sum="efc4ba473c747b5b0dc5b5ac7fbeb8c4" name="tests/bson/bson-undefined-tostring-001.phpt" role="test" />
<file md5sum="40d8bb19b4d396749f94324a6e21cbcb" name="tests/bson/bson-undefined_error-001.phpt" role="test" />
<file md5sum="44f4e512930061f4c42daa0b0a60bfe3" name="tests/bson/bson-unknown-001.phpt" role="test" />
<file md5sum="4319ea68e884e60f54e36bb2c82b699d" name="tests/bson/bson-utcdatetime-001.phpt" role="test" />
<file md5sum="de22f1e3d63048ab3db3b3514ce45bf2" name="tests/bson/bson-utcdatetime-002.phpt" role="test" />
<file md5sum="4a7ceed02905927b3e2df8c5cc957d98" name="tests/bson/bson-utcdatetime-003.phpt" role="test" />
<file md5sum="de4188f960c7fd6debed280d2ce4da02" name="tests/bson/bson-utcdatetime-004.phpt" role="test" />
<file md5sum="ebcbd881098aeef861090012f341282d" name="tests/bson/bson-utcdatetime-005.phpt" role="test" />
<file md5sum="982f7f8d65d0f7f222f9b2512786dc4c" name="tests/bson/bson-utcdatetime-006.phpt" role="test" />
<file md5sum="322715ac6f412974a9dacb1dc7a1ebc9" name="tests/bson/bson-utcdatetime-007.phpt" role="test" />
<file md5sum="d254384c4d47ea4242c61ded0e391d66" name="tests/bson/bson-utcdatetime-clone-001.phpt" role="test" />
<file md5sum="6728e628d6cd1def65b21b5d58c477b4" name="tests/bson/bson-utcdatetime-compare-001.phpt" role="test" />
<file md5sum="8272da2bda9a4289184e655f6822550c" name="tests/bson/bson-utcdatetime-get_properties-001.phpt" role="test" />
<file md5sum="334df91a905a2ca36f77b385271e77ab" name="tests/bson/bson-utcdatetime-get_properties-002.phpt" role="test" />
<file md5sum="87a0dfcedd4205a3da922c2f10a05e7e" name="tests/bson/bson-utcdatetime-int-size-001.phpt" role="test" />
<file md5sum="56191c433baac3e51c249dec24a34a5e" name="tests/bson/bson-utcdatetime-int-size-002.phpt" role="test" />
<file md5sum="a93b633b97ec16f0b7707205f4709d12" name="tests/bson/bson-utcdatetime-jsonserialize-001.phpt" role="test" />
<file md5sum="69cf474f8b42d60ddea971ea57a092bc" name="tests/bson/bson-utcdatetime-jsonserialize-002.phpt" role="test" />
<file md5sum="ae56b03f19d04e0f0e6159220830dcd4" name="tests/bson/bson-utcdatetime-serialization-001.phpt" role="test" />
<file md5sum="1f5cca24baa36821a313dbcabf70846f" name="tests/bson/bson-utcdatetime-serialization-002.phpt" role="test" />
<file md5sum="83425ce215a17789ba2cd09d9c272224" name="tests/bson/bson-utcdatetime-serialization-003.phpt" role="test" />
<file md5sum="953a3066ecbfb702bab335eee8fa2bea" name="tests/bson/bson-utcdatetime-serialization-004.phpt" role="test" />
<file md5sum="a8f6d095646ba51b3fd9788f6be3dd23" name="tests/bson/bson-utcdatetime-serialization_error-001.phpt" role="test" />
<file md5sum="bb9575e11adaeda47d544a78e5cede26" name="tests/bson/bson-utcdatetime-serialization_error-002.phpt" role="test" />
<file md5sum="53fdeaf7c37bd0a410d2ba04a0a1e884" name="tests/bson/bson-utcdatetime-serialization_error-003.phpt" role="test" />
<file md5sum="9d764d6fea3f1414b967e7aa9a20e02b" name="tests/bson/bson-utcdatetime-serialization_error-004.phpt" role="test" />
<file md5sum="5f4ac622d87e508604308b21ae43f835" name="tests/bson/bson-utcdatetime-set_state-001.phpt" role="test" />
<file md5sum="cdbb4d6a6cd72816568163b8f54a0b9f" name="tests/bson/bson-utcdatetime-set_state-002.phpt" role="test" />
<file md5sum="ddd4b46bb4a6912b2d4f089f0d661cc4" name="tests/bson/bson-utcdatetime-set_state_error-001.phpt" role="test" />
<file md5sum="d5e321205232b014070cb2f4986e2f86" name="tests/bson/bson-utcdatetime-set_state_error-002.phpt" role="test" />
<file md5sum="1b9dd88668a06f402a8567d13d47dea7" name="tests/bson/bson-utcdatetime-todatetime-001.phpt" role="test" />
<file md5sum="8a6c7f3a7120a6135e4d8153da1fe675" name="tests/bson/bson-utcdatetime-todatetime-002.phpt" role="test" />
<file md5sum="71574612145585e471c5777f97b4721e" name="tests/bson/bson-utcdatetime-tostring-001.phpt" role="test" />
<file md5sum="ccc05d6334ea2bfebe4f35f9cc9a47dc" name="tests/bson/bson-utcdatetime_error-001.phpt" role="test" />
<file md5sum="d87151a333e0bbdb938955184366451e" name="tests/bson/bson-utcdatetime_error-002.phpt" role="test" />
<file md5sum="2e08d89b5ae15ad631aa99ab75374a9c" name="tests/bson/bson-utcdatetime_error-003.phpt" role="test" />
<file md5sum="d1aea5ef2f3fd0eb229ee2d5d83b5f2c" name="tests/bson/bson-utcdatetime_error-004.phpt" role="test" />
<file md5sum="a67824badfe3e9a6cfb5aea0577edaad" name="tests/bson/bson-utcdatetimeinterface-001.phpt" role="test" />
<file md5sum="d3e4cf8c1076daa382830ce04144bccc" name="tests/bson/bug0274.phpt" role="test" />
<file md5sum="703c3782b42782bbb822a94aa3c2d121" name="tests/bson/bug0325.phpt" role="test" />
<file md5sum="83c306e8ce09efc5d522f828243736c7" name="tests/bson/bug0334-001.phpt" role="test" />
<file md5sum="210085eaff5b9efea56a5b1ce1a5710c" name="tests/bson/bug0334-002.phpt" role="test" />
<file md5sum="2040b00df19f44645120f86708a6bbb6" name="tests/bson/bug0341.phpt" role="test" />
<file md5sum="0cdeba17452a000dab636ae0ee32f9d9" name="tests/bson/bug0347.phpt" role="test" />
<file md5sum="1eb798c06998f02912ece8b791d8366f" name="tests/bson/bug0528.phpt" role="test" />
<file md5sum="3813fc4b5a63c2d33d8b3cffaca0e8d5" name="tests/bson/bug0531-001.phpt" role="test" />
<file md5sum="e099504467387df42af07a35a74fcd31" name="tests/bson/bug0544.phpt" role="test" />
<file md5sum="2f82e244799d87c8d65772a78ecbacbf" name="tests/bson/bug0592.phpt" role="test" />
<file md5sum="6881f25614a80996fa9edaa608abb5bc" name="tests/bson/bug0623.phpt" role="test" />
<file md5sum="da12dca645be8512da84fde89ebc893a" name="tests/bson/bug0631.phpt" role="test" />
<file md5sum="b982dd73d598f1466905d11fdf43bdb2" name="tests/bson/bug0672.phpt" role="test" />
<file md5sum="9264b5948771b436ed31cf559ade001a" name="tests/bson/bug0894-001.phpt" role="test" />
<file md5sum="d0c1fd240ccf37b9af58f7e892278b60" name="tests/bson/bug0923-001.phpt" role="test" />
<file md5sum="8f38c32d045e96c06538bec87e8e7dcd" name="tests/bson/bug0923-002.phpt" role="test" />
<file md5sum="455a94f4f8a0ff8fd27e52d96438fd59" name="tests/bson/bug0939-001.phpt" role="test" />
<file md5sum="ec18f7aa32d251859f5ecae309a7da6c" name="tests/bson/bug0974-001.phpt" role="test" />
<file md5sum="a69437b114d2d538b5bb591598ca3493" name="tests/bson/bug1006-001.phpt" role="test" />
<file md5sum="38e1666dc67a7ca49646a9d787400e2e" name="tests/bson/bug1006-002.phpt" role="test" />
<file md5sum="22c30ca9d73e86406d2d6f74861366b7" name="tests/bson/bug1053.phpt" role="test" />
<file md5sum="b32de2d6a5a540a853ad9ae92b466e63" name="tests/bson/bug1067.phpt" role="test" />
<file md5sum="6e4cd77ba6ba82ebf68c6a366733094e" name="tests/bson/bug1266.phpt" role="test" />
<file md5sum="2cf98072672acfd21d0da25bad891ac6" name="tests/bson/bug1598-001.phpt" role="test" />
<file md5sum="14399bc891511ef249b27b2a377e7319" name="tests/bson/bug1598-002.phpt" role="test" />
<file md5sum="cbd0992c9a32e8c1777f75256ec30ade" name="tests/bson/bug1839-001.phpt" role="test" />
<file md5sum="e95661dcc62bf6e6d287187b0e00a151" name="tests/bson/bug1839-002.phpt" role="test" />
<file md5sum="aa36dbea2e9c29d58b15f0a3ed5211cd" name="tests/bson/bug1839-003.phpt" role="test" />
<file md5sum="9dcb7cfdee07ae5e41bffd58ac7b48a1" name="tests/bson/bug1839-004.phpt" role="test" />
<file md5sum="f71c4bb04f368828e4371ebf9b68f4e2" name="tests/bson/bug1839-005.phpt" role="test" />
<file md5sum="637bf7ef46dbb397aa0bb17f1712a698" name="tests/bson/bug1839-006.phpt" role="test" />
<file md5sum="9f35b64bb1bff9746febd2ec22c8dc06" name="tests/bson/bug1839-007.phpt" role="test" />
<file md5sum="b689bc7a94b208aff702848e5dbf9416" name="tests/bson/bug1839-008.phpt" role="test" />
+ <file md5sum="b27c6755b0a5dc3fee79d28931d38b8e" name="tests/bson/bug2083-001.phpt" role="test" />
<file md5sum="334d9e27adf0080811c164edc4a09604" name="tests/bson/typemap-001.phpt" role="test" />
<file md5sum="7d45dc9c4e491d5405fdb3bdc1eaa84b" name="tests/bson/typemap-002.phpt" role="test" />
<file md5sum="20fb7177932f34e5d3bb02791c1e4530" name="tests/bson/typemap-003.phpt" role="test" />
<file md5sum="0ce89d13ac86a496bf018b656a6b6ec8" name="tests/bson/typemap-004.phpt" role="test" />
<file md5sum="588aefd123e8ae0d1a4d4e2c4cfa1e9c" name="tests/bson/typemap-005.phpt" role="test" />
<file md5sum="6e028e5000a0609a96478a8d955c8b42" name="tests/bson/typemap-006.phpt" role="test" />
<file md5sum="907a18be6ca57629a5c5222dcc61fce2" name="tests/bson/typemap-007.phpt" role="test" />
<file md5sum="55f4be2106b3f9222216570cb4e53df8" name="tests/bulk/bug0667.phpt" role="test" />
<file md5sum="e64d115fba82e356ad50e008520a491f" name="tests/bulk/bulkwrite-count-001.phpt" role="test" />
<file md5sum="0a96053f6e2e81ba25f21c62ab6512fa" name="tests/bulk/bulkwrite-countable-001.phpt" role="test" />
- <file md5sum="d82fab930893ce11122510d6f27380c3" name="tests/bulk/bulkwrite-debug-001.phpt" role="test" />
+ <file md5sum="b52772c3894ff1dccd8ceb9a968b6a0e" name="tests/bulk/bulkwrite-ctor-comment-001.phpt" role="test" />
+ <file md5sum="1946e3bd30d4a205fee39eb832e04544" name="tests/bulk/bulkwrite-ctor-comment_error-001.phpt" role="test" />
+ <file md5sum="6d8e83061e32d86535416517f768f5bf" name="tests/bulk/bulkwrite-ctor-let-001.phpt" role="test" />
+ <file md5sum="6c396a5e4c76136dbf975410932a1a60" name="tests/bulk/bulkwrite-ctor-let_error-001.phpt" role="test" />
+ <file md5sum="9c33ddb49a4bd9265a52116e65280ef9" name="tests/bulk/bulkwrite-debug-001.phpt" role="test" />
<file md5sum="1b437c5f96c7e0b7e58adee71d5c9477" name="tests/bulk/bulkwrite-debug-002.phpt" role="test" />
<file md5sum="258ae0a1c622c643e8f8872ad7fc47a9" name="tests/bulk/bulkwrite-delete-001.phpt" role="test" />
<file md5sum="1ccd740b537c38b2c63e287ef7c59b61" name="tests/bulk/bulkwrite-delete-002.phpt" role="test" />
<file md5sum="455cebe9732350024cafd321188e1f44" name="tests/bulk/bulkwrite-delete_error-001.phpt" role="test" />
<file md5sum="8b72f9f86c38e21f2c62a529ac39dfd4" name="tests/bulk/bulkwrite-delete_error-002.phpt" role="test" />
<file md5sum="5c2928e7429cd633e042e59561ff4f00" name="tests/bulk/bulkwrite-delete_error-003.phpt" role="test" />
<file md5sum="e1ac1619f3114f9175e1d0249dbfafb7" name="tests/bulk/bulkwrite-delete_error-005.phpt" role="test" />
<file md5sum="a0f4f9800e1215bd5ae006a8b4ce93e7" name="tests/bulk/bulkwrite-insert-001.phpt" role="test" />
<file md5sum="5b0444ab63abf63403518d4e91af4e89" name="tests/bulk/bulkwrite-insert-004.phpt" role="test" />
<file md5sum="f78b72d1cf92e87ae55c01f387e349ff" name="tests/bulk/bulkwrite-insert_error-001.phpt" role="test" />
<file md5sum="a20b0d320adf61d20988b8dcda9580ae" name="tests/bulk/bulkwrite-insert_error-002.phpt" role="test" />
<file md5sum="59c60a17514366c03448112a41fbe726" name="tests/bulk/bulkwrite-insert_error-003.phpt" role="test" />
<file md5sum="90f30610837b3c4dacf3121bdbdfe680" name="tests/bulk/bulkwrite-update-001.phpt" role="test" />
<file md5sum="8257aa4b9b034288c463fa67c72a78e1" name="tests/bulk/bulkwrite-update-002.phpt" role="test" />
<file md5sum="72717aa03bbb8050feebc3bd78747035" name="tests/bulk/bulkwrite-update-003.phpt" role="test" />
<file md5sum="f377f9003530d52b5eef96cccd1e042d" name="tests/bulk/bulkwrite-update-004.phpt" role="test" />
<file md5sum="d9e18f23a4604f922ac662c01782614b" name="tests/bulk/bulkwrite-update_error-001.phpt" role="test" />
<file md5sum="40e78e07b505520a85a69a1fd9f01cae" name="tests/bulk/bulkwrite-update_error-002.phpt" role="test" />
<file md5sum="83fdd3168f859cb31b0afdac24d46dfe" name="tests/bulk/bulkwrite-update_error-003.phpt" role="test" />
<file md5sum="08abf78018bdd6d3bb652f86f5653905" name="tests/bulk/bulkwrite-update_error-004.phpt" role="test" />
<file md5sum="9a7d39da76a5c30b106dc891da1f55f7" name="tests/bulk/bulkwrite-update_error-005.phpt" role="test" />
<file md5sum="d83616a08c8691c84b3f155f7809d18b" name="tests/bulk/bulkwrite-update_error-008.phpt" role="test" />
<file md5sum="bd5f1f654b138089ea753c5e20d589f2" name="tests/bulk/bulkwrite_error-001.phpt" role="test" />
<file md5sum="2b2784e0a4fa3c6628a932ee53126946" name="tests/bulk/bulkwrite_error-002.phpt" role="test" />
<file md5sum="9620e8719fb39c100f23862926e2d9ce" name="tests/bulk/write-0001.phpt" role="test" />
<file md5sum="39c8e831ed0f1566c5dd8ebd4edf4bd3" name="tests/bulk/write-0002.phpt" role="test" />
<file md5sum="8a59042397146a6403b05d49d19927fc" name="tests/causal-consistency/causal-consistency-001.phpt" role="test" />
<file md5sum="d3e9eae691d9574829c6ac4fc15679cc" name="tests/causal-consistency/causal-consistency-002.phpt" role="test" />
<file md5sum="7b9976bef2af039a9fd8c6e92a681533" name="tests/causal-consistency/causal-consistency-003.phpt" role="test" />
<file md5sum="d0a3779ae5032b82cfd007fac79d66d7" name="tests/causal-consistency/causal-consistency-004.phpt" role="test" />
<file md5sum="08d0f259d8c3d9d30d45592ee12d7ef3" name="tests/causal-consistency/causal-consistency-005.phpt" role="test" />
<file md5sum="f846641c4b1f23847d7e9ed24bc2fda1" name="tests/causal-consistency/causal-consistency-006.phpt" role="test" />
<file md5sum="8939f754bbda25f29dec934c71aa6436" name="tests/causal-consistency/causal-consistency-007.phpt" role="test" />
<file md5sum="94d13af15b1f05867936624a980c5af6" name="tests/causal-consistency/causal-consistency-008.phpt" role="test" />
<file md5sum="39354f752f54b2dd511a726e72eb197e" name="tests/causal-consistency/causal-consistency-009.phpt" role="test" />
<file md5sum="91098da345011767e321e75deef99a1a" name="tests/causal-consistency/causal-consistency-010.phpt" role="test" />
<file md5sum="c4ce8b5d2f34064ab19f21e2f7049e2f" name="tests/causal-consistency/causal-consistency-011.phpt" role="test" />
<file md5sum="2528cc9b914cd2e641f673a8bff58c17" name="tests/causal-consistency/causal-consistency-012.phpt" role="test" />
- <file md5sum="f4f472cc8b013465c3fbb600ceaecc53" name="tests/clientEncryption/clientEncryption-constants.phpt" role="test" />
- <file md5sum="14746b6a0288ff389bcd8b147f8b22de" name="tests/clientEncryption/clientEncryption-createDataKey-001.phpt" role="test" />
- <file md5sum="0143c3a0ce8c2faea1accbef594e1dd8" name="tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt" role="test" />
- <file md5sum="34f12363170f2783a4841a5b2113c299" name="tests/clientEncryption/clientEncryption-decrypt-001.phpt" role="test" />
- <file md5sum="7509d4f9bed0416d757ae0d932a1cc67" name="tests/clientEncryption/clientEncryption-encrypt-001.phpt" role="test" />
+ <file md5sum="45a5d842bcc0575dd9442022e5fa2401" name="tests/clientEncryption/clientEncryption-constants.phpt" role="test" />
+ <file md5sum="ee1488efcbbbcbc8b975b4fbbb0cafc4" name="tests/clientEncryption/clientEncryption-createDataKey-001.phpt" role="test" />
+ <file md5sum="d469e156b4dc861fdce0d5389b7f1ca1" name="tests/clientEncryption/clientEncryption-createDataKey_error-001.phpt" role="test" />
+ <file md5sum="f13a45a1a6a1dea39b571c38e2405310" name="tests/clientEncryption/clientEncryption-ctor-001.phpt" role="test" />
+ <file md5sum="5b52cafe718fb96587dcae0ed590f734" name="tests/clientEncryption/clientEncryption-ctor_error-001.phpt" role="test" />
+ <file md5sum="c689cb2040793fe58bfb0a6176561a9f" name="tests/clientEncryption/clientEncryption-ctor_error-002.phpt" role="test" />
+ <file md5sum="5ec0b985250ca14527a3932b91301097" name="tests/clientEncryption/clientEncryption-decrypt-001.phpt" role="test" />
+ <file md5sum="691f4dffc306d430556b68fcb64b331e" name="tests/clientEncryption/clientEncryption-encrypt-001.phpt" role="test" />
<file md5sum="ef68cd61887cefb041597f5d81a7b673" name="tests/command/command-ctor-001.phpt" role="test" />
<file md5sum="81fbf19cf9cd5f5383c49d9fd3f177e8" name="tests/command/command_error-001.phpt" role="test" />
<file md5sum="4933197dd276292bc02bae8d3bce1728" name="tests/command/cursor-batchsize-001.phpt" role="test" />
<file md5sum="a783f1f889f4ba7a819ed1e55fd8a989" name="tests/command/cursor-batchsize-002.phpt" role="test" />
+ <file md5sum="c2ffda9b0ebe21702a7ae66d1fe40850" name="tests/command/cursor-comment-001.phpt" role="test" />
<file md5sum="dbbcfc4b838dcf02fac66f4e7aa1ffdc" name="tests/command/cursor-tailable-001.phpt" role="test" />
<file md5sum="e1994473378fa4935533460deec15f5b" name="tests/command/findAndModify-001.phpt" role="test" />
<file md5sum="0f0c8d871b716d4b0311b846d98b684c" name="tests/command/update-001.phpt" role="test" />
<file md5sum="007ea6228ce0a8dc4ed9ca6201facec7" name="tests/connect/bug0720.phpt" role="test" />
<file md5sum="ad508af588e129119d0e9a4f6b82c890" name="tests/connect/bug1015.phpt" role="test" />
<file md5sum="0ebcb8e508d1978211d1fe84732360cf" name="tests/connect/bug1045.phpt" role="test" />
<file md5sum="556c4d26da417b73c82bcb0ed9ab41e0" name="tests/connect/compression_error-001.phpt" role="test" />
<file md5sum="341af7c42107c40210903b7cb57070b2" name="tests/connect/compression_error-002.phpt" role="test" />
<file md5sum="83ff07823c743c67c76d808bac72bdd3" name="tests/connect/replicaset-seedlist-001.phpt" role="test" />
<file md5sum="689439f028c731f0daca49ae282096e2" name="tests/connect/replicaset-seedlist-002.phpt" role="test" />
<file md5sum="a4fc8812cf174d4c5d216704fce536ca" name="tests/connect/standalone-auth-001.phpt" role="test" />
<file md5sum="ab62017c209508bcc9cdb1dc4cde8c3b" name="tests/connect/standalone-auth_error-001.phpt" role="test" />
<file md5sum="c678e843cf60d1363dfd1195531f8a86" name="tests/connect/standalone-plain-0001.phpt" role="test" />
<file md5sum="36c31dca4f718a0162c118c50196877a" name="tests/connect/standalone-plain-0002.phpt" role="test" />
<file md5sum="f57b8f13c14f0098bab50c5af6eb386a" name="tests/connect/standalone-ssl-no_verify-001.phpt" role="test" />
<file md5sum="afb6291e139049ced590708ec4c524de" name="tests/connect/standalone-ssl-no_verify-002.phpt" role="test" />
<file md5sum="5bd2e78cc438937ba63f4ebdcc7c09b7" name="tests/connect/standalone-ssl-no_verify-003.phpt" role="test" />
<file md5sum="a34af3798467d094259a52dfacd12c27" name="tests/connect/standalone-ssl-verify_cert-001.phpt" role="test" />
<file md5sum="64fa53c106def6b1fb64936d4815c1f4" name="tests/connect/standalone-ssl-verify_cert-002.phpt" role="test" />
<file md5sum="240022b71966207b7b3a7336cba3a0e3" name="tests/connect/standalone-ssl-verify_cert-003.phpt" role="test" />
<file md5sum="3f0b35cfea9bc855d3637e39dc28c590" name="tests/connect/standalone-ssl-verify_cert-error-001.phpt" role="test" />
<file md5sum="b76eb381dbf0e69a1aa17521717e5228" name="tests/connect/standalone-ssl-verify_cert-error-002.phpt" role="test" />
<file md5sum="36a7dfc2fa0f2841086845a0dc514a92" name="tests/connect/standalone-ssl-verify_cert-error-003.phpt" role="test" />
<file md5sum="6f1ccb813ebceec352a3dcdf94e903db" name="tests/connect/standalone-x509-auth-001.phpt" role="test" />
<file md5sum="72b1b75461b4ddeeae1e3bd447d01201" name="tests/connect/standalone-x509-auth-002.phpt" role="test" />
<file md5sum="fed7282c9290a51a9409de4f15ceef6f" name="tests/connect/standalone-x509-error-0001.phpt" role="test" />
<file md5sum="b9d9eb16149f4334b7207d57c6819a9b" name="tests/connect/standalone-x509-extract_username-001.phpt" role="test" />
<file md5sum="edb99d7994524c07755b6b24ad6f30ba" name="tests/connect/standalone-x509-extract_username-002.phpt" role="test" />
<file md5sum="be75a888807351e00540edebf19c921b" name="tests/cursor/bug0671-001.phpt" role="test" />
<file md5sum="de71b16365183778e7d3386f2c077470" name="tests/cursor/bug0732-001.phpt" role="test" />
<file md5sum="034b4c5be16697c07400868165f6a410" name="tests/cursor/bug0849-001.phpt" role="test" />
<file md5sum="c70dca73cab9c3883a5995f0f26f149e" name="tests/cursor/bug0924-001.phpt" role="test" />
<file md5sum="c6433cc5a09c138bf717fa58da889b68" name="tests/cursor/bug0924-002.phpt" role="test" />
<file md5sum="a8fd3482471b5872f1be4807eba87196" name="tests/cursor/bug1050-001.phpt" role="test" />
<file md5sum="979b627261c140a612f9700f65344f68" name="tests/cursor/bug1050-002.phpt" role="test" />
<file md5sum="963697c64f74660a5adf28d1ad23ff4f" name="tests/cursor/bug1151-001.phpt" role="test" />
<file md5sum="121a051c3f32dda640c00d7b60025fac" name="tests/cursor/bug1151-002.phpt" role="test" />
<file md5sum="25f41f7dee1132a7354f21b8fa0f0119" name="tests/cursor/bug1151-003.phpt" role="test" />
<file md5sum="739f511357f2205d495da8dd59c17cd2" name="tests/cursor/bug1151-004.phpt" role="test" />
<file md5sum="b164823899b354b7ab8183b027d9207e" name="tests/cursor/bug1152-001.phpt" role="test" />
<file md5sum="cd34d162e92b07b7c5cf016532f4cd45" name="tests/cursor/bug1152-002.phpt" role="test" />
<file md5sum="1d2e6bd077d3d59cdec119361fa53b27" name="tests/cursor/bug1162-001.phpt" role="test" />
<file md5sum="a67938c9bc4c584c654d0f98659f72a0" name="tests/cursor/bug1274-001.phpt" role="test" />
<file md5sum="4574073e5ad7f2a7306912c1b93a2312" name="tests/cursor/bug1274-002.phpt" role="test" />
<file md5sum="f56bde35dc916acfc3cba7c0ae77d93a" name="tests/cursor/bug1274-003.phpt" role="test" />
<file md5sum="b7e0f253d88d86e087d6118eb58c4651" name="tests/cursor/bug1274-004.phpt" role="test" />
<file md5sum="10baa2d2575ad212500b244b7a3f17f2" name="tests/cursor/bug1274-005.phpt" role="test" />
<file md5sum="b413244ca68fe63c6165a6590c91a6de" name="tests/cursor/bug1274-006.phpt" role="test" />
<file md5sum="efedd67316e0098a7f504cc9bc88f4d0" name="tests/cursor/bug1419-001.phpt" role="test" />
- <file md5sum="052f67e9ee173efd4ee000d30870a7ae" name="tests/cursor/bug1529-001.phpt" role="test" />
+ <file md5sum="aa6342e72f669f4a88edaede7952a2e4" name="tests/cursor/bug1529-001.phpt" role="test" />
<file md5sum="0287863386284b368c94796c8563818b" name="tests/cursor/bug1713-001.phpt" role="test" />
<file md5sum="03bc65d514988acceecd8b830c41f152" name="tests/cursor/cursor-001.phpt" role="test" />
<file md5sum="bf69deaf6361488462540564d8a8b657" name="tests/cursor/cursor-IteratorIterator-001.phpt" role="test" />
<file md5sum="67cadd0d7513523b7b83f0fffb5d2c67" name="tests/cursor/cursor-IteratorIterator-002.phpt" role="test" />
<file md5sum="c099283c71f289238f24febdf4e91a02" name="tests/cursor/cursor-IteratorIterator-003.phpt" role="test" />
<file md5sum="ce2b204d53dde74e4f820cef9ebcf283" name="tests/cursor/cursor-NoRewindIterator-001.phpt" role="test" />
<file md5sum="55ac0cb41e23fd4d7cfafec98db222a9" name="tests/cursor/cursor-destruct-001.phpt" role="test" />
<file md5sum="007dfe8e75d7a3b53f17cba2155544f4" name="tests/cursor/cursor-getmore-001.phpt" role="test" />
<file md5sum="43dc536482d1d475ca02ad3818b99b9f" name="tests/cursor/cursor-getmore-002.phpt" role="test" />
<file md5sum="b18d1c583fc853cd30e933b67a7106c1" name="tests/cursor/cursor-getmore-003.phpt" role="test" />
<file md5sum="1b3d6811a9036c2118bc8fa8d07d3996" name="tests/cursor/cursor-getmore-004.phpt" role="test" />
<file md5sum="34ce76ce804bb6033cd494128ee0fcc7" name="tests/cursor/cursor-getmore-005.phpt" role="test" />
<file md5sum="a777fda21b29aa1a7971eb582cecec1b" name="tests/cursor/cursor-getmore-006.phpt" role="test" />
<file md5sum="6a28996e14074c84f2c98392786503b8" name="tests/cursor/cursor-isDead-001.phpt" role="test" />
<file md5sum="30d5decc604a425560270049a5ee695b" name="tests/cursor/cursor-isDead-002.phpt" role="test" />
<file md5sum="a587b8ffaf32c40cf2cd6e541b0fbbf1" name="tests/cursor/cursor-iterator-001.phpt" role="test" />
<file md5sum="7415ad3c7ac10d6052686ee1a5169dca" name="tests/cursor/cursor-iterator-002.phpt" role="test" />
<file md5sum="cd965b5a7e8a1037ef83cb2a6dd139b1" name="tests/cursor/cursor-iterator-003.phpt" role="test" />
<file md5sum="8fb2fbf644c00ee7e0bf977f8a1f211a" name="tests/cursor/cursor-iterator_handlers-001.phpt" role="test" />
<file md5sum="9ee993379dae963fa0d04f2311f20f35" name="tests/cursor/cursor-rewind-001.phpt" role="test" />
<file md5sum="f36441689efbf83b3d3b8268bcbe8771" name="tests/cursor/cursor-session-001.phpt" role="test" />
<file md5sum="a313da7bb52134b2bf9e099afdef50af" name="tests/cursor/cursor-session-002.phpt" role="test" />
<file md5sum="df735d7c9d38a25949a369df84d5eb0b" name="tests/cursor/cursor-session-003.phpt" role="test" />
<file md5sum="e96c4ca6aa15446f99ee6507188c4204" name="tests/cursor/cursor-session-004.phpt" role="test" />
<file md5sum="2cdda5f635087458d91722cb829357c1" name="tests/cursor/cursor-setTypeMap_error-001.phpt" role="test" />
<file md5sum="8610f9892fb81dde0b9031042cd6d3c5" name="tests/cursor/cursor-setTypeMap_error-002.phpt" role="test" />
<file md5sum="7f470a3db7be533cf0a2049a0e1adb26" name="tests/cursor/cursor-setTypeMap_error-003.phpt" role="test" />
<file md5sum="22cfc18c129aed3a0ea3b62277ba69ff" name="tests/cursor/cursor-setTypeMap_error-004.phpt" role="test" />
<file md5sum="b84aece5c9dbc1284e9200e75b63713d" name="tests/cursor/cursor-tailable-001.phpt" role="test" />
<file md5sum="b91df472b35c89949aab04c55b91999d" name="tests/cursor/cursor-tailable-002.phpt" role="test" />
<file md5sum="60a670668cf45f8e2ad86a58ddd4ed8b" name="tests/cursor/cursor-tailable-003.phpt" role="test" />
<file md5sum="fb143952fe649c057eb164922963ea39" name="tests/cursor/cursor-tailable_error-001.phpt" role="test" />
<file md5sum="9a11f5ea30986c1ab3d7a72397fe417e" name="tests/cursor/cursor-tailable_error-002.phpt" role="test" />
<file md5sum="b5bda059f5a97bb8b3b012891ba29460" name="tests/cursor/cursor-toArray-001.phpt" role="test" />
<file md5sum="eafd09d1e9e8eed41e4efa188f1f4750" name="tests/cursor/cursor-toArray-002.phpt" role="test" />
<file md5sum="11ce7d49c58b1efbef42e52612f2ed3e" name="tests/cursor/cursor_error-001.phpt" role="test" />
<file md5sum="74ee254ba8edcea3575d523499bc542a" name="tests/cursor/cursorinterface-001.phpt" role="test" />
<file md5sum="d35e1eff5ad7b32efb76838dd4345d0e" name="tests/cursor/cursorinterface-002.phpt" role="test" />
<file md5sum="edc4273b932edaa535af383ec047ad31" name="tests/cursor/cursorinterface-003.phpt" role="test" />
<file md5sum="fb4f47efe165b4a8ab62c9a1c52419ba" name="tests/cursorid/cursorid-001.phpt" role="test" />
<file md5sum="1011840881ca3b8ef05dacdd5b6d4ece" name="tests/cursorid/cursorid-002.phpt" role="test" />
<file md5sum="6ed65377ec9bbc81ab150ddfeb46f6da" name="tests/cursorid/cursorid-debug-001.phpt" role="test" />
<file md5sum="a2a84e7cbab924addae7560d92d40d93" name="tests/cursorid/cursorid-debug-002.phpt" role="test" />
<file md5sum="50a9a5368994bd5d8535529423f829e3" name="tests/cursorid/cursorid-debug-003.phpt" role="test" />
<file md5sum="730abb0e89433ef5d8a42012cc89d5f9" name="tests/cursorid/cursorid-serialization-001.phpt" role="test" />
<file md5sum="533a1cf52e30959e59c5ae53cb7d64a2" name="tests/cursorid/cursorid-serialization-002.phpt" role="test" />
<file md5sum="a76f1ca7cee09b8823fc2e09e661c2d2" name="tests/cursorid/cursorid-serialization_error-001.phpt" role="test" />
<file md5sum="9e166a70145710c11e86a29b45dbd054" name="tests/cursorid/cursorid-serialization_error-002.phpt" role="test" />
<file md5sum="0afe67043b96fca72dda54ec7f61986c" name="tests/cursorid/cursorid-set_state-001.phpt" role="test" />
<file md5sum="0c5d91a8e0ebfdf67f6e67ec86affc4c" name="tests/cursorid/cursorid-set_state_error-001.phpt" role="test" />
<file md5sum="f8f9533dc57a5175c028bffb66af1b16" name="tests/cursorid/cursorid-tostring-001.phpt" role="test" />
<file md5sum="c1e706da3f7795132d8a2b15beadb9bb" name="tests/cursorid/cursorid-var_export-001.phpt" role="test" />
<file md5sum="dfd23c235da73521f540440dfdd942f6" name="tests/cursorid/cursorid_error-001.phpt" role="test" />
<file md5sum="e9d41f8bd860cf7bc7aecf888a6e5f03" name="tests/exception/bulkwriteexception-getwriteresult-001.phpt" role="test" />
<file md5sum="0c742d44e6e7d6cc44043ff7c7d52dfd" name="tests/exception/bulkwriteexception-haserrorlabel-001.phpt" role="test" />
<file md5sum="107d048dac2bfeb88038407043231966" name="tests/exception/bulkwriteexception-haserrorlabel-002.phpt" role="test" />
<file md5sum="9affde6e5226e248967e3ee33a5feef0" name="tests/exception/bulkwriteexception-haserrorlabel_error-001.phpt" role="test" />
<file md5sum="9b577a17a9a125ab32ad48010d3b7909" name="tests/exception/commandexception-getresultdocument-001.phpt" role="test" />
<file md5sum="f517ae8a8ad62e3fa2fe69d282367ea4" name="tests/exception/commandexception-haserrorlabel-001.phpt" role="test" />
<file md5sum="69b64eec21ec54c479dfe557269598ab" name="tests/exception/commandexception-haserrorlabel_error-001.phpt" role="test" />
<file md5sum="6bcc1ed27df3ddbe16f549c82803d0cf" name="tests/exception/exception-001.phpt" role="test" />
<file md5sum="0f64ba7a9c355b2ee9a30d5f3f2241b8" name="tests/exception/runtimeexception-haserrorlabel-001.phpt" role="test" />
<file md5sum="98fe8f2b6fc815b91199a9d9fb9320f3" name="tests/exception/runtimeexception-haserrorlabel_error-001.phpt" role="test" />
<file md5sum="d078443aa427bf7a9b9fa31383027c38" name="tests/functional/cursor-001.phpt" role="test" />
<file md5sum="c617d75116254e986cfb55680329fdf7" name="tests/functional/cursorid-001.phpt" role="test" />
<file md5sum="e2ec8630d72d7056d7e354dfa7c8ceea" name="tests/functional/query-sort-001.phpt" role="test" />
<file md5sum="70eadbd23fde7c9fe3e47c0660019662" name="tests/functional/query-sort-002.phpt" role="test" />
<file md5sum="5ebf5ea95564a7e037329ded2b56a48e" name="tests/functional/query-sort-003.phpt" role="test" />
<file md5sum="9ff28a88ea444b1e2fdb93cb9d57a042" name="tests/functional/query-sort-004.phpt" role="test" />
<file md5sum="6bbd8a73a4ddc363257f26a055744e05" name="tests/ini/ini-debug-ini_get-001.phpt" role="test" />
<file md5sum="329a0fb960668dfb38b5d59a221c39f5" name="tests/ini/ini-debug-ini_get-002.phpt" role="test" />
<file md5sum="8eb3c43b6e36a4ddb9df1e05439ae08d" name="tests/ini/ini-debug-phpinfo-001.phpt" role="test" />
<file md5sum="09aca68640353346b8794e157930e547" name="tests/ini/ini-debug-phpinfo-002.phpt" role="test" />
- <file md5sum="cc08d1004d1ab7608990fff4451f9f69" name="tests/ini/ini-mock_service_id-ini_get-001.phpt" role="test" />
- <file md5sum="dcaeb7fde859686df50b77a3a0242960" name="tests/ini/ini-mock_service_id-ini_get-002.phpt" role="test" />
- <file md5sum="451ece5646c829209d0fb03f5dfb1d5d" name="tests/ini/ini-mock_service_id-phpinfo-001.phpt" role="test" />
- <file md5sum="2b4777e59a0ffb0103ed998f9c7a10a1" name="tests/ini/ini-mock_service_id-phpinfo-002.phpt" role="test" />
<file md5sum="4c270b3a7c57500dba85a79938df1495" name="tests/manager/bug0572.phpt" role="test" />
<file md5sum="f0346e6cd2ba9520eef5021167879c4e" name="tests/manager/bug0851-001.phpt" role="test" />
<file md5sum="d5af337dd2aa7220b61b71deacb2a0ef" name="tests/manager/bug0851-002.phpt" role="test" />
<file md5sum="eb1c288def3ad2711f856313fabd08ee" name="tests/manager/bug0912-001.phpt" role="test" />
<file md5sum="f6de9f3ae346da76b6a0f777ed1bb04a" name="tests/manager/bug0913-001.phpt" role="test" />
<file md5sum="581f3f676bb14c8f81e76890e69864f4" name="tests/manager/bug0940-001.phpt" role="test" />
<file md5sum="4a8161bfdfd6cc6611c33d7c22323e35" name="tests/manager/bug0940-002.phpt" role="test" />
<file md5sum="499aaafa901f396dea56ef1dd94887be" name="tests/manager/bug1163-001.phpt" role="test" />
<file md5sum="3b75a0aded454ff7a0b1d602db1ece5f" name="tests/manager/bug1701-001.phpt" role="test" />
<file md5sum="5e03095c0330adf9c2a8207f861eb31f" name="tests/manager/manager-addSubscriber-001.phpt" role="test" />
<file md5sum="b82b18aae62824212cbea901095d6891" name="tests/manager/manager-addSubscriber-002.phpt" role="test" />
<file md5sum="69f21c1b26508112f80b5795264bfd6e" name="tests/manager/manager-addSubscriber-003.phpt" role="test" />
<file md5sum="df4637bb253994b085da23cb7c2baf02" name="tests/manager/manager-addSubscriber-004.phpt" role="test" />
<file md5sum="dffea1ba61ff80a301a251c7266353f5" name="tests/manager/manager-addSubscriber-005.phpt" role="test" />
<file md5sum="11c7dd46d560091cb685cfa96509f887" name="tests/manager/manager-addSubscriber-006.phpt" role="test" />
- <file md5sum="2787ed29d23447eead4f2e5b5fcbf3f5" name="tests/manager/manager-createClientEncryption-001.phpt" role="test" />
+ <file md5sum="a82e94f14792da1c8e98885ab49c0d2b" name="tests/manager/manager-createClientEncryption-001.phpt" role="test" />
<file md5sum="cc2ec9dedc92e65426c43fa6e3446b88" name="tests/manager/manager-createClientEncryption-error-001.phpt" role="test" />
- <file md5sum="117f989d4a45f417b318ef64b061c1a6" name="tests/manager/manager-createClientEncryption-error-002.phpt" role="test" />
+ <file md5sum="eb71f85d2eb9c38292ad932af4a3b4ba" name="tests/manager/manager-createClientEncryption-error-002.phpt" role="test" />
<file md5sum="d582d6ff744cdbf6f65a37e63faac924" name="tests/manager/manager-ctor-001.phpt" role="test" />
<file md5sum="ddb6ad56c0bddfdcddc28eac459c2ec7" name="tests/manager/manager-ctor-002.phpt" role="test" />
<file md5sum="bf482d24f1467be19b603557a6cb8e6c" name="tests/manager/manager-ctor-003.phpt" role="test" />
<file md5sum="cd62592a5c1c3b6c855b698735a1b9eb" name="tests/manager/manager-ctor-004.phpt" role="test" />
<file md5sum="23db0653a78cb7318c9978f1fc87bba9" name="tests/manager/manager-ctor-005.phpt" role="test" />
<file md5sum="7747cbf6bee84e93ed0ca1bb249af376" name="tests/manager/manager-ctor-006.phpt" role="test" />
<file md5sum="63826ceaf67ba68e92278c9f212ea931" name="tests/manager/manager-ctor-007.phpt" role="test" />
<file md5sum="5114f45044457fc9fa9b6913bb412a7b" name="tests/manager/manager-ctor-008.phpt" role="test" />
<file md5sum="7ee075e78215384bc775165f5bcaecc2" name="tests/manager/manager-ctor-appname-001.phpt" role="test" />
<file md5sum="407f236f707abcb938e7f065dd1346fc" name="tests/manager/manager-ctor-appname_error-001.phpt" role="test" />
<file md5sum="0f29f362757476ecaa36f936d16a7c20" name="tests/manager/manager-ctor-auth_mechanism-001.phpt" role="test" />
<file md5sum="7e334d9c4f17adc4ec5be12d461207b6" name="tests/manager/manager-ctor-auth_mechanism-002.phpt" role="test" />
<file md5sum="2e7cfd7ab77f97ab8261f464f84fb030" name="tests/manager/manager-ctor-auth_mechanism-error-001.phpt" role="test" />
<file md5sum="b36422d0897ec7f315fdb5f3391d7341" name="tests/manager/manager-ctor-auth_source-001.phpt" role="test" />
- <file md5sum="85b83ea4ac48a57132906b006c01d8de" name="tests/manager/manager-ctor-auto_encryption-001.phpt" role="test" />
- <file md5sum="aab3b7de7b4834fd3d93f0ca5a8b79cd" name="tests/manager/manager-ctor-auto_encryption-error-001.phpt" role="test" />
- <file md5sum="78ec79aeb3fb1e221759a0632dafe0be" name="tests/manager/manager-ctor-auto_encryption-error-002.phpt" role="test" />
- <file md5sum="95745423b41e3b940a46a33dbf55b111" name="tests/manager/manager-ctor-auto_encryption-error-003.phpt" role="test" />
+ <file md5sum="1ed47b84a11a06a152f88dcade51d40e" name="tests/manager/manager-ctor-auto_encryption-001.phpt" role="test" />
+ <file md5sum="53b6f08d0119fe3e487ccd14141853f5" name="tests/manager/manager-ctor-auto_encryption-002.phpt" role="test" />
+ <file md5sum="cd5bc0eccd387c9609e5f89d0446572b" name="tests/manager/manager-ctor-auto_encryption-error-001.phpt" role="test" />
+ <file md5sum="4c289dc44bc8b0cb26e33502fdc77fa8" name="tests/manager/manager-ctor-auto_encryption-error-002.phpt" role="test" />
+ <file md5sum="0734c1b7c60959c0789413aca4d18a24" name="tests/manager/manager-ctor-auto_encryption-error-003.phpt" role="test" />
+ <file md5sum="7d5d4dcae193c17364199e3f071841e1" name="tests/manager/manager-ctor-auto_encryption-error-004.phpt" role="test" />
<file md5sum="bbd66e27c8ae892d3ba42417a0bc0fd7" name="tests/manager/manager-ctor-directconnection-001.phpt" role="test" />
<file md5sum="e85a2529c8de114992f22289800615fc" name="tests/manager/manager-ctor-directconnection-error-001.phpt" role="test" />
<file md5sum="b3680d5e2c654cba916f7e523b04ee9c" name="tests/manager/manager-ctor-directconnection-error-002.phpt" role="test" />
<file md5sum="0a4c7fdb304b664df108aa9a6fa54e82" name="tests/manager/manager-ctor-disableClientPersistence-001.phpt" role="test" />
<file md5sum="2e3bbe239f1aba35a1c6ba9589f8ee76" name="tests/manager/manager-ctor-disableClientPersistence-002.phpt" role="test" />
<file md5sum="10c3c2d46b5447b1a7c1b446cef8f5d4" name="tests/manager/manager-ctor-disableClientPersistence-003.phpt" role="test" />
<file md5sum="220dfefa93b81ded8cf90c1be371a6d5" name="tests/manager/manager-ctor-disableClientPersistence-004.phpt" role="test" />
<file md5sum="5f46a29a8e3b5c36a013946b19d0f22a" name="tests/manager/manager-ctor-disableClientPersistence-005.phpt" role="test" />
- <file md5sum="5cce6589b645b6cdf775facb76805dc3" name="tests/manager/manager-ctor-disableClientPersistence-006.phpt" role="test" />
- <file md5sum="9c6f8ae4606f7c6d09c3150426ccc144" name="tests/manager/manager-ctor-disableClientPersistence-007.phpt" role="test" />
+ <file md5sum="3e34e2072d0e054fddc7bdb6ac3c8237" name="tests/manager/manager-ctor-disableClientPersistence-006.phpt" role="test" />
+ <file md5sum="f6ffd08e1d928971f96f3498eb7a7de6" name="tests/manager/manager-ctor-disableClientPersistence-007.phpt" role="test" />
<file md5sum="9af2ff3c80a4511cd0e30d445dd681aa" name="tests/manager/manager-ctor-disableClientPersistence-008.phpt" role="test" />
<file md5sum="3f629511676dda931a85988f7fab2f53" name="tests/manager/manager-ctor-disableClientPersistence-009.phpt" role="test" />
<file md5sum="891cb09a2517e005b2f568f976f06cb5" name="tests/manager/manager-ctor-disableClientPersistence-010.phpt" role="test" />
<file md5sum="d8f9cef48b537b356664ea15b17eb55e" name="tests/manager/manager-ctor-disableClientPersistence-011.phpt" role="test" />
- <file md5sum="01c99b2ff9bbc25b0bc3c6d74552710f" name="tests/manager/manager-ctor-disableClientPersistence_error-001.phpt" role="test" />
+ <file md5sum="b80f61209563751f07a4a285c0b72986" name="tests/manager/manager-ctor-disableClientPersistence_error-001.phpt" role="test" />
<file md5sum="684d21bfb847f1d4f949c55ada08c349" name="tests/manager/manager-ctor-driver-metadata-001.phpt" role="test" />
<file md5sum="620dd66d04240a1cbfbc33373117085c" name="tests/manager/manager-ctor-duplicate-option-001.phpt" role="test" />
<file md5sum="9311bb62f8740436ef91ef7a0fe5c97a" name="tests/manager/manager-ctor-duplicate-option-002.phpt" role="test" />
<file md5sum="d6b52ffcafa9ceaf363ebdb07c10cc75" name="tests/manager/manager-ctor-duplicate-option-003.phpt" role="test" />
<file md5sum="7538039ec421e2ae634e91ba24999408" name="tests/manager/manager-ctor-duplicate-option-004.phpt" role="test" />
<file md5sum="b5a10d899434b9deef074274da9e6259" name="tests/manager/manager-ctor-loadBalanced_error-001.phpt" role="test" />
<file md5sum="ee7822e3b58b7abb5ccee0a87dc86e4d" name="tests/manager/manager-ctor-read_concern-001.phpt" role="test" />
<file md5sum="c3050181118743d791b3ed29bdb4dd03" name="tests/manager/manager-ctor-read_concern-error-001.phpt" role="test" />
<file md5sum="79e97d46bf35dde168a2b2c8b304d259" name="tests/manager/manager-ctor-read_preference-001.phpt" role="test" />
<file md5sum="a68f0249fa21dc829486e9b349d5835a" name="tests/manager/manager-ctor-read_preference-002.phpt" role="test" />
<file md5sum="a542b958f8d6382715bc565c70ad6f34" name="tests/manager/manager-ctor-read_preference-error-001.phpt" role="test" />
<file md5sum="168b9448ba25614c452395a7801acd2d" name="tests/manager/manager-ctor-read_preference-error-002.phpt" role="test" />
<file md5sum="27ca549dbb89c00049059ec7aa61e080" name="tests/manager/manager-ctor-read_preference-error-004.phpt" role="test" />
<file md5sum="15ff7aaa3b2ccb96efac1fd5817e7496" name="tests/manager/manager-ctor-server.phpt" role="test" />
<file md5sum="e012ca65947f9a4fb9f07c6194a7ddb0" name="tests/manager/manager-ctor-serverApi-001.phpt" role="test" />
<file md5sum="fd58121e4d808d98a6ab5e723fb0948b" name="tests/manager/manager-ctor-serverApi-error-001.phpt" role="test" />
<file md5sum="189f7b0da30ee877dd930d11b14b6a1a" name="tests/manager/manager-ctor-srvMaxHosts_error-001.phpt" role="test" />
<file md5sum="d3c81af87b476fadf7ab31a0830a750e" name="tests/manager/manager-ctor-srvServiceName_error-001.phpt" role="test" />
<file md5sum="0f5384a769df66ede31e0c1bcd91db3b" name="tests/manager/manager-ctor-ssl-001.phpt" role="test" />
<file md5sum="5b0ee7ee781a81ef427fcc42d0af2441" name="tests/manager/manager-ctor-ssl-002.phpt" role="test" />
<file md5sum="80664e19f82704d7f9fbb9973d34bd4b" name="tests/manager/manager-ctor-ssl-003.phpt" role="test" />
<file md5sum="5acad9aa9837e9e164e90fea64608727" name="tests/manager/manager-ctor-ssl-deprecated-001.phpt" role="test" />
<file md5sum="31a9a1a525cd162eefcd61443a10ce72" name="tests/manager/manager-ctor-ssl-deprecated-002.phpt" role="test" />
<file md5sum="485381d433a7d2df4e2864183167783d" name="tests/manager/manager-ctor-tls-error-001.phpt" role="test" />
<file md5sum="78fd7230fed15c73d514a4f5bb6b28db" name="tests/manager/manager-ctor-wireversion.phpt" role="test" />
<file md5sum="f5f725515b3e0d3000a190ca90a48902" name="tests/manager/manager-ctor-write_concern-001.phpt" role="test" />
<file md5sum="f57f8e8063d723e1cd9e01a7e65cdcf6" name="tests/manager/manager-ctor-write_concern-002.phpt" role="test" />
<file md5sum="a795c0a05f3f14eee39dc899c6b8b353" name="tests/manager/manager-ctor-write_concern-003.phpt" role="test" />
<file md5sum="243320fdfc028f0156dab89e0a4111fd" name="tests/manager/manager-ctor-write_concern-004.phpt" role="test" />
<file md5sum="3082087d08245cfd506d8e9c065552eb" name="tests/manager/manager-ctor-write_concern-005.phpt" role="test" />
<file md5sum="19a3af22d908692a494ff19407488831" name="tests/manager/manager-ctor-write_concern-006.phpt" role="test" />
<file md5sum="5d28e6043e9e02f5cb9d8cf1888467be" name="tests/manager/manager-ctor-write_concern-error-001.phpt" role="test" />
<file md5sum="90ccf4bb2ee95f53ffbb1e9fb28c77c0" name="tests/manager/manager-ctor-write_concern-error-002.phpt" role="test" />
<file md5sum="e5da84659c4d520d3b4136e0d269bbc6" name="tests/manager/manager-ctor-write_concern-error-003.phpt" role="test" />
<file md5sum="b673d755c80327aa2ad66909956a6edb" name="tests/manager/manager-ctor-write_concern-error-005.phpt" role="test" />
<file md5sum="b84a33ba0c7e0ffbc2d281a260891c96" name="tests/manager/manager-ctor-write_concern-error-006.phpt" role="test" />
<file md5sum="2ad014b8f8dfde5313342d05f0d8198a" name="tests/manager/manager-ctor-write_concern-error-007.phpt" role="test" />
<file md5sum="3ad6b15c16b8d14633b5f677b94a0050" name="tests/manager/manager-ctor_error-001.phpt" role="test" />
<file md5sum="ad3bd333cd908ee4c406c7b110e97f61" name="tests/manager/manager-ctor_error-002.phpt" role="test" />
<file md5sum="2be80650701a83ae0b95140279131df4" name="tests/manager/manager-ctor_error-003.phpt" role="test" />
<file md5sum="3626db363099e33cd39331fde78f46c3" name="tests/manager/manager-ctor_error-004.phpt" role="test" />
<file md5sum="1ea3fe7629cdebd837254fd1b0730514" name="tests/manager/manager-ctor_error-005.phpt" role="test" />
<file md5sum="be738dc790fc658a6ce32235b04b1d4b" name="tests/manager/manager-debug-001.phpt" role="test" />
<file md5sum="fed182f4305d260702f56990d7977c91" name="tests/manager/manager-debug-002.phpt" role="test" />
<file md5sum="b99cf3e782d7e1fba6a320e7815305f5" name="tests/manager/manager-debug-003.phpt" role="test" />
<file md5sum="4259a7b351904d6953d98b315be1ae65" name="tests/manager/manager-destruct-001.phpt" role="test" />
<file md5sum="9858166f195e0b105301c23b6436fdea" name="tests/manager/manager-executeBulkWrite-001.phpt" role="test" />
<file md5sum="9206434f496fb925d1b0a499f4f5b790" name="tests/manager/manager-executeBulkWrite-002.phpt" role="test" />
<file md5sum="d677e3dbe915d7799541477aeb4ea377" name="tests/manager/manager-executeBulkWrite-003.phpt" role="test" />
<file md5sum="3c8bc99af44c66e6c3d36a5a4d5bd8ba" name="tests/manager/manager-executeBulkWrite-004.phpt" role="test" />
<file md5sum="9e2e4162b402edd002462bb5125df34e" name="tests/manager/manager-executeBulkWrite-005.phpt" role="test" />
<file md5sum="795731bd50229fee29f2f80356f9df66" name="tests/manager/manager-executeBulkWrite-006.phpt" role="test" />
<file md5sum="65087ac5e6795aec5235055a07b42d5d" name="tests/manager/manager-executeBulkWrite-007.phpt" role="test" />
<file md5sum="ea6d63c6200730caf72ab5985375bc23" name="tests/manager/manager-executeBulkWrite-008.phpt" role="test" />
<file md5sum="22eecd73ad4e7f112efb4f91dcde274c" name="tests/manager/manager-executeBulkWrite-009.phpt" role="test" />
<file md5sum="1e4b2286bc8e60d3000a70c555857d55" name="tests/manager/manager-executeBulkWrite-010.phpt" role="test" />
<file md5sum="7ab463e67470819d06afba936154682d" name="tests/manager/manager-executeBulkWrite-011.phpt" role="test" />
<file md5sum="09cce0f9669e62dade4ec2f527cccac6" name="tests/manager/manager-executeBulkWrite-012.phpt" role="test" />
<file md5sum="4a08d8ca47b6634ac392e8551282cd50" name="tests/manager/manager-executeBulkWrite-013.phpt" role="test" />
<file md5sum="d518608f1d6ba9e787603aa42e95a87a" name="tests/manager/manager-executeBulkWrite-014.phpt" role="test" />
<file md5sum="17edeebb5d2d6fe81f16ff75186ecb14" name="tests/manager/manager-executeBulkWrite_error-001.phpt" role="test" />
<file md5sum="055caec5920283895721528c49541692" name="tests/manager/manager-executeBulkWrite_error-002.phpt" role="test" />
<file md5sum="a71df0ff298839d4b40c4791fd9d36ed" name="tests/manager/manager-executeBulkWrite_error-003.phpt" role="test" />
<file md5sum="88da3b97b15660e6185a1e9a1bc993ef" name="tests/manager/manager-executeBulkWrite_error-004.phpt" role="test" />
<file md5sum="25e5cd8215e8cbe5e8e54a2568296075" name="tests/manager/manager-executeBulkWrite_error-005.phpt" role="test" />
<file md5sum="78bf40680ecc66aa370a9bd96e4aa8f9" name="tests/manager/manager-executeBulkWrite_error-006.phpt" role="test" />
<file md5sum="b3ace17b87a0ff9a38535aab0735318f" name="tests/manager/manager-executeBulkWrite_error-007.phpt" role="test" />
<file md5sum="4fc2ff48edb6d3b24c055a79c3768528" name="tests/manager/manager-executeBulkWrite_error-008.phpt" role="test" />
<file md5sum="7c989b5bd98732cfecc3bc46488e76ed" name="tests/manager/manager-executeBulkWrite_error-009.phpt" role="test" />
<file md5sum="0230472d8a9e6e5f979972a5296447e0" name="tests/manager/manager-executeBulkWrite_error-010.phpt" role="test" />
<file md5sum="2e16b236ed0b9d83c4dbdd460678d664" name="tests/manager/manager-executeBulkWrite_error-011.phpt" role="test" />
<file md5sum="ec99c21e5928121af04ce66bf708f252" name="tests/manager/manager-executeCommand-001.phpt" role="test" />
<file md5sum="e6bfa30363f74cc2ca3b6fb94556cef8" name="tests/manager/manager-executeCommand-002.phpt" role="test" />
<file md5sum="8b42bf17bf134bb02b95a04345ba26e8" name="tests/manager/manager-executeCommand-003.phpt" role="test" />
<file md5sum="824027c39963dc2ab0a6998722f6b62b" name="tests/manager/manager-executeCommand-004.phpt" role="test" />
<file md5sum="eb54735876d5b2cfa2254f36dee96fcb" name="tests/manager/manager-executeCommand-005.phpt" role="test" />
<file md5sum="25703dba306cfa484ea7c7fe150d9a86" name="tests/manager/manager-executeCommand-006.phpt" role="test" />
<file md5sum="c77cc61748533707a12f5fd68839fe9b" name="tests/manager/manager-executeCommand-007.phpt" role="test" />
<file md5sum="414cb9ff3e5179fd483cd2a9d1d5c6c5" name="tests/manager/manager-executeCommand_error-001.phpt" role="test" />
<file md5sum="3a6361131801e5716a8ceacc11632924" name="tests/manager/manager-executeCommand_error-002.phpt" role="test" />
<file md5sum="ac72ebf6080b999ac922854f877c0896" name="tests/manager/manager-executeCommand_error-003.phpt" role="test" />
<file md5sum="609298cc6697cfa6303b3a16ad29fbf2" name="tests/manager/manager-executeCommand_error-004.phpt" role="test" />
<file md5sum="7f2ac9637e5fea5e5a796dffa612ad7b" name="tests/manager/manager-executeCommand_error-005.phpt" role="test" />
<file md5sum="a4bd4054f9e33874b706920dacee6ecf" name="tests/manager/manager-executeQuery-002.phpt" role="test" />
<file md5sum="ceec6777086895ff43b3618b203809d8" name="tests/manager/manager-executeQuery-003.phpt" role="test" />
<file md5sum="72528bc2e1f521b5f490893616cfe893" name="tests/manager/manager-executeQuery-004.phpt" role="test" />
<file md5sum="539863b58b1307304c52d9d9760f29e5" name="tests/manager/manager-executeQuery-005.phpt" role="test" />
<file md5sum="d2b957d04be0f84243425f051329a30c" name="tests/manager/manager-executeQuery-006.phpt" role="test" />
<file md5sum="4397e3a049cf85e53f15beea02220ddc" name="tests/manager/manager-executeQuery-007.phpt" role="test" />
<file md5sum="18e9275267d96345a2365a618bf09ada" name="tests/manager/manager-executeQuery_error-001.phpt" role="test" />
<file md5sum="77de256019cf2c997e2dab1f5bc3a9e0" name="tests/manager/manager-executeQuery_error-002.phpt" role="test" />
<file md5sum="3c9dbb9e16de715ecd2f14d46afe8d0b" name="tests/manager/manager-executeQuery_error-003.phpt" role="test" />
<file md5sum="7dbc24d4236d40e4ab7701ebffb5e2f5" name="tests/manager/manager-executeReadCommand-001.phpt" role="test" />
<file md5sum="a0b869caad05b5965cce7cf826904f3c" name="tests/manager/manager-executeReadCommand-002.phpt" role="test" />
<file md5sum="5c93e515f5a14d09fc062d959d105b08" name="tests/manager/manager-executeReadCommand-003.phpt" role="test" />
<file md5sum="10bf137557e0d4db82110694c981d5c6" name="tests/manager/manager-executeReadCommand_error-001.phpt" role="test" />
<file md5sum="4764835d6787201f3457712cf4282f04" name="tests/manager/manager-executeReadWriteCommand-001.phpt" role="test" />
<file md5sum="c813dd43cd5321f0af87763f6b1d9b80" name="tests/manager/manager-executeReadWriteCommand-002.phpt" role="test" />
<file md5sum="4969e1c51e63c5de7dae2228323f51d2" name="tests/manager/manager-executeReadWriteCommand-003.phpt" role="test" />
<file md5sum="7c1a531a50d4abdda38e30aecb95cb28" name="tests/manager/manager-executeReadWriteCommand_error-001.phpt" role="test" />
<file md5sum="c9399ff2f0afba6d4f6eddeef157a0d2" name="tests/manager/manager-executeReadWriteCommand_error-002.phpt" role="test" />
<file md5sum="60e8d449b9e05e92f7bd388728a49fa3" name="tests/manager/manager-executeWriteCommand-001.phpt" role="test" />
<file md5sum="1ad68515d769c576adedc214870fec71" name="tests/manager/manager-executeWriteCommand-002.phpt" role="test" />
<file md5sum="caa13ad0a35b45393296fee760c8624e" name="tests/manager/manager-executeWriteCommand-003.phpt" role="test" />
<file md5sum="3ae03d1aff8ebbc34f63713fc61a3871" name="tests/manager/manager-executeWriteCommand_error-001.phpt" role="test" />
<file md5sum="d0786f10e106a21127d5fffdaac12d90" name="tests/manager/manager-executeWriteCommand_error-002.phpt" role="test" />
<file md5sum="3552239623dd45961c879ac52a69ec17" name="tests/manager/manager-executeWriteCommand_error-003.phpt" role="test" />
<file md5sum="209ae7fa335c75ccbd98deed9d4719f7" name="tests/manager/manager-executeWriteCommand_error-004.phpt" role="test" />
+ <file md5sum="5875642929f298e3a02c719869fa392b" name="tests/manager/manager-getencryptedfieldsmap-001.phpt" role="test" />
<file md5sum="0c869cc5b61b1891fb9860b5c631797f" name="tests/manager/manager-getreadconcern-001.phpt" role="test" />
<file md5sum="f01ca8d5ec0497d3c83c20fbfbd78df9" name="tests/manager/manager-getreadpreference-001.phpt" role="test" />
<file md5sum="03b5f6a61ced57942d19e3179196e2f3" name="tests/manager/manager-getservers-001.phpt" role="test" />
<file md5sum="ecd5cca20434921ed49475e5bf0a9264" name="tests/manager/manager-getservers-002.phpt" role="test" />
<file md5sum="5cb96f5b8c994e360692ef80b430085d" name="tests/manager/manager-getwriteconcern-001.phpt" role="test" />
<file md5sum="56dac5c4a4ee50a9c4fd1d8d818bf61a" name="tests/manager/manager-invalidnamespace.phpt" role="test" />
<file md5sum="7611f59a99a3162f15f8b284b87018ca" name="tests/manager/manager-removeSubscriber-001.phpt" role="test" />
<file md5sum="97919b0457d262d662abe995a9a07f1e" name="tests/manager/manager-removeSubscriber-002.phpt" role="test" />
<file md5sum="59cf29ecacb6f5d625af2b0f72a65445" name="tests/manager/manager-selectServer-001.phpt" role="test" />
<file md5sum="2041bf47ba3d52885998335f0fa3f103" name="tests/manager/manager-selectServer-002.phpt" role="test" />
<file md5sum="afb93c16286dc405a8eca6d0e6c52aef" name="tests/manager/manager-selectserver_error-001.phpt" role="test" />
<file md5sum="8e039926e7293962b4b2fbe1f4b4b02b" name="tests/manager/manager-set-uri-options-001.phpt" role="test" />
<file md5sum="4da747c692390c6ea147ecb6e09f5bd8" name="tests/manager/manager-set-uri-options-002.phpt" role="test" />
<file md5sum="1845b7c3854d5664f89e56717b122139" name="tests/manager/manager-set-uri-options-003.phpt" role="test" />
<file md5sum="78e7c65e46fb7e80e2e6bba7663636bb" name="tests/manager/manager-startSession_error-001.phpt" role="test" />
<file md5sum="e7e0836d2bfd71c6f2d8f89a7705ad27" name="tests/manager/manager-startSession_error-002.phpt" role="test" />
<file md5sum="da2ad1d3d56ad8751c548c3790b56841" name="tests/manager/manager-var-dump-001.phpt" role="test" />
<file md5sum="4866b19eb11b9ad4a9afc8ecb16dee9e" name="tests/manager/manager-wakeup.phpt" role="test" />
<file md5sum="9fbed7bd60817812ebb3ad0c1554082c" name="tests/manager/manager_error-001.phpt" role="test" />
<file md5sum="2dd9863434c753dd55242243d48091c9" name="tests/query/bug0430-001.phpt" role="test" />
<file md5sum="6cfbe0ca5de33e4402bf779a44d64b4e" name="tests/query/bug0430-002.phpt" role="test" />
<file md5sum="6004d177d8ffc04a0a295eb824697e4a" name="tests/query/bug0430-003.phpt" role="test" />
<file md5sum="1cb4b1ce61547c8a149732444808d884" name="tests/query/query-ctor-001.phpt" role="test" />
<file md5sum="1cf3ecf0a05cc2c305042b47e712e351" name="tests/query/query-ctor-002.phpt" role="test" />
<file md5sum="739343c4dd6b03ab5c3dfec995fe6bff" name="tests/query/query-ctor-003.phpt" role="test" />
<file md5sum="c78b0601cac5a186e6e7c386f89ee4ef" name="tests/query/query-ctor-004.phpt" role="test" />
<file md5sum="71f1fa84dbf281b67d942863248f7e31" name="tests/query/query-ctor-005.phpt" role="test" />
<file md5sum="64bda823995da00efceed4b07627f18f" name="tests/query/query-ctor-006.phpt" role="test" />
+ <file md5sum="3c80409b2b9bd22dffa3d8ffc716b01d" name="tests/query/query-ctor-comment-001.phpt" role="test" />
+ <file md5sum="0d4485fc0aa31d268bc2baa5686b9242" name="tests/query/query-ctor-comment_error-001.phpt" role="test" />
+ <file md5sum="5078962036b85de42c714bb9675d1338" name="tests/query/query-ctor-let-001.phpt" role="test" />
+ <file md5sum="b0586fe9f2f19e047ec79f71b615dd18" name="tests/query/query-ctor-let_error-001.phpt" role="test" />
<file md5sum="a8feb530a36c277f0c0e29bb9972f88c" name="tests/query/query-ctor_error-001.phpt" role="test" />
- <file md5sum="5becf772e73317d13feb71669b09ca74" name="tests/query/query-ctor_error-002.phpt" role="test" />
+ <file md5sum="295a7bf781144a1b151f18c2cd7d8633" name="tests/query/query-ctor_error-002.phpt" role="test" />
<file md5sum="2ac2f168d04925cff53e63ec1454ea95" name="tests/query/query-ctor_error-003.phpt" role="test" />
<file md5sum="cd5bf5c6f72e4e1edb89a2fc560a3900" name="tests/query/query-ctor_error-004.phpt" role="test" />
<file md5sum="d535216394d0c494d16c1b3314a9a84c" name="tests/query/query-ctor_error-005.phpt" role="test" />
<file md5sum="771c2de819fa84ec3f8d89336beb1e14" name="tests/query/query-ctor_error-006.phpt" role="test" />
<file md5sum="8cf658f5cd18c7b5fc9b71e668699910" name="tests/query/query-debug-001.phpt" role="test" />
+ <file md5sum="57f3ca7bf3cfc8f4891162117e0e43ee" name="tests/query/query-debug-002.phpt" role="test" />
+ <file md5sum="89aa0ffb2fb2c78383b8936cff504061" name="tests/query/query-debug-003.phpt" role="test" />
<file md5sum="872a288691976f48f0f5c0b03e5cd2ed" name="tests/query/query_error-001.phpt" role="test" />
<file md5sum="a235c15b6d12006dd86cd3fc9d364abd" name="tests/readConcern/bug1598-001.phpt" role="test" />
<file md5sum="5b87f36784f6bfaf2d80fd5cd79c4571" name="tests/readConcern/bug1598-002.phpt" role="test" />
<file md5sum="f1fbd66fd9c60d9285188b66d445db7f" name="tests/readConcern/readconcern-bsonserialize-001.phpt" role="test" />
<file md5sum="39158d99f0278d6471a58bac33619583" name="tests/readConcern/readconcern-bsonserialize-002.phpt" role="test" />
<file md5sum="d964c2eae3f1a7ec5daf4296a9429e0c" name="tests/readConcern/readconcern-constants.phpt" role="test" />
<file md5sum="673f3d6d7729381139502491fd69dda4" name="tests/readConcern/readconcern-ctor-001.phpt" role="test" />
<file md5sum="c1f4a3040b96c582e164b9d6aa50e12c" name="tests/readConcern/readconcern-ctor_error-001.phpt" role="test" />
<file md5sum="a745c3afbb8fe5d09d7207d0d0b4934d" name="tests/readConcern/readconcern-ctor_error-002.phpt" role="test" />
<file md5sum="d0389718048d152dd41da2168e340354" name="tests/readConcern/readconcern-debug-001.phpt" role="test" />
<file md5sum="c6ecab3439c2b4249bedd2c6dc299dcf" name="tests/readConcern/readconcern-getlevel-001.phpt" role="test" />
<file md5sum="7bc12b0529eef007f25068e8a410d755" name="tests/readConcern/readconcern-isdefault-001.phpt" role="test" />
<file md5sum="5de358d3debd897a124379358f7a5e0b" name="tests/readConcern/readconcern-serialization-001.phpt" role="test" />
<file md5sum="9fa914142b00f41ba75dd34ffdabc917" name="tests/readConcern/readconcern-serialization-002.phpt" role="test" />
<file md5sum="d8d54e56154f941e7459801886d77c32" name="tests/readConcern/readconcern-serialization_error-001.phpt" role="test" />
<file md5sum="9eac2093a5a8d08fb4bccb9c7aee98c6" name="tests/readConcern/readconcern-serialization_error-002.phpt" role="test" />
<file md5sum="d2fa9df1d03888e6b7d56e076730d645" name="tests/readConcern/readconcern-set_state-001.phpt" role="test" />
<file md5sum="324870d2b3da8a4730a2684ffb878724" name="tests/readConcern/readconcern-set_state_error-001.phpt" role="test" />
<file md5sum="8fff1e579d6d65883c570d0d1deafa5a" name="tests/readConcern/readconcern-var_export-001.phpt" role="test" />
<file md5sum="626fe59437a671f6c480e6a813dcf777" name="tests/readConcern/readconcern_error-001.phpt" role="test" />
<file md5sum="a80a89eb47df461d92dddac847792979" name="tests/readPreference/bug0146-001.phpt" role="test" />
<file md5sum="5bbbd73884d0d64989109201e7e1bf3f" name="tests/readPreference/bug0851-001.phpt" role="test" />
<file md5sum="bdc1634fe23391ae15928e87da27e5dc" name="tests/readPreference/bug1598-001.phpt" role="test" />
<file md5sum="fd65990a31032d72fd2a97e4d9425ea4" name="tests/readPreference/bug1598-002.phpt" role="test" />
<file md5sum="20d09af75e7eb7eda7844ad5bb0de8e4" name="tests/readPreference/bug1698-001.phpt" role="test" />
<file md5sum="4306e546d698e0aab6805c3f6132ca91" name="tests/readPreference/readpreference-bsonserialize-001.phpt" role="test" />
<file md5sum="b46b5fd1a651f731ffcb052491b75afc" name="tests/readPreference/readpreference-bsonserialize-002.phpt" role="test" />
<file md5sum="961998132bc79161663699fd64b369b2" name="tests/readPreference/readpreference-constants.phpt" role="test" />
<file md5sum="d8641784d6b9e66b8b44dfaa0328abd6" name="tests/readPreference/readpreference-ctor-001.phpt" role="test" />
<file md5sum="221ff341be838431d0b6aa95e1680e16" name="tests/readPreference/readpreference-ctor-002.phpt" role="test" />
<file md5sum="956253c23bd1901c67ae7268dd48cdc7" name="tests/readPreference/readpreference-ctor_error-001.phpt" role="test" />
<file md5sum="8de3ed037e390f8098ddf490b29e2efb" name="tests/readPreference/readpreference-ctor_error-002.phpt" role="test" />
<file md5sum="c5078470f13c591d8c18afc7df2d70ed" name="tests/readPreference/readpreference-ctor_error-003.phpt" role="test" />
<file md5sum="a27b9291c564dddb16ac7483e57e25d2" name="tests/readPreference/readpreference-ctor_error-004.phpt" role="test" />
<file md5sum="18f7711b47781d30db39b6bd166edf57" name="tests/readPreference/readpreference-ctor_error-005.phpt" role="test" />
<file md5sum="f0b9407f58356bb69079e1f9a43624d4" name="tests/readPreference/readpreference-ctor_error-006.phpt" role="test" />
<file md5sum="54296349ca6f684ae2b562b20b42b5c3" name="tests/readPreference/readpreference-ctor_error-007.phpt" role="test" />
<file md5sum="a77bcca3541615a47d80c3704075cb58" name="tests/readPreference/readpreference-debug-001.phpt" role="test" />
<file md5sum="1c1e56ded53731dba637bb13d90a1a55" name="tests/readPreference/readpreference-getHedge-001.phpt" role="test" />
<file md5sum="aa4a310fc1d92319cd41f84838974a65" name="tests/readPreference/readpreference-getMaxStalenessMS-001.phpt" role="test" />
<file md5sum="917131aadbd26697fbc3ac5923fa46bf" name="tests/readPreference/readpreference-getMaxStalenessMS-002.phpt" role="test" />
<file md5sum="2300bc05051a0d0dc183ebe1d699190a" name="tests/readPreference/readpreference-getMode-001.phpt" role="test" />
<file md5sum="8114a801f07aafd9330c9143bb02672a" name="tests/readPreference/readpreference-getModeString-001.phpt" role="test" />
<file md5sum="2a58ca560ca933e763397fdecd6e1c22" name="tests/readPreference/readpreference-getTagSets-001.phpt" role="test" />
<file md5sum="74a95fd229d950e7116b5ff0fd78db56" name="tests/readPreference/readpreference-getTagSets-002.phpt" role="test" />
<file md5sum="5c062e9eb9ece5c8967d62178c0d6a04" name="tests/readPreference/readpreference-serialization-001.phpt" role="test" />
<file md5sum="b5394883c72067d2a5772f44c9b1a5eb" name="tests/readPreference/readpreference-serialization-002.phpt" role="test" />
<file md5sum="ba5157287a7a47945c70c95f3ceb7f4a" name="tests/readPreference/readpreference-serialization_error-001.phpt" role="test" />
<file md5sum="85301553f88548b69ced7b3cdfb51853" name="tests/readPreference/readpreference-serialization_error-002.phpt" role="test" />
<file md5sum="e0af4202d10db8f83c89490880038d93" name="tests/readPreference/readpreference-set_state-001.phpt" role="test" />
<file md5sum="b03909a4a689849dc38bcac0dfa3291f" name="tests/readPreference/readpreference-set_state_error-001.phpt" role="test" />
<file md5sum="862edb823e451326954908c96fa3337d" name="tests/readPreference/readpreference-set_state_error-002.phpt" role="test" />
<file md5sum="429144cec33308148cf1025b9dd65c3d" name="tests/readPreference/readpreference-var_export-001.phpt" role="test" />
<file md5sum="b2df8c5d8346e04359efa29eaab86f3c" name="tests/readPreference/readpreference_error-001.phpt" role="test" />
<file md5sum="7b9704e8f22a7f21c6bea50af2fdc2c1" name="tests/replicaset/bug0155.phpt" role="test" />
<file md5sum="10bda8d50276bcea0dc8ab4e1b0e07fa" name="tests/replicaset/bug0898-001.phpt" role="test" />
<file md5sum="3055fdc9202aedd4e2ed6c49dd0343c4" name="tests/replicaset/bug0898-002.phpt" role="test" />
<file md5sum="044c6ba1198a0424e3fff63672ed47cf" name="tests/replicaset/manager-selectserver-001.phpt" role="test" />
<file md5sum="2d4284bfa26035c5dd491f19b1bebd29" name="tests/replicaset/readconcern-001.phpt" role="test" />
<file md5sum="a1de1b9494b169e78f99a1f39c1fd398" name="tests/replicaset/writeconcernerror-001.phpt" role="test" />
<file md5sum="0e20788b5f4f6622a2b31818a02fa654" name="tests/replicaset/writeconcernerror-002.phpt" role="test" />
<file md5sum="42e2d59aa909b6596f4ccb42f7e0b766" name="tests/replicaset/writeresult-getserver-001.phpt" role="test" />
<file md5sum="4061e3b29126ff0b33bc2c801832f015" name="tests/replicaset/writeresult-getserver-002.phpt" role="test" />
<file md5sum="ac1b65aa5b5c0456805a416a786d3853" name="tests/retryable-reads/retryable-reads-001.phpt" role="test" />
<file md5sum="d8ce7be28b1ab665c10d8bb8820b05c6" name="tests/retryable-reads/retryable-reads-002.phpt" role="test" />
<file md5sum="14de621ed64577f72173b257b87bacc8" name="tests/retryable-reads/retryable-reads_error-001.phpt" role="test" />
<file md5sum="8bdd3d167752e7fd68781f2b6d2b22a2" name="tests/retryable-reads/retryable-reads_error-002.phpt" role="test" />
<file md5sum="b86269868a56f8e9417de735ab85f336" name="tests/retryable-writes/retryable-writes-001.phpt" role="test" />
<file md5sum="7b8a14e05f8c3913e83ce9ce2bf77602" name="tests/retryable-writes/retryable-writes-002.phpt" role="test" />
<file md5sum="3f010d40a6d741b594f4f9cb238fd264" name="tests/retryable-writes/retryable-writes-003.phpt" role="test" />
<file md5sum="716542a9bed46b7c70259b160b58fb02" name="tests/retryable-writes/retryable-writes-004.phpt" role="test" />
<file md5sum="2ac8fa15762869e31b47b743b346a18d" name="tests/retryable-writes/retryable-writes-005.phpt" role="test" />
<file md5sum="f73fcc5beca298ed93cfbb920be52a51" name="tests/retryable-writes/retryable-writes_error-001.phpt" role="test" />
<file md5sum="04e696099a0d8845402c7a388e98e1aa" name="tests/server/bug0671-002.phpt" role="test" />
<file md5sum="48b01991b47cc25751a6cf7796aeddaf" name="tests/server/server-constants.phpt" role="test" />
<file md5sum="118b30ef453ec6253600d76cdd450803" name="tests/server/server-construct-001.phpt" role="test" />
<file md5sum="b3317c5a9c1822a706abd8380ad39b96" name="tests/server/server-debug.phpt" role="test" />
<file md5sum="7b1c205df7700100ddd510fe1c02bfa6" name="tests/server/server-errors.phpt" role="test" />
<file md5sum="a3c68c2927886b94de39b084c8fbc4d8" name="tests/server/server-executeBulkWrite-001.phpt" role="test" />
<file md5sum="4011b0e8fc004882a109ab4a38b578e1" name="tests/server/server-executeBulkWrite-002.phpt" role="test" />
<file md5sum="e2cee1b0a112c818cdcaeca6090f04f6" name="tests/server/server-executeBulkWrite-003.phpt" role="test" />
<file md5sum="29a12e54466a36faaa535f04bd5e92de" name="tests/server/server-executeBulkWrite-004.phpt" role="test" />
<file md5sum="e07a73cf6359944cbfa0447604577158" name="tests/server/server-executeBulkWrite-005.phpt" role="test" />
<file md5sum="43fe553e0a8c0d6bf7d3c9b88903490a" name="tests/server/server-executeBulkWrite-006.phpt" role="test" />
<file md5sum="0a6b753ae3c4c7ac989abd4e3639fdfe" name="tests/server/server-executeBulkWrite-007.phpt" role="test" />
<file md5sum="8febec6c2f0d437d0ec29caf8a1bda06" name="tests/server/server-executeBulkWrite-008.phpt" role="test" />
<file md5sum="8e8c4e7c00f1db9cc303003d29b95693" name="tests/server/server-executeBulkWrite-009.phpt" role="test" />
<file md5sum="cc438e01de7f07dc121dcd437db0bf21" name="tests/server/server-executeBulkWrite_error-001.phpt" role="test" />
<file md5sum="d26c83bab1f51da481f749441588a788" name="tests/server/server-executeBulkWrite_error-002.phpt" role="test" />
<file md5sum="c6b762d00285a92cb2ca9d5582bb78fc" name="tests/server/server-executeCommand-001.phpt" role="test" />
<file md5sum="d3106f7b4c539fcb68943b81ae359a14" name="tests/server/server-executeCommand-002.phpt" role="test" />
<file md5sum="e867fd6de4d48341eb04052d8c3abe6c" name="tests/server/server-executeCommand-003.phpt" role="test" />
<file md5sum="3a3566ebf6c370cd3dd90006b5704622" name="tests/server/server-executeCommand-004.phpt" role="test" />
<file md5sum="323185711766653ac8feec208bfb5290" name="tests/server/server-executeCommand-005.phpt" role="test" />
<file md5sum="2a25e3913470653deaa12187b4cc3130" name="tests/server/server-executeCommand-006.phpt" role="test" />
<file md5sum="b1a79ead9ea13c33b6cf3c88ea3a63a9" name="tests/server/server-executeCommand-007.phpt" role="test" />
<file md5sum="b57c30db64e71a0394be9894434c0391" name="tests/server/server-executeCommand-008.phpt" role="test" />
<file md5sum="34ba337b799b4d9ac1f6de03ee8c4847" name="tests/server/server-executeCommand-009.phpt" role="test" />
<file md5sum="cb2851e0b80b29bec23b3d87244f6fb5" name="tests/server/server-executeCommand-010.phpt" role="test" />
<file md5sum="ea1e0ec450e478317d828026c3e86f80" name="tests/server/server-executeCommand_error-001.phpt" role="test" />
<file md5sum="0fba40ada9f345ba296a11e771a4fa28" name="tests/server/server-executeQuery-001.phpt" role="test" />
<file md5sum="7d6abfb7e95373573fbf6fa59e721734" name="tests/server/server-executeQuery-002.phpt" role="test" />
<file md5sum="4ecb73a09f7235029478726ec577be85" name="tests/server/server-executeQuery-003.phpt" role="test" />
<file md5sum="786fb95ad650d21a3738b31654d6db09" name="tests/server/server-executeQuery-004.phpt" role="test" />
<file md5sum="c5d8945fac786607c94d46310e17d17b" name="tests/server/server-executeQuery-006.phpt" role="test" />
<file md5sum="6963aebb29068bce72a8beea91e61cf8" name="tests/server/server-executeQuery-007.phpt" role="test" />
<file md5sum="7537ffc55664b14a250232fc0fd518c8" name="tests/server/server-executeQuery-008.phpt" role="test" />
<file md5sum="6500fb13222358652861ca10c4ce7146" name="tests/server/server-executeQuery-009.phpt" role="test" />
<file md5sum="8a38e31a280aa3fed36b36c3b0a8d931" name="tests/server/server-executeQuery-010.phpt" role="test" />
<file md5sum="6acd6ddda6ea8aa46921b3e5eed81c5e" name="tests/server/server-executeQuery-011.phpt" role="test" />
<file md5sum="56345d55c13ffde2693d42d1b23cdbf9" name="tests/server/server-executeQuery-012.phpt" role="test" />
<file md5sum="b82554034b4271053bbe208858cda081" name="tests/server/server-executeQuery-013.phpt" role="test" />
<file md5sum="eb481ae7199a421ce81145f4d0c006ea" name="tests/server/server-executeQuery_error-001.phpt" role="test" />
<file md5sum="91eb77d6bff81a929cbb1d55bd90101a" name="tests/server/server-executeReadCommand-001.phpt" role="test" />
<file md5sum="8b6fc02521a1901f05e353370e7f8ee5" name="tests/server/server-executeReadCommand-002.phpt" role="test" />
<file md5sum="8fc7bcc947d50d6fccf64fdb34b01e5d" name="tests/server/server-executeReadCommand-003.phpt" role="test" />
<file md5sum="f57782a263590833f8c5bd5a58f30f17" name="tests/server/server-executeReadCommand_error-001.phpt" role="test" />
<file md5sum="62ca987f8a6a03cdc25e0fc0bb28525e" name="tests/server/server-executeReadWriteCommand-001.phpt" role="test" />
<file md5sum="d1fe71cee62f9491a73b09551840825c" name="tests/server/server-executeReadWriteCommand-002.phpt" role="test" />
<file md5sum="b6350951e4aeb9270d940b551cf5145e" name="tests/server/server-executeReadWriteCommand-003.phpt" role="test" />
<file md5sum="16db14f702d8d12e9e457e4fbe889a60" name="tests/server/server-executeReadWriteCommand_error-001.phpt" role="test" />
<file md5sum="1c54f99b3627a37c0f36be8eff4cb025" name="tests/server/server-executeWriteCommand-001.phpt" role="test" />
<file md5sum="97b1c9cf42fbf431702c78183c6571db" name="tests/server/server-executeWriteCommand-002.phpt" role="test" />
<file md5sum="2f93789872e1453422986a2ed7052f26" name="tests/server/server-executeWriteCommand-003.phpt" role="test" />
<file md5sum="ac22aefe6d4f07faa75c8a0b938bfc78" name="tests/server/server-executeWriteCommand_error-001.phpt" role="test" />
<file md5sum="6daab74c8cc8188626f6659df04c30a2" name="tests/server/server-getInfo-001.phpt" role="test" />
<file md5sum="a0c7cbf92555d8c8a961edbfdac92685" name="tests/server/server-getLatency-001.phpt" role="test" />
<file md5sum="d48bdb590104928b42ace95b62f7ed0a" name="tests/server/server-getLatency-002.phpt" role="test" />
<file md5sum="53d08da4a63f4b403a592c0c4b29526a" name="tests/server/server-getServerDescription-001.phpt" role="test" />
<file md5sum="8c836609ad6a434770df70781ff73dfa" name="tests/server/server-getTags-001.phpt" role="test" />
<file md5sum="93d1818b704c415bb309c58044b299c4" name="tests/server/server-getTags-002.phpt" role="test" />
<file md5sum="eed3333d1956c2ec13d99ad095c5e91c" name="tests/server/server_error-001.phpt" role="test" />
<file md5sum="47317cff71d468ebe61d741d71a2e499" name="tests/serverApi/serverApi-bsonserialize-001.phpt" role="test" />
<file md5sum="afde498a7cdeae0f161a7b130f1c4d8c" name="tests/serverApi/serverApi-bsonserialize-002.phpt" role="test" />
<file md5sum="a2392cc37aa1d30469140b791cc8ed84" name="tests/serverApi/serverApi-construct-001.phpt" role="test" />
<file md5sum="abf58c35668375559c6268ae126efe6d" name="tests/serverApi/serverApi-debug.phpt" role="test" />
<file md5sum="bdb265aef44a27c94c0cf12cde912ad9" name="tests/serverApi/serverApi-serialization-001.phpt" role="test" />
<file md5sum="75592b40a340f12455f9c8e3c0fa3721" name="tests/serverApi/serverApi-serialization-002.phpt" role="test" />
<file md5sum="2a910b096a80f610866743257752fd87" name="tests/serverApi/serverApi-serialization_error-001.phpt" role="test" />
<file md5sum="68e6b4f290def40b8c9821ac19faf65e" name="tests/serverApi/serverApi-serialization_error-002.phpt" role="test" />
<file md5sum="7a06c82daaaf45e17dc0cc29a0332331" name="tests/serverApi/serverApi-set_state-001.phpt" role="test" />
<file md5sum="8e58f2fb54c09f56da57773a188a1c73" name="tests/serverApi/serverApi-set_state_error-001.phpt" role="test" />
<file md5sum="ee3d952d72cb7109d370d125e280c609" name="tests/serverApi/serverApi-var_export-001.phpt" role="test" />
<file md5sum="ee1b9429abdc682a0dab5810d5065a49" name="tests/serverDescription/serverDescription-constants.phpt" role="test" />
<file md5sum="0720df3be175bba730376d3dfcc562e0" name="tests/serverDescription/serverDescription-debug-001.phpt" role="test" />
<file md5sum="ee5fcc26ac6494d62d213df062118079" name="tests/serverDescription/serverDescription-getHelloResponse-001.phpt" role="test" />
<file md5sum="85a5f91600730b9909cebef3263269fe" name="tests/serverDescription/serverDescription-getHost-001.phpt" role="test" />
<file md5sum="6260e17daf2ed937773a019b560c0628" name="tests/serverDescription/serverDescription-getLastUpdateTime-001.phpt" role="test" />
<file md5sum="ee367002592bead6eb0f38a96d59fc17" name="tests/serverDescription/serverDescription-getLastUpdateTime-002.phpt" role="test" />
<file md5sum="6da7822ec082fd74c42095dbf0c705ac" name="tests/serverDescription/serverDescription-getPort-001.phpt" role="test" />
<file md5sum="07a5cf52ad8e035fc2ca6e0ed4e08654" name="tests/serverDescription/serverDescription-getRoundTripTime-001.phpt" role="test" />
<file md5sum="00fa91c208967234609f1c70f51b8f4b" name="tests/serverDescription/serverDescription-getType-001.phpt" role="test" />
<file md5sum="5ca27edd77b32610b16217a1115a1cf8" name="tests/serverDescription/serverDescription-var_export-001.phpt" role="test" />
<file md5sum="88d6b70b08d0499be1df22f03ffe33fd" name="tests/session/bug1274-001.phpt" role="test" />
<file md5sum="f033ecdb9f9e8b47690540bec04c6a35" name="tests/session/bug1274-002.phpt" role="test" />
<file md5sum="0bfd943e10668b0cadc1356fd6064f73" name="tests/session/bug1274-003.phpt" role="test" />
<file md5sum="77e7a7474ad07ab60895238d17dab331" name="tests/session/bug1274-004.phpt" role="test" />
<file md5sum="e71c67dd24c0f8fd77c6920cc11f6122" name="tests/session/bug1274-005.phpt" role="test" />
<file md5sum="775888594331e6b95ff5e15b91a8108e" name="tests/session/bug1274-006.phpt" role="test" />
<file md5sum="896e2c257f1ff67f40decad2eae240f1" name="tests/session/session-001.phpt" role="test" />
<file md5sum="d9c39708e7b704bff2d55e04dc289623" name="tests/session/session-002.phpt" role="test" />
<file md5sum="bacf01b37692d00170fa99fdf9740b78" name="tests/session/session-003.phpt" role="test" />
<file md5sum="50d18fb03e0c133f58a48ac0567cce0b" name="tests/session/session-004.phpt" role="test" />
<file md5sum="55028dc0255b302ea1e48b70d9c84633" name="tests/session/session-005.phpt" role="test" />
<file md5sum="a1534efa6e4be70889ce4e3cdd5bfeb4" name="tests/session/session-advanceClusterTime-001.phpt" role="test" />
<file md5sum="1f64cf2fc890b0cddf04b0a0694fd2c2" name="tests/session/session-advanceOperationTime-001.phpt" role="test" />
<file md5sum="35cc4f4df8c4f6823d639be1e1d3f5d0" name="tests/session/session-advanceOperationTime-002.phpt" role="test" />
<file md5sum="6f76a36f7de08f9d8928b425ca388223" name="tests/session/session-advanceOperationTime-003.phpt" role="test" />
<file md5sum="5dc2a52220fb2e0147197a20dbe80e34" name="tests/session/session-advanceOperationTime_error-001.phpt" role="test" />
<file md5sum="9d6bd97bb6d06b11ffbee3897619fbf4" name="tests/session/session-commitTransaction-001.phpt" role="test" />
<file md5sum="ae4075d8629d54ce74448dc56562af31" name="tests/session/session-constants.phpt" role="test" />
<file md5sum="364e7846648fa0d2442d8a787b89f5bc" name="tests/session/session-debug-001.phpt" role="test" />
<file md5sum="bb1f735378f1e0cb8abb4bea4438e5c3" name="tests/session/session-debug-002.phpt" role="test" />
<file md5sum="24417c11eedcf8ce4f777201a249a807" name="tests/session/session-debug-003.phpt" role="test" />
<file md5sum="b8428d2436e019d424a16f1e64ae8fe5" name="tests/session/session-debug-004.phpt" role="test" />
<file md5sum="ae285b35b2f4f0a2c615611ffab7fdbb" name="tests/session/session-debug-005.phpt" role="test" />
<file md5sum="64fbca8cff0dfd7fc2d000578de4d48a" name="tests/session/session-debug-006.phpt" role="test" />
<file md5sum="ba684bae99a0d29fd195dc20a97cd621" name="tests/session/session-debug-007.phpt" role="test" />
<file md5sum="007301127176ed86d3717a4a120fcabf" name="tests/session/session-endSession-001.phpt" role="test" />
<file md5sum="be157fd514c0e54b02ddd0d001e9b733" name="tests/session/session-endSession-002.phpt" role="test" />
<file md5sum="047663a229a1398ddf09580af0b1065f" name="tests/session/session-getClusterTime-001.phpt" role="test" />
<file md5sum="dd1b4d449e49ff4ad12b7dcae787a045" name="tests/session/session-getLogicalSessionId-001.phpt" role="test" />
<file md5sum="c7731b7bb01087a5a302e193d4d4de04" name="tests/session/session-getOperationTime-001.phpt" role="test" />
<file md5sum="4f144ae06868c02faddbeaf7a3c99a85" name="tests/session/session-getTransactionOptions-001.phpt" role="test" />
<file md5sum="d8861674e657c7f538bfec79587d8daa" name="tests/session/session-getTransactionState-001.phpt" role="test" />
<file md5sum="98249ded70f51f54fb0dc937ac016c8c" name="tests/session/session-isDirty-001.phpt" role="test" />
<file md5sum="79abf68b491c002b36c67b1485dcea20" name="tests/session/session-isInTransaction-001.phpt" role="test" />
<file md5sum="d2e85244ca1595ea1aea216ce74cb3b0" name="tests/session/session-startTransaction-001.phpt" role="test" />
<file md5sum="66b3d2185152fed858c46a333cf7cfb4" name="tests/session/session-startTransaction_error-001.phpt" role="test" />
<file md5sum="1038a9b5241b4813d8e96c0faa6077f6" name="tests/session/session-startTransaction_error-002.phpt" role="test" />
<file md5sum="527836016953f63af235bcf561df0b14" name="tests/session/session-startTransaction_error-004.phpt" role="test" />
<file md5sum="42b86984fefc51b3d42b108fde6ab12e" name="tests/session/session-startTransaction_error-005.phpt" role="test" />
<file md5sum="b8c07f225df0eae46ed4d8a33916327d" name="tests/session/session-startTransaction_error-006.phpt" role="test" />
<file md5sum="ab46db00e6f8fb756a7f98309033472f" name="tests/session/session-startTransaction_error-007.phpt" role="test" />
<file md5sum="cf9cb4bd8e63acaad16ffb6a1b3cf4e1" name="tests/session/transaction-integration-001.phpt" role="test" />
<file md5sum="0e8b366aa9781103bb1fc37fc685b9ab" name="tests/session/transaction-integration-002.phpt" role="test" />
<file md5sum="c0a958f2da4e0e64e946b2d21a391475" name="tests/session/transaction-integration-003.phpt" role="test" />
<file md5sum="2205a55501e7d1b51873749f6f73380b" name="tests/session/transaction-integration_error-001.phpt" role="test" />
<file md5sum="8f80677316e350aa0f839263120d32df" name="tests/session/transaction-integration_error-002.phpt" role="test" />
<file md5sum="005c410b5eae4853c8181e9da9dfe9d9" name="tests/session/transaction-integration_error-003.phpt" role="test" />
<file md5sum="8d57f720d8c54d0a09ed8dd5c3b57998" name="tests/session/transaction-integration_error-004.phpt" role="test" />
<file md5sum="8dd43ac797e59ffd3386b81f97f63795" name="tests/standalone/bug0166.phpt" role="test" />
<file md5sum="f8500fd70f234db2c5b176de9768fc18" name="tests/standalone/bug0231.phpt" role="test" />
<file md5sum="d3780db83fa5dd757b2fa14e6e8cee69" name="tests/standalone/bug0357.phpt" role="test" />
<file md5sum="a52e716f71c0399292a9ce6086279e26" name="tests/standalone/bug0545.phpt" role="test" />
<file md5sum="7ec0be606371d41790ba43b1de8fc308" name="tests/standalone/bug0655.phpt" role="test" />
<file md5sum="ec3c0bb4e15c9c29e46f84c4b0189794" name="tests/standalone/command-aggregate-001.phpt" role="test" />
<file md5sum="545faf9d019b2c579f0cebc65e78927a" name="tests/standalone/connectiontimeoutexception-001.phpt" role="test" />
<file md5sum="514f314c056df7faec52e42ba5f20dc9" name="tests/standalone/executiontimeoutexception-001.phpt" role="test" />
<file md5sum="4d78ffda28c4d6ec4201ad9c7311bd9d" name="tests/standalone/executiontimeoutexception-002.phpt" role="test" />
<file md5sum="859da0ba6f58581e57e0ae594c1244b0" name="tests/standalone/manager-as-singleton.phpt" role="test" />
<file md5sum="54dc16a86c37e04384e2c6454ef056b7" name="tests/standalone/query-errors.phpt" role="test" />
<file md5sum="bb25fc25c134935d184b9f5dff5a9a79" name="tests/standalone/update-multi-001.phpt" role="test" />
<file md5sum="4c04398fae3e97c595c2b2c6d48b5586" name="tests/standalone/write-error-001.phpt" role="test" />
<file md5sum="ca8f516beab9a92fd2b3c4dcbc45a6cb" name="tests/standalone/writeresult-isacknowledged-001.phpt" role="test" />
<file md5sum="4f4e56bd6416741285c1972bec97f3d2" name="tests/standalone/writeresult-isacknowledged-002.phpt" role="test" />
<file md5sum="07c512735db3b178e4ff36a431a75be2" name="tests/standalone/writeresult-isacknowledged-003.phpt" role="test" />
<file md5sum="3add3334968577e9622a91649d79c63a" name="tests/topologyDescription/topologyDescription-constants.phpt" role="test" />
<file md5sum="0f25ad220b80ad5aca349816149e7480" name="tests/topologyDescription/topologyDescription-debug-001.phpt" role="test" />
<file md5sum="e89dfd665169fbbe7ed036501d596257" name="tests/topologyDescription/topologyDescription-getServers-001.phpt" role="test" />
<file md5sum="291dfdadfdc642294374718279a2b036" name="tests/topologyDescription/topologyDescription-getType-001.phpt" role="test" />
<file md5sum="938f51370502bf9dee250c99d16b5bf3" name="tests/topologyDescription/topologyDescription-hasReadableServer-001.phpt" role="test" />
<file md5sum="ea94018ffe9dfd249fc47d3fc90ef1fc" name="tests/topologyDescription/topologyDescription-hasReadableServer-002.phpt" role="test" />
<file md5sum="a3a27c569f84e1b42affdf3276d8eddb" name="tests/topologyDescription/topologyDescription-hasReadableServer_error-001.phpt" role="test" />
<file md5sum="43e93f52f18c7a4150d64b7bfbbc12fb" name="tests/topologyDescription/topologyDescription-hasWritableServer-001.phpt" role="test" />
<file md5sum="59adebd29ef983f00c4d55cfc4b2d10d" name="tests/utils/PHONGO-FIXTURES.json.gz" role="test" />
<file md5sum="20bcdb186e464bebff08400730d55afd" name="tests/utils/basic-skipif.inc" role="test" />
- <file md5sum="97e5555e09949a5c3807a3d11dc3f0f0" name="tests/utils/basic.inc" role="test" />
+ <file md5sum="cd0ebccd5f078b9d597b68328b0ead1a" name="tests/utils/basic.inc" role="test" />
<file md5sum="d45f34ff6fd0f526099f3131d5d17b11" name="tests/utils/classes.inc" role="test" />
<file md5sum="4134acafdc5eb51800213b41043116ba" name="tests/utils/observer.php" role="test" />
- <file md5sum="ab4a44a9c4d270b02b7c68cf1cad873c" name="tests/utils/skipif.php" role="test" />
- <file md5sum="662bc4ba852dccb67ca53d2b4028deb7" name="tests/utils/tools.php" role="test" />
+ <file md5sum="1ef8faf5fd6b4bfb784d85a8031efbec" name="tests/utils/skipif.php" role="test" />
+ <file md5sum="d36c8822865e57fb3262be82919309cc" name="tests/utils/tools.php" role="test" />
<file md5sum="64ee8e2ef24e46d681df686739aa4e69" name="tests/writeConcern/bug1598-001.phpt" role="test" />
<file md5sum="2627d7f0df83428223b79249b0223243" name="tests/writeConcern/bug1598-002.phpt" role="test" />
<file md5sum="47c5356af82d44e77f1ed1a19dee9915" name="tests/writeConcern/writeconcern-bsonserialize-001.phpt" role="test" />
<file md5sum="073e73d11253900ad6d1e3e1b0656d20" name="tests/writeConcern/writeconcern-bsonserialize-002.phpt" role="test" />
<file md5sum="a02e1015d4bc797ff8a68613342f28c5" name="tests/writeConcern/writeconcern-bsonserialize-003.phpt" role="test" />
<file md5sum="64c7fb44e466938561d753546b82c22f" name="tests/writeConcern/writeconcern-bsonserialize-004.phpt" role="test" />
<file md5sum="08cc65bfe3d89314eca5a43616e12202" name="tests/writeConcern/writeconcern-constants.phpt" role="test" />
<file md5sum="3dbbdae846359bf00358aad47b0b7ae6" name="tests/writeConcern/writeconcern-ctor-001.phpt" role="test" />
<file md5sum="1f9f66d9446fa0f5ce954d88abe56e70" name="tests/writeConcern/writeconcern-ctor-002.phpt" role="test" />
<file md5sum="04b1a413620234518b86f7ce3d5c7be0" name="tests/writeConcern/writeconcern-ctor_error-001.phpt" role="test" />
<file md5sum="406313ae1d92e1e1f55eb223a4128012" name="tests/writeConcern/writeconcern-ctor_error-002.phpt" role="test" />
<file md5sum="727cc4fe9885dc11716446782384160f" name="tests/writeConcern/writeconcern-ctor_error-003.phpt" role="test" />
<file md5sum="be881f8e0077d593ce05110808600265" name="tests/writeConcern/writeconcern-ctor_error-004.phpt" role="test" />
<file md5sum="6ff4840ca262801e9e58c69253f45ae8" name="tests/writeConcern/writeconcern-ctor_error-005.phpt" role="test" />
<file md5sum="22dfaec3917fe798f71c15d857a36921" name="tests/writeConcern/writeconcern-debug-001.phpt" role="test" />
<file md5sum="56555f30c1e42233cb65ef12a0fb870b" name="tests/writeConcern/writeconcern-debug-002.phpt" role="test" />
<file md5sum="7feb66ce332c7b57016aa3f40e157480" name="tests/writeConcern/writeconcern-debug-003.phpt" role="test" />
<file md5sum="544bc7904161390cd99e1603b71eb0c6" name="tests/writeConcern/writeconcern-getjournal-001.phpt" role="test" />
<file md5sum="c64faac6dd9eeb55bb27b2d82acb7d86" name="tests/writeConcern/writeconcern-getw-001.phpt" role="test" />
<file md5sum="9ec2c850fc6202678ea402e96a56e530" name="tests/writeConcern/writeconcern-getwtimeout-001.phpt" role="test" />
<file md5sum="c63e6a803d425dd751247d43f24b3525" name="tests/writeConcern/writeconcern-getwtimeout-002.phpt" role="test" />
<file md5sum="7ac2556e20b9fda6524d291b695f9241" name="tests/writeConcern/writeconcern-isdefault-001.phpt" role="test" />
<file md5sum="fa9b7c79b76f3be41e38eb3268b90b4b" name="tests/writeConcern/writeconcern-serialization-001.phpt" role="test" />
<file md5sum="4e7ddcacb814ab0585f8a523530c722a" name="tests/writeConcern/writeconcern-serialization-002.phpt" role="test" />
<file md5sum="629db53508eb8c174e1113c8896dfb9d" name="tests/writeConcern/writeconcern-serialization_error-001.phpt" role="test" />
<file md5sum="745107ee996786aaa39efa12836ed56b" name="tests/writeConcern/writeconcern-serialization_error-002.phpt" role="test" />
<file md5sum="d114d86a919cd387a4f16d9c2f1308db" name="tests/writeConcern/writeconcern-set_state-001.phpt" role="test" />
<file md5sum="6866ee01eeb3334135ae6daf61f1463d" name="tests/writeConcern/writeconcern-set_state_error-001.phpt" role="test" />
<file md5sum="898c846d82ef5860cad45d52ff82e31c" name="tests/writeConcern/writeconcern-var_export-001.phpt" role="test" />
<file md5sum="17b4be0b8f641686cbfa42b324101697" name="tests/writeConcern/writeconcern_error-001.phpt" role="test" />
<file md5sum="430f003448f59e4f09350361df0d0a64" name="tests/writeConcernError/writeconcernerror-debug-001.phpt" role="test" />
<file md5sum="0207b3ca1ce7331ac9070db62dd5f975" name="tests/writeConcernError/writeconcernerror-getcode-001.phpt" role="test" />
<file md5sum="b7ddc77b7dfab4eea7ebf4f17f26a067" name="tests/writeConcernError/writeconcernerror-getinfo-001.phpt" role="test" />
<file md5sum="ec2da2427cf424b319c87857cdf9ad08" name="tests/writeConcernError/writeconcernerror-getmessage-001.phpt" role="test" />
<file md5sum="3aca836caa673a3a3f636679f5216839" name="tests/writeConcernError/writeconcernerror_error-001.phpt" role="test" />
<file md5sum="5e4dafe8f5dbe27f4628ad27c597d4b9" name="tests/writeError/writeerror-debug-001.phpt" role="test" />
<file md5sum="0bd364116e4769f2267bc4957eec4b26" name="tests/writeError/writeerror-getCode-001.phpt" role="test" />
<file md5sum="239052e89e6a23ff9ad83cb504e84115" name="tests/writeError/writeerror-getIndex-001.phpt" role="test" />
<file md5sum="b2a070ca4c4ecb4655b9e26a8b42d1bd" name="tests/writeError/writeerror-getInfo-001.phpt" role="test" />
<file md5sum="c838ad909ca5988e9f09ccea7387a1ff" name="tests/writeError/writeerror-getInfo-002.phpt" role="test" />
<file md5sum="8f029a6c06d58a0ba358b281589e3712" name="tests/writeError/writeerror-getMessage-001.phpt" role="test" />
<file md5sum="8c4a875920ce58be5d2b2bd54329f277" name="tests/writeError/writeerror_error-001.phpt" role="test" />
<file md5sum="b018cf23e251de1fbafba2e1afef0d85" name="tests/writeResult/bug0671-003.phpt" role="test" />
<file md5sum="c6837064d64637aed3931a7645db441d" name="tests/writeResult/writeresult-debug-001.phpt" role="test" />
<file md5sum="95dda8392be9692e9a40baa976b4641a" name="tests/writeResult/writeresult-debug-002.phpt" role="test" />
<file md5sum="528005c11553cf65c27292a21c846eed" name="tests/writeResult/writeresult-getdeletedcount-001.phpt" role="test" />
<file md5sum="48174d244bb948935bd9f2a6b6dab367" name="tests/writeResult/writeresult-getdeletedcount-002.phpt" role="test" />
<file md5sum="77194d0db2a6c41f1e449ccebf5bb8c3" name="tests/writeResult/writeresult-getinsertedcount-001.phpt" role="test" />
<file md5sum="4be749561c8ea4f2699ff8b6c200dc03" name="tests/writeResult/writeresult-getinsertedcount-002.phpt" role="test" />
<file md5sum="ba801c202cd4376858f2bb6cbf80dd2a" name="tests/writeResult/writeresult-getmatchedcount-001.phpt" role="test" />
<file md5sum="4d61dde1268b3b907cb81632f11d6094" name="tests/writeResult/writeresult-getmatchedcount-002.phpt" role="test" />
<file md5sum="5d5e9abd30c4abb7847c1de3419c28c7" name="tests/writeResult/writeresult-getmodifiedcount-001.phpt" role="test" />
<file md5sum="585bdc0f2a8ae1dcb53856cb14e37663" name="tests/writeResult/writeresult-getmodifiedcount-002.phpt" role="test" />
<file md5sum="d7048d2116d38c5e32fa1b81cfac1221" name="tests/writeResult/writeresult-getserver-001.phpt" role="test" />
<file md5sum="7713f25147d7307652fccf53314438b4" name="tests/writeResult/writeresult-getupsertedcount-001.phpt" role="test" />
<file md5sum="406ad88c641c58d3d155767d1bd5f33f" name="tests/writeResult/writeresult-getupsertedcount-002.phpt" role="test" />
<file md5sum="394e1ffea610e9132248ca78a99a4a34" name="tests/writeResult/writeresult-getupsertedids-001.phpt" role="test" />
<file md5sum="7c57183e3aee5d65e7c40313042ac91c" name="tests/writeResult/writeresult-getupsertedids-002.phpt" role="test" />
<file md5sum="3eb2168110c0d9eda93dab94d1f659d7" name="tests/writeResult/writeresult-getwriteconcernerror-001.phpt" role="test" />
<file md5sum="0d2bc8d0be8bd62a0a1c098aa342c936" name="tests/writeResult/writeresult-getwriteerrors-001.phpt" role="test" />
<file md5sum="6c58b57bc400142dc88ce373dacdc1f5" name="tests/writeResult/writeresult-getwriteerrors-002.phpt" role="test" />
<file md5sum="97f22e293b467de65fce989d9ee0f227" name="tests/writeResult/writeresult-isacknowledged-001.phpt" role="test" />
<file md5sum="089e1618e09d5e4ba4b79eb4c1f54ea3" name="tests/writeResult/writeresult_error-001.phpt" role="test" />
- <file md5sum="7803ac4d804109b882c4c8591405dd32" name="CONTRIBUTING.md" role="doc" />
+ <file md5sum="d5067526821192dbf0245ed98c1713c7" name="CONTRIBUTING.md" role="doc" />
<file md5sum="198d0ffaabbd88f77e9b9067b694ca10" name="CREDITS" role="doc" />
<file md5sum="b1e01b26bacfc2232046c90a330332b3" name="LICENSE" role="doc" />
<file md5sum="362fa5548c9527dac7da5d7c27d05444" name="Makefile.frag" role="src" />
<file md5sum="eda1e5a174576bf6e8d51d4293f41236" name="README.md" role="doc" />
<file md5sum="eadbe8ccffa540f5ac53ffc59e36a727" name="THIRD_PARTY_NOTICES" role="doc" />
<file md5sum="0962c850da28d6d16b471cc9e9c976d9" name="Vagrantfile" role="test" />
- <file md5sum="18ea7643965f36d7589eb3611fbf3e0b" name="config.m4" role="src" />
- <file md5sum="2798243a4062157db91bdb0a43f82160" name="config.w32" role="src" />
+ <file md5sum="3a39bd085df57e5134666bf61104ac2a" name="config.m4" role="src" />
+ <file md5sum="cea9422e7c018a00c17442c0e6594167" name="config.w32" role="src" />
+ <file md5sum="3139c7824cd9d1220bb270f6d5a942ca" name="phongo_version.h" role="src" />
<file md5sum="8175849dff2928ca833bb0779e53adcc" name="php_phongo.c" role="src" />
- <file md5sum="d5a9061f36ea5e4d8b1ea162cea26c3b" name="php_phongo.h" role="src" />
+ <file md5sum="5af92fa52eaf0af0512f8c114aa48c33" name="php_phongo.h" role="src" />
</dir>
</contents>
<dependencies>
<required>
<php>
<min>7.2.0</min>
<max>8.99.99</max>
</php>
<pearinstaller>
<min>1.4.8</min>
</pearinstaller>
</required>
</dependencies>
<providesextension>mongodb</providesextension>
<extsrcrelease />
</package>

File Metadata

Mime Type
application/octet-stream
Expires
Thu, Sep 11, 1:16 PM (2 d)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
JI8XWXlamv35
Default Alt Text
(5 MB)

Event Timeline