Skip to content

#69 support compile under Windows#723

Merged
lidaobing merged 47 commits into
mainfrom
bf_69_windows_2
Jul 14, 2026
Merged

#69 support compile under Windows#723
lidaobing merged 47 commits into
mainfrom
bf_69_windows_2

Conversation

@lidaobing

@lidaobing lidaobing commented Jul 5, 2026

Copy link
Copy Markdown
Member

/close #69

  • send/recv msg
  • send/recv image
  • send/recv file
  • send/recv dir
  • scan neighbors when start
  • chat log / system log
  • crash problem

Summary by Sourcery

Modernize time formatting and networking includes while aligning string allocation with GLib utilities.

Bug Fixes:

  • Use GLib g_strdup for string duplication to ensure consistency with GLib memory management.

Enhancements:

  • Replace gettimeofday/localtime-based timestamp generation with GLib GDateTime for log output.
  • Introduce a cross-platform iptux_network.h header to centralize network-related includes for Windows and Unix-like systems.
  • Clean up low-level networking includes from utility headers to reduce unnecessary dependencies.

Tests:

  • Update UiModelsTest to use GLib g_strdup for test data string allocation.

Summary by Sourcery

Add Windows support for building and running iptux, including network, file transfer, logging, and UI behavior adaptations, while tightening IP handling and error reporting across platforms.

New Features:

  • Support compiling and running iptux on Windows via MSYS2/Clang, including Windows-specific socket and file opening behavior.
  • Introduce Windows-specific helpers for opening files/paths from the UI and for handling case-insensitive string search.

Bug Fixes:

  • Fix crashes and logging failures by checking file descriptor validity and write results for chat and system logs.
  • Harden IP parsing and validation by replacing raw inet_pton/inet_ntop uses with GLib-based helpers and explicit IPv4 checks, returning explicit errors on invalid addresses.
  • Avoid duplicate filenames and path handling issues by using GLib path utilities for splitting and joining paths across platforms.
  • Resolve issues with file transfer progress and EOF handling by checking read/write results and treating zero-length reads correctly.

Enhancements:

  • Abstract low-level networking headers and types into a shared iptux_network.h for cross-platform socket compatibility.
  • Modernize many time-handling call sites to use thread-safe variants (localtime_r/localtime_s) and GLib GDateTime-based formatting.
  • Refine file transfer logic to use GSocket/GOutputStream for receiving files and to add more detailed logging around send/receive failures.
  • Rework AnalogFS path handling to use GLib path APIs, improving portability and robustness.
  • Improve broadcast-address discovery to support Windows adapters via GetAdaptersAddresses while retaining Unix implementations.
  • Extend CoreThread and TcpData to work directly with GSocket/GInetAddress, including structured error reporting via a new iptux_core error domain.
  • Normalize message source typing and logging macros, and replace raw strdup/new with GLib g_strdup in several models and program data paths.
  • Make tests and utilities more robust by using binary-safe file I/O and GLib-aware IP helpers.

Build:

  • Update Meson build scripts and dependencies to link the correct Windows networking libraries (ws2_32, iphlpapi), conditionally build crash utilities, and relax some Clang warning flags for cross-platform builds.
  • Modernize the Windows GitHub Actions workflow to use newer checkout and MSYS2/Clang toolchains, add required dependencies, and run a version check after tests.

CI:

  • Refresh the Windows CI workflow to align with the new toolchain and build configuration and to verify the built binary runs on Windows.

Tests:

  • Adjust core, UI, and utils tests to use the new IP helper functions, GLib string duplication, and to skip time- and path-dependent tests on Windows where necessary.

@lidaobing lidaobing self-assigned this Jul 5, 2026
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

Test Results

69 tests  ±0   69 ✅ ±0   3s ⏱️ ±0s
32 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit 4ad47ae. ± Comparison against base commit 6b98e8e.

♻️ This comment has been updated with latest results.

sourcery-ai[bot]

This comment was marked as outdated.

