]> gitweb.hhaalo.de Git - sane-kds-s2000w-net.git/commitdiff
add validation for string and int
authorBastian Dehn <hhaalo@arcor.de>
Sat, 25 Oct 2025 17:27:36 +0000 (19:27 +0200)
committerBastian Dehn <hhaalo@arcor.de>
Sat, 25 Oct 2025 17:27:36 +0000 (19:27 +0200)
src/kds_s2000w_handler.h
src/kds_s2000w_handler_opts.c
src/kds_s2000w_handler_opts.h
src/kds_s2000w_net.c
tests/kds_s2000w_net_set_opt_tests.c

index c391f6ddd81f865b12a8a16a41553628e514f8ef..1d7080fe21f203be10159fb33e3f45fd89ca070b 100644 (file)
@@ -63,8 +63,8 @@ connection_state_t kds_s2000w_handler_open(const char* devicename, void** handle
 void kds_s2000w_handler_close(handler_t* h);
 void kds_s2000w_handler_recreate_session(handler_t* h);
 
-void kds_s2000w_handler_opts_get_option(handler_t* handle, uint32_t option, void* value, int32_t* info);
-void kds_s2000w_handler_opts_set_option(handler_t* handle, uint32_t option, void* value, int32_t* info);
+int32_t kds_s2000w_handler_opts_get_option(handler_t* handle, uint32_t option, void* value, int32_t* info);
+int32_t kds_s2000w_handler_opts_set_option(handler_t* handle, uint32_t option, void* value, int32_t* info);
 
 void kds_s2000w_handler_start_scan(const handler_t* h);
 void kds_s2000w_handler_stop_scan(const handler_t* h);
index 60e58b878eaf2a75aa9b92578c1d414081ede060..a6ffc7b702768b4c8e518ea7fdf956c857835a52 100644 (file)
@@ -15,6 +15,11 @@ enum {
        RELOAD_PARAMS = 4
 };
 
+enum {
+       GOOD = 0,
+       INVAL = 4
+};
+
 void _kds_s2000w_handler_opts_write_value_to_json(json_object* value_object, SANE_Value_Type value_type, void* value)
 {
        if (value_type == SANE_TYPE_INT || value_type == SANE_TYPE_BOOL) {
@@ -130,6 +135,25 @@ json_object* _kds_s2000w_handler_opts_load_config(handler_t* h)
        return config;
 }
 
+bool _kds_s2000w_opts_validate(SANE_Option_Descriptor* descriptor, const void* value)
+{
+       if (descriptor->constraint_type == SANE_CONSTRAINT_RANGE) {
+               const int32_t* int_value = (const int32_t*) value;
+               bool valid = *int_value >= descriptor->constraint.range->min;
+               return valid && *int_value <= descriptor->constraint.range->max;
+       }
+
+       if (descriptor->constraint_type == SANE_CONSTRAINT_STRING_LIST) {
+               const char* str_value = (const char*) value;
+               for (int32_t i = 0; descriptor->constraint.string_list[i] != NULL; i++) {
+                       if (strcmp(descriptor->constraint.string_list[i], str_value) == 0)
+                               return true;
+               }
+       }
+
+       return false;
+}
+
 void _kds_s2000w_handler_opts_set_valid_coord_x(option_descriptor_t* descriptor, handler_t* h)
 {
        bool valid = h->coord->offset_x >= 0 && h->coord->offset_x <= 75;
@@ -443,7 +467,7 @@ void _kds_s2000w_handler_opts_set_depends_opts(const handler_t* h,
        }
 }
 
-void kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* value, int32_t* info)
+int32_t kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* value, int32_t* info)
 {
        json_object* config = _kds_s2000w_handler_opts_load_config(h);
 
@@ -451,7 +475,7 @@ void kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* val
        if (strcmp(descriptor->config_name, OPTION_COUNT) == 0) {
                int32_t* int_value = (int32_t*) value;
                *int_value = kds_s2000w_option_descriptors_get_max_option_count();
-               return;
+               return GOOD;
        }
 
        json_object* value_object = json_object_object_get(config, descriptor->config_name);
@@ -461,7 +485,7 @@ void kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* val
                h->coord->offset_x = json_object_get_int(value_object);
                uint32_t pixel = kds_s2000w_pixel_converter_tenth_inch_to_pixel(GUI_DPI, h->coord->offset_x);
                *int_value = pixel;
-               return;
+               return GOOD;
        }
 
        if (strcmp(descriptor->config_name, IMAGE_OFFSET_Y) == 0) {
@@ -469,7 +493,7 @@ void kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* val
                h->coord->offset_y = json_object_get_int(value_object);
                uint32_t pixel = kds_s2000w_pixel_converter_tenth_inch_to_pixel(GUI_DPI, h->coord->offset_y);
                *int_value = pixel;
-               return;
+               return GOOD;
        }
 
        if (strcmp(descriptor->config_name, IMAGE_WIDTH) == 0) {
@@ -480,7 +504,7 @@ void kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* val
                uint32_t width_pixel = kds_s2000w_pixel_converter_tenth_inch_to_pixel(GUI_DPI, h->coord->width);
                uint32_t offset_x_pixel = kds_s2000w_pixel_converter_tenth_inch_to_pixel(GUI_DPI, tenth_inch_offset_x);
                *int_value = offset_x_pixel + width_pixel;
-               return;
+               return GOOD;
        }
 
        if (strcmp(descriptor->config_name, IMAGE_HEIGHT) == 0) {
@@ -491,16 +515,17 @@ void kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* val
                uint32_t height_pixel = kds_s2000w_pixel_converter_tenth_inch_to_pixel(GUI_DPI, h->coord->height);
                uint32_t offset_y_pixel = kds_s2000w_pixel_converter_tenth_inch_to_pixel(GUI_DPI, tenth_inch_offset_y);
                *int_value = offset_y_pixel + height_pixel;
-               return;
+               return GOOD;
        }
 
        _kds_s2000w_handler_opts_write_value(value_object, descriptor->descriptor->type, value);
