Skip to content

Commit

Permalink
Merge branch 'flipperdevices:dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Z3BRO authored Oct 1, 2024
2 parents b72b2c8 + 913a86b commit a7675d7
Show file tree
Hide file tree
Showing 70 changed files with 871 additions and 313 deletions.
2 changes: 1 addition & 1 deletion applications/debug/rpc_debug_app/rpc_debug_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static void rpc_debug_app_tick_event_callback(void* context) {
static void
rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) {
if(data == NULL || data_size == 0) {
strncpy(buf, "<Data empty>", buf_size);
strlcpy(buf, "<Data empty>", buf_size);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static void rpc_debug_app_scene_input_error_code_result_callback(void* context)

void rpc_debug_app_scene_input_error_code_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "666", TEXT_STORE_SIZE);
strlcpy(app->text_store, "666", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error code");
text_input_set_validator(
app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ static void rpc_debug_app_scene_input_error_text_result_callback(void* context)

void rpc_debug_app_scene_input_error_text_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
strlcpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error text");
text_input_set_result_callback(
app->text_input,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
strlcpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);

text_box_set_text(app->text_box, app->text_store);
text_box_set_font(app->text_box, TextBoxFontHex);
Expand Down
51 changes: 51 additions & 0 deletions applications/debug/unit_tests/tests/furi/furi_errno_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <furi.h>
#include <errno.h>
#include "../test.h" // IWYU pragma: keep

#define TAG "ErrnoTest"
#define THREAD_CNT 16
#define ITER_CNT 1000

static int32_t errno_fuzzer(void* context) {
int start_value = (int)context;
int32_t fails = 0;

for(int i = start_value; i < start_value + ITER_CNT; i++) {
errno = i;
furi_thread_yield();
if(errno != i) fails++;
}

for(int i = 0; i < ITER_CNT; i++) {
errno = 0;
furi_thread_yield();
UNUSED(strtol("123456", NULL, 10)); // -V530
furi_thread_yield();
if(errno != 0) fails++;

errno = 0;
furi_thread_yield();
UNUSED(strtol("123456123456123456123456123456123456123456123456", NULL, 10)); // -V530
furi_thread_yield();
if(errno != ERANGE) fails++;
}

return fails;
}

void test_errno_saving(void) {
FuriThread* threads[THREAD_CNT];

for(int i = 0; i < THREAD_CNT; i++) {
int start_value = i * ITER_CNT;
threads[i] = furi_thread_alloc_ex("ErrnoFuzzer", 1024, errno_fuzzer, (void*)start_value);
furi_thread_set_priority(threads[i], FuriThreadPriorityNormal);
furi_thread_start(threads[i]);
}

for(int i = 0; i < THREAD_CNT; i++) {
furi_thread_join(threads[i]);
mu_assert_int_eq(0, furi_thread_get_return_code(threads[i]));
furi_thread_free(threads[i]);
}
}
6 changes: 6 additions & 0 deletions applications/debug/unit_tests/tests/furi/furi_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ void test_furi_concurrent_access(void);
void test_furi_pubsub(void);
void test_furi_memmgr(void);
void test_furi_event_loop(void);
void test_errno_saving(void);

static int foo = 0;

Expand Down Expand Up @@ -42,6 +43,10 @@ MU_TEST(mu_test_furi_event_loop) {
test_furi_event_loop();
}

MU_TEST(mu_test_errno_saving) {
test_errno_saving();
}

MU_TEST_SUITE(test_suite) {
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
MU_RUN_TEST(test_check);
Expand All @@ -51,6 +56,7 @@ MU_TEST_SUITE(test_suite) {
MU_RUN_TEST(mu_test_furi_pubsub);
MU_RUN_TEST(mu_test_furi_memmgr);
MU_RUN_TEST(mu_test_furi_event_loop);
MU_RUN_TEST(mu_test_errno_saving);
}

int run_minunit_test_furi(void) {
Expand Down
87 changes: 68 additions & 19 deletions applications/debug/unit_tests/tests/storage/storage_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
// This is a hack to access internal storage functions and definitions
#include <storage/storage_i.h>

#define UNIT_TESTS_PATH(path) EXT_PATH("unit_tests/" path)
#define UNIT_TESTS_RESOURCES_PATH(path) EXT_PATH("unit_tests/" path)
#define UNIT_TESTS_PATH(path) EXT_PATH(".tmp/unit_tests/" path)

#define STORAGE_LOCKED_FILE EXT_PATH("locked_file.test")
#define STORAGE_LOCKED_FILE UNIT_TESTS_PATH("locked_file.test")
#define STORAGE_LOCKED_DIR STORAGE_INT_PATH_PREFIX

#define STORAGE_TEST_DIR UNIT_TESTS_PATH("test_dir")
Expand Down Expand Up @@ -369,44 +370,92 @@ MU_TEST(storage_file_rename) {
Storage* storage = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(storage);

mu_check(write_file_13DA(storage, EXT_PATH("file.old")));
mu_check(check_file_13DA(storage, EXT_PATH("file.old")));
mu_check(write_file_13DA(storage, UNIT_TESTS_PATH("file.old")));
mu_check(check_file_13DA(storage, UNIT_TESTS_PATH("file.old")));
mu_assert_int_eq(
FSE_OK, storage_common_rename(storage, EXT_PATH("file.old"), EXT_PATH("file.new")));
mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, EXT_PATH("file.old"), NULL));
mu_assert_int_eq(FSE_OK, storage_common_stat(storage, EXT_PATH("file.new"), NULL));
mu_check(check_file_13DA(storage, EXT_PATH("file.new")));
mu_assert_int_eq(FSE_OK, storage_common_remove(storage, EXT_PATH("file.new")));
FSE_OK,
storage_common_rename(storage, UNIT_TESTS_PATH("file.old"), UNIT_TESTS_PATH("file.new")));
mu_assert_int_eq(
FSE_NOT_EXIST, storage_common_stat(storage, UNIT_TESTS_PATH("file.old"), NULL));
mu_assert_int_eq(FSE_OK, storage_common_stat(storage, UNIT_TESTS_PATH("file.new"), NULL));
mu_check(check_file_13DA(storage, UNIT_TESTS_PATH("file.new")));
mu_assert_int_eq(FSE_OK, storage_common_remove(storage, UNIT_TESTS_PATH("file.new")));

storage_file_free(file);
furi_record_close(RECORD_STORAGE);
}

static const char* dir_rename_tests[][2] = {
{UNIT_TESTS_PATH("dir.old"), UNIT_TESTS_PATH("dir.new")},
{UNIT_TESTS_PATH("test_dir"), UNIT_TESTS_PATH("test_dir-new")},
{UNIT_TESTS_PATH("test"), UNIT_TESTS_PATH("test-test")},
};

MU_TEST(storage_dir_rename) {
Storage* storage = furi_record_open(RECORD_STORAGE);

storage_dir_create(storage, EXT_PATH("dir.old"));
for(size_t i = 0; i < COUNT_OF(dir_rename_tests); i++) {
const char* old_path = dir_rename_tests[i][0];
const char* new_path = dir_rename_tests[i][1];

storage_dir_create(storage, old_path);
mu_check(storage_dir_rename_check(storage, old_path));

mu_assert_int_eq(FSE_OK, storage_common_rename(storage, old_path, new_path));
mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, old_path, NULL));
mu_check(storage_dir_rename_check(storage, new_path));

storage_dir_remove(storage, new_path);
mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, new_path, NULL));
}