@lidaobing
lidaobing marked this pull request as draft July 5, 2026 01:32
@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 38.31169% with 190 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.58%. Comparing base (6b98e8e) to head (4ad47ae).

Files with missing lines Patch % Lines
src/iptux-core/internal/RecvFileData.cpp 0.00% 53 Missing ⚠️
src/iptux-core/internal/AnalogFS.cpp 12.50% 35 Missing ⚠️
src/iptux-utils/utils.cpp 63.85% 30 Missing ⚠️
src/iptux-core/internal/SendFileData.cpp 0.00% 27 Missing ⚠️
src/iptux/DataSettings.cpp 0.00% 19 Missing ⚠️
src/iptux-core/internal/TcpData.cpp 73.07% 7 Missing ⚠️
src/iptux-core/CoreThread.cpp 71.42% 4 Missing ⚠️
src/iptux/LogSystem.cpp 78.94% 4 Missing ⚠️
src/iptux-core/internal/SendFile.cpp 0.00% 2 Missing ⚠️
src/iptux-core/internal/support.cpp 33.33% 2 Missing ⚠️
... and 5 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #723      +/-   ##
==========================================
- Coverage   51.88%   51.58%   -0.30%     
==========================================
  Files          64       64              
  Lines        8714     8865     +151     
==========================================
+ Hits         4521     4573      +52     
- Misses       4193     4292      +99     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lidaobing lidaobing changed the title 1 #69 support compile under Windows Jul 5, 2026
Comment thread src/iptux-core/ModelsTest.cpp
lidaobing and others added 10 commits July 5, 2026 19:34
Add a Windows implementation based on GetAdaptersAddresses and compute\nbroadcast addresses from each IPv4 unicast prefix. Keep the existing\nUnix ioctl path unchanged and add required Windows link libraries\n(iphlpapi, ws2_32) in meson for core/core-test targets.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR advances Windows build support for iptux (the C++/GTK LAN messenger) by introducing Windows-friendly build/link settings, consolidating networking platform includes, and replacing several POSIX-only helpers with GLib/GIO alternatives to improve cross-platform portability.

Changes:

  • Add Windows-specific Meson dependencies/linking (e.g., ws2_32, iphlpapi) and a GitHub Actions Windows CI workflow update (MSYS2 CLANG64).
  • Centralize platform networking includes via iptux_network.h and adjust code to use GLib/GIO APIs for IP parsing/formatting and file/path handling.
  • Introduce Windows path launching helper and gate/adjust tests and time APIs for Windows builds.

Reviewed changes