+       return GOOD;
 }
 
-void kds_s2000w_handler_opts_set_option(handler_t* h, uint32_t option, void* value, int32_t* info)
+int32_t kds_s2000w_handler_opts_set_option(handler_t* h, uint32_t option, void* value, int32_t* info)
 {
        if (h->scan_status->state == STARTED)
-               return;
+               return GOOD;
 
        json_object* config = _kds_s2000w_handler_opts_load_config(h);
        option_descriptor_t* descriptor = kds_s2000w_option_descriptors_full_get_by_number(option);
@@ -525,6 +550,10 @@ void kds_s2000w_handler_opts_set_option(handler_t* h, uint32_t option, void* val
        if (h->profile > PROFILE_MIN)
                _kds_s2000w_handler_opts_set_depends_opts(h, descriptor->config_name, config);
 
+       if (!_kds_s2000w_opts_validate(descriptor->descriptor, value))
+               return INVAL;
+
        _kds_s2000w_handler_opts_set_info_option(descriptor, info);
        _kds_s2000w_handler_opts_set_options(h);
+       return GOOD;
 }
\ No newline at end of file
index 4c0a2762d3da1dd7cb21c290215cb86613cf3001..75ccd69880fef5dcf2edc49737ffe839c34e3767 100644 (file)
@@ -3,7 +3,7 @@
 #include <stdint.h>
 #include "kds_s2000w_handler.h"
 
-void kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* value, int32_t* info);
-void kds_s2000w_handler_opts_set_option(handler_t* h, uint32_t option, void* value, int32_t* info);
+int32_t kds_s2000w_handler_opts_get_option(handler_t* h, uint32_t option, void* value, int32_t* info);
+int32_t kds_s2000w_handler_opts_set_option(handler_t* h, uint32_t option, void* value, int32_t* info);
 
 #endif
\ No newline at end of file
index fd8a6888dea243a7553bbdd50191aa238217ed44..6292392cca3c1e0a371eee3d94595a6f5bbf71e1 100644 (file)
@@ -127,10 +127,10 @@ SANE_Status sane_kds_s2000w_net_control_option(SANE_Handle handle,
 
        handler_t* h = (handler_t*) handle;
        if (action == SANE_ACTION_GET_VALUE)
-               kds_s2000w_handler_opts_get_option(h, option, value, info);
+               return kds_s2000w_handler_opts_get_option(h, option, value, info);
 
        if (action == SANE_ACTION_SET_VALUE)
-               kds_s2000w_handler_opts_set_option(h, option, value, info);
+               return kds_s2000w_handler_opts_set_option(h, option, value, info);
 
        return SANE_STATUS_GOOD;
 }
index d3f3937b8fb6bc73791a49f719a47277f45b541e..a8e97fef28575dc9bf0e61911ecd74a4f53551b5 100644 (file)
@@ -166,11 +166,43 @@ void kds_s2000w_net_set_option_int(void** state)
        set_value = NULL;
 }
 
+void kds_s2000w_net_set_invalid_option_string(void** state)
+{
+       int32_t* info = malloc(sizeof(int32_t));
+       if (info == NULL)
+               return;
+
+       response_t* resp = (response_t*) *state;
+       handler_t* h = kds_s2000w_handler_init();
+       *info = 0;
+       response_t* set_opt_resp = kds_s2000w_client_response_init();
+       set_opt_resp->code = 200;
+
+       will_return(mock_response, resp);
+       will_return(__wrap_kds_s2000w_client_get_option, 0);
+       will_return(mock_response, set_opt_resp);
+       will_return(__wrap_kds_s2000w_client_set_option, 0);
+       expect_function_call(__wrap_kds_s2000w_client_get_option);
+       expect_function_call(__wrap_kds_s2000w_client_set_option);
+
+       SANE_Status status = sane_kds_s2000w_net_control_option(h, 3, SANE_ACTION_SET_VALUE, "Bunt", info);
+
+       assert_int_equal(status, SANE_STATUS_INVAL);
+
+       kds_s2000w_client_response_free(set_opt_resp);
+       set_opt_resp = NULL;
+       kds_s2000w_handler_free(h);
+       h = NULL;
+       free(info);
+       info = NULL;
+}
+
 int main()
 {
        const struct CMUnitTest net_tests[] = {
                cmocka_unit_test_setup_teardown(kds_s2000w_net_set_option_string, setup_default_option, teardown_default_option),
-               cmocka_unit_test_setup_teardown(kds_s2000w_net_set_option_int, setup_default_option, teardown_default_option)
+               cmocka_unit_test_setup_teardown(kds_s2000w_net_set_option_int, setup_default_option, teardown_default_option),
+               cmocka_unit_test_setup_teardown(kds_s2000w_net_set_invalid_option_string, setup_default_option, teardown_default_option)
        };
 
        return cmocka_run_group_tests(net_tests, NULL, NULL);