webui icon indicating copy to clipboard operation
webui copied to clipboard

get_float does not work correctly

Open ttytm opened this issue 1 year ago • 10 comments

Bug Description

https://github.com/webui-dev/webui/blob/9518b9e8442c9cbd275110c4e7871d0fe9f934b7/examples/C/call_c_from_js/main.c#L35

prints:

my_function_integer 4: 12345,000000

Expected Behavior

my_function_integer 4: 12345.6789

Reproduction Steps

The call_c_from_js example can be used as reproduction

Error Logs

No response

Possible Solution

No response

Version

2.5.0-beta

Environment Details (OS name, version, etc.)

Linux 6.6.33-1-lts x86_64 GNU/Linux
cc (GCC) 14.1.1 20240522

ttytm avatar Jun 16 '24 02:06 ttytm

With a fix the asserts in the added test can be enabled

https://github.com/webui-dev/webui/blob/6cefcb1f3d2f1b5f2d1573b0dc3f42fcd3ce2578/tests/call_c_from_js.c#L36-L51

ttytm avatar Jun 16 '24 02:06 ttytm

I will look into that tomorrow, Thank you for the report @ttytm.

hassandraga avatar Jun 16 '24 03:06 hassandraga

I can't reproduce the issue. Ubuntu 22.04.3 LTS Mozilla Firefox 126.0 my_function_integer 4: 12345.678900

Probably we may need the full logs to know what's going on. Also, the browser or WV you are using.

hassandraga avatar Jun 18 '24 15:06 hassandraga

Happens in chrome and Firefox for me.