Copilot reviewed 52 out of 52 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/main/meson.build Conditional crash utils / link args for Windows
src/main/iptux.cpp Windows-safe localtime_* + disable crash handler
src/iptux/UiModelsTest.cpp Use g_strdup; skip some tests on Windows
src/iptux/UiModels.cpp Update message source enum name
src/iptux/UIHelperWindows.h Declare Windows “open path” helper
src/iptux/UIHelperWindows.cpp Implement Windows path launcher (ShellExecuteW)
src/iptux/UiHelperTest.cpp Skip TZ/image tests on Windows
src/iptux/UiHelper.h Use iptux_network.h; add iptux_open_path
src/iptux/UiHelper.cpp Implement iptux_open_path + Windows branch; localtime_*
src/iptux/UiCoreThread.h Remove non-portable network include
src/iptux/UiCoreThread.cpp Remove non-portable socket include
src/iptux/RevisePal.cpp Cast for ntohl formatting portability
src/iptux/meson.build Add Windows deps and build UiHelperWindows.cpp
src/iptux/MainWindow.h Undef Windows CreateWindow macro collision
src/iptux/MainWindow.cpp Add Windows strcasestr compat + localtime_*
src/iptux/LogSystem.cpp Add logging, error checks, GLib path building
src/iptux/DialogPeer.cpp Use g_build_filename for received file paths
src/iptux/DataSettings.h Add missing <string> include
src/iptux/DataSettings.cpp Replace getline/inet_pton flow with portable parsing helpers
src/iptux/callback.cpp Use nullptr for GTK dialog sentinel
src/iptux/Application.cpp Avoid SIGPIPE handling on Windows; open log paths
src/iptux-utils/UtilsTest.cpp Skip dupPath test on Windows
src/iptux-utils/utils.h Introduce iptux_network.h, add GSocket read/write overloads, add is_ipv4
src/iptux-utils/utils.cpp Use GLib networking helpers; add GSocket read/write; portable dir iteration
src/iptux-utils/TestHelper.cpp Read test data as binary
src/iptux-utils/output.h Qualify logging macros with ::iptux::
src/iptux-utils/output.cpp Switch timestamp formatting to GDateTime
src/iptux-utils/meson.build Add Windows libs to utils deps
src/iptux-utils/Exception.cpp Inline getErrorCode() in header
src/iptux-core/ProgramData.cpp Use g_strdup for filepath duplication
src/iptux-core/ModelsTest.cpp Use new IP helpers in tests
src/iptux-core/Models.cpp Remove non-portable network include
src/iptux-core/meson.build Add Windows libs (ws2_32, iphlpapi) to core deps
src/iptux-core/internal/TcpData.cpp Use O_BINARY; use this->socket consistently
src/iptux-core/internal/support.cpp Add Windows broadcast discovery path; adjust socket reuse helper
src/iptux-core/internal/SendFileData.h Switch from fd int to GSocket*
src/iptux-core/internal/SendFileData.cpp Use GSocket*, O_BINARY, GLib basename/IP formatting
src/iptux-core/internal/SendFile.h Switch send APIs to GSocket*
src/iptux-core/internal/SendFile.cpp Adapt send pipeline to GSocket* + GLib basename
src/iptux-core/internal/RecvFileData.h Add GOutputStream* receive path
src/iptux-core/internal/RecvFileData.cpp Use GIO stream writing for Windows-friendly receiving
src/iptux-core/internal/iptux_network.h New cross-platform networking include hub
src/iptux-core/internal/Command.cpp Use O_BINARY; update enum usage; sendto cast tweak
src/iptux-core/internal/AnalogFS.cpp Use GLib path building/current dir for portability
src/iptux-core/CoreThread.cpp Remove non-portable socket include
src/api/iptux-core/TransFileModel.h Add <cstdint> include
src/api/iptux-core/Models.h Windows networking include + enum rename
src/api/iptux-core/Exception.h Inline getErrorCode()
src/api/iptux-core/CoreThread.h Remove non-portable network include
meson.build Add warning suppressions helpful for clang/Windows toolchains
.github/workflows/windows.yml Update Windows CI (checkout v4, MSYS2 CLANG64, extra checks)
.gitattributes Enforce LF endings and mark binaries/testdata
Comments suppressed due to low confidence (1)

src/iptux-core/internal/RecvFileData.cpp:521

  • g_output_stream_write_all() returns gboolean (TRUE/FALSE), not -1. Comparing the return value to -1 will never detect failures, so receive-to-file may silently ignore write errors and report success incorrectly.

Comment thread src/iptux-core/internal/support.cpp Outdated
Comment thread src/iptux/DataSettings.cpp Outdated
Comment thread src/iptux-core/internal/AnalogFS.cpp Outdated
Comment thread src/iptux/UIHelperWindows.cpp
Comment on lines +7 to +28
void iptux_launch_file_windows(const char* utf8_path) {
int len = MultiByteToWideChar(CP_UTF8, 0, utf8_path, -1, NULL, 0);
wchar_t* w_path = (wchar_t*)malloc(len * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, utf8_path, -1, w_path, len);

HINSTANCE result = ShellExecuteW(
NULL, // 父窗口句柄
L"open", // 操作类型:打开
w_path, // 文件路径
NULL, // 命令行参数
NULL, // 工作目录
SW_SHOWNORMAL // 显示方式
);

// 3. 释放内存
free(w_path);

// 检查是否成功
if ((INT_PTR)result <= 32) {
LOG_ERROR("Failed to open path: %s, error code: %jd", utf8_path, (intmax_t)(INT_PTR)result);
}
}
Comment thread src/iptux-core/internal/SendFile.cpp Outdated
lidaobing and others added 5 commits July 8, 2026 21:11
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@iptux-src iptux-src deleted a comment from sourcery-ai Bot Jul 14, 2026
@lidaobing
lidaobing marked this pull request as ready for review July 14, 2026 05:13
@lidaobing
lidaobing merged commit 520742e into main Jul 14, 2026
16 of 19 checks passed
@lidaobing
lidaobing deleted the bf_69_windows_2 branch July 14, 2026 05:14
@sourcery-ai

