@@ -7,12 +7,14 @@ use base64::Engine;
77use binaryninja:: download:: DownloadProvider ;
88use serde:: Deserialize ;
99use serde_json:: json;
10- use std:: collections:: HashMap ;
10+ use std:: collections:: { HashMap , HashSet } ;
1111use std:: str:: FromStr ;
12+ use std:: time:: Instant ;
1213use uuid:: Uuid ;
1314use warp:: chunk:: ChunkKind ;
1415use warp:: r#type:: guid:: TypeGUID ;
1516use warp:: r#type:: { ComputedType , Type } ;
17+ use warp:: signature:: constraint:: ConstraintGUID ;
1618use warp:: signature:: function:: { Function , FunctionGUID } ;
1719use warp:: target:: Target ;
1820use warp:: WarpFile ;
@@ -30,7 +32,8 @@ pub struct NetworkClient {
3032impl NetworkClient {
3133 pub fn new ( server_url : String , server_token : Option < String > ) -> Self {
3234 // TODO: This might want to be kept for the request header?
33- let mut headers: Vec < ( String , String ) > = vec ! [ ] ;
35+ let mut headers: Vec < ( String , String ) > =
36+ vec ! [ ( "Content-Encoding" . to_string( ) , "gzip" . to_string( ) ) ] ;
3437 if let Some ( token) = & server_token {
3538 headers. push ( ( "authorization" . to_string ( ) , format ! ( "Bearer {}" , token) ) ) ;
3639 }
@@ -214,13 +217,14 @@ impl NetworkClient {
214217 source : Option < SourceId > ,
215218 source_tags : & [ SourceTag ] ,
216219 guids : & [ FunctionGUID ] ,
220+ constraints : & [ ConstraintGUID ] ,
217221 ) -> serde_json:: Value {
218- let guids_str: Vec < String > = guids. iter ( ) . map ( |g| g. to_string ( ) ) . collect ( ) ;
222+ let guids_str: HashSet < String > = guids. iter ( ) . map ( |g| g. to_string ( ) ) . collect ( ) ;
219223 // TODO: The limit here needs to be somewhat flexible. But 1000 will do for now.
220224 let mut body = json ! ( {
221225 "format" : "flatbuffer" ,
222226 "guids" : guids_str,
223- "limit" : 1000
227+ "limit" : 10000 ,
224228 } ) ;
225229 if let Some ( target_id) = target {
226230 body[ "target_id" ] = json ! ( target_id) ;
@@ -231,6 +235,11 @@ impl NetworkClient {
231235 if !source_tags. is_empty ( ) {
232236 body[ "source_tags" ] = json ! ( source_tags) ;
233237 }
238+ if !constraints. is_empty ( ) {
239+ let constraint_guids_str: HashSet < String > =
240+ constraints. iter ( ) . map ( |g| g. to_string ( ) ) . collect ( ) ;
241+ body[ "constraints" ] = json ! ( constraint_guids_str) ;
242+ }
234243 body
235244 }
236245
@@ -244,13 +253,13 @@ impl NetworkClient {
244253 target : Option < NetworkTargetId > ,
245254 source : Option < SourceId > ,
246255 guids : & [ FunctionGUID ] ,
256+ constraints : & [ ConstraintGUID ] ,
247257 ) -> Result < WarpFile < ' static > , String > {
248258 let query_functions_url = format ! ( "{}/api/v1/functions/query" , self . server_url) ;
249259 // TODO: Allow for source tags? We really only need this in query_functions_source as that
250260 // TODO: is what prevents a undesired source from being "known" to the container.
251- let payload = Self :: query_functions_body ( target, source, & [ ] , guids) ;
261+ let payload = Self :: query_functions_body ( target, source, & [ ] , guids, constraints ) ;
252262 let mut inst = self . provider . create_instance ( ) . unwrap ( ) ;
253-
254263 let resp = inst. post_json ( & query_functions_url, self . headers . clone ( ) , & payload) ?;
255264 if !resp. is_success ( ) {
256265 return Err ( format ! (
@@ -275,7 +284,10 @@ impl NetworkClient {
275284 ) -> Result < HashMap < SourceId , Vec < FunctionGUID > > , String > {
276285 let query_functions_source_url =
277286 format ! ( "{}/api/v1/functions/query/source" , self . server_url) ;
278- let payload = Self :: query_functions_body ( target, None , tags, guids) ;
287+ // NOTE: We do not filter by constraint guids here since this pass is only responsible for
288+ // returning the source ids, not the actual function data, see [`NetworkClient::query_functions`]
289+ // for the place where the constraints are applied, and _do_ matter.
290+ let payload = Self :: query_functions_body ( target, None , tags, guids, & [ ] ) ;
279291 let mut inst = self . provider . create_instance ( ) . unwrap ( ) ;
280292
281293 let resp = inst. post_json ( & query_functions_source_url, self . headers . clone ( ) , & payload) ?;
0 commit comments