Skip to content

Commit 3412096

Browse files
[SQUASH] Add Required v1 API Features With Tests & CI (#2)
* marking v1 * Debug Mode * Remove Local Database Feature Local database management turned out to not be such a good idea. Why? because now users can apply existing analysis in rizin and cutter plugins and hence no need to track binary id or analysis id or hashes of uploaded files. If this new feature were not to be added, then local db management is a very helpful feature to have IMO * Log Now Available Globally - Auth Check endpoint works - Log object management removed, Log now available globally. Logging will be initialized as soon as the library is loaded and all logs will be stored in tmpdir. * Auth Check Takes Host Param As Well API key works correctly only with it's corresponding host. Auth check now sets the host as well. * Get AI Models Add new endpoint to get available AI models * Remove Redundant Model Arguments Plugins now don't use a static modelname-version syntax to specify versions. All AI model information is passed into the struct of arguments of API that requires it. * Mock API * [BUG] Add Tests There are some bugs found during execution of these tests Strange, I never thought they'd exist like this. While writing the tests I thought they'd be useless. * Fix Some Memory Leaks The bug still remains unfixed. * [BUGFIX] Remove Free On Json String The json string getter method does not duplicate the string and hence ownership still remained with cJSON object. One of the Json getter method destroyed the returned string and hence it was a double-free bug, because in the end the cJSON object tried to destroy it was well. Phew! * Update README For cJSON Dependency Recently faced a RPATH issue when building and installing cJSON from source on Mac OS. The updated README provides hints on how that can be fixed. * [HACK] Add CI Tests & Make Up For Poor Documentation Documentation for `/v1/ann/symbol/batch` seems to be incorrect. Can't wait for getting a response and then making decision based on that, so for now moving ahead with a hack to optionally check for `function_matches` field the second time. I'm referring to the JSON response parsing code in Response.c * Update ci.yaml To Run On Any Commit/Push * CI Error Fix * Update CI To Create TMP Directory & Display Logs * To Review & Merge Some small non-necessary fixes to follow a proper coding style throughout. * Use `memmove` in vec_remove * `FREE` Automatically Sets To `NULL` No need to explicitly sets variables to `NULL` after using `FREE` on them, this is automatically done in `FREE` macro
1 parent c47ee65 commit 3412096

28 files changed

+1735
-275650
lines changed

.github/workflows/ci.yaml

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: CMake Build and Test
2+
3+
on:
4+
push: # Trigger on any push to any branch
5+
pull_request: # Trigger on any PR
6+
7+
jobs:
8+
build-and-test:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
# Checkout the repository
13+
- name: Checkout code
14+
uses: actions/checkout@v3
15+
16+
# Set up dependencies
17+
- name: Install dependencies
18+
run: |
19+
sudo apt-get update
20+
sudo apt-get install -y cmake gcc g++ ninja-build libcurl4-openssl-dev pkg-config
21+
22+
# Configure the build
23+
- name: Configure with CMake
24+
run: |
25+
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
26+
27+
# Build the project
28+
- name: Build the project
29+
run: |
30+
ninja -C build
31+
32+
# Create temporary directory for logs
33+
- name: Create temporary directory
34+
run: |
35+
export TMP=$(mktemp -d)
36+
echo "Temporary directory created at $TMP"
37+
echo "TMP=$TMP" >> $GITHUB_ENV
38+
39+
# Run tests
40+
- name: Run tests
41+
run: |
42+
./build/bin/reai_test
43+
44+
# Output logs from the temporary directory
45+
- name: Display logs
46+
run: |
47+
echo "Logs from $TMP:"
48+
ls "$TMP"
49+
cat "$TMP"/* || echo "No log files found"

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
Build/
1+
Build*/
2+
build*/
23
.cache/
34
compile_commands.json
45
*.DS_Store

CMakeLists.txt

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.12)
33
project(CREAIT LANGUAGES C VERSION 0.1.1)
44
include(FetchContent)
55
include(ExternalProject)
6+
include(CTest)
67

78
option(BUILD_SHARED_LIBS "Build using shared libraries" OFF)
89

