From e365266b4a89d56306719332e818c66fa3d5f4fb Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Sun, 1 Feb 2026 16:37:34 -0700 Subject: [PATCH 01/22] Update OpenSSL trust store and GDK_BACKEND settings --- .github/workflows/appimage-build.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/appimage-build.yml b/.github/workflows/appimage-build.yml index d268669d..a4ed3fd5 100644 --- a/.github/workflows/appimage-build.yml +++ b/.github/workflows/appimage-build.yml @@ -99,11 +99,21 @@ jobs: export GIO_EXTRA_MODULES="$APPDIR/usr/lib/gio/modules${GIO_EXTRA_MODULES:+:$GIO_EXTRA_MODULES}" fi - # OpenSSL trust store override (fixes “unable to get local issuer certificate (20)”) + # OpenSSL trust store override export SSL_CERT_FILE="${SSL_CERT_FILE:-$APPDIR/etc/ssl/certs/ca-certificates.crt}" export SSL_CERT_DIR="${SSL_CERT_DIR:-$APPDIR/etc/ssl/certs}" export CURL_CA_BUNDLE="${CURL_CA_BUNDLE:-$SSL_CERT_FILE}" + # Prefer Wayland if the session provides it, but keep X11 fallback. + # Don't override if the user already set GDK_BACKEND explicitly. + if [ -z "${GDK_BACKEND:-}" ]; then + if [ -n "${WAYLAND_DISPLAY:-}" ] || [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then + export GDK_BACKEND="wayland,x11" + else + export GDK_BACKEND="x11" + fi + fi + exec "$APPDIR/usr/bin/zoitechat" "$@" EOF chmod +x AppRun From 7be145b94aae3242ccc1ced68e42f0db5fba46ab Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Sun, 1 Feb 2026 16:39:38 -0700 Subject: [PATCH 02/22] Clarify OpenSSL trust store override and clean up code Added a comment to clarify the purpose of the OpenSSL trust store override and removed unnecessary code related to GDK_BACKEND configuration. --- .github/workflows/appimage-build.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/appimage-build.yml b/.github/workflows/appimage-build.yml index a4ed3fd5..d268669d 100644 --- a/.github/workflows/appimage-build.yml +++ b/.github/workflows/appimage-build.yml @@ -99,21 +99,11 @@ jobs: export GIO_EXTRA_MODULES="$APPDIR/usr/lib/gio/modules${GIO_EXTRA_MODULES:+:$GIO_EXTRA_MODULES}" fi - # OpenSSL trust store override + # OpenSSL trust store override (fixes “unable to get local issuer certificate (20)”) export SSL_CERT_FILE="${SSL_CERT_FILE:-$APPDIR/etc/ssl/certs/ca-certificates.crt}" export SSL_CERT_DIR="${SSL_CERT_DIR:-$APPDIR/etc/ssl/certs}" export CURL_CA_BUNDLE="${CURL_CA_BUNDLE:-$SSL_CERT_FILE}" - # Prefer Wayland if the session provides it, but keep X11 fallback. - # Don't override if the user already set GDK_BACKEND explicitly. - if [ -z "${GDK_BACKEND:-}" ]; then - if [ -n "${WAYLAND_DISPLAY:-}" ] || [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then - export GDK_BACKEND="wayland,x11" - else - export GDK_BACKEND="x11" - fi - fi - exec "$APPDIR/usr/bin/zoitechat" "$@" EOF chmod +x AppRun From 049d3c19af2db4ee3b501b3a0b06f99c0e97bbd0 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Sun, 1 Feb 2026 22:24:25 -0700 Subject: [PATCH 03/22] Add MSYS2 setup and improve dependency installation Added MSYS2 setup step for GTK build fallback and updated the installation process for dependencies. Enhanced error handling and ensured proper paths for GTK and Lua headers. --- .github/workflows/windows-build.yml | 273 ++++++++++++++++++++++++++-- 1 file changed, 262 insertions(+), 11 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 0e835b16..78499521 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -32,32 +32,262 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup MSYS2 (for GTK build fallback) + uses: msys2/setup-msys2@v2 + with: + msys2-location: C:\tools\msys64 + update: true + install: >- + base-devel + git + unzip + p7zip + - uses: actions/setup-python@v5 with: - python-version: '3.14.2' + python-version: "3.14.2" architecture: ${{ matrix.arch }} - - name: Install Dependencies + - name: Install Dependencies (GTK3 toolchain + packagers) + env: + GITHUB_TOKEN: ${{ github.token }} + shell: pwsh run: | - New-Item -Name "deps" -ItemType "Directory" + $ErrorActionPreference = "Stop" + New-Item -Name "deps" -ItemType "Directory" -Force | Out-Null + + # Inno Setup + IDP (kept as-is) Invoke-WebRequest http://files.jrsoftware.org/is/5/innosetup-5.5.9-unicode.exe -OutFile deps\innosetup-unicode.exe & deps\innosetup-unicode.exe /VERYSILENT | Out-Null Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe & deps\idpsetup.exe /VERYSILENT - Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z - & 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk - + # WinSparkle / gendef / perl (kept as-is) Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z - & 7z.exe x deps\gendef.7z -oC:\gtk-build + & 7z.exe x deps\gendef.7z -oC:\gtk-build | Out-Null Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z - & 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle + & 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle | Out-Null Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z - & 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }} + & 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }} | Out-Null + + # Discover perl.exe and persist its bin dir. + $perlExe = Get-ChildItem -Path "C:\gtk-build\perl-5.20\${{ matrix.platform }}" -Recurse -File -Filter "perl.exe" | Select-Object -First 1 + if (-not $perlExe) { throw "perl.exe not found under C:\gtk-build\perl-5.20\${{ matrix.platform }}" } + "PERL_BIN=$($perlExe.Directory.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + + function Find-GtkPrefix([string]$root) { + $gtkH = Get-ChildItem -Path $root -Recurse -File -Filter "gtk.h" | + Where-Object { $_.FullName -match '\\include\\gtk-3\.0\\gtk\\gtk\.h$' } | + Select-Object -First 1 + if (-not $gtkH) { return $null } + return $gtkH.Directory.Parent.Parent.Parent.FullName + } + + function Ensure-Junction([string]$linkPath, [string]$targetPath) { + if (Test-Path $linkPath) { + cmd /c rmdir /s /q "$linkPath" | Out-Null + } + New-Item -Path $linkPath -ItemType Junction -Value $targetPath | Out-Null + } + + function Copy-AliasLib([string]$libDir, [string]$targetName, [string[]]$sourcePatterns) { + $target = Join-Path $libDir $targetName + if (Test-Path $target) { return } + + $src = $null + foreach ($pat in $sourcePatterns) { + $src = Get-ChildItem -Path $libDir -File -Filter "*.lib" | Where-Object { $_.Name -match $pat } | Select-Object -First 1 + if ($src) { break } + } + + if ($src) { + Copy-Item $src.FullName $target -Force + Write-Host "Alias: $targetName <= $($src.Name)" + } else { + Write-Host "Alias not created: $targetName (no match in $libDir)" + } + } + + function Ensure-GlibGenmarshalWrapper([string]$gtkBin) { + $wrapperPath = Join-Path $gtkBin "glib-genmarshal" + $exePath = Join-Path $gtkBin "glib-genmarshal.exe" + + $realPath = Join-Path $gtkBin "glib-genmarshal.real" + if (Test-Path $realPath) { Remove-Item $realPath -Force } + + if (Test-Path $wrapperPath) { + $first = (Get-Content -Path $wrapperPath -TotalCount 1 -ErrorAction SilentlyContinue) + if ($first -notmatch 'import os') { + Move-Item $wrapperPath $realPath -Force + } + } + + if (-not (Test-Path $exePath) -and -not (Test-Path $realPath)) { + $cand = Get-ChildItem -Path $gtkBin -File -Filter "glib-genmarshal*" | Select-Object -First 1 + if ($cand) { + Move-Item $cand.FullName $realPath -Force + } + } + + if (-not (Test-Path $exePath) -and -not (Test-Path $realPath)) { + throw "GTK3 prefix present, but no glib-genmarshal tool found under $gtkBin" + } + + $wrapper = @( + "import os, subprocess, sys", + "base = os.path.dirname(__file__)", + "exe = os.path.join(base, 'glib-genmarshal.exe')", + "real = os.path.join(base, 'glib-genmarshal.real')", + "tool = exe if os.path.exists(exe) else real", + "if not os.path.exists(tool):", + " sys.stderr.write('glib-genmarshal tool not found\\n')", + " sys.exit(1)", + "if tool.lower().endswith('.exe'):", + " sys.exit(subprocess.call([tool] + sys.argv[1:]))", + "first = b''", + "try:", + " with open(tool, 'rb') as f: first = f.readline().lower()", + "except Exception:", + " pass", + "if b'perl' in first:", + " sys.exit(subprocess.call(['perl', tool] + sys.argv[1:]))", + "sys.exit(subprocess.call([sys.executable, tool] + sys.argv[1:]))" + ) + $wrapper | Set-Content -Path $wrapperPath -Encoding ASCII + } + + function Ensure-LuaHeaders([string]$gtkInc) { + # Put headers in BOTH include\ and include\lua\ to satisfy either include style. + $luaDir = Join-Path $gtkInc "lua" + New-Item -Path $luaDir -ItemType Directory -Force | Out-Null + + $zip = "deps\luajit-v2.1.zip" + $dst = "deps\luajit-src" + if (Test-Path $dst) { Remove-Item $dst -Recurse -Force } + New-Item -Path $dst -ItemType Directory -Force | Out-Null + + Invoke-WebRequest https://github.com/LuaJIT/LuaJIT/archive/refs/heads/v2.1.zip -OutFile $zip + Expand-Archive -Force $zip -DestinationPath $dst + + $srcDir = Get-ChildItem -Path $dst -Directory | Select-Object -First 1 + if (-not $srcDir) { throw "LuaJIT source zip extracted, but no top directory found." } + + $hdrRoot = Join-Path $srcDir.FullName "src" + foreach ($h in @("lua.h", "lualib.h", "lauxlib.h", "luaconf.h")) { + $p = Join-Path $hdrRoot $h + if (-not (Test-Path $p)) { throw "LuaJIT header missing: $p" } + + Copy-Item $p (Join-Path $gtkInc $h) -Force + Copy-Item $p (Join-Path $luaDir $h) -Force + } + + if (-not (Test-Path (Join-Path $gtkInc "lua.h"))) { throw "lua.h was not installed into $gtkInc" } + if (-not (Test-Path (Join-Path $luaDir "lua.h"))) { throw "lua.h was not installed into $luaDir" } + } + + # ------------------------------------------ + # GTK: Prefer prebuilt wingtk/gvsbuild GTK3 bundles. + # If missing for x86 (win32), build GTK3 via gvsbuild from source. + # ------------------------------------------ + $wantArch = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" } + $wantPlat = "${{ matrix.platform }}" + + $extractRoot = "C:\_gtk_extract" + if (Test-Path $extractRoot) { Remove-Item $extractRoot -Recurse -Force } + New-Item -Path $extractRoot -ItemType Directory -Force | Out-Null + + $gtkPrefix = $null + + $headers = @{ + "User-Agent" = "zoitechat-ci" + "Authorization" = "Bearer $env:GITHUB_TOKEN" + "X-GitHub-Api-Version" = "2022-11-28" + } + + try { + $release = Invoke-RestMethod -Headers $headers -Uri "https://api.github.com/repos/wingtk/gvsbuild/releases/latest" + $asset = $release.assets | + Where-Object { + ($_.name -match '^GTK3_Gvsbuild_.*_(x64|x86)\.zip$' -or $_.name -match '(?i)gtk3.*(x64|x86)\.zip$') -and + $_.name -match "_$wantArch\.zip$" + } | + Select-Object -First 1 + + if ($asset) { + $bundlePath = "deps\gtk3-$wantArch-bundle.zip" + Invoke-WebRequest $asset.browser_download_url -OutFile $bundlePath + Expand-Archive -Force $bundlePath -DestinationPath $extractRoot + + $gtkPrefix = Find-GtkPrefix $extractRoot + if (-not $gtkPrefix) { throw "GTK3 bundle extracted, but gtk.h not found. Layout unexpected." } + + Write-Host "Detected GTK prefix: $gtkPrefix" + } else { + Write-Host "No prebuilt GTK3 bundle found for $wantArch. Will build GTK3 from source via gvsbuild." + } + } catch { + Write-Host "Prebuilt GTK3 discovery failed: $($_.Exception.Message)" + Write-Host "Will build GTK3 from source via gvsbuild." + } + + if (-not $gtkPrefix) { + $gvsDir = "C:\gtk-build\github\gvsbuild" + if (-not (Test-Path $gvsDir)) { + New-Item -Path "C:\gtk-build\github" -ItemType Directory -Force | Out-Null + git clone --depth 1 https://github.com/wingtk/gvsbuild.git $gvsDir + } + + Push-Location $gvsDir + python -m pip install --upgrade pip + python -m pip install -r requirements.txt + + python .\build.py build -p=$wantArch --vs-ver=16 --msys-dir=C:\tools\msys64 --gtk3-ver=3.24 -c=release gtk3 + Pop-Location + + $gtkPrefix = "C:\gtk-build\gtk\$wantArch\release" + if (-not (Test-Path (Join-Path $gtkPrefix "include\gtk-3.0\gtk\gtk.h"))) { + throw "gvsbuild finished, but expected GTK headers were not found under $gtkPrefix" + } + } + + # Normalize GTK location to the path your solution expects: + $normBase = "C:\gtk-build\gtk\$wantPlat" + New-Item -Path $normBase -ItemType Directory -Force | Out-Null + $normRel = Join-Path $normBase "release" + Ensure-Junction $normRel $gtkPrefix + + $gtkBin = Join-Path $normRel "bin" + $gtkLib = Join-Path $normRel "lib" + $gtkInc = Join-Path $normRel "include" + + if (-not (Test-Path $gtkBin)) { throw "GTK bin dir missing at $gtkBin" } + if (-not (Test-Path $gtkLib)) { throw "GTK lib dir missing at $gtkLib" } + if (-not (Test-Path $gtkInc)) { throw "GTK include dir missing at $gtkInc" } + + Ensure-GlibGenmarshalWrapper $gtkBin + Ensure-LuaHeaders $gtkInc + + # Expected import libs (some projects hardcode these exact names) + Copy-AliasLib $gtkLib "gtk-3.0.lib" @('^gtk-3-0\.lib$', '^gtk-3\.lib$', '^gtk-3.*\.lib$', '^gtk-win32-2\.0\.lib$') + Copy-AliasLib $gtkLib "gdk-3.0.lib" @('^gdk-3-0\.lib$', '^gdk-3\.lib$', '^gdk-3.*\.lib$') + Copy-AliasLib $gtkLib "gdk-win32-3.0.lib" @('^gdk-win32-3-0\.lib$', '^gdk-win32-3\.lib$', '^gdk-win32-3.*\.lib$') + + # Legacy GTK2 name expected by older vcxproj (keep it) + Copy-AliasLib $gtkLib "gtk-win32-2.0.lib" @('^gtk-3\.0\.lib$', '^gtk-3-0\.lib$', '^gtk-3\.lib$', '^gtk-3.*\.lib$') + + # OpenSSL legacy names (keep older projects happy if referenced) + Copy-AliasLib $gtkLib "ssleay32.lib" @('^libssl\.lib$', '^ssl\.lib$') + Copy-AliasLib $gtkLib "libeay32.lib" @('^libcrypto\.lib$', '^crypto\.lib$') + + # libxml2 legacy name + Copy-AliasLib $gtkLib "libxml2.lib" @('^libxml2.*\.lib$') + + # Persist GTK root for later steps. + "GTK_ROOT=$normRel" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 # Resolve python root from setup-python $pyRoot = $env:pythonLocation @@ -75,9 +305,31 @@ jobs: python -m pip install cffi - name: Build + shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" + set "GTKROOT=%GTK_ROOT%" + if not exist "%GTKROOT%\include\gtk-3.0\gtk\gtk.h" ( + echo Missing GTK headers under %GTKROOT% + dir "%GTKROOT%\include\gtk-3.0\gtk" + exit /b 1 + ) + + if not exist "%GTKROOT%\include\lua.h" ( + echo Missing lua.h under %GTKROOT%\include + dir "%GTKROOT%\include" + ) + if not exist "%GTKROOT%\include\lua\lua.h" ( + echo Missing lua\lua.h under %GTKROOT%\include\lua + dir "%GTKROOT%\include\lua" + ) + + set "PATH=%PERL_BIN%;%GTKROOT%\bin;%PATH%" + set "LIB=%GTKROOT%\lib;%LIB%" + set "INCLUDE=%GTKROOT%\include\lua;%GTKROOT%\include;%INCLUDE%" + set "CL=/I""%GTKROOT%\include"" /I""%GTKROOT%\include\lua"" %CL%" + set "PYTHON_DIR=C:\gtk-build\python-3.14.2\${{ matrix.platform }}" if not exist "%PYTHON_DIR%\libs\python314.lib" ( echo Missing %PYTHON_DIR%\libs\python314.lib @@ -89,13 +341,12 @@ jobs: set "INCLUDE=%PYTHON_DIR%\include;%INCLUDE%" msbuild win32\zoitechat.sln /m /verbosity:minimal /p:Configuration=Release /p:Platform=${{ matrix.platform }} - shell: cmd - name: Preparing Artifacts + shell: cmd run: | move ..\zoitechat-build\${{ matrix.platform }}\ZoiteChat*.exe .\ move ..\zoitechat-build .\ - shell: cmd - name: Upload Installer id: upload_installer From cf2e44f3d5e5597f762d4405f3f1bd0f3bba8346 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Sun, 1 Feb 2026 22:25:20 -0700 Subject: [PATCH 04/22] Refactor Windows build workflow by removing MSYS2 setup Removed MSYS2 setup and dependency installation steps for GTK build fallback. Updated Python version syntax and adjusted paths for dependencies. --- .github/workflows/windows-build.yml | 273 ++-------------------------- 1 file changed, 11 insertions(+), 262 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 78499521..0e835b16 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -32,262 +32,32 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup MSYS2 (for GTK build fallback) - uses: msys2/setup-msys2@v2 - with: - msys2-location: C:\tools\msys64 - update: true - install: >- - base-devel - git - unzip - p7zip - - uses: actions/setup-python@v5 with: - python-version: "3.14.2" + python-version: '3.14.2' architecture: ${{ matrix.arch }} - - name: Install Dependencies (GTK3 toolchain + packagers) - env: - GITHUB_TOKEN: ${{ github.token }} - shell: pwsh + - name: Install Dependencies run: | - $ErrorActionPreference = "Stop" + New-Item -Name "deps" -ItemType "Directory" - New-Item -Name "deps" -ItemType "Directory" -Force | Out-Null - - # Inno Setup + IDP (kept as-is) Invoke-WebRequest http://files.jrsoftware.org/is/5/innosetup-5.5.9-unicode.exe -OutFile deps\innosetup-unicode.exe & deps\innosetup-unicode.exe /VERYSILENT | Out-Null Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe & deps\idpsetup.exe /VERYSILENT - # WinSparkle / gendef / perl (kept as-is) + Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z + & 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk + Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z - & 7z.exe x deps\gendef.7z -oC:\gtk-build | Out-Null + & 7z.exe x deps\gendef.7z -oC:\gtk-build Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z - & 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle | Out-Null + & 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z - & 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }} | Out-Null - - # Discover perl.exe and persist its bin dir. - $perlExe = Get-ChildItem -Path "C:\gtk-build\perl-5.20\${{ matrix.platform }}" -Recurse -File -Filter "perl.exe" | Select-Object -First 1 - if (-not $perlExe) { throw "perl.exe not found under C:\gtk-build\perl-5.20\${{ matrix.platform }}" } - "PERL_BIN=$($perlExe.Directory.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - - function Find-GtkPrefix([string]$root) { - $gtkH = Get-ChildItem -Path $root -Recurse -File -Filter "gtk.h" | - Where-Object { $_.FullName -match '\\include\\gtk-3\.0\\gtk\\gtk\.h$' } | - Select-Object -First 1 - if (-not $gtkH) { return $null } - return $gtkH.Directory.Parent.Parent.Parent.FullName - } - - function Ensure-Junction([string]$linkPath, [string]$targetPath) { - if (Test-Path $linkPath) { - cmd /c rmdir /s /q "$linkPath" | Out-Null - } - New-Item -Path $linkPath -ItemType Junction -Value $targetPath | Out-Null - } - - function Copy-AliasLib([string]$libDir, [string]$targetName, [string[]]$sourcePatterns) { - $target = Join-Path $libDir $targetName - if (Test-Path $target) { return } - - $src = $null - foreach ($pat in $sourcePatterns) { - $src = Get-ChildItem -Path $libDir -File -Filter "*.lib" | Where-Object { $_.Name -match $pat } | Select-Object -First 1 - if ($src) { break } - } - - if ($src) { - Copy-Item $src.FullName $target -Force - Write-Host "Alias: $targetName <= $($src.Name)" - } else { - Write-Host "Alias not created: $targetName (no match in $libDir)" - } - } - - function Ensure-GlibGenmarshalWrapper([string]$gtkBin) { - $wrapperPath = Join-Path $gtkBin "glib-genmarshal" - $exePath = Join-Path $gtkBin "glib-genmarshal.exe" - - $realPath = Join-Path $gtkBin "glib-genmarshal.real" - if (Test-Path $realPath) { Remove-Item $realPath -Force } - - if (Test-Path $wrapperPath) { - $first = (Get-Content -Path $wrapperPath -TotalCount 1 -ErrorAction SilentlyContinue) - if ($first -notmatch 'import os') { - Move-Item $wrapperPath $realPath -Force - } - } - - if (-not (Test-Path $exePath) -and -not (Test-Path $realPath)) { - $cand = Get-ChildItem -Path $gtkBin -File -Filter "glib-genmarshal*" | Select-Object -First 1 - if ($cand) { - Move-Item $cand.FullName $realPath -Force - } - } - - if (-not (Test-Path $exePath) -and -not (Test-Path $realPath)) { - throw "GTK3 prefix present, but no glib-genmarshal tool found under $gtkBin" - } - - $wrapper = @( - "import os, subprocess, sys", - "base = os.path.dirname(__file__)", - "exe = os.path.join(base, 'glib-genmarshal.exe')", - "real = os.path.join(base, 'glib-genmarshal.real')", - "tool = exe if os.path.exists(exe) else real", - "if not os.path.exists(tool):", - " sys.stderr.write('glib-genmarshal tool not found\\n')", - " sys.exit(1)", - "if tool.lower().endswith('.exe'):", - " sys.exit(subprocess.call([tool] + sys.argv[1:]))", - "first = b''", - "try:", - " with open(tool, 'rb') as f: first = f.readline().lower()", - "except Exception:", - " pass", - "if b'perl' in first:", - " sys.exit(subprocess.call(['perl', tool] + sys.argv[1:]))", - "sys.exit(subprocess.call([sys.executable, tool] + sys.argv[1:]))" - ) - $wrapper | Set-Content -Path $wrapperPath -Encoding ASCII - } - - function Ensure-LuaHeaders([string]$gtkInc) { - # Put headers in BOTH include\ and include\lua\ to satisfy either include style. - $luaDir = Join-Path $gtkInc "lua" - New-Item -Path $luaDir -ItemType Directory -Force | Out-Null - - $zip = "deps\luajit-v2.1.zip" - $dst = "deps\luajit-src" - if (Test-Path $dst) { Remove-Item $dst -Recurse -Force } - New-Item -Path $dst -ItemType Directory -Force | Out-Null - - Invoke-WebRequest https://github.com/LuaJIT/LuaJIT/archive/refs/heads/v2.1.zip -OutFile $zip - Expand-Archive -Force $zip -DestinationPath $dst - - $srcDir = Get-ChildItem -Path $dst -Directory | Select-Object -First 1 - if (-not $srcDir) { throw "LuaJIT source zip extracted, but no top directory found." } - - $hdrRoot = Join-Path $srcDir.FullName "src" - foreach ($h in @("lua.h", "lualib.h", "lauxlib.h", "luaconf.h")) { - $p = Join-Path $hdrRoot $h - if (-not (Test-Path $p)) { throw "LuaJIT header missing: $p" } - - Copy-Item $p (Join-Path $gtkInc $h) -Force - Copy-Item $p (Join-Path $luaDir $h) -Force - } - - if (-not (Test-Path (Join-Path $gtkInc "lua.h"))) { throw "lua.h was not installed into $gtkInc" } - if (-not (Test-Path (Join-Path $luaDir "lua.h"))) { throw "lua.h was not installed into $luaDir" } - } - - # ------------------------------------------ - # GTK: Prefer prebuilt wingtk/gvsbuild GTK3 bundles. - # If missing for x86 (win32), build GTK3 via gvsbuild from source. - # ------------------------------------------ - $wantArch = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" } - $wantPlat = "${{ matrix.platform }}" - - $extractRoot = "C:\_gtk_extract" - if (Test-Path $extractRoot) { Remove-Item $extractRoot -Recurse -Force } - New-Item -Path $extractRoot -ItemType Directory -Force | Out-Null - - $gtkPrefix = $null - - $headers = @{ - "User-Agent" = "zoitechat-ci" - "Authorization" = "Bearer $env:GITHUB_TOKEN" - "X-GitHub-Api-Version" = "2022-11-28" - } - - try { - $release = Invoke-RestMethod -Headers $headers -Uri "https://api.github.com/repos/wingtk/gvsbuild/releases/latest" - $asset = $release.assets | - Where-Object { - ($_.name -match '^GTK3_Gvsbuild_.*_(x64|x86)\.zip$' -or $_.name -match '(?i)gtk3.*(x64|x86)\.zip$') -and - $_.name -match "_$wantArch\.zip$" - } | - Select-Object -First 1 - - if ($asset) { - $bundlePath = "deps\gtk3-$wantArch-bundle.zip" - Invoke-WebRequest $asset.browser_download_url -OutFile $bundlePath - Expand-Archive -Force $bundlePath -DestinationPath $extractRoot - - $gtkPrefix = Find-GtkPrefix $extractRoot - if (-not $gtkPrefix) { throw "GTK3 bundle extracted, but gtk.h not found. Layout unexpected." } - - Write-Host "Detected GTK prefix: $gtkPrefix" - } else { - Write-Host "No prebuilt GTK3 bundle found for $wantArch. Will build GTK3 from source via gvsbuild." - } - } catch { - Write-Host "Prebuilt GTK3 discovery failed: $($_.Exception.Message)" - Write-Host "Will build GTK3 from source via gvsbuild." - } - - if (-not $gtkPrefix) { - $gvsDir = "C:\gtk-build\github\gvsbuild" - if (-not (Test-Path $gvsDir)) { - New-Item -Path "C:\gtk-build\github" -ItemType Directory -Force | Out-Null - git clone --depth 1 https://github.com/wingtk/gvsbuild.git $gvsDir - } - - Push-Location $gvsDir - python -m pip install --upgrade pip - python -m pip install -r requirements.txt - - python .\build.py build -p=$wantArch --vs-ver=16 --msys-dir=C:\tools\msys64 --gtk3-ver=3.24 -c=release gtk3 - Pop-Location - - $gtkPrefix = "C:\gtk-build\gtk\$wantArch\release" - if (-not (Test-Path (Join-Path $gtkPrefix "include\gtk-3.0\gtk\gtk.h"))) { - throw "gvsbuild finished, but expected GTK headers were not found under $gtkPrefix" - } - } - - # Normalize GTK location to the path your solution expects: - $normBase = "C:\gtk-build\gtk\$wantPlat" - New-Item -Path $normBase -ItemType Directory -Force | Out-Null - $normRel = Join-Path $normBase "release" - Ensure-Junction $normRel $gtkPrefix - - $gtkBin = Join-Path $normRel "bin" - $gtkLib = Join-Path $normRel "lib" - $gtkInc = Join-Path $normRel "include" - - if (-not (Test-Path $gtkBin)) { throw "GTK bin dir missing at $gtkBin" } - if (-not (Test-Path $gtkLib)) { throw "GTK lib dir missing at $gtkLib" } - if (-not (Test-Path $gtkInc)) { throw "GTK include dir missing at $gtkInc" } - - Ensure-GlibGenmarshalWrapper $gtkBin - Ensure-LuaHeaders $gtkInc - - # Expected import libs (some projects hardcode these exact names) - Copy-AliasLib $gtkLib "gtk-3.0.lib" @('^gtk-3-0\.lib$', '^gtk-3\.lib$', '^gtk-3.*\.lib$', '^gtk-win32-2\.0\.lib$') - Copy-AliasLib $gtkLib "gdk-3.0.lib" @('^gdk-3-0\.lib$', '^gdk-3\.lib$', '^gdk-3.*\.lib$') - Copy-AliasLib $gtkLib "gdk-win32-3.0.lib" @('^gdk-win32-3-0\.lib$', '^gdk-win32-3\.lib$', '^gdk-win32-3.*\.lib$') - - # Legacy GTK2 name expected by older vcxproj (keep it) - Copy-AliasLib $gtkLib "gtk-win32-2.0.lib" @('^gtk-3\.0\.lib$', '^gtk-3-0\.lib$', '^gtk-3\.lib$', '^gtk-3.*\.lib$') - - # OpenSSL legacy names (keep older projects happy if referenced) - Copy-AliasLib $gtkLib "ssleay32.lib" @('^libssl\.lib$', '^ssl\.lib$') - Copy-AliasLib $gtkLib "libeay32.lib" @('^libcrypto\.lib$', '^crypto\.lib$') - - # libxml2 legacy name - Copy-AliasLib $gtkLib "libxml2.lib" @('^libxml2.*\.lib$') - - # Persist GTK root for later steps. - "GTK_ROOT=$normRel" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + & 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }} # Resolve python root from setup-python $pyRoot = $env:pythonLocation @@ -305,31 +75,9 @@ jobs: python -m pip install cffi - name: Build - shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" - set "GTKROOT=%GTK_ROOT%" - if not exist "%GTKROOT%\include\gtk-3.0\gtk\gtk.h" ( - echo Missing GTK headers under %GTKROOT% - dir "%GTKROOT%\include\gtk-3.0\gtk" - exit /b 1 - ) - - if not exist "%GTKROOT%\include\lua.h" ( - echo Missing lua.h under %GTKROOT%\include - dir "%GTKROOT%\include" - ) - if not exist "%GTKROOT%\include\lua\lua.h" ( - echo Missing lua\lua.h under %GTKROOT%\include\lua - dir "%GTKROOT%\include\lua" - ) - - set "PATH=%PERL_BIN%;%GTKROOT%\bin;%PATH%" - set "LIB=%GTKROOT%\lib;%LIB%" - set "INCLUDE=%GTKROOT%\include\lua;%GTKROOT%\include;%INCLUDE%" - set "CL=/I""%GTKROOT%\include"" /I""%GTKROOT%\include\lua"" %CL%" - set "PYTHON_DIR=C:\gtk-build\python-3.14.2\${{ matrix.platform }}" if not exist "%PYTHON_DIR%\libs\python314.lib" ( echo Missing %PYTHON_DIR%\libs\python314.lib @@ -341,12 +89,13 @@ jobs: set "INCLUDE=%PYTHON_DIR%\include;%INCLUDE%" msbuild win32\zoitechat.sln /m /verbosity:minimal /p:Configuration=Release /p:Platform=${{ matrix.platform }} + shell: cmd - name: Preparing Artifacts - shell: cmd run: | move ..\zoitechat-build\${{ matrix.platform }}\ZoiteChat*.exe .\ move ..\zoitechat-build .\ + shell: cmd - name: Upload Installer id: upload_installer From 303d5cc581cb758f6f6e6c626f4240e27c08fd08 Mon Sep 17 00:00:00 2001 From: deepend Date: Tue, 3 Feb 2026 13:28:35 -0700 Subject: [PATCH 05/22] preparation for upcoming release 2.17.4 --- changelog.rst | 7 +++++++ data/misc/net.zoite.Zoitechat.appdata.xml.in | 10 ++++++++++ meson.build | 2 +- win32/version.txt | 2 +- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/changelog.rst b/changelog.rst index 6dbcb054..586cc8a5 100644 --- a/changelog.rst +++ b/changelog.rst @@ -1,6 +1,13 @@ ZoiteChat ChangeLog ================= +2.17.4 (2026-02-03) +------------------- + +- STS handling now persists server policies, enforces upgrades more consistently, and falls back to current ports when needed. +- Windows build workflow updated (MSYS2 setup changes) and OpenSSL trust store handling tightened for safer TLS connections. +- Reduced GLib coupling in multiple Windows subsystems (spellcheck, history, sysinfo) plus small stability fixes. + 2.17.3 (2026-01-17) ------------------- diff --git a/data/misc/net.zoite.Zoitechat.appdata.xml.in b/data/misc/net.zoite.Zoitechat.appdata.xml.in index 023d250f..c030cdd2 100644 --- a/data/misc/net.zoite.Zoitechat.appdata.xml.in +++ b/data/misc/net.zoite.Zoitechat.appdata.xml.in @@ -25,6 +25,16 @@ zoitechat.desktop + + +