sourcery-ai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Reviewer's Guide

Enable building and running iptux on Windows by introducing a cross‑platform networking abstraction, replacing POSIX‑only APIs with GLib/GIO and Windows‑aware code paths, and tightening file/log handling and tests while updating the Windows CI workflow.

Sequence diagram for TCP file data request using GSocket

sequenceDiagram
  participant TcpHandlerThread as TcpHandlerThreadFunc
  participant TcpData as TcpData
  participant CoreThread as CoreThread
  participant SendFile as SendFile
  participant SendFileData as SendFileData

  TcpHandlerThread->>TcpData: TcpDataEntry(coreThread, clientSocket, error)
  TcpData->>TcpData: DispatchTcpData(error)
  TcpData->>CoreThread: GetPal(gaddr)
  CoreThread-->>TcpData: PalInfo::Ptr
  TcpData->>TcpData: read_ipmsg_prefix(socket, buf, MAX_SOCKLEN)
  TcpData->>SendFile: RequestDataEntry(coreThread, socket, fileattr, attach)
  SendFile->>SendFileData: new SendFileData(coreThread, socket, file)
  SendFileData->>SendFileData: SendFileDataEntry()
  SendFileData->>SendFileData: SendRegularFile()
  SendFileData->>SendFileData: SendData(fd, filesize)
  SendFileData->>socket: xwrite(socket, buf, size)
Loading

Sequence diagram for receiving regular file with GSocket and GOutputStream

sequenceDiagram
  participant RecvFileData as RecvFileData
  participant Command as Command
  participant GSocket as GSocket
  participant GFileOutputStream as GFileOutputStream

  RecvFileData->>GSocket: g_socket_new(...)
  RecvFileData->>Command: SendAskData(GSocket, key, packetn, fileid, 0)
  Command-->>RecvFileData: success/fail
  RecvFileData->>RecvFileData: assert_filename_inexist(file->filepath)
  RecvFileData->>GFileOutputStream: g_file_replace(gfile,..., error)
  RecvFileData->>RecvFileData: RecvData(GSocket, GOutputStream, filesize, 0)
  RecvFileData->>GSocket: g_socket_receive(sock, buf, size,...)
  RecvFileData->>GFileOutputStream: g_output_stream_write_all(os, buf, size,...)
  RecvFileData->>GFileOutputStream: g_output_stream_close(os,...)
Loading

File-Level Changes

Change Details Files
Introduce cross-platform networking and IP utilities and migrate call sites away from direct POSIX socket APIs.
  • Add iptux_network.h to centralize platform-dependent networking headers/types and define MSG_NOSIGNAL and socklen_t on Windows.
  • Refactor utilities to use GInetAddress for IPv4 string/binary conversions and add an is_ipv4 helper.
  • Extend xwrite/xread/read_ipmsg_prefix to work with both file descriptors and GSocket, and add iptux_inet_address_to_in_addr for converting GInetAddress to in_addr.
  • Adjust Command, SendFile, RecvFileData, TcpData, support, CoreThread, and UI code to use the new helpers and GSocket-based APIs instead of raw POSIX socket calls.
