Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lang/mrustc/Portfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set rust_version_major_underscore [join [lrange [split ${rust_version} .-] 0 1]

# Subport mrustc-rust has its own versioning
version ${rust_version_major}-20260802
revision 0
revision 1
epoch 1

categories lang devel
Expand Down Expand Up @@ -164,6 +164,7 @@ pre-patch {
system -W ${workpath}/${name}-${github.version} "patch -p1 < [shellescape ${filespath}/0023-hir_typeck-find-trait-object-methods-through-custom-.patch]"
system -W ${workpath}/${name}-${github.version} "patch -p1 < [shellescape ${filespath}/0024-hir_typeck-bind-path-ivars-against-non-generic-impls.patch]"
system -W ${workpath}/${name}-${github.version} "patch -p1 < [shellescape ${filespath}/0025-toml-decode-u-U-escapes-to-real-UTF-8.patch]"
system -W ${workpath}/${name}-${github.version} "patch -p1 < [shellescape ${filespath}/0026-minicargo-Preserve-the-semver-pre-release-suffix-in-.patch]"
# Patch the Rust source code with the patch included with mrustc:
system -W ${workpath}/rustc-${rust_version}-src "patch -p0 < [shellescape ${worksrcpath}/rustc-${rust_version}-src.patch]"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
From 0ef4515caa7185727a069de5996cd07c7a5c3c74 Mon Sep 17 00:00:00 2001
From: Dani Sarfati <dani@funkervogt.com>
Date: Fri, 7 Aug 2026 18:59:59 -0400
Subject: [PATCH] minicargo: Preserve the semver pre-release suffix in
CARGO_PKG_VERSION

`PackageVersion::from_string` parsed the `+build` suffix but not `-prerelease`,
so `3.0.0-alpha.2` silently became plain `3.0.0`. Build scripts that derive an
identifier from CARGO_PKG_VERSION then generate the wrong name: protobuf's
build.rs emits `VERSION_3_0_0` while its codegen'd .rs files reference
`VERSION_3_0_0_ALPHA_2`, which fails to resolve.

The new `prerelease` field is deliberately not part of `cmp`/`operator==` --
pre-release ordering rules are subtle and changing resolution behaviour is a
separate concern. It is exposed only through `to_string_full()`, used for
CARGO_PKG_VERSION; `operator<<` is unchanged so crate tags and output filenames
do not churn.
---
tools/minicargo/build.cpp | 3 ++-
tools/minicargo/manifest.cpp | 10 +++++++++-
tools/minicargo/manifest.h | 15 ++++++++++++++-
3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp
index 3b1dd2a9..f6141bfd 100644
--- a/tools/minicargo/build.cpp
+++ b/tools/minicargo/build.cpp
@@ -743,7 +743,8 @@ namespace {
{
env.push_back("CARGO_MANIFEST_DIR", manifest.directory().to_absolute());
env.push_back("CARGO_PKG_NAME", manifest.name());
- env.push_back("CARGO_PKG_VERSION", ::format(manifest.version()));
+ // Full form: build scripts derive identifiers from this
+ env.push_back("CARGO_PKG_VERSION", manifest.version().to_string_full());
env.push_back("CARGO_PKG_VERSION_MAJOR", ::format(manifest.version().major));
env.push_back("CARGO_PKG_VERSION_MINOR", ::format(manifest.version().minor));
env.push_back("CARGO_PKG_VERSION_PATCH", ::format(manifest.version().patch));
diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp
index b3b80644..8696ac56 100644
--- a/tools/minicargo/manifest.cpp
+++ b/tools/minicargo/manifest.cpp
@@ -1560,7 +1560,15 @@ PackageVersion PackageVersion::from_string(const ::std::string& s)
rv.patch = 0;
rv.patch_set = false;
}
- if(iss.peek() == '+') {
+ // Semver is `-prerelease` then `+build`
+ if(iss.peek() == '-') {
+ iss.get();
+ ::std::getline(iss, rv.prerelease, '+');
+ if(!iss.eof()) { // getline ate the '+'
+ iss >> rv.free_text;
+ }
+ }
+ else if(iss.peek() == '+') {
iss.get();
iss >> rv.free_text;
}
diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h
index 545ae38a..e7583a2e 100644
--- a/tools/minicargo/manifest.h
+++ b/tools/minicargo/manifest.h
@@ -36,7 +36,8 @@ struct PackageVersion
unsigned minor;
unsigned patch;
bool patch_set;
- std::string free_text;
+ std::string free_text; // Semver `+build`
+ std::string prerelease; // Semver `-prerelease`; not part of ordering

explicit PackageVersion()
: major(0), minor(0), patch(0), patch_set(false) {}
@@ -114,6 +115,18 @@ struct PackageVersion
}
return os;
}
+
+ /// Full version string, for CARGO_PKG_VERSION (`operator<<` feeds crate tags)
+ std::string to_string_full() const {
+ std::string rv = std::to_string(major) + "." + std::to_string(minor);
+ if(patch_set)
+ rv += "." + std::to_string(patch);
+ if(!prerelease.empty())
+ rv += "-" + prerelease;
+ if(!free_text.empty())
+ rv += "+" + free_text;
+ return rv;
+ }
};
struct PackageVersionSpec
{
--
2.43.0

143 changes: 143 additions & 0 deletions net/rustdesk-ppc-agent/Portfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem 1.0
PortGroup github 1.0
PortGroup cargo 1.0

# The agent is a subdirectory of a RustDesk fork rather than a repository of its
# own, so three things are set by hand:
# - the tag is prefixed `ppc-agent-`, to keep it clear of upstream RustDesk's
# own 1.x tags on the same fork;
# - `name` is set, because github.setup would otherwise call this port
# `rustdesk`, which it is not;
# - `worksrcdir` descends into the subdirectory. GitHub names an archive
# directory `<repo>-<tag>`, so tag `ppc-agent-0.1.0` of repo `rustdesk`
# unpacks to `rustdesk-ppc-agent-0.1.0/`.
github.setup danifunker rustdesk 0.1.0 ppc-agent-
name rustdesk-ppc-agent
distname rustdesk-ppc-agent-0.1.0
worksrcdir ${distname}/rustdesk-ppc-agent
revision 0
categories net
license GPL-3
maintainers {@danifunker gmail.com:danifunkervogt} \
openmaintainer

# 32-bit only: the capture path is CGDisplayBaseAddress and the input path is
# CGPostMouseEvent, and the whole thing is built and tested as ppc.
supported_archs ppc
installs_libs no

description RustDesk agent (controlled side) for PowerPC Mac OS X

long_description A minimal RustDesk agent for PowerPC Macs: it serves screen, \
keyboard, mouse and clipboard to a standard RustDesk client, \
over a direct connection or a rendezvous server. This is the \
controlled side only -- there is no GUI client. The protocol \
is reimplemented against RustDesk's own .proto files rather \
than ported from upstream's tokio-based tree, which is what \
keeps the dependency graph at ~30 crates and inside the \
subset of Rust mrustc handles.

github.tarball_from archive

checksums ${distname}${extract.suffix} \
rmd160 4b56a05c1e2d67c134cffec6ed19d989f388e848 \
sha256 9dbc60b8acfa92dbffcc7b87ee87dea69593042f8a686665ec9a0b25b0cbdbcc \
size 758541

# libvpx VP8 encode (the agent links it statically)
# libsodium the RustDesk handshake (via sodiumoxide)
# zstd, zlib clipboard decompression from modern peers
depends_lib-append port:libvpx \
port:libsodium \
port:zstd \
port:zlib

# AltiVec is not optional for this port: both libvpx's encoder paths and the
# agent's own C shims use it, so a G3 cannot run the result. See the upstream
# BACKLOG section 13 for the measurements.

cargo.offline_cmd

# protobuf 3.0.0-alpha.2's BufReadIter::read_exact_to_vec reserves capacity and
# then indexes past the end of a zero-length slice -- UB on a length taken
# straight off the wire. It survives a release build but aborts under the debug
# assertions this toolchain builds libstd with.
patch.dir ${workpath}
patchfiles protobuf-3.0.0-alpha.2.patch

# SODIUM_LIB_DIR libsodium-sys looks here rather than running pkg-config
# PPC_LIBS_DIR build.rs turns this into -L for the statically linked libs
build.env-append SODIUM_LIB_DIR=${prefix}/lib \
PPC_LIBS_DIR=${prefix}/lib

cargo.crates \
block-buffer 0.10.4 3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71 \
cc 1.4.0 5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9 \
cfg-if 1.0.4 9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801 \
cpufeatures 0.2.17 59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280 \
crypto-common 0.1.7 78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a \
digest 0.10.7 9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292 \
ed25519 1.5.3 91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7 \
find-msvc-tools 0.1.9 5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582 \
generic-array 0.14.7 85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a \
libc 0.2.174 1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776 \
libsodium-sys 0.2.7 6b779387cd56adfbc02ea4a668e704f729be8d6a6abd2c27ca5ee537849a92fd \
log 0.4.33 0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad \
pkg-config 0.3.33 19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e \
proc-macro2 1.0.107 985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9 \
protobuf 3.0.0-alpha.2 9d5ef59c35c7472ce5e1b6c5924b87585143d1fc2cf39eae0009bba6c4df62f1 \
quote 1.0.47 1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001 \
same-file 1.0.6 93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502 \
serde 1.0.229 4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba \
serde_core 1.0.229 67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48 \
serde_derive 1.0.229 e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348 \
sha2 0.10.9 a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283 \
shlex 2.0.1 f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba \
signature 1.6.4 74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c \
sodiumoxide 0.2.7 e26be3acb6c2d9a7aac28482586a7856436af4cfe7100031d219de2d2ecb0028 \
syn 3.0.3 53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3 \
typenum 1.20.1 b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20 \
unicode-ident 1.0.24 e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75 \
version_check 0.9.5 0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a \
walkdir 2.5.0 29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b \
winapi-util 0.1.11 c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22 \
windows-link 0.2.1 f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5 \
windows-sys 0.61.2 ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc

destroot {
xinstall -m 0755 \
${worksrcpath}/target/[cargo.rust_platform]/release/rustdesk-agent \
${destroot}${prefix}/bin/

# A launchd *agent* template, not a startupitem. The agent has to run inside
# the logged-in user's Aqua session: PasteboardCreate returns -4960 from an
# ssh login or a detached screen, so a LaunchDaemon serves a session with no
# working clipboard. Installed as a template because it is per-user and the
# binary path has to be substituted in.
xinstall -d ${destroot}${prefix}/share/${name}
xinstall -m 0644 ${worksrcpath}/deploy/com.rustdesk.ppc-agent.plist.in \
${destroot}${prefix}/share/${name}/
xinstall -m 0644 ${worksrcpath}/README.md \
${destroot}${prefix}/share/${name}/
}

notes "
To run the agent at login, install the LaunchAgent template into your own\
account and substitute the paths:

mkdir -p ~/Library/LaunchAgents
sed -e 's|@BIN@|${prefix}/bin/rustdesk-agent|' \\
-e 's|@LOG@|'\$HOME'/rustdesk-ppc-agent/agent.log|' \\
-e 's|@PORT@|21118|' \\
${prefix}/share/${name}/com.rustdesk.ppc-agent.plist.in \\
> ~/Library/LaunchAgents/com.rustdesk.ppc-agent.plist
launchctl load ~/Library/LaunchAgents/com.rustdesk.ppc-agent.plist

It must be a LaunchAgent rather than a LaunchDaemon: the clipboard only works\
inside the logged-in Aqua session. This starts the agent at *login*, not at\
boot, so a Mac meant to be reachable unattended needs automatic login enabled.

This is the controlled side only. Connect to it with a standard RustDesk client.
"
37 changes: 37 additions & 0 deletions net/rustdesk-ppc-agent/files/protobuf-3.0.0-alpha.2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
protobuf 3.0.0-alpha.2: fix out-of-bounds indexing in the wire-parse path

`BufReadIter::read_exact_to_vec` calls `reserve_exact(count)` and then
`get_unchecked_mut(..count)`. `reserve_exact` grows *capacity*, not length, so
at that point `target.len()` is 0 and the range is past the end of the slice.
It happens to work in a release build because the allocation is real, but it is
undefined behaviour, and `count` comes straight off the wire.

libstd as built by the mrustc port has debug assertions enabled, so std's
precondition check fires and aborts:

unsafe precondition(s) violated: slice::get_unchecked_mut requires that the
range is within the slice

Replaced with a safe `resize`, which costs one memset of a buffer that is about
to be overwritten anyway.

--- .home/.cargo/macports/protobuf-3.0.0-alpha.2/src/buf_read_iter.rs
+++ .home/.cargo/macports/protobuf-3.0.0-alpha.2/src/buf_read_iter.rs
@@ -352,12 +352,11 @@
}
}
} else {
- target.reserve_exact(count);
-
- unsafe {
- self.read_exact(&mut target.get_unchecked_mut(..count))?;
- target.set_len(count);
- }
+ // `reserve_exact` grows capacity, not length, so the original
+ // `get_unchecked_mut(..count)` here indexed past the end of a
+ // zero-length slice - UB on a wire-controlled length.
+ target.resize(count, 0);
+ self.read_exact(&mut target[..count])?;
}

debug_assert_eq!(count, target.len());