get_float does not work correctly
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
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
I will look into that tomorrow, Thank you for the report @ttytm.
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.
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
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.
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.
[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);
[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.
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.
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
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
Please re-open if the issue still exists.