src/iptux-core/internal/iptux_network.h
src/iptux-utils/utils.cpp
src/iptux-utils/utils.h
src/iptux-core/internal/Command.cpp
src/iptux-core/internal/SendFile.cpp
src/iptux-core/internal/SendFileData.cpp
src/iptux-core/internal/RecvFileData.cpp
src/iptux-core/internal/TcpData.cpp
src/iptux-core/CoreThread.cpp
src/iptux-core/internal/support.cpp
src/iptux/UiHelper.h
src/iptux/UiHelper.cpp
src/iptux-core/Models.cpp
src/api/iptux-core/Models.h
src/iptux-core/ModelsTest.cpp
src/iptux/DataSettings.cpp
Make file I/O, path handling, and directory traversal portable and more robust.
  • Replace custom filename/path splitting and joining with GLib path functions (g_path_get_basename, g_path_get_dirname, g_build_filename).
  • Change directory walking in utils to use GDir instead of DIR/readdir, and wrap AnalogFS path merging around GLib path utilities.
  • Ensure binary-safe file opens on Windows by adding O_BINARY and guarding O_LARGEFILE, including for send/recv file code and TCP sublayer storage.
  • Adjust ProgramData and tests to use GLib-aware string/file handling and binary modes where appropriate.
src/iptux-utils/utils.cpp
src/iptux-core/internal/RecvFileData.cpp
src/iptux-core/internal/SendFileData.cpp
src/iptux-core/internal/AnalogFS.cpp
src/iptux-core/ProgramData.cpp
src/iptux-utils/TestHelper.cpp
src/iptux/DialogPeer.cpp
src/iptux/RevisePal.cpp
Improve time handling and logging to use GLib primitives and add more diagnostics.
  • Switch low-level logging timestamp generation to GDateTime in output.cpp.
  • Make several localtime_r calls portable with localtime_s on Windows in utils, MainWindow, UiHelper, and main entry.
  • Harden LogSystem initialization and logging by building platform-independent log paths, logging initialization state, and checking write/open failures.
  • Introduce a small iptux_error error domain and propagate detailed GError information from TcpData and TCP handler threads.
src/iptux-utils/output.cpp
src/iptux-utils/utils.cpp
src/iptux/LogSystem.cpp
src/iptux/MainWindow.cpp
src/iptux/UiHelper.cpp
src/main/iptux.cpp
src/iptux-core/internal/TcpData.cpp
src/iptux-core/internal/iptux_error.h
src/iptux/Application.cpp
Add Windows-specific helpers and conditionals for UI and tests.
  • Introduce UIHelperWindows.{h,cpp} implementing iptux_launch_file_windows and route iptux_open_path through it on Windows.
  • Fix name clashes and missing APIs on Windows (e.g., strcasestr compat, undefine CreateWindow macro).
  • Guard POSIX-only tests (timezone, image sizing, dupPath, some Gtk text checks) with !WIN32 conditions so the test suite compiles on Windows.
src/iptux/UIHelperWindows.h
src/iptux/UIHelperWindows.cpp
src/iptux/UiHelper.h
src/iptux/UiHelper.cpp
src/iptux/MainWindow.cpp
src/iptux/UiHelperTest.cpp
src/iptux/UiModelsTest.cpp
src/iptux-utils/UtilsTest.cpp
src/iptux/MainWindow.h
Update message and model enums and usage to reflect new naming and GLib conventions.
  • Rename MessageSourceType::ERROR to MessageSourceType::MST_ERROR and update all uses (logging, UI message formatting, error feedback).
  • Inline Exception::getErrorCode and tidy up unused declarations.
  • Switch some strdup calls in core/models/UI tests to g_strdup for GLib-managed strings.
src/api/iptux-core/Models.h
src/iptux/UiModels.cpp
src/iptux-core/internal/Command.cpp
src/api/iptux-core/Exception.h
src/iptux-utils/Exception.cpp
src/iptux-core/ProgramData.cpp
src/iptux/UiModelsTest.cpp
Modernize build configuration and add a Windows CI workflow using MSYS2/clang.
  • Adjust meson.build to add warning suppressions needed for clang, conditionally link crash utils and -ldl only on non-Windows, and wire in ws2_32/iphlpapi/libs on Windows for core, utils, and UI targets.
  • Update src/main/meson.build and src/iptux-core/meson.build to centralize platform-specific dependencies.
  • Revise .github/workflows/windows.yml to use msys2/setup-msys2@v2 with CLANG64 toolchain, appropriate mingw-w64-clang packages, run tests, and verify iptux --version.