Fixes and minor features:

+
    +
  • STS handling now persists server policies, enforces upgrades more consistently, and falls back to current ports when needed.
  • +
  • Windows build workflow updated (MSYS2 setup changes) and OpenSSL trust store handling tightened for safer TLS connections.
  • +
  • Reduced GLib coupling in multiple Windows subsystems (spellcheck, history, sysinfo) plus small stability fixes.
  • +
+
+

Fixes and minor features:

diff --git a/meson.build b/meson.build index 8383b0ba..63e53231 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('zoitechat', 'c', - version: '2.17.3', + version: '2.17.4', meson_version: '>= 0.47.0', default_options: [ 'c_std=gnu89', diff --git a/win32/version.txt b/win32/version.txt index 15d0fc4c..b92cdb1d 100644 --- a/win32/version.txt +++ b/win32/version.txt @@ -1 +1 @@ -2.17.3 +2.17.4 From 0a737c4d7294416144fa9ff0c2ef3bff762b36d7 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Tue, 3 Feb 2026 22:05:48 -0700 Subject: [PATCH 06/22] Delete .github/workflows/msys-build.yml --- .github/workflows/msys-build.yml | 56 -------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 .github/workflows/msys-build.yml diff --git a/.github/workflows/msys-build.yml b/.github/workflows/msys-build.yml deleted file mode 100644 index 20683120..00000000 --- a/.github/workflows/msys-build.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: MSYS2 Build - -on: - push: - branches: [master] - pull_request: - branches: [master] - -jobs: - msys2_build: - runs-on: windows-latest - defaults: - run: - shell: msys2 {0} - - steps: - - uses: actions/checkout@v4 - - - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: >- - mingw-w64-x86_64-gcc - mingw-w64-x86_64-pkg-config - mingw-w64-x86_64-python-cffi - mingw-w64-x86_64-meson - mingw-w64-x86_64-ninja - mingw-w64-x86_64-gtk2 - mingw-w64-x86_64-gtk-update-icon-cache - mingw-w64-x86_64-luajit - mingw-w64-x86_64-desktop-file-utils - mingw-w64-x86_64-gettext-tools - - - name: Sanity check gettext ITS rules - run: | - set -eux - which msgfmt || true - msgfmt --version - ls -la /mingw64/share/gettext-*/its || true - - - name: Configure - run: | - set -eux - rm -rf build - meson setup build \ - -Dtext-frontend=true \ - -Ddbus=disabled \ - -Dwith-upd=false \ - -Dwith-perl=false - - - name: Build - run: ninja -C build - - - name: Test - run: ninja -C build test From 3290f15439f3d3fd23d6064aae14c3725465d344 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Tue, 3 Feb 2026 22:06:42 -0700 Subject: [PATCH 07/22] Remove MSYS2 Build badge from README Removed MSYS2 build badge from the README. --- readme.md | 1 - 1 file changed, 1 deletion(-) diff --git a/readme.md b/readme.md index 5addc74b..cd148c8b 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,6 @@ [![Flatpak Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/flatpak-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/flatpak-build.yml) [![AppImage Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/appimage-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/appimage-build.yml) [![Windows Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/windows-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/windows-build.yml) -[![MSYS2 Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/msys-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/msys-build.yml) [![OpenBSD Build](https://github.com/ZoiteChat/zoitechat/actions/workflows/openbsd-build.yml/badge.svg)](https://github.com/ZoiteChat/zoitechat/actions/workflows/openbsd-build.yml) [![Version][github-version-img]][github-version-uri] [![Downloads][github-downloads-img]][github-downloads-uri] [![Size][github-size-img]][github-size-img] [![Last Commit][github-commit-img]][github-commit-img] [![Contributors][contribs-all-img]](#contributors-) From 89a8f3eb0a462e0e61127e6ed32b053394df9afb Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 10:19:26 -0700 Subject: [PATCH 08/22] Updated STS handling to require an explicit port in insecure-connection capability upgrades, ignoring incomplete policies without upgrading. --- src/common/sts.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/common/sts.c b/src/common/sts.c index d5dae4bf..9d57a905 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -553,15 +553,7 @@ sts_handle_capability (struct server *serv, const char *value) { if (!has_port) { - if (serv->port > 0) - { - port = (guint16) serv->port; - has_port = TRUE; - } - else - { - return FALSE; - } + return FALSE; } #ifdef USE_OPENSSL if (serv->sts_upgrade_in_progress) From b09e6a54055b39928dfa4928db0c7684eee76bb8 Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 10:30:13 -0700 Subject: [PATCH 09/22] Updated STS policy handling to require an active connection port when already on TLS, ignoring any advertised port token before storing the profile. --- src/common/sts.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/sts.c b/src/common/sts.c index 9d57a905..010904dc 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -593,14 +593,15 @@ sts_handle_capability (struct server *serv, const char *value) { time_t now = time (NULL); time_t expires_at = now + (time_t) duration; - guint16 effective_port = serv->port > 0 ? (guint16) serv->port : port; + guint16 effective_port = 0; sts_profile *profile; - if (effective_port == 0) + if (serv->port <= 0) { return FALSE; } + effective_port = (guint16) serv->port; profile = sts_profile_new (hostname, effective_port, expires_at, duration, has_preload ? preload : FALSE); sts_profile_store (profile); From 3d8d3958ea27fe2388753c0976c941d49f03a97d Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 11:35:40 -0700 Subject: [PATCH 10/22] Updated STS parsing to treat duplicate port, duration, or preload keys as invalid by returning FALSE immediately when repeats are encountered. --- src/common/sts.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/common/sts.c b/src/common/sts.c index 010904dc..b336615d 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -338,7 +338,13 @@ sts_parse_value (const char *value, guint16 *port, guint64 *duration, gboolean * { gint64 port_value; - if (*has_port || !val) + if (*has_port) + { + g_strfreev (tokens); + return FALSE; + } + + if (!val) { continue; } @@ -354,7 +360,13 @@ sts_parse_value (const char *value, guint16 *port, guint64 *duration, gboolean * { guint64 duration_value; - if (*has_duration || !val) + if (*has_duration) + { + g_strfreev (tokens); + return FALSE; + } + + if (!val) { continue; } @@ -367,7 +379,8 @@ sts_parse_value (const char *value, guint16 *port, guint64 *duration, gboolean * { if (*has_preload) { - continue; + g_strfreev (tokens); + return FALSE; } *preload = TRUE; *has_preload = TRUE; From b9bc65e3c21c2a113d9c66ec8aae30dd0b7bc2ad Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 11:39:20 -0700 Subject: [PATCH 11/22] Updated STS parsing to only accept preload when it appears without a value, ignoring tokens like preload=0. --- src/common/sts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/sts.c b/src/common/sts.c index b336615d..6dd4869f 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -377,7 +377,7 @@ sts_parse_value (const char *value, guint16 *port, guint64 *duration, gboolean * } else if (!g_ascii_strcasecmp (key, "preload")) { - if (*has_preload) + if (*has_preload || val) { g_strfreev (tokens); return FALSE; From 78a00b5b880f4b3d7476f1ce57aadb0882427502 Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 11:57:54 -0700 Subject: [PATCH 12/22] Updated STS policy handling to preserve any existing stored port on secure updates rather than overwriting it from the current TLS port, keeping secure-path updates focused on duration/preload. --- src/common/sts.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/sts.c b/src/common/sts.c index 6dd4869f..17ea0823 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -607,14 +607,15 @@ sts_handle_capability (struct server *serv, const char *value) time_t now = time (NULL); time_t expires_at = now + (time_t) duration; guint16 effective_port = 0; + sts_profile *existing_profile; sts_profile *profile; - if (serv->port <= 0) + existing_profile = sts_profile_lookup (hostname, now); + if (existing_profile) { - return FALSE; + effective_port = existing_profile->port; } - effective_port = (guint16) serv->port; profile = sts_profile_new (hostname, effective_port, expires_at, duration, has_preload ? preload : FALSE); sts_profile_store (profile); From eae5a209d384cf065c314262ce3af46ba8669796 Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 11:58:13 -0700 Subject: [PATCH 13/22] Updated STS parsing to ignore preload tokens that include a value while preserving duplicate-preload rejection for valid tokens. --- src/common/sts.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/common/sts.c b/src/common/sts.c index 17ea0823..82c57ed2 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -377,7 +377,12 @@ sts_parse_value (const char *value, guint16 *port, guint64 *duration, gboolean * } else if (!g_ascii_strcasecmp (key, "preload")) { - if (*has_preload || val) + if (val) + { + continue; + } + + if (*has_preload) { g_strfreev (tokens); return FALSE; From 2ecf1c18fb897158dea1fb206bfd734b465b3815 Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 12:41:32 -0700 Subject: [PATCH 14/22] Added STS value parsing in CAP ACK handling so sts= capability values are applied immediately before toggling capabilities. --- src/common/inbound.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/common/inbound.c b/src/common/inbound.c index fc1fa3cc..081b3185 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1713,6 +1713,26 @@ void inbound_cap_ack (server *serv, char *nick, char *extensions, const message_tags_data *tags_data) { + if (extensions) + { + char **tokens = g_strsplit (extensions, " ", 0); + int i; + + for (i = 0; tokens[i]; i++) + { + char **parts = g_strsplit (tokens[i], "=", 2); + + if (!g_strcmp0 (parts[0], "sts") && parts[1] && parts[1][0]) + { + sts_handle_capability (serv, parts[1]); + } + + g_strfreev (parts); + } + + g_strfreev (tokens); + } + EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions, NULL, NULL, 0, tags_data->timestamp); From 3d030a96b7291454fb196b0842dbf0b3cf03e96c Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 12:42:04 -0700 Subject: [PATCH 15/22] =?UTF-8?q?Updated=20sts=5Fhandle=5Fcapability=20to?= =?UTF-8?q?=20return=20FALSE=20after=20logging=20the=20no=E2=80=91TLS=20wa?= =?UTF-8?q?rning,=20so=20the=20insecure=20upgrade=20path=20doesn=E2=80=99t?= =?UTF-8?q?=20stop=20capability=20negotiation;=20it=20still=20returns=20TR?= =?UTF-8?q?UE=20only=20when=20an=20STS=20upgrade/reconnect=20is=20initiate?= =?UTF-8?q?d=20or=20already=20in=20progress.=20Confirmed=20inbound=5Fcap?= =?UTF-8?q?=5Fls=20only=20returns=20early=20when=20sts=5Fupgrade=5Ftrigger?= =?UTF-8?q?ed=20is=20set=20by=20sts=5Fhandle=5Fcapability,=20which=20now?= =?UTF-8?q?=20only=20happens=20for=20real=20upgrade/reconnect=20initiation?= =?UTF-8?q?=20or=20in=E2=80=91progress=20upgrades.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/sts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/sts.c b/src/common/sts.c index 82c57ed2..eef2a71b 100644 --- a/src/common/sts.c +++ b/src/common/sts.c @@ -588,12 +588,13 @@ sts_handle_capability (struct server *serv, const char *value) serv->disconnect (serv->server_session, FALSE, -1); serv->connect (serv, host_copy, (int) port, serv->no_login); } + return TRUE; #else PrintTextf (serv->server_session, _("STS upgrade requested for %s, but TLS is not available.\n"), hostname); + return FALSE; #endif - return TRUE; } if (!has_duration) From f58785c2e0aafbf4cde65a357c4cc5d1c8508289 Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 12:42:22 -0700 Subject: [PATCH 16/22] Added an explicit diagnostic when an STS capability token lacks a value while keeping the ignore policy unchanged. --- src/common/inbound.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/inbound.c b/src/common/inbound.c index 081b3185..d3fd4139 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1900,6 +1900,11 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, { sts_upgrade_triggered |= sts_handle_capability (serv, value); } + else + { + PrintTextf (serv->server_session, + _("Invalid STS capability token without value")); + } continue; } From 983ae5337b9932b9572fb80e79d9535556af8aa9 Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 12:57:07 -0700 Subject: [PATCH 17/22] Added a diagnostic message when an STS capability token is missing its value, while keeping the ignore behavior intact. --- src/common/inbound.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/inbound.c b/src/common/inbound.c index d3fd4139..169d1689 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1903,7 +1903,11 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, else { PrintTextf (serv->server_session, +<<<<<<< ours _("Invalid STS capability token without value")); +======= + _("Invalid STS capability token without a value; ignoring.")); +>>>>>>> theirs } continue; } From 9aba312c8e4d5bfeda6873c6e98822222d24662b Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 4 Feb 2026 13:13:51 -0700 Subject: [PATCH 18/22] Resolved the merge conflict in STS capability handling by keeping the clearer warning message for missing values. --- src/common/inbound.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index 169d1689..6cb27ba3 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1903,11 +1903,7 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, else { PrintTextf (serv->server_session, -<<<<<<< ours - _("Invalid STS capability token without value")); -======= _("Invalid STS capability token without a value; ignoring.")); ->>>>>>> theirs } continue; } From 1e21f2b1480461c83654db29483b8f5ac3ff415b Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:19:02 -0700 Subject: [PATCH 19/22] Update SourceDir from 'rel' to 'release' --- win32/installer/zoitechat.iss.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/installer/zoitechat.iss.tt b/win32/installer/zoitechat.iss.tt index 14de669c..4dc1ba31 100644 --- a/win32/installer/zoitechat.iss.tt +++ b/win32/installer/zoitechat.iss.tt @@ -28,7 +28,7 @@ DefaultGroupName=ZoiteChat AllowNoIcons=yes SolidCompression=yes Compression=lzma2/ultra64 -SourceDir=..\rel +SourceDir=..\release OutputDir=.. #if APPARCH == "x64" OutputBaseFilename={#APPNAM}-{#APPVER}_x64 From 1c8db65b201467e2d4f069f1ce2985076412c3c1 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:20:06 -0700 Subject: [PATCH 20/22] Change SourceDir path in installer script --- win32/installer/zoitechat.iss.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/installer/zoitechat.iss.tt b/win32/installer/zoitechat.iss.tt index 4dc1ba31..14de669c 100644 --- a/win32/installer/zoitechat.iss.tt +++ b/win32/installer/zoitechat.iss.tt @@ -28,7 +28,7 @@ DefaultGroupName=ZoiteChat AllowNoIcons=yes SolidCompression=yes Compression=lzma2/ultra64 -SourceDir=..\release +SourceDir=..\rel OutputDir=.. #if APPARCH == "x64" OutputBaseFilename={#APPNAM}-{#APPVER}_x64 From 5c7991e873417ca3c935fd16c32f72bf0c98b18a Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:51:03 -0700 Subject: [PATCH 21/22] Update gio-2.0 and GLib version requirements --- meson.build | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index 63e53231..e83882cc 100644 --- a/meson.build +++ b/meson.build @@ -13,7 +13,7 @@ gnome = import('gnome') cc = meson.get_compiler('c') -libgio_dep = dependency('gio-2.0', version: '>= 2.36.0') +libgio_dep = dependency('gio-2.0', version: '>= 2.86.0') libgmodule_dep = dependency('gmodule-2.0') libcanberra_dep = dependency('libcanberra', version: '>= 0.22', @@ -47,8 +47,8 @@ config_h.set('G_DISABLE_SINGLE_INCLUDES', true) config_h.set('GTK_DISABLE_DEPRECATED', true) config_h.set('GTK_DISABLE_SINGLE_INCLUDES', true) config_h.set('GDK_PIXBUF_DISABLE_SINGLE_INCLUDES', true) -config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_36') -config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_36') +config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_86') +config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_84') # Detected features config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr')) From 65411b8ccb48bcb1123af8022229c5883aba9a05 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:53:17 -0700 Subject: [PATCH 22/22] Update gio-2.0 and GLib version requirements --- meson.build | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index e83882cc..63e53231 100644 --- a/meson.build +++ b/meson.build @@ -13,7 +13,7 @@ gnome = import('gnome') cc = meson.get_compiler('c') -libgio_dep = dependency('gio-2.0', version: '>= 2.86.0') +libgio_dep = dependency('gio-2.0', version: '>= 2.36.0') libgmodule_dep = dependency('gmodule-2.0') libcanberra_dep = dependency('libcanberra', version: '>= 0.22', @@ -47,8 +47,8 @@ config_h.set('G_DISABLE_SINGLE_INCLUDES', true) config_h.set('GTK_DISABLE_DEPRECATED', true) config_h.set('GTK_DISABLE_SINGLE_INCLUDES', true) config_h.set('GDK_PIXBUF_DISABLE_SINGLE_INCLUDES', true) -config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_86') -config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_84') +config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_36') +config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_36') # Detected features config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr'))