@@ -204,6 +204,67 @@ def test_headers_are_set(self, t_http_client_class):
204204 {"header" : "value" }
205205 )
206206
207+ @patch ("databricks.sql.auth.thrift_http_client.THttpClient" )
208+ def test_binary_protocol_preserves_unbounded_string_and_container_limits (
209+ self , t_http_client_class
210+ ):
211+ """thrift>=0.25.0 changed TBinaryProtocol's default string_length_limit
212+ from unbounded (None) to ~15.6 MiB (DEFAULT_STRING_LENGTH_LIMIT) as part
213+ of its CVE-2026-85494 fix. The connector must pass these limits through
214+ explicitly so a thrift upgrade cannot silently cap -- or regress -- the
215+ size of result data (e.g. inline Arrow batches) it can read, since the
216+ connector already governs its own result size via buffer_size_bytes.
217+ """
218+ import thrift .protocol .TBinaryProtocol
219+
220+ with patch (
221+ "thrift.protocol.TBinaryProtocol.TBinaryProtocol"
222+ ) as mock_protocol_class :
223+ ThriftDatabricksClient (
224+ "foo" ,
225+ 123 ,
226+ "bar" ,
227+ [],
228+ auth_provider = AuthProvider (),
229+ ssl_options = SSLOptions (),
230+ http_client = MagicMock (),
231+ )
232+
233+ _ , kwargs = mock_protocol_class .call_args
234+ self .assertIsNone (kwargs .get ("string_length_limit" ))
235+ self .assertIsNone (kwargs .get ("container_length_limit" ))
236+
237+ def test_binary_protocol_reads_result_larger_than_thrift_default_limit (self ):
238+ """Guard against relying on thrift's new (>=0.25.0) default
239+ string_length_limit of ~15.6 MiB, which is smaller than the
240+ connector's own DEFAULT_RESULT_BUFFER_SIZE_BYTES (100 MiB). A field
241+ larger than thrift's default limit, but within the connector's own
242+ result-size bound, must still read successfully.
243+ """
244+ from thrift .transport import TTransport
245+ from thrift .protocol import TBinaryProtocol
246+
247+ from databricks .sql .backend .thrift_backend import (
248+ THRIFT_BINARY_PROTOCOL_STRING_LENGTH_LIMIT ,
249+ THRIFT_BINARY_PROTOCOL_CONTAINER_LENGTH_LIMIT ,
250+ )
251+
252+ oversized_payload = b"x" * (
253+ 20 * 1024 * 1024
254+ ) # 20 MiB > thrift's ~15.6 MiB default
255+
256+ write_buffer = TTransport .TMemoryBuffer ()
257+ TBinaryProtocol .TBinaryProtocol (write_buffer ).writeBinary (oversized_payload )
258+
259+ read_buffer = TTransport .TMemoryBuffer (write_buffer .getvalue ())
260+ protocol = TBinaryProtocol .TBinaryProtocol (
261+ read_buffer ,
262+ string_length_limit = THRIFT_BINARY_PROTOCOL_STRING_LENGTH_LIMIT ,
263+ container_length_limit = THRIFT_BINARY_PROTOCOL_CONTAINER_LENGTH_LIMIT ,
264+ )
265+
266+ self .assertEqual (protocol .readBinary (), oversized_payload )
267+
207268 def test_proxy_headers_are_set (self ):
208269
209270 from databricks .sql .common .http_utils import create_basic_proxy_auth_headers
0 commit comments