mounriverstudio-bin
The package downloads a prebuilt binary from a dynamically generated URL obtained via an API call to api.mounriver.com, which is not in the source array and uses a non-standard host, creating a supply-chain risk if the API or download URL is compromised.
Triggered rules
external_download_not_in_source
curl/wget fetches a URL on a non-allowlisted host that is not part of source=(), so it is not checksum-verified by makepkg.
-
PKGBUILD:74
local _info_json=$(curl -s "https://api.mounriver.com/mountriver/api/version/fetchRecent2?swType=2&osType=LINUX&lang=en") -
PKGBUILD:88
local _dl_json=$(curl -s "https://api.mounriver.com/mountriver/api/version/getDownloadUrl?resourceId=${_soft_id}")
source_untrusted_domain
One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).
-
PKGBUILD:67
source=('https://ipfs.io/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH')
llm_review
An AI model (qwen/qwen3-235b-a22b-07-25) reviewed this and agrees it is MEDIUM (confidence 95%): The package downloads a prebuilt binary from a dynamically generated URL obtained via an API call to api.mounriver.com, which is not in the source array and uses a non-standard host, creating a supply-chain risk if the API or download URL is compromised.
PKGBUILD
3 offending line(s) highlighted# Maintainer: taotieren <admin@taotieren.com>
# Contributor: t3u <t3u@t3u.uk>
pkgbase=mounriverstudio-bin
pkgname=(${pkgbase})
pkgdesc="MounRiver Studio Ⅱ(MRS2)为MounRiver Studio的换代版本,从V2.1.0开始,框架更换至更现代的VSCode,并深度定制开发。在工程管理、代码编辑、编译、调试等方面均兼容之前版本,并在效率和功能等方面进行提升,着力将MRS打造为更加轻量化、智能化、高效化的RISC-V IDE。同时,提供Windows/Linux/macOS 以及国产操作系统版本"
pkgver=250
pkgrel=1
arch=('x86_64')
url='http://www.mounriver.com/'
license=('LicenseRef-commercial')
provides=('MounRiverStudio-Linux' ${pkgname%-bin})
conflicts=(${pkgname%-bin})
depends=(
alsa-lib
at-spi2-core
bash
cairo
dbus
expat
gcc-libs
glib2
glibc
gtk3
hidapi
libcups
libdrm
libjaylink
libsecret
libusb
libx11
libxcb
libxcomposite
libxdamage
libxext
libxfixes
libxkbcommon
libxkbfile
libxrandr
libudev.so
nspr
nss
mesa
pango
python
python-pygments
# AUR
# ncurses5-compat-libs
)
makedepends=('tar' 'jq' 'curl')
optdepends=('ch34x-dkms-git: CH341SER driver with fixed bug'
'i2c-ch341-dkms: CH341 USB-I2C adapter driver'
'spi-ch341-usb-dkms: SPI/GPIO driver for CH341'
'ch341eepromtool: An i2c serial EEPROM programming tool for the WCH CH341A'
'ch341prog-git: A simple command line tool (programmer) interfacing with ch341a'
'ch341eeprom-git: A libusb based programming tool for 24xx I²C EEPROMs using the WCH CH341A'
'ch343ser-dkms: USB serial driver for ch342/ch343/ch344/ch347/ch347f/ch9101/ch9102/ch9103/ch9104, etc (dkms).'
'wchisp: WCH ISP Tool in Rust'
"ezp-chip-data-editor: QT based editor chip database for EZP2019, EZP2019+, EZP2020, EZP2023, EZP2025, MinPro programmer devices"
"imsprog: MSProg - software for CH341A-based programmers to work with I2C, SPI and MicroWire EEPROM/Flash chips"
"sfp-master: SFP-module programmer for CH341a devices"
)
# empty dummy file hosted on IPFS to satisfy updpkgsums/lilac checks
# the content hash is guaranteed to be immutable
# the real source file is downloaded dynamically in prepare() due to short-lived URL signatures
source=('https://ipfs.io/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH')
sha256sums=('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
options=('!strip' '!debug')
# automatic version detection & download via MounRiver API
prepare() {
msg "Querying MounRiver API for the latest Linux version..."
local _info_json=$(curl -s "https://api.mounriver.com/mountriver/api/version/fetchRecent2?swType=2&osType=LINUX&lang=en")
local _soft_id=$(echo "${_info_json}" | jq -r '.result[0].upgradeRelationBoList[] | select(.softFileType == 1) | .softReId')
local _filename=$(echo "${_info_json}" | jq -r '.result[0].upgradeRelationBoList[] | select(.softFileType == 1) | .softFileName')
local _api_version=$(echo "${_info_json}" | jq -r '.result[0].version')
if [[ "${_soft_id}" == "null" || -z "${_soft_id}" ]]; then
error "Failed to retrieve software ID from API."
return 1
fi
msg "Found Version: ${_api_version} (File: ${_filename}, ID: ${_soft_id})"
msg "Fetching dynamic download link..."
local _dl_json=$(curl -s "https://api.mounriver.com/mountriver/api/version/getDownloadUrl?resourceId=${_soft_id}")
local _dl_url=$(echo "${_dl_json}" | jq -r '.data // .result')
if [[ "${_dl_url}" == "null" || -z "${_dl_url}" || "${_dl_url}" != http* ]]; then
error "Failed to retrieve valid download URL."
return 1
fi
if [ ! -f "${_filename}" ]; then
msg "Downloading ${_filename}..."
curl -L -o "${_filename}" "${_dl_url}"
else
msg "File ${_filename} already exists, skipping download."
fi
# Cleanup old extraction
local _old_dir=$(find . -maxdepth 1 -mindepth 1 -type d -print -quit)
if [ -n "$_old_dir" ]; then
rm -rf "$_old_dir"
fi
msg "Extracting ${_filename}..."
tar -xf "${_filename}"
}
package() {
cd "${srcdir}/"
local _extracted_dir=$(find . -maxdepth 1 -mindepth 1 -type d -print -quit)
if [[ -z "${_extracted_dir}" ]]; then
error "Extracted directory not found!"
return 1
fi
msg "Installing from: ${_extracted_dir}"
mkdir -p "${pkgdir}/usr/share"
cp -r "${_extracted_dir}" "${pkgdir}/usr/share/MRS2"
msg "Fixing permissions..."
find "${pkgdir}/usr/share/MRS2" -type d -exec chmod 755 {} \;
find "${pkgdir}/usr/share/MRS2" -perm 600 -exec chmod 644 {} \;
cd "${pkgdir}/usr/share/MRS2"
if [ -d "beforeinstall" ]; then
msg "Installing udev rules..."
sed -i 's|plugdev|uucp|g' beforeinstall/50-wch.rules
sed -i 's|plugdev|uucp|g' beforeinstall/60-openocd.rules
install -Dm0644 "beforeinstall/50-wch.rules" "${pkgdir}/usr/lib/udev/rules.d/50-mrs2.rules"
install -Dm0644 "beforeinstall/60-openocd.rules" "${pkgdir}/usr/lib/udev/rules.d/60-openocd-mrs2.rules"
install -Dm0755 "beforeinstall/load.sh" "${pkgdir}/usr/bin/${pkgname%-bin}"
msg "Cleaning up beforeinstall directory..."
rm -rf "beforeinstall"
fi
local _res_path="MRS-linux-x64/resources/app/resources/linux/components/WCH/Others/CommunicationLib/default"
if [ -d "${_res_path}" ]; then
sed -i 's|plugdev|uucp|g' ${_res_path}/50-wch.rules
sed -i 's|plugdev|uucp|g' ${_res_path}/60-openocd.rules
fi
msg "Generating Desktop Entry..."
local _icon_src="MRS-linux-x64/resources/app/resources/linux/code.png"
if [ -f "${_icon_src}" ]; then
install -Dm644 "${_icon_src}" "${pkgdir}/usr/share/pixmaps/MounRiverStudio2.png"
fi
install -Dm644 /dev/stdin "${pkgdir}/usr/share/applications/mounriverstudio.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=MounRiver Studio Ⅱ
Exec=/usr/bin/${pkgname%-bin} %F
Icon=MounRiverStudio2
MimeType=application/x-mrs-project;
Comment=MounRiver Stduio Ⅱ is a free integrated development environment for embedded MCU.
Categories=TextEditor;Development;IDE;
EOF
msg "Creating OpenOCD wrappers..."
install -Dm0755 /dev/stdin "${pkgdir}/usr/bin/openocd-mrs2-arm" <<EOF
#!/bin/env bash
exec /usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/OpenOCD/OpenOCD/bin/openocd -f /usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/OpenOCD/OpenOCD/bin/wch-arm.cfg "\$@"
EOF
install -Dm0755 /dev/stdin "${pkgdir}/usr/bin/openocd-mrs2-riscv" <<EOF
#!/bin/env bash
exec /usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/OpenOCD/OpenOCD/bin/openocd -f /usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/OpenOCD/OpenOCD/bin/wch-riscv.cfg "\$@"
EOF
install -Dm0644 /dev/stdin "${pkgdir}/etc/profile.d/${pkgname%-bin}.sh" <<EOF
#!/bin/sh
[ -d '/usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/Toolchain/RISC-V Embedded GCC12/bin/' ] && append_path '/usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/Toolchain/RISC-V Embedded GCC12/bin/'
[ -d '/usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/Toolchain/RISC-V Embedded GCC/bin/' ] && append_path '/usr/share/MRS2/MRS-linux-x64/resources/app/resources/linux/components/WCH/Toolchain/RISC-V Embedded GCC/bin/'
export PATH
EOF
}
# vim: ts=4 sw=4 et
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-09-17 00:27:14 | Medium | 3 |
| 2026-09-16 00:03:17 | Medium | 3 |
| 2026-09-15 00:25:31 | Medium | 3 |
| 2026-09-14 00:27:57 | Medium | 3 |
| 2026-09-13 00:19:54 | Medium | 3 |
| 2026-09-12 00:25:17 | Medium | 3 |
| 2026-09-11 00:19:22 | Medium | 3 |
| 2026-09-10 00:22:44 | Medium | 3 |
| 2026-09-09 00:04:09 | Medium | 3 |
| 2026-09-08 00:18:08 | Medium | 3 |
| 2026-09-07 00:30:15 | Medium | 3 |
| 2026-09-06 00:17:06 | Medium | 3 |
| 2026-09-05 00:16:27 | Medium | 3 |
| 2026-09-04 00:03:13 | Medium | 3 |
| 2026-09-03 00:15:47 | Medium | 3 |
| 2026-09-02 00:02:31 | Medium | 3 |
| 2026-09-01 00:11:19 | Medium | 3 |
| 2026-08-31 00:19:57 | Medium | 3 |
| 2026-08-30 00:04:14 | Medium | 3 |
| 2026-08-29 00:29:17 | Medium | 3 |