Skip to content

Commit ef97d47

Browse files
committed
Add API to insert Activities after a specified Activity.
1 parent 5192206 commit ef97d47

File tree

5 files changed

+94
-2
lines changed

5 files changed

+94
-2
lines changed

binaryninjaapi.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10213,6 +10213,22 @@ namespace BinaryNinja {
1021310213
*/
1021410214
bool Insert(const std::string& activity, const std::vector<std::string>& activities);
1021510215

10216+
/*! Insert an activity after the specified activity and at the same level.
10217+
10218+
\param activity Name of the activity to insert the new one after
10219+
\param newActivity Name of the new activity to be inserted
10220+
\return true on success, false otherwise
10221+
*/
10222+
bool InsertAfter(const std::string& activity, const std::string& newActivity);
10223+
10224+
/*! Insert a list of activities after the specified activity and at the same level.
10225+
10226+
\param activity Name of the activity to insert the new one after
10227+
\param newActivity Name of the new activities to be inserted
10228+
\return true on success, false otherwise
10229+
*/
10230+
bool InsertAfter(const std::string& activity, const std::vector<std::string>& activities);
10231+
1021610232
/*! Remove an activity by name
1021710233

1021810234
\param activity Name of the activity to remove

binaryninjacore.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 97
40+
#define BN_CURRENT_CORE_ABI_VERSION 98
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
@@ -5508,6 +5508,7 @@ extern "C"
55085508
BINARYNINJACOREAPI bool BNWorkflowAssignSubactivities(BNWorkflow* workflow, const char* activity, const char** activities, size_t size);
55095509
BINARYNINJACOREAPI bool BNWorkflowClear(BNWorkflow* workflow);
55105510
BINARYNINJACOREAPI bool BNWorkflowInsert(BNWorkflow* workflow, const char* activity, const char** activities, size_t size);
5511+
BINARYNINJACOREAPI bool BNWorkflowInsertAfter(BNWorkflow* workflow, const char* activity, const char** activities, size_t size);
55115512
BINARYNINJACOREAPI bool BNWorkflowRemove(BNWorkflow* workflow, const char* activity);
55125513
BINARYNINJACOREAPI bool BNWorkflowReplace(BNWorkflow* workflow, const char* activity, const char* newActivity);
55135514

python/workflow.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ def clear(self) -> bool:
487487
"""
488488
return core.BNWorkflowClear(self.handle)
489489

490-
def insert(self, activity: ActivityType, activities: List[str]) -> bool:
490+
def insert(self, activity: ActivityType, activities: Union[List[str], str]) -> bool:
491491
"""
492492
``insert`` Insert the list of ``activities`` before the specified ``activity`` and at the same level.
493493
@@ -496,11 +496,29 @@ def insert(self, activity: ActivityType, activities: List[str]) -> bool:
496496
:return: True on success, False otherwise
497497
:rtype: bool
498498
"""
499+
if isinstance(activities, str):
500+
activities = [activities]
499501
input_list = (ctypes.c_char_p * len(activities))()
500502
for i in range(0, len(activities)):
501503
input_list[i] = str(activities[i]).encode('charmap')
502504
return core.BNWorkflowInsert(self.handle, str(activity), input_list, len(activities))
503505

506+
def insert_after(self, activity: ActivityType, activities: Union[List[str], str]) -> bool:
507+
"""
508+
``insert_after`` Insert the list of ``activities`` after the specified ``activity`` and at the same level.
509+
510+
:param str activity: the Activity node for which to insert ``activities`` after
511+
:param list[str] activities: the list of Activities to insert
512+
:return: True on success, False otherwise
513+
:rtype: bool
514+
"""
515+
if isinstance(activities, str):
516+
activities = [activities]
517+
input_list = (ctypes.c_char_p * len(activities))()
518+
for i in range(0, len(activities)):
519+
input_list[i] = str(activities[i]).encode('charmap')
520+
return core.BNWorkflowInsertAfter(self.handle, str(activity), input_list, len(activities))
521+
504522
def remove(self, activity: ActivityType) -> bool:
505523
"""
506524
``remove`` Remove the specified ``activity``.

rust/src/workflow.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,34 @@ impl Workflow {
529529
}
530530
}
531531

532+
/// Insert the list of `activities` after the specified `activity` and at the same level.
533+
///
534+
/// * `activity` - the Activity node for which to insert `activities` after
535+
/// * `activities` - the list of Activities to insert
536+
pub fn insert_after<A, I>(&self, activity: A, activities: I) -> bool
537+
where
538+
A: BnStrCompatible,
539+
I: IntoIterator,
540+
I::Item: BnStrCompatible,
541+
{
542+
let input_list: Vec<_> = activities
543+
.into_iter()
544+
.map(|a| a.into_bytes_with_nul())
545+
.collect();
546+
let mut input_list_ptr: Vec<*const _> = input_list
547+
.iter()
548+
.map(|x| x.as_ref().as_ptr() as *const c_char)
549+
.collect();
550+
unsafe {
551+
BNWorkflowInsertAfter(
552+
self.handle.as_ptr(),
553+
activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char,
554+
input_list_ptr.as_mut_ptr(),
555+
input_list.len(),
556+
)
557+
}
558+
}
559+
532560
/// Remove the specified `activity`
533561
pub fn remove<A: BnStrCompatible>(&self, activity: A) -> bool {
534562
unsafe {

workflow.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,35 @@ bool Workflow::Insert(const string& activity, const vector<string>& activities)
415415
}
416416

417417

418+
bool Workflow::InsertAfter(const string& activity, const string& newActivity)
419+
{
420+
char* buffer[1];
421+
buffer[0] = BNAllocString(newActivity.c_str());
422+
423+
bool result = BNWorkflowInsertAfter(m_object, activity.c_str(), (const char**)buffer, 1);
424+
BNFreeString(buffer[0]);
425+
return result;
426+
}
427+
428+
429+
bool Workflow::InsertAfter(const string& activity, const vector<string>& activities)
430+
{
431+
char** buffer = new char*[activities.size()];
432+
if (!buffer)
433+
return false;
434+
435+
for (size_t i = 0; i < activities.size(); i++)
436+
buffer[i] = BNAllocString(activities[i].c_str());
437+
438+
bool result = BNWorkflowInsertAfter(m_object, activity.c_str(), (const char**)buffer, activities.size());
439+
440+
for (size_t i = 0; i < activities.size(); i++)
441+
BNFreeString(buffer[i]);
442+
delete[] buffer;
443+
return result;
444+
}
445+
446+
418447
bool Workflow::Remove(const string& activity)
419448
{
420449
return BNWorkflowRemove(m_object, activity.c_str());

0 commit comments

Comments
 (0)