@@ -11,10 +12,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
1112
set(CMAKE_LIRBARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
1213
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
1314

14-
set(CMAKE_C_STANDARD 23)
15-
set(CMAKE_C_STANDARD_REQUIRED ON)
16-
set(CMAKE_C_EXTENSIONS OFF)
17-
1815
# generate a compile_commands.json for LSP clients
1916
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
2017

@@ -25,6 +22,7 @@ find_package(CURL REQUIRED)
2522

2623
# Add library source
2724
add_subdirectory(Source)
25+
add_subdirectory(Test)
2826

2927
# Add installation target for include files
3028
install(DIRECTORY Include/Reai DESTINATION include)

Include/Reai/Api/Reai.h

+20-10
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,27 @@ extern "C" {
2525
typedef struct Reai Reai; /* opaque object */
2626
typedef struct ReaiResponse ReaiResponse;
2727
typedef struct ReaiRequest ReaiRequest;
28-
typedef struct ReaiDb ReaiDb;
29-
typedef struct ReaiLog ReaiLog;
3028

31-
Reai* reai_create (CString host, CString api_key, CString model);
29+
Reai* reai_create (CString host, CString api_key);
30+
Reai* reai_set_mock_handler (
31+
Reai* reai,
32+
ReaiResponse* (*mock_handler) (
33+
Reai* reai,
34+
ReaiRequest* req,
35+
ReaiResponse* response,
36+
CString endpoint,
37+
Uint32* http_code
38+
)
39+
);
3240
void reai_destroy (Reai* reai);
3341
ReaiResponse* reai_request (Reai* reai, ReaiRequest* req, ReaiResponse* response);
34-
Reai* reai_set_db (Reai* reai, ReaiDb* db);
35-
Reai* reai_set_logger (Reai* reai, ReaiLog* logger);
36-
Reai* reai_update_all_analyses_status_in_db (Reai* reai);
3742

38-
CString reai_upload_file (Reai* reai, ReaiResponse* response, CString file_path);
43+
Bool reai_auth_check (Reai* reai, ReaiResponse* response, CString host, CString api_key);
44+
CString reai_upload_file (Reai* reai, ReaiResponse* response, CString file_path);
3945
ReaiBinaryId reai_create_analysis (
4046
Reai* reai,
4147
ReaiResponse* response,
42-
ReaiModel model,
48+
CString ai_model,
4349
Uint64 base_addr,
4450
ReaiFnInfoVec* fn_info_vec,
4551
Bool is_private,
@@ -77,7 +83,8 @@ extern "C" {
7783
ReaiBinaryId bin_id,
7884
Size max_results_per_function,
7985
Float64 max_distance,
80-
CStrVec* collection
86+
CStrVec* collection,
87+
Bool debug_mode
8188
);
8289

8390
ReaiAnnFnMatchVec* reai_batch_function_symbol_ann (
@@ -87,9 +94,12 @@ extern "C" {
8794
U64Vec* speculative_fn_ids,
8895
Size max_results_per_function,
8996
Float64 max_distance,
90-
CStrVec* collection
97+
CStrVec* collection,
98+
Bool debug_mode
9199
);
92100

101+
CStrVec* reai_get_available_models (Reai* reai, ReaiResponse* response);
102+
93103
#ifdef __cplusplus
94104
}
95105
#endif

Include/Reai/Api/Request.h

+16-15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <Reai/Common.h>
1313
#include <Reai/FnInfo.h>
1414
#include <Reai/Types.h>
15+
#include <Reai/Util/CStrVec.h>
1516
#include <Reai/Util/IntVec.h>
1617

1718
#ifdef __cplusplus
@@ -53,7 +54,7 @@ extern "C" {
5354
REAI_REQUEST_TYPE_UPLOAD_FILE,
5455
/* REAI_REQUEST_TYPE_GET_CONFIG, */
5556
REAI_REQUEST_TYPE_SEARCH,
56-
/* REAI_REQUEST_TYPE_GET_MODELS, */
57+
REAI_REQUEST_TYPE_GET_MODELS,
5758

5859
/* analysis api */
5960
REAI_REQUEST_TYPE_CREATE_ANALYSIS,
@@ -72,22 +73,13 @@ extern "C" {
7273
REAI_REQUEST_TYPE_BATCH_BINARY_SYMBOL_ANN,
7374
REAI_REQUEST_TYPE_BATCH_FUNCTION_SYMBOL_ANN,
7475

76+
/* ai decompilation */
77+
REAI_REQUEST_TYPE_BEGIN_AI_DECOMPILATION,
78+
REAI_REQUEST_TYPE_POLL_AI_DECOMPILATION,
79+
7580
REAI_REQUEST_TYPE_MAX /**< Total number of request types */
7681
} ReaiRequestType;
7782

78-
/**
79-
* @b Represents the BinNet model to use in RevEngAI created analysis.
80-
* This is used in create analysis request type.
81-
* */
82-
typedef enum ReaiModel {
83-
REAI_MODEL_UNKNOWN = 0,
84-
REAI_MODEL_X86_WINDOWS,
85-
REAI_MODEL_X86_LINUX,
86-
REAI_MODEL_X86_MACOS,
87-
REAI_MODEL_X86_ANDROID,
88-
REAI_MODEL_MAX
89-
} ReaiModel;
90-
9183
/**
9284
* @b Structure to be prepared with valid field values before making request to API
9385
* endpoint.
@@ -96,12 +88,17 @@ extern "C" {
9688
ReaiRequestType type; /**< @b Type of request. */
9789

9890
union {
91+
struct {
92+
CString host;
93+
CString api_key;
94+
} auth_check;
95+
9996
struct {
10097
CString file_path; /**< @b Complete file path to be uploaded */
10198
} upload_file;
10299

103100
struct {
104-
ReaiModel model; /**< @b BinNet model to be used */
101+
CString ai_model; /**< @b BinNet model to be used */
105102
CString platform_opt; /**< @b Idk the possible values of this enum. */
106103
CString isa_opt; /**< @b Idk possible values of this one as well. */
107104
ReaiFileOption file_opt; /**< @b Info about file type. */
@@ -168,6 +165,10 @@ extern "C" {
168165
ReaiFunctionId* speculative_function_ids;
169166
Size speculative_function_id_count;
170167
} batch_function_symbol_ann;
168+
169+
struct {
170+
ReaiFunctionId function_id;
171+
} begin_ai_decompilation, poll_ai_decompilation;
171172
};
172173
} ReaiRequest;
173174

Include/Reai/Api/Response.h

+34-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <Reai/AnalysisInfo.h>
1212
#include <Reai/AnnFnMatch.h>
1313
#include <Reai/Api/Request.h>
14+
#include <Reai/ApiError.h>
1415
#include <Reai/FnInfo.h>
1516
#include <Reai/QueryResult.h>
1617

@@ -33,8 +34,8 @@ extern "C" {
3334
/* utility api */
3435
REAI_RESPONSE_TYPE_UPLOAD_FILE = REAI_REQUEST_TYPE_UPLOAD_FILE,
3536
/* REAI_RESPONSE_TYPE_GET_CONFIG = REAI_REQUEST_TYPE_GET_CONFIG, */
36-
REAI_RESPONSE_TYPE_SEARCH = REAI_REQUEST_TYPE_SEARCH,
37-
/* REAI_RESPONSE_TYPE_GET_MODELS = REAI_REQUEST_TYPE_GET_MODELS, */
37+
REAI_RESPONSE_TYPE_SEARCH = REAI_REQUEST_TYPE_SEARCH,
38+
REAI_RESPONSE_TYPE_GET_MODELS = REAI_REQUEST_TYPE_GET_MODELS,
3839

3940
/* analysis api */
4041
REAI_RESPONSE_TYPE_CREATE_ANALYSIS = REAI_REQUEST_TYPE_CREATE_ANALYSIS,
@@ -53,6 +54,10 @@ extern "C" {
5354
REAI_RESPONSE_TYPE_BATCH_BINARY_SYMBOL_ANN = REAI_REQUEST_TYPE_BATCH_BINARY_SYMBOL_ANN,
5455
REAI_RESPONSE_TYPE_BATCH_FUNCTION_SYMBOL_ANN = REAI_REQUEST_TYPE_BATCH_FUNCTION_SYMBOL_ANN,
5556

57+
/* ai decompilation */
58+
REAI_RESPONSE_TYPE_BEGIN_AI_DECOMPILATION = REAI_REQUEST_TYPE_BEGIN_AI_DECOMPILATION,
59+
REAI_RESPONSE_TYPE_POLL_AI_DECOMPILATION = REAI_REQUEST_TYPE_POLL_AI_DECOMPILATION,
60+
5661
REAI_RESPONSE_TYPE_VALIDATION_ERR,
5762
REAI_RESPONSE_TYPE_MAX, /* enum value less than this is valid */
5863
} ReaiResponseType;
@@ -108,7 +113,11 @@ extern "C" {
108113
struct {
109114
Bool success; /**< @b Is true when request was successful */
110115
CString message; /**< @b Message returned by request */
111-
} health_check, auth_check, delete_analysis;
116+
} health_check, delete_analysis;
117+
118+
struct {
119+
CString message;
120+
} auth_check;
112121

113122
struct {
114123
Bool success; /**< @b Is true when request was successful */
@@ -157,6 +166,28 @@ extern "C" {
157166
} settings;
158167
ReaiAnnFnMatchVec* function_matches;
159168
} batch_binary_symbol_ann, batch_function_symbol_ann;
169+
170+
struct {
171+
Bool success;
172+
CStrVec* models;
173+
} get_models;
174+
175+
struct {
176+
Bool status;
177+
CString message;
178+
ReaiApiErrors* errors;
179+
} begin_ai_decompilation;
180+
181+
struct {
182+
Bool status;
183+
struct {
184+
CString status;
185+
CString decompilation;
186+
// TODO: function mapping?
187+
} data;
188+
CString message;
189+
ReaiApiErrors* errors;
190+
} poll_ai_decompilation;
160191
};
161192
} ReaiResponse;
162193

Include/Reai/ApiError.h

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @file ApiError.h
3+
* @date 5th Dec 2024
4+
* @author Siddharth Mishra (admin@brightprogrammer.in)
5+
* @copyright Copyright (c) RevEngAI. All Rights Reserved.
6+
* */
7+
8+
#ifndef REAI_API_ERROR_H
9+
#define REAI_API_ERROR_H
10+
11+
#include <Reai/Types.h>
12+
#include <Reai/Util/Vec.h>
13+
14+
typedef struct {
15+
CString code;
16+
CString message;
17+
} ReaiApiError;
18+
19+
ReaiApiError* reai_api_error_clone_init (ReaiApiError* dst, ReaiApiError* src);
20+
ReaiApiError* reai_api_error_clone_deinit (ReaiApiError* clone);
21+
22+
REAI_MAKE_VEC (
23+
ReaiApiErrors,
24+
api_error,
25+
ReaiApiError,
26+
reai_api_error_clone_init,
27+
reai_api_error_vec_init
28+
);
29+
30+
#endif // REAI_API_ERROR_H

0 commit comments

Comments
 (0)