Logs `call_c_from_js` example:
[User] webui_new_window()
[User] webui_get_new_window_id()
[Core]          WebUI v2.5.0-beta.1 (GNU/Linux, GCC, Non-Encrypted)
[Core]          _webui_init()
[Core]          _webui_get_current_path()
[Core]          _webui_malloc([4096])
[Core]          _webui_ptr_add(0x0x5c0f4c35d6b0)
[Core]          _webui_malloc([4096])
[Core]          _webui_ptr_add(0x0x5c0f4c35f6c0)
[User] webui_new_window_id([1])
[Core]          _webui_malloc([2296])
[Core]          _webui_ptr_add(0x0x5c0f4c361750)
[Core]          _webui_malloc([4096])
[Core]          _webui_ptr_add(0x0x5c0f4c362760)
[Core]          _webui_malloc([4096])
[Core]          _webui_ptr_add(0x0x5c0f4c364770)
[User] webui_new_window_id() -> New window #1 @ 0x0x5c0f4c361750
[User] webui_new_window_id() -> New window Token 0x9AD7C4FE (2597831934)
[User] webui_bind([1], [MyID_One], [0x0x5c0f4b48fa79])
[Core]          _webui_malloc([12])
[Core]          _webui_ptr_add(0x0x5c0f4c366780)
[Core]          _webui_get_cb_index([1/MyID_One])
[Core]          _webui_set_cb_index([1/MyID_One])
[User] webui_bind([1], [MyID_Two], [0x0x5c0f4b48fae3])
[Core]          _webui_malloc([12])
[Core]          _webui_ptr_add(0x0x5c0f4c3667a0)
[Core]          _webui_get_cb_index([1/MyID_Two])
[Core]          _webui_set_cb_index([1/MyID_Two])
[User] webui_bind([1], [MyID_Three], [0x0x5c0f4b48fbdf])
[Core]          _webui_malloc([14])
[Core]          _webui_ptr_add(0x0x5c0f4c3667c0)
[Core]          _webui_get_cb_index([1/MyID_Three])
[Core]          _webui_set_cb_index([1/MyID_Three])
[User] webui_bind([1], [MyID_Four], [0x0x5c0f4b48fd82])
[Core]          _webui_malloc([13])
[Core]          _webui_ptr_add(0x0x5c0f4c3667e0)
[Core]          _webui_get_cb_index([1/MyID_Four])
[Core]          _webui_set_cb_index([1/MyID_Four])
[User] webui_bind([1], [MyID_RawBinary], [0x0x5c0f4b48fc6b])
[Core]          _webui_malloc([18])
[Core]          _webui_ptr_add(0x0x5c0f4c366800)
[Core]          _webui_get_cb_index([1/MyID_RawBinary])
[Core]          _webui_set_cb_index([1/MyID_RawBinary])
[User] webui_show([1])
[Core]          _webui_show([1])
[Core]          _webui_malloc([2151])
[Core]          _webui_ptr_add(0x0x5c0f4c366830)
[Core]          _webui_is_valid_url([<!DOCTYP...])
[Core]          _webui_show() -> Embedded HTML:
- - -[HTML]- - - - - - - - - -
<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <script src="webui.js"></script>    <title>Call C from JavaScript Example</title>    <style>       body {            font-family: 'Arial', 
sans-serif;            color: white;            background: linear-gradient(to right, #507d91, #1c596f, #022737);            text-align: center;            font-size: 18px;        }        button, i
nput {            padding: 10px;            margin: 10px;            border-radius: 3px;            border: 1px solid #ccc;            box-shadow: 0 3px 5px rgba(0,0,0,0.1);      
.2s;        }        button {            background: #3498db;            color: #fff;             cursor: pointer;            font-size: 16px;        }        h1 { text-shadow: -7
57 57 / 76%); }        button:hover { background: #c9913d; }        input:focus { outline: none; border-color: #3498db; }    </style>  </head>  <body>    <h1>WebUI - Call C from J
p>Call C functions with arguments (<em>See the logs in your terminal</em>)</p>    <button onclick="webui.call('MyID_One', 'Hello', 'World');">Call my_function_string()</button>   
click="webui.call('MyID_Two', 123, 456, 789, 12345.6789);">Call my_function_integer()</button>    <br>    <button onclick="webui.call('MyID_Three', true, false);">Call my_function
    <br>    <button onclick="webui.call('MyID_RawBinary', new Uint8Array([0x41,0x42,0x43]), big_arr);">      Call my_function_raw_binary()</button>    <br>    <p>Call a C function
ponse</p>    <button onclick="MyJS();">Call my_function_with_response()</button>    <div>Double: <input type="text" id="MyInputID" value="2"></div>    <script>      const arr_size
 const big_arr = new Uint8Array(arr_size);      big_arr[0] = 0xA1;      big_arr[arr_size - 1] = 0xA2;      function MyJS() {        const MyInput = document.getElementById('MyInpu
 number = MyInput.value;        webui.call('MyID_Four', number, 2).then((response) => {            MyInput.value = response;        });      }    </script>  </body></html>
- - - - - - - - - - - - - - - -
[Core]          _webui_show_window(HTML, [1])
[Core]          _webui_get_free_port()
[Core]          _webui_port_is_used([16282])
[Core]          _webui_socket_test_listen_mg([16282])
[Core]          _webui_malloc([64])
[Core]          _webui_ptr_add(0x0x5c0f4c367840)
[Core]          _webui_malloc([32])
[Core]          _webui_ptr_add(0x0x5c0f4c367b90)
[Core]          _webui_malloc([22])
[Core]          _webui_ptr_add(0x0x5c0f4c3680b0)
[Core]          _webui_wv_show([http://localhost:16282])
[Core]          _webui_wv_show() -> GTK loaded [libgtk-3.so.0]
[Core]          _webui_wv_show() -> WebKit loaded [libwebkit2gtk-4.1.so.0]
[Core]          _webui_malloc([22])
[Core]          _webui_ptr_add(0x0x5c0f4c468bf0)
[Core]          _webui_malloc([56])
[Core]          _webui_ptr_add(0x0x5c0f4c56cb80)
[Core]          _webui_wv_show() -> New WebView window
[Core]          _webui_wv_create()
[Core]          [Thread .] _webui_webview_thread()
[Core]          [Thread .] _webui_webview_thread() -> Started
[Core]          _webui_wv_show() -> Return [1]
[Core]          _webui_show_window() -> WebView Found.
[Core]          _webui_free_mem(0x0x5c0f4c3680b0)
[Core]          _webui_free_mem(0x0x5c0f4c3680b0) -> Free 32 bytes
[Core]          _webui_show_window() -> Waiting for window connection
[Core]          _webui_server_thread()
[Core]          _webui_server_thread([1]) -> URL: [http://localhost:16282]
[Core]          _webui_malloc([64])
[Core]          _webui_ptr_add(0x0x713464000b70)
[Core]          _webui_server_thread([1]) -> Listening Success
[Core]          _webui_server_thread([1]) -> HTTP/WS Port: 127.0.0.1:16282
[Core]          _webui_server_thread([1]) -> Timeout is 15 seconds
[Core]          _webui_server_thread([1]) -> Root path: .
[Core]          _webui_server_thread([1]) -> Waiting for first HTTP request
[Core]          _webui_http_handler()
[Core]          _webui_http_handler() -> GET [/]
[Core]          _webui_http_handler() -> Embedded Index HTML
[Core]          _webui_http_send()
[Core]          _webui_http_handler() -> HTTP Status Code: 200
[Core]          _webui_server_thread([1]) -> Waiting for first connection
[Core]          _webui_http_handler()
[Core]          _webui_http_handler() -> GET [/webui.js]
[Core]          _webui_http_handler() -> WebUI-Bridge
[Core]          _webui_generate_js_bridge()
[Core]          _webui_malloc([138])
[Core]          _webui_ptr_add(0x0x713458005020)
[Core]          _webui_malloc([21406])
[Core]          _webui_ptr_add(0x0x713458006540)
[Core]          _webui_free_mem(0x0x713458005020)
[Core]          _webui_free_mem(0x0x713458005020) -> Free 256 bytes
[Core]          _webui_http_send()
[Core]          _webui_free_mem(0x0x713458006540)
[Core]          _webui_free_mem(0x0x713458006540) -> Free 32768 bytes
[Core]          _webui_http_handler() -> HTTP Status Code: 200
[Core]          _webui_ws_connect_handler()
[Core]          _webui_ws_ready_handler()
[Core]          _webui_receive([1], [2], [0])
[Core]          _webui_malloc([40])
[Core]          _webui_ptr_add(0x0x713474004ba0)
[Core]          [Thread .] _webui_process_thread()
[Core]          _webui_process(1)
[Core]          _webui_process(1) -> Start
[Core]          _webui_process(1) -> WebSocket connected
[Core]          _webui_process(1) -> Finished.
[Core]          _webui_free_mem(0x0x71346402a5e0)
[Core]          _webui_free_mem(0x0x713474004ba0)
[Core]          _webui_free_mem(0x0x713474004ba0) -> Free 64 bytes
[Loop] webui_wait()
[Loop] webui_wait() -> Waiting (Timeout in 15 seconds)
[Loop] webui_wait() -> Linux WebView loop
[Core]          _webui_server_thread([1]) -> Window Connected.
[Core]          _webui_wv_event_title()
[Core]          _webui_ws_data_handler()
[Core]          _webui_receive([1], [1], [49])
[Core]          _webui_malloc([49])
[Core]          _webui_ptr_add(0x0x713474004ba0)
[Core]          _webui_malloc([40])
[Core]          _webui_ptr_add(0x0x713474004bf0)
[Core]          _webui_ws_data_handler() -> Finished.
[Core]          [Thread .] _webui_process_thread()
[Core]          _webui_process(2)
[Core]          _webui_process(2) -> Start
[Core]          _webui_get_token()
[Core]          _webui_get_token() -> 0x9AD7C4FE
[Core]          _webui_get_id()
[Core]          _webui_get_id() -> 0xFFFF
[Core]          _webui_process(2) -> Data received
[Core]          _webui_process(2) -> Packet Size : 49 bytes
[Core]          _webui_process(2) -> Packet Header : [ 0xDD 0xFE 0xC4 0xD7 0x9A 0xFF 0xFF 0xF9 ]
[Core]          _webui_process(2) -> Packet Token: 0x9AD7C4FE (2597831934)
[Core]          _webui_process(2) -> Packet ID: 0xFFFF (65535)
[Core]          _webui_process(2) -> Packet Data: []
[Core]          _webui_process(2) -> WEBUI_CMD_CALL_FUNC 
[Core]          _webui_process(2) -> Call ID: [65535] 
[Core]          _webui_process(2) -> Element: [MyID_Two] 
[Core]          _webui_generate_internal_id([1], [MyID_Two])
[Core]          _webui_malloc([12])
[Core]          _webui_ptr_add(0x0x71346c000bb0)
[Core]          _webui_malloc([288])
[Core]          _webui_ptr_add(0x0x71346c000bd0)
[Core]          _webui_process(2) -> Argument 0: 3 bytes
[Core]          _webui_process(2) -> Argument 1: 3 bytes
[Core]          _webui_process(2) -> Argument 2: 3 bytes
[Core]          _webui_process(2) -> Argument 3: 10 bytes
[Core]          _webui_process(2) -> Expected and received 23 bytes of data.
[Core]          _webui_get_cb_index([1/MyID_Two])
[Core]          _webui_process(2) -> Calling user callback
[Call]
[User] webui_get_count()
my_function_integer: There is 4 arguments in this event
[User] webui_get_int()
[User] webui_get_int_at([0])
[User] webui_get_string_at([0])
[User] webui_get_int_at([1])
[User] webui_get_string_at([1])
[User] webui_get_int_at([2])
[User] webui_get_string_at([2])
my_function_integer 1: 123
my_function_integer 2: 456
my_function_integer 3: 789
[User] webui_get_float_at([3])
[User] webui_get_string_at([3])
my_function_integer 4: 12345,000000
[Core]          _webui_process(2) -> user-callback response []
[Core]          _webui_send()
[Core]          _webui_send() -> Token = 0x9AD7C4FE 
[Core]          _webui_send() -> ID = 0xFFFF 
[Core]          _webui_send() -> CMD = 0xf9 
[Core]          _webui_send() -> Data = 0 bytes 
[Core]          _webui_malloc([9])
[Core]          _webui_ptr_add(0x0x71346c000de0)
[Core]          _webui_ws_send()
[Core]          _webui_ws_send() -> Packet size: 9 bytes 
[Core]          _webui_ws_send() -> Packet hex : [ 0xDD 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xF9 0x00 ]
[Core]          _webui_ws_send() -> 9 bytes sent.
[Core]          _webui_free_mem(0x0x71346c000de0)
[Core]          _webui_free_mem(0x0x71346c000de0) -> Free 16 bytes
[Core]          _webui_free_mem(0x0x5c0f4b4c20bb)
[Core]          _webui_free_mem(0x0x71346c000bb0)
[Core]          _webui_free_mem(0x0x71346c000bb0) -> Free 16 bytes
[Core]          _webui_free_mem(0x0x71346c000bd0)
[Core]          _webui_free_mem(0x0x71346c000bd0) -> Free 512 bytes
[Core]          _webui_process(2) -> Finished.
[Core]          _webui_free_mem(0x0x713474004ba0)
[Core]          _webui_free_mem(0x0x713474004ba0) -> Free 64 bytes
[Core]          _webui_free_mem(0x0x713474004bf0)
[Core]          _webui_free_mem(0x0x713474004bf0) -> Free 64 bytes

ttytm avatar Jun 18 '24 16:06 ttytm

I see it doesn't reproduces in CI (asserts for floats are currently commented out, values are only printed):

JS passed:

await webui.assert_float(1.0, 2.3, 3.45);

backed prints:

num1: 1.000000, num2: 2.300000, num3: 3.450000

ref. Test Static step in: webui-dev/webui/actions/runs/9541169685/job/26293993613

Looks correct on the ubuntu runner.

ttytm avatar Jun 18 '24 16:06 ttytm

The get_string call doesn't look right:

[User] webui_get_float_at([3])
[User] webui_get_string_at([3])

The example is unchanged ofc.

ttytm avatar Jun 18 '24 16:06 ttytm

[Core]          _webui_process(2) -> Argument 0: 3 bytes
[Core]          _webui_process(2) -> Argument 1: 3 bytes
[Core]          _webui_process(2) -> Argument 2: 3 bytes
[Core]          _webui_process(2) -> Argument 3: 10 bytes
[Core]          _webui_process(2) -> Expected and received 23 bytes of data.

Looks correct, the UI (bridge) sent all data. Can you please try:

assert(num3 == 3.45f);

hassandraga avatar Jun 18 '24 19:06 hassandraga

[Core]          _webui_process(2) -> Argument 0: 3 bytes
[Core]          _webui_process(2) -> Argument 1: 3 bytes
[Core]          _webui_process(2) -> Argument 2: 3 bytes
[Core]          _webui_process(2) -> Argument 3: 10 bytes
[Core]          _webui_process(2) -> Expected and received 23 bytes of data.

Looks correct, the UI (bridge) sent all data. Can you please try:

assert(num3 == 3.45f);

I'm receiving a 00 decimal so in the test its 3.00 and the assert does not work.

As the logs show, my_function_integer 4: 12345,000000 when 12345.6789 was passed.

ttytm avatar Jun 19 '24 02:06 ttytm

Yes, I want to make sure that the actual value is .0, I want to be sure the issue is not with the print format.

hassandraga avatar Jun 19 '24 03:06 hassandraga

Yep the check failed, tested with atof/strtod/sscanf. The conversion works correctly when setlocale(LC_NUMERIC, "C"); is set.

Then the assert works with the fully specified number:

assert(num3 == 3.450000); // true (requires setlocal on the tested machine)
assert(num3 == 3.45f); // false

ttytm avatar Jun 19 '24 14:06 ttytm

I tried to reproduce the issue, but I can't, it always works fine for me. I manually test it in:

  • Windows x86
  • Linux x86
  • macOS i7 x86
  • macOS ARM M2
  • Linux ARM

hassandraga avatar Jul 08 '24 23:07 hassandraga

Please re-open if the issue still exists.

hassandraga avatar Jul 08 '24 23:07 hassandraga