furi_record_close(RECORD_STORAGE);
}

mu_check(storage_dir_rename_check(storage, EXT_PATH("dir.old")));
MU_TEST(storage_equiv_and_subdir) {
Storage* storage = furi_record_open(RECORD_STORAGE);

mu_assert_int_eq(
FSE_OK, storage_common_rename(storage, EXT_PATH("dir.old"), EXT_PATH("dir.new")));
mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, EXT_PATH("dir.old"), NULL));
mu_check(storage_dir_rename_check(storage, EXT_PATH("dir.new")));
true,
storage_common_equivalent_path(storage, UNIT_TESTS_PATH("blah"), UNIT_TESTS_PATH("blah")));
mu_assert_int_eq(
true,
storage_common_equivalent_path(
storage, UNIT_TESTS_PATH("blah/"), UNIT_TESTS_PATH("blah/")));
mu_assert_int_eq(
false,
storage_common_equivalent_path(
storage, UNIT_TESTS_PATH("blah"), UNIT_TESTS_PATH("blah-blah")));
mu_assert_int_eq(
false,
storage_common_equivalent_path(
storage, UNIT_TESTS_PATH("blah/"), UNIT_TESTS_PATH("blah-blah/")));

storage_dir_remove(storage, EXT_PATH("dir.new"));
mu_assert_int_eq(FSE_NOT_EXIST, storage_common_stat(storage, EXT_PATH("dir.new"), NULL));
mu_assert_int_eq(
true, storage_common_is_subdir(storage, UNIT_TESTS_PATH("blah"), UNIT_TESTS_PATH("blah")));
mu_assert_int_eq(
true,
storage_common_is_subdir(storage, UNIT_TESTS_PATH("blah"), UNIT_TESTS_PATH("blah/blah")));
mu_assert_int_eq(
false,
storage_common_is_subdir(storage, UNIT_TESTS_PATH("blah/blah"), UNIT_TESTS_PATH("blah")));
mu_assert_int_eq(
false,
storage_common_is_subdir(storage, UNIT_TESTS_PATH("blah"), UNIT_TESTS_PATH("blah-blah")));