meson.build
src/main/meson.build
src/iptux-core/meson.build
src/iptux-utils/meson.build
src/iptux/meson.build
.github/workflows/windows.yml

Assessment against linked issues

Issue Objective Addressed Explanation
#69 Enable the project to compile and run on Windows (including necessary portability fixes, build system changes, and CI configuration).

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 6 issues, and left some high level feedback:

  • In CoreThread's tcpHandlerThreadFunc, res is used after the try/catch block but is never initialized if TcpDataEntry throws before assigning it; consider initializing res to a known value and only checking it when the call actually returns.
  • TcpData::DispatchTcpData assumes the GError** passed in is non-null and calls g_set_error/g_set_error_literal unconditionally; it would be safer either to require and assert a non-null error pointer or guard these calls when error is nullptr to avoid undefined behavior.
  • RecvFileData::RecvRegularFile now computes a fullpath via assert_filename_inexist and writes to that path, but utime is still called with file->filepath; updating timestamps on fullpath instead would avoid mismatches when the destination filename is altered.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In CoreThread's tcpHandlerThreadFunc, `res` is used after the try/catch block but is never initialized if TcpDataEntry throws before assigning it; consider initializing `res` to a known value and only checking it when the call actually returns.
- TcpData::DispatchTcpData assumes the GError** passed in is non-null and calls g_set_error/g_set_error_literal unconditionally; it would be safer either to require and assert a non-null error pointer or guard these calls when error is nullptr to avoid undefined behavior.
- RecvFileData::RecvRegularFile now computes a `fullpath` via assert_filename_inexist and writes to that path, but utime is still called with `file->filepath`; updating timestamps on `fullpath` instead would avoid mismatches when the destination filename is altered.

## Individual Comments

### Comment 1
<location path="src/iptux-core/internal/RecvFileData.cpp" line_range="462-463" />
<code_context>
       return finishsize;
+    }
+
+    gsize bytes_written = 0;
+    if (g_output_stream_write_all(os, buf, size, &bytes_written, nullptr,
+                                  &error) == -1) {
+      LOG_WARN("g_output_stream_write_all failed: %s", error->message);
</code_context>
<issue_to_address>
**issue (bug_risk):** Incorrect check of g_output_stream_write_all() return value

`g_output_stream_write_all()` returns a `gboolean`, so the `== -1` check will never trigger and write errors will be ignored, leaving `error` potentially unset. This should instead check for `FALSE` and only use `error` when non-null. Also verify the intended return value semantics on short writes; `finishsize + bytes_written` may not match what callers expect.
</issue_to_address>

### Comment 2
<location path="src/iptux-utils/utils.cpp" line_range="711-720" />
<code_context>
   return offset;
 }