furi_record_close(RECORD_STORAGE);
}

MU_TEST_SUITE(storage_rename) {
MU_RUN_TEST(storage_file_rename);
MU_RUN_TEST(storage_dir_rename);
MU_RUN_TEST(storage_equiv_and_subdir);

Storage* storage = furi_record_open(RECORD_STORAGE);
storage_dir_remove(storage, EXT_PATH("dir.old"));
storage_dir_remove(storage, EXT_PATH("dir.new"));
for(size_t i = 0; i < COUNT_OF(dir_rename_tests); i++) {
storage_dir_remove(storage, dir_rename_tests[i][0]);
storage_dir_remove(storage, dir_rename_tests[i][1]);
}
furi_record_close(RECORD_STORAGE);
}

Expand Down Expand Up @@ -653,7 +702,7 @@ MU_TEST(test_md5_calc) {
Storage* storage = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(storage);

const char* path = UNIT_TESTS_PATH("storage/md5.txt");
const char* path = UNIT_TESTS_RESOURCES_PATH("storage/md5.txt");
const char* md5_cstr = "2a456fa43e75088fdde41c93159d62a2";
const uint8_t md5[MD5_HASH_SIZE] = {
0x2a,
Expand Down
2 changes: 1 addition & 1 deletion applications/examples/example_thermo/example_thermo.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ static void example_thermo_draw_callback(Canvas* canvas, void* ctx) {
snprintf(text_store, TEXT_STORE_SIZE, "Temperature: %+.1f%c", (double)temp, temp_units);
} else {
/* Or show a message that no data is available */
strncpy(text_store, "-- No data --", TEXT_STORE_SIZE);
strlcpy(text_store, "-- No data --", TEXT_STORE_SIZE);
}

canvas_draw_str_aligned(canvas, middle_x, 58, AlignCenter, AlignBottom, text_store);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
ID 1234:abcd Generic:USB Keyboard
REM Declare ourselves as a generic usb keyboard

REM This will install qFlipper on Linux/Gnome, using the latest AppImage package

REM Open a terminal
ALT F2
DELAY 1000
STRINGLN gnome-terminal --maximize
DELAY 1000

REM Ensure we have a folder to run executables from
STRINGLN mkdir -p $HOME/.local/bin

REM Download the latest AppImage
STRINGLN curl -fsSL "https://update.flipperzero.one/qFlipper/release/linux-amd64/AppImage" -o "$HOME/.local/bin/qFlipper"
DELAY 1000

REM Make it executable
STRINGLN chmod +x $HOME/.local/bin/qFlipper

REM Extract the appimage in /tmp to install icon and .desktop file
STRINGLN cd /tmp
STRINGLN $HOME/.local/bin/qFlipper --appimage-extract > /dev/null
STRINGLN sed "s@Exec=qFlipper@Exec=$HOME/.local/bin/qFlipper@" squashfs-root/usr/share/applications/qFlipper.desktop > $HOME/.local/share/applications/qFlipper.desktop
STRINGLN mkdir -p $HOME/.local/share/icons/hicolor/512x512/apps
STRINGLN cp squashfs-root/usr/share/icons/hicolor/512x512/apps/qFlipper.png $HOME/.local/share/icons/hicolor/512x512/apps/qFlipper.png
STRINGLN rm -rf squashfs-root
STRINGLN cd

REM Depending on the Linux distribution and display manager
REM there might be several ways to update desktop entries
REM try all
STRINGLN xdg-desktop-menu forceupdate || true
STRINGLN update-desktop-database ~/.local/share/applications || true

STRINGLN echo "
ENTER
REPEAT 60
STRINGLN ==========================================================================================
STRINGLN qFlipper has been installed to $HOME/.local/bin/
STRINGLN It should appear in your Applications menu.
STRINGLN If it does not, you might want to log out and log in again.
ENTER
STRINGLN If you prefer to run qFlipper from your terminal, either use the absolute path
STRINGLN or make sure $HOME/.local/bin/ is included in your PATH environment variable.
ENTER
STRINGLN Additional configurations might be required by your Linux distribution such as
STRINGLN group membership, udev rules or else.
STRINGLN ==========================================================================================
STRINGLN "
87 changes: 87 additions & 0 deletions applications/main/bad_usb/resources/badusb/demo_gnome.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
ID 1234:abcd Generic:USB Keyboard
REM Declare ourselves as a generic usb keyboard
REM You can override this to use something else
REM Check the `lsusb` command to know your own devices IDs

REM This is BadUSB demo script for Linux/Gnome

REM Open terminal window
DELAY 1000
ALT F2
DELAY 500
STRING gnome-terminal --maximize
DELAY 500
ENTER
DELAY 750

REM Clear the screen in case some banner was displayed
STRING clear
ENTER

REM Bigger shell script example
STRING cat > /dev/null << EOF
ENTER

STRING Hello World!
ENTER

DEFAULT_DELAY 50

STRING =
REPEAT 59
ENTER
ENTER

STRING _.-------.._ -,
ENTER
HOME
STRING .-"'''"--..,,_/ /'-, -, \
ENTER
HOME
STRING .:" /:/ /'\ \ ,_..., '. | |
ENTER
HOME
STRING / ,----/:/ /'\ _\~'_-"' _;
ENTER
HOME
STRING ' / /'"""'\ \ \.~'_-' ,-"'/
ENTER
HOME
STRING | | | 0 | | .-' ,/' /
ENTER
HOME
STRING | ,..\ \ ,.-"' ,/' /
ENTER
HOME
STRING ; : '/'""\' ,/--==,/-----,
ENTER
HOME
STRING | '-...| -.___-Z:_______J...---;
ENTER
HOME
STRING : ' _-'
ENTER
HOME
STRING _L_ _ ___ ___ ___ ___ ____--"'
ENTER
HOME
STRING | __|| | |_ _|| _ \| _ \| __|| _ \
ENTER
HOME
STRING | _| | |__ | | | _/| _/| _| | /
ENTER
HOME
STRING |_| |____||___||_| |_| |___||_|_\
ENTER
HOME
ENTER

STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script format
ENTER
STRING More information about script syntax can be found here:
ENTER
STRING https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/file_formats/BadUsbScriptFormat.md
ENTER

STRING EOF
ENTER
1 change: 0 additions & 1 deletion applications/main/gpio/scenes/gpio_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ ADD_SCENE(gpio, test, Test)
ADD_SCENE(gpio, usb_uart, UsbUart)
ADD_SCENE(gpio, usb_uart_cfg, UsbUartCfg)
ADD_SCENE(gpio, usb_uart_close_rpc, UsbUartCloseRpc)
ADD_SCENE(gpio, exit_confirm, ExitConfirm)
Loading

0 comments on commit a7675d7

Please sign in to comment.