+ssize_t xread(GSocket* sock, void* buf, size_t count) {
+  size_t offset;
+  ssize_t size;
+
+  size = -1;
+  offset = 0;
+  while ((offset != count) && (size != 0)) {
+    if ((size = g_socket_receive(sock, (gchar*)buf + offset, count - offset,
+                                 NULL, NULL)) == -1) {
+      if (errno == EINTR)
+        continue;
+      return -1;
</code_context>
<issue_to_address>
**issue (bug_risk):** Using errno with g_socket_receive() is unreliable; prefer GError

These GSocket-based helpers assume g_socket_receive() sets errno and treat EINTR specially, but GLib reports errors via GError, not errno. This can lead to incorrect handling of errors/interrupts. Please use the GError** parameter, inspect the error domain/code for interruptions (or rely on GLib’s built-in handling), and avoid errno-based logic with GSocket.
</issue_to_address>

### Comment 3
<location path="src/iptux/DataSettings.cpp" line_range="1113" />
<code_context>
+    if (*(buffer + strspn(buffer, "\t\x20")) == '#')
       continue;
-    switch (sscanf(lineptr, "%s - %s //%s", buf[0], buf[1], buf[2])) {
+    switch (sscanf(buffer, "%1023s - %1023s //%1023s", buf[0], buf[1], buf[2])) {
       case 3:
-        if (inet_pton(AF_INET, buf[0], &ipv4) <= 0 ||
</code_context>
<issue_to_address>
**issue (bug_risk):** sscanf width specifiers should be tied to MAX_BUFLEN, not hard-coded 1023

`buf` is `char buf[3][MAX_BUFLEN]`, but the format string uses `%1023s`. If `MAX_BUFLEN` is reduced below 1024, this can overflow the buffer. Please derive the width from `MAX_BUFLEN` (e.g., via `G_STRINGIFY(MAX_BUFLEN-1)` or a compile-time constant) so it always matches the buffer size.
</issue_to_address>

### Comment 4
<location path="src/iptux-core/internal/AnalogFS.cpp" line_range="55-64" />
<code_context>
  * @return 成功与否
  */
 int AnalogFS::chdir(const char* dir) {
-  size_t len;
-  char* ptr;
-
-  if (strcmp(dir, ".") == 0)
-    return 0;
+  char* new_path;

-  if (*dir != '/') {
-    if (strcmp(dir, "..") == 0) {
-      ptr = strrchr(path, '/');
-      if (ptr != path)
-        *ptr = '\0';
-    } else {
-      len = strlen(path);
-      ptr = (char*)(*(path + 1) != '\0' ? "/" : "");
-      snprintf(path + len, MAX_PATHLEN - len, "%s%s", ptr, dir);
-    }
-  } else
-    snprintf(path, MAX_PATHLEN, "%s", dir);
+  if (g_path_is_absolute(dir)) {
+    new_path = g_strdup(dir);
+  } else {
+    new_path = g_build_filename(this->path, dir, NULL);
+  }

+  if (!new_path) {
+    LOG_WARN("Failed to build new path from \"%s\" and \"%s\"", this->path,
+             dir);
+    return -1;
+  }
+  if (strlen(new_path) >= MAX_PATHLEN) {
+    LOG_WARN("New path \"%s\" exceeds maximum length of %d", new_path,
+             MAX_PATHLEN);
+    g_free(new_path);
+    return -1;
+  }
</code_context>
<issue_to_address>
**question (bug_risk):** New chdir/mergepath implementation no longer handles ".." semantics

Previously, AnalogFS::chdir/mergepath explicitly processed "." and ".." to update `path` and move up directories. The new code delegates to `g_build_filename()`, which leaves `..` segments in the string (e.g. `path/..`) instead of normalizing them. Any callers expecting filesystem-like handling of `.`/`..` may now see different traversal behavior. If this change is not deliberate, consider normalizing the resulting path (e.g., via GFile or manual `.`/`..` collapsing) before storing it.
</issue_to_address>

### Comment 5
<location path="src/iptux-core/internal/TcpData.cpp" line_range="60" />
<code_context>

 static gpointer tcpHandlerThreadFunc(gpointer data) {
   TcpHandlerData* handlerData = static_cast<TcpHandlerData*>(data);
+  GError* error = nullptr;
+  bool res;
+
   try {
</code_context>
<issue_to_address>
**issue (bug_risk):** Possible use of uninitialized `res` when an exception is thrown early

In `tcpHandlerThreadFunc`, `bool res` is only set inside the `try` block. If `TcpDataEntry` throws before `res` is assigned, the later `if (!res)` will read an uninitialized value, causing undefined behavior. Initialize `res` to `false` before the `try` block to ensure safe and consistent error handling.
</issue_to_address>

### Comment 6
<location path="src/iptux-utils/utils.cpp" line_range="646" />
<code_context>
   return offset;
 }

+ssize_t xwrite(GSocket* sock, const void* buf, size_t count) {
+  size_t offset;
+  ssize_t size;
</code_context>
<issue_to_address>
**suggestion:** Logging errno for GSocket write errors may be misleading

In this GSocket-based xwrite(), the error handling currently logs `strerror(errno)`, but g_socket_send() reports failures via GError, so errno may not reflect the actual issue. To keep accurate diagnostics, use a GError** with g_socket_send(), log the GError message, and avoid relying on errno in this path.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +462 to +463
gsize bytes_written = 0;
if (g_output_stream_write_all(os, buf, size, &bytes_written, nullptr,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Incorrect check of g_output_stream_write_all() return value

g_output_stream_write_all() returns a gboolean, so the == -1 check will never trigger and write errors will be ignored, leaving error potentially unset. This should instead check for FALSE and only use error when non-null. Also verify the intended return value semantics on short writes; finishsize + bytes_written may not match what callers expect.

Comment thread src/iptux-utils/utils.cpp
Comment on lines +711 to +720
ssize_t xread(GSocket* sock, void* buf, size_t count) {
size_t offset;
ssize_t size;

size = -1;
offset = 0;
while ((offset != count) && (size != 0)) {
if ((size = g_socket_receive(sock, (gchar*)buf + offset, count - offset,
NULL, NULL)) == -1) {
if (errno == EINTR)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Using errno with g_socket_receive() is unreliable; prefer GError

These GSocket-based helpers assume g_socket_receive() sets errno and treat EINTR specially, but GLib reports errors via GError, not errno. This can lead to incorrect handling of errors/interrupts. Please use the GError** parameter, inspect the error domain/code for interruptions (or rely on GLib’s built-in handling), and avoid errno-based logic with GSocket.

if (*(buffer + strspn(buffer, "\t\x20")) == '#')
continue;
switch (sscanf(lineptr, "%s - %s //%s", buf[0], buf[1], buf[2])) {
switch (sscanf(buffer, "%1023s - %1023s //%1023s", buf[0], buf[1], buf[2])) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): sscanf width specifiers should be tied to MAX_BUFLEN, not hard-coded 1023

buf is char buf[3][MAX_BUFLEN], but the format string uses %1023s. If MAX_BUFLEN is reduced below 1024, this can overflow the buffer. Please derive the width from MAX_BUFLEN (e.g., via G_STRINGIFY(MAX_BUFLEN-1) or a compile-time constant) so it always matches the buffer size.

Comment on lines -55 to -64
return 0;
char* new_path;

if (*dir != '/') {
if (strcmp(dir, "..") == 0) {
ptr = strrchr(path, '/');
if (ptr != path)
*ptr = '\0';
} else {
len = strlen(path);
ptr = (char*)(*(path + 1) != '\0' ? "/" : "");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (bug_risk): New chdir/mergepath implementation no longer handles ".." semantics

Previously, AnalogFS::chdir/mergepath explicitly processed "." and ".." to update path and move up directories. The new code delegates to g_build_filename(), which leaves .. segments in the string (e.g. path/..) instead of normalizing them. Any callers expecting filesystem-like handling of ./.. may now see different traversal behavior. If this change is not deliberate, consider normalizing the resulting path (e.g., via GFile or manual ./.. collapsing) before storing it.

tdata.socket = socket;
tdata.sock = g_socket_get_fd(socket);
tdata.DispatchTcpData();
return tdata.DispatchTcpData(error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Possible use of uninitialized res when an exception is thrown early

In tcpHandlerThreadFunc, bool res is only set inside the try block. If TcpDataEntry throws before res is assigned, the later if (!res) will read an uninitialized value, causing undefined behavior. Initialize res to false before the try block to ensure safe and consistent error handling.

Comment thread src/iptux-utils/utils.cpp
return offset;
}

ssize_t xwrite(GSocket* sock, const void* buf, size_t count) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Logging errno for GSocket write errors may be misleading

In this GSocket-based xwrite(), the error handling currently logs strerror(errno), but g_socket_send() reports failures via GError, so errno may not reflect the actual issue. To keep accurate diagnostics, use a GError** with g_socket_send(), log the GError message, and avoid relying on errno in this path.

@sonarqubecloud

Copy link
Copy Markdown

❌ The last analysis has failed.

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

有没有办法编译成windows版的?